naett.c

Tiny cross-platform HTTP / HTTPS client library in C.
git clone git://git.finwo.net/lib/naett.c
Log | Files | Refs | README | LICENSE

test.c (6044B)


      1 #include "../naett.h"
      2 #include <stdlib.h>
      3 #include <unistd.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 
      7 #if __ANDROID__
      8 #include <android/log.h>
      9 #define LOG(...) ((void)__android_log_print(ANDROID_LOG_INFO, "naett", __VA_ARGS__))
     10 #else
     11 #define LOG(...) printf(__VA_ARGS__)
     12 #endif  // __ANDROID__
     13 
     14 int fail(const char* where, const char* message) {
     15     LOG("%s: FAIL - %s\n", where, message);
     16     return 0;
     17 }
     18 
     19 void trace(const char* where, const char* message) {
     20     LOG("%s: %s\n", where, message);
     21 }
     22 
     23 int verifyBody(naettRes* res, const char* expected) {
     24     int bodyLength = 0;
     25     const char* body = naettGetBody(res, &bodyLength);
     26 
     27     if (body != NULL && strncmp(body, expected, bodyLength) != 0) {
     28         LOG("Expected body: [\n%s\n], got body of length %d: [\n%.*s]\n", expected, bodyLength, bodyLength, body);
     29         return fail(__func__, "");
     30     }
     31 
     32     if (strlen(expected) != bodyLength) {
     33         LOG("Body length (%d) does not match expected length (%lu)", bodyLength, (unsigned long)strlen(expected));
     34         return fail(__func__, "");
     35     }
     36 
     37     const char* lengthString = naettGetHeader(res, "Content-Length");
     38     if (lengthString == NULL) {
     39         return fail(__func__, "Expected 'Content-Length' header");
     40     }
     41     const int expectedLength = atoi(lengthString);
     42     if (bodyLength != expectedLength) {
     43         LOG("Received body (%d) and 'Content-Length' (%d) mismatch.", bodyLength, expectedLength);
     44         return fail(__func__, "");
     45     }
     46 
     47     return 1;
     48 }
     49 
     50 int runGETTest(const char* endpoint) {
     51     trace(__func__, "begin");
     52 
     53     char testURL[512];
     54     snprintf(testURL, sizeof(testURL), "%s/get", endpoint);
     55 
     56     naettReq* req = naettRequest(testURL, naettMethod("GET"), naettHeader("accept", "naett/testresult"));
     57     if (req == NULL) {
     58         return fail(__func__, "Failed to create request");
     59     }
     60 
     61     naettRes* res = naettMake(req);
     62     if (res == NULL) {
     63         return fail(__func__, "Failed to make request");
     64     }
     65 
     66     while (!naettComplete(res)) {
     67         usleep(100 * 1000);
     68     }
     69 
     70     int status = naettGetStatus(res);
     71 
     72     if (status < 0) {
     73         return fail(__func__, "Connection failed");
     74     }
     75 
     76     if (!verifyBody(res, "OK")) {
     77         return 0;
     78     }
     79 
     80     if (naettGetStatus(res) != 200) {
     81         return fail(__func__, "Expected 200");
     82     }
     83 
     84     naettClose(res);
     85     naettFree(req);
     86 
     87     trace(__func__, "end");
     88 
     89     return 1;
     90 }
     91 
     92 int runPOSTTest(const char* endpoint) {
     93     trace(__func__, "begin");
     94 
     95     char testURL[512];
     96     snprintf(testURL, sizeof(testURL), "%s/post", endpoint);
     97 
     98     naettReq* req = naettRequest(
     99         testURL, naettMethod("POST"), naettHeader("accept", "naett/testresult"), naettBody("TestRequest!", 12));
    100     if (req == NULL) {
    101         return fail(__func__, "Failed to create request");
    102     }
    103 
    104     naettRes* res = naettMake(req);
    105     if (res == NULL) {
    106         return fail(__func__, "Failed to make request");
    107     }
    108 
    109     while (!naettComplete(res)) {
    110         usleep(100 * 1000);
    111     }
    112 
    113     if (naettGetStatus(res) < 0) {
    114         return fail(__func__, "Connection failed");
    115     }
    116 
    117     if (!verifyBody(res, "OK")) {
    118         return 0;
    119     }
    120 
    121     if (naettGetStatus(res) != 200) {
    122         return fail(__func__, "Expected 200");
    123     }
    124 
    125     naettClose(res);
    126     naettFree(req);
    127 
    128     trace(__func__, "end");
    129 
    130     return 1;
    131 }
    132 
    133 int runRedirectTest(const char* endpoint) {
    134     trace(__func__, "begin");
    135 
    136     char testURL[512];
    137     snprintf(testURL, sizeof(testURL), "%s/redirect", endpoint);
    138 
    139     trace(__func__, "Creating request");
    140     naettReq* req = naettRequest(testURL, naettMethod("GET"));
    141     if (req == NULL) {
    142         return fail(__func__, "Failed to create request");
    143     }
    144 
    145     trace(__func__, "Making request");
    146     naettRes* res = naettMake(req);
    147     if (res == NULL) {
    148         return fail(__func__, "Failed to make request");
    149     }
    150 
    151     trace(__func__, "Waiting for completion");
    152     while (!naettComplete(res)) {
    153         usleep(100 * 1000);
    154     }
    155 
    156     if (naettGetStatus(res) < 0) {
    157         return fail(__func__, "Connection failed");
    158     }
    159 
    160     trace(__func__, "Verifying body");
    161     if (!verifyBody(res, "Redirected")) {
    162         return 0;
    163     }
    164 
    165     if (naettGetStatus(res) != 200) {
    166         return fail(__func__, "Expected 200");
    167     }
    168 
    169     naettClose(res);
    170     naettFree(req);
    171 
    172     trace(__func__, "end");
    173 
    174     return 1;
    175 }
    176 
    177 int runStressTest(const char* endpoint) {
    178     trace(__func__, "begin");
    179 
    180     char testURL[512];
    181     snprintf(testURL, sizeof(testURL), "%s/stress", endpoint);
    182 
    183     naettReq* req = naettRequest(testURL, naettMethod("GET"), naettHeader("accept", "naett/testresult"));
    184     if (req == NULL) {
    185         return fail(__func__, "Failed to create request");
    186     }
    187 
    188     for (int i = 0; i < 8000; i++) {
    189         naettRes* res = naettMake(req);
    190         if (res == NULL) {
    191             return fail(__func__, "Failed to make request");
    192         }
    193 
    194         while (!naettComplete(res)) {
    195             usleep(1 * 1000);
    196         }
    197 
    198         int status = naettGetStatus(res);
    199 
    200         if (status < 0) {
    201             return fail(__func__, "Connection failed");
    202         }
    203 
    204         if (!verifyBody(res, "OK")) {
    205             return 0;
    206         }
    207 
    208         if (naettGetStatus(res) != 200) {
    209             return fail(__func__, "Expected 200");
    210         }
    211 
    212         naettClose(res);
    213     }
    214 
    215     naettFree(req);
    216 
    217     trace(__func__, "end");
    218 
    219     return 1;
    220 }
    221 
    222 int runTests(const char* endpoint) {
    223     if (!runGETTest(endpoint)) {
    224         return 0;
    225     }
    226     if (!runPOSTTest(endpoint)) {
    227         return 0;
    228     }
    229     if (!runRedirectTest(endpoint)) {
    230         return 0;
    231     }
    232     if (!runStressTest(endpoint)) {
    233         return 0;
    234     }
    235     return 1;
    236 }
    237 
    238 #if INCLUDE_MAIN
    239 
    240 int main(int argc, char** argv) {
    241     const char* endpoint = "http://localhost:4711";
    242 
    243     if (argc >= 2) {
    244         endpoint = argv[1];
    245     }
    246 
    247     printf("Running tests using %s\n", endpoint);
    248 
    249     naettInit(NULL);
    250     if (runTests(endpoint)) {
    251         printf("All tests pass OK\n");
    252         return 0;
    253     } else {
    254         printf("Tests failed!\n");
    255         return 1;
    256     }
    257 }
    258 
    259 #endif  // INCLUDE_MAIN