fixed buffer management in case of packet fragmentation; improved test pattern with pseudo random to avoid pattern simulation

Fork of NSAPITests by Licio Mapelli

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NSAPITests.cpp Source File

NSAPITests.cpp

00001 #include "NetworkStack.h"
00002 #include "TCPSocket.h"
00003 #include "UDPSocket.h"
00004 #include <stdio.h>
00005 #include "string.h"
00006 
00007 #define NSAPI_MAX_DATA_SIZE 2048
00008 #define NSAPI_TEST_HOST "mbed.org"
00009 #define NSAPI_TEST_IP   "8.8.4.4"
00010 
00011 uint8_t tx_test_buffer[NSAPI_MAX_DATA_SIZE];
00012 uint8_t rx_test_buffer[NSAPI_MAX_DATA_SIZE];
00013 
00014 int nsapi_networkstack_get_ip_address_test(NetworkStack *stack)
00015 {
00016     if (!stack->get_ip_address()[0]) {
00017         printf("error: 'get_ip_address()' did not return an IP address\r\n");
00018         return -1;
00019     }
00020 
00021     return 0;
00022 }
00023 
00024 int nsapi_networkstack_gethostbyname_test(NetworkStack *stack, SocketAddress *address, const char *test_host)
00025 {
00026     int ret = stack->gethostbyname(address, NSAPI_TEST_HOST);
00027 
00028     if (ret) {
00029         printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", NSAPI_TEST_HOST, ret);
00030         return -1;
00031     } else if (!address) {
00032         printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", NSAPI_TEST_HOST);
00033         return -2;
00034     }
00035 
00036     ret = stack->gethostbyname(address, NSAPI_TEST_IP);
00037 
00038     if (ret) {
00039         printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", NSAPI_TEST_IP, ret);
00040         return -1;
00041     } else if (!address) {
00042         printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", NSAPI_TEST_IP);
00043         return -2;
00044     }
00045 
00046     ret = stack->gethostbyname(address, test_host);
00047 
00048     if (ret) {
00049         printf("error: 'gethostbyname(\"%s\")' failed with code %d\r\n", test_host, ret);
00050         return -1;
00051     } else if (!address) {
00052         printf("error: 'gethostbyname(\"%s\")' returned null IP address\r\n", test_host);
00053         return -2;
00054     }
00055 
00056     return 0;
00057 }
00058 
00059 static void nsapi_buffer_init(uint8_t *buffer, unsigned size)
00060 {
00061     for (unsigned i = 0; i < size; i++) {
00062         buffer[i] = rand() % 256;
00063     }
00064 }
00065 
00066 static bool nsapi_buffer_check(const uint8_t *buffer, unsigned size)
00067 {
00068     for (unsigned i = 0; i < size; i++) {
00069         if (buffer[i] != tx_test_buffer[i]) {
00070             return false;
00071         }
00072     }
00073 
00074     return true;
00075 }
00076 
00077 static void nsapi_tcp_flush(TCPSocket *socket)
00078 {
00079     socket->set_timeout(1000);
00080     socket->recv(rx_test_buffer, sizeof rx_test_buffer);
00081     socket->set_timeout(-1);
00082 }
00083 
00084 int nsapi_tcp_open_test(TCPSocket *udp, NetworkStack *stack)
00085 {
00086     int ret = udp->open(stack);
00087 
00088     if (ret) {
00089         printf("error: 'open(%p)' failed with code %d\r\n", stack, ret);
00090         return -1;
00091     } else {
00092         return 0;
00093     }
00094 }
00095 
00096 int nsapi_tcp_connect_test(TCPSocket *tcp, SocketAddress *addr)
00097 {
00098     int ret = tcp->connect(*addr);
00099 
00100     if (ret) {
00101         printf("error: 'connect(SocketAddress(%s, %d))' failed with code %d\r\n",
00102                 addr->get_ip_address(), addr->get_port(), ret);
00103         return -1;
00104     } else {
00105         return 0;
00106     }
00107 }
00108 
00109 static int nsapi_tcp_blocking_test_helper(TCPSocket *tcp, unsigned size)
00110 {
00111     unsigned total;
00112     nsapi_tcp_flush(tcp);
00113     nsapi_buffer_init(tx_test_buffer, size);
00114 
00115     for (total = 0; total < size;) {
00116         int ret = tcp->send(tx_test_buffer+total, size-total);
00117 
00118         if (ret < 0) {
00119             printf("error: 'send(buffer, %d)' failed during test with code %d\r\n", size, ret);
00120             return -1;
00121         }
00122 
00123         total += ret;
00124     }
00125     
00126     memset(rx_test_buffer, 0, size);    
00127     for (total = 0; total < size;) {
00128         int ret = tcp->recv(rx_test_buffer+total, (sizeof rx_test_buffer)-total);
00129 
00130         if (ret < 0) {
00131             printf("error: 'recv(buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00132             return -2;
00133         }
00134 
00135         total += ret;
00136     }
00137 
00138     if (total != size || !nsapi_buffer_check(rx_test_buffer, size)) {
00139         printf("error: 'recv(buffer, %d)' recieved incorrect data with length %d\r\n", sizeof rx_test_buffer, total);
00140         return -3;
00141     }
00142 
00143     return 0;
00144 }
00145 
00146 int nsapi_tcp_blocking_test(TCPSocket *tcp)
00147 {
00148     for (unsigned size = 64; size <= NSAPI_MAX_DATA_SIZE; size *= 2) {
00149         printf("%s: size %d\r\n", __func__, size);
00150 
00151         int ret = nsapi_tcp_blocking_test_helper(tcp, size);
00152         if (ret) {
00153             return ret;
00154         }
00155     }
00156 
00157     return 0;
00158 }
00159 
00160 static int nsapi_tcp_non_blocking_test_helper(TCPSocket *tcp, unsigned size)
00161 {
00162     unsigned total;
00163     nsapi_tcp_flush(tcp);
00164     nsapi_buffer_init(tx_test_buffer, size);
00165 
00166     // First check to make sure `recv` will not block and return 0 for bytes received.
00167     tcp->set_blocking(false);
00168     int ret = tcp->recv(rx_test_buffer, sizeof rx_test_buffer);
00169 
00170     if (ret != NSAPI_ERROR_WOULD_BLOCK) {
00171         if (ret < 0) {
00172             printf("error: 'recv(buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00173             return -4;
00174         } else {
00175             printf("error: 'recv(buffer, %d)' returned %d when no data was expected\r\n", sizeof rx_test_buffer, ret);
00176             return -5;
00177         }
00178     }
00179 
00180     for (total = 0; total < size;) {
00181         int ret = tcp->send(tx_test_buffer+total, size-total);
00182 
00183         if (ret < 0) {
00184             printf("error: 'send(buffer, %d)' failed during test with code %d\r\n", size, ret);
00185             return -1;
00186         }
00187 
00188         total += ret;
00189     }
00190 
00191     memset (rx_test_buffer, 0, size);
00192     for (total = 0; total < size;) {
00193         ret = tcp->recv(rx_test_buffer+total, (sizeof rx_test_buffer)-total);
00194 
00195         if (ret == NSAPI_ERROR_WOULD_BLOCK) {
00196             continue;
00197         } else if (ret < 0) {
00198             printf("error: 'recv(buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00199             return -2;
00200         } else {
00201             total += ret;
00202         }
00203     }
00204 
00205     if (total != size || !nsapi_buffer_check(rx_test_buffer, size)) {
00206         printf("error: 'recv(buffer, %d)' recieved incorrect data with length %d\r\n", sizeof rx_test_buffer, total);
00207         return -3;
00208     }
00209     
00210     return 0;
00211 }
00212 
00213 int nsapi_tcp_non_blocking_test(TCPSocket *tcp)
00214 {
00215     for (unsigned size = 64; size <= NSAPI_MAX_DATA_SIZE; size *= 2) {
00216         printf("%s: size %d\r\n", __func__, size);
00217 
00218         int ret = nsapi_tcp_non_blocking_test_helper(tcp, size);
00219         if (ret) {
00220             return ret;
00221         }
00222     }
00223 
00224     return 0;
00225 }
00226 
00227 int nsapi_tcp_close_test(TCPSocket *tcp)
00228 {
00229     int ret = tcp->close();
00230 
00231     if (ret) {
00232         printf("error 'close()' failed with code %d\r\n", ret);
00233         return -1;
00234     } else {
00235         return 0;
00236     }
00237 }
00238 
00239 static void nsapi_udp_flush(UDPSocket *udp)
00240 {
00241     udp->set_timeout(1000);
00242     udp->recvfrom(0, rx_test_buffer, sizeof rx_test_buffer);
00243     udp->set_timeout(-1);
00244 }
00245 
00246 int nsapi_udp_open_test(UDPSocket *udp, NetworkStack *stack)
00247 {
00248     int ret = udp->open(stack);
00249 
00250     if (ret) {
00251         printf("error: 'open(%p)' failed with code %d\r\n", stack, ret);
00252         return -1;
00253     } else {
00254         return 0;
00255     }
00256 }
00257 
00258 static int nsapi_udp_blocking_test_helper(UDPSocket *udp, SocketAddress *addr, unsigned size)
00259 {
00260     unsigned total;
00261     nsapi_udp_flush(udp);
00262     nsapi_buffer_init(tx_test_buffer, size);
00263 
00264     for (total = 0; total < size;) {
00265         int ret = udp->sendto(*addr, tx_test_buffer+total, size-total);
00266 
00267         if (ret < 0) {
00268             printf("error: 'sendto(SocketAddress(%s, %d), buffer, %d)' failed during test with code %d\r\n", 
00269                     addr->get_ip_address(), addr->get_port(), size, ret);
00270             return -1;
00271         }
00272 
00273         total += ret;
00274     }
00275     
00276     memset(rx_test_buffer, 0, size);
00277     for (total = 0; total < size;) {
00278         int ret = udp->recvfrom(0, rx_test_buffer+total, (sizeof rx_test_buffer)-total);
00279 
00280         if (ret < 0) {
00281             printf("error: 'recvfrom(0, buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00282             return -2;
00283         }
00284 
00285         total += ret;
00286     }
00287 
00288     if (total != size || !nsapi_buffer_check(rx_test_buffer, size)) {
00289         printf("error: 'recvfrom(0, buffer, %d)' recieved incorrect data with length %d\r\n", sizeof rx_test_buffer, total);
00290         return -3;
00291     }
00292 
00293     return 0;
00294 }
00295 
00296 int nsapi_udp_blocking_test(UDPSocket *udp, SocketAddress *addr)
00297 {
00298     for (unsigned size = 64; size <= NSAPI_MAX_DATA_SIZE; size *= 2) {
00299         printf("%s: size %d\r\n", __func__, size);
00300 
00301         int ret = nsapi_udp_blocking_test_helper(udp, addr, size);
00302         if (ret) {
00303             return ret;
00304         }
00305     }
00306 
00307     return 0;
00308 }
00309 
00310 int nsapi_udp_non_blocking_test_helper(UDPSocket *udp, SocketAddress *addr, unsigned size)
00311 {
00312     unsigned total;
00313     nsapi_udp_flush(udp);
00314     nsapi_buffer_init(tx_test_buffer, size);
00315 
00316     // First check to make sure `recv` will not block and return 0 for bytes received.
00317     udp->set_blocking(false);
00318     int ret = udp->recvfrom(0, rx_test_buffer, sizeof rx_test_buffer);
00319 
00320     if (ret != NSAPI_ERROR_WOULD_BLOCK) {
00321         if (ret < 0) {
00322             printf("error: 'recvfrom(0, buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00323             return -4;
00324         } else {
00325             printf("error: 'recvfrom(0, buffer, %d)' returned %d when no data was expected\r\n", sizeof rx_test_buffer, ret);
00326             return -5;
00327         }
00328     }
00329 
00330     for (total = 0; total < size;) {
00331         int ret = udp->sendto(*addr, tx_test_buffer+total, size-total);
00332 
00333         if (ret < 0) {
00334             printf("error: 'sendto(SocketAddress(%s, %d), buffer, %d)' failed during test with code %d\r\n", 
00335                     addr->get_ip_address(), addr->get_port(), size, ret);
00336             return -1;
00337         }
00338 
00339         total += ret;
00340     }
00341  
00342     memset(rx_test_buffer, 0, size);
00343     for (total = 0; total < size;) {
00344         ret = udp->recvfrom(0, rx_test_buffer+total, (sizeof rx_test_buffer)-total);
00345 
00346         if (ret == NSAPI_ERROR_WOULD_BLOCK) {
00347             continue;
00348         } else if (ret < 0) {
00349             printf("error: 'recv(buffer, %d)' failed during test with code %d\r\n", sizeof rx_test_buffer, ret);
00350             return -2;
00351         } else {
00352             total += ret;
00353         }
00354     }
00355 
00356     if (total != size || !nsapi_buffer_check(rx_test_buffer, size)) {
00357         printf("error: 'recv(buffer, %d)' recieved incorrect data with length %d\r\n", sizeof rx_test_buffer, total);
00358         return -3;
00359     }
00360     
00361     return 0;
00362 }
00363 
00364 int nsapi_udp_non_blocking_test(UDPSocket *udp, SocketAddress *addr)
00365 {
00366     for (unsigned size = 64; size <= NSAPI_MAX_DATA_SIZE; size *= 2) {
00367         printf("%s: size %d\r\n", __func__, size);
00368 
00369         int ret = nsapi_udp_non_blocking_test_helper(udp, addr, size);
00370         if (ret) {
00371             return ret;
00372         }
00373     }
00374 
00375     return 0;
00376 }
00377 
00378 int nsapi_udp_close_test(UDPSocket *udp)
00379 {
00380     int ret = udp->close();
00381 
00382     if (ret) {
00383         printf("error 'close()' failed with code %d\r\n", ret);
00384         return -1;
00385     } else {
00386         return 0;
00387     }
00388 }
00389 
00390 int nsapi_tests(const char *name, NetworkStack *stack, const char *test_host, uint16_t test_port)
00391 {
00392     SocketAddress address(0, test_port);
00393     TCPSocket tcp;
00394     UDPSocket udp;
00395 
00396     int result = 0;
00397 
00398 #define NSAPI_MARK_TESTS(tests)                                 \
00399     printf("\r\n\r\nRunning %s Tests\r\n\r\n", tests)
00400 
00401 #define NSAPI_RUN_TEST(test, ...)                               \
00402     do {                                                        \
00403         printf("---------------------\r\n");                    \
00404         printf("%s: running...\r\n", #test);                    \
00405         int test##_result = test(__VA_ARGS__);                  \
00406         if (!test##_result) {                                   \
00407             printf("%s: PASS\r\n", #test);                      \
00408         } else {                                                \
00409             printf("%s: FAIL (%d)\r\n", #test, test##_result);  \
00410         }                                                       \
00411         result |= test##_result;                                \
00412     } while (0)
00413 
00414     NSAPI_MARK_TESTS("NetworkStack");
00415     NSAPI_RUN_TEST(nsapi_networkstack_get_ip_address_test, stack);
00416     NSAPI_RUN_TEST(nsapi_networkstack_gethostbyname_test, stack, &address, test_host);
00417 
00418     NSAPI_MARK_TESTS("UDPSocket");
00419     NSAPI_RUN_TEST(nsapi_udp_open_test, &udp, stack);
00420     NSAPI_RUN_TEST(nsapi_udp_blocking_test, &udp, &address);
00421     NSAPI_RUN_TEST(nsapi_udp_non_blocking_test, &udp, &address);
00422     NSAPI_RUN_TEST(nsapi_udp_close_test, &udp);
00423 
00424     NSAPI_MARK_TESTS("TCPSocket");
00425     NSAPI_RUN_TEST(nsapi_tcp_open_test, &tcp, stack);
00426     NSAPI_RUN_TEST(nsapi_tcp_connect_test, &tcp, &address);
00427     NSAPI_RUN_TEST(nsapi_tcp_blocking_test, &tcp);
00428     NSAPI_RUN_TEST(nsapi_tcp_non_blocking_test, &tcp);
00429     NSAPI_RUN_TEST(nsapi_tcp_close_test, &tcp);
00430 
00431     if (result == 0) {
00432         printf("\r\n\r\n--- ALL TESTS PASSING ---\r\n");
00433     } else {
00434         printf("\r\n\r\n--- TEST FAILURES OCCURRED ---\r\n");
00435     }
00436 
00437     return result;
00438 }
00439