Making udp_echo_parallel test more robust against network issues.

Making the test more forgiven for minor networking issues. Also adding
more debug prints to make it easier to see which packets are coming from
where.
pull/4369/head
Brian Daniels 2017-04-28 11:32:50 -05:00 committed by Martin Kojtal
parent acaf435d64
commit dc87aaad1c
1 changed files with 78 additions and 35 deletions

View File

@ -29,8 +29,20 @@ EthernetInterface net;
SocketAddress udp_addr; SocketAddress udp_addr;
Mutex iomutex; Mutex iomutex;
void prep_buffer(char *tx_buffer, size_t tx_size) { // NOTE: assuming that "id" stays in the single digits
for (size_t i=0; i<tx_size; ++i) { void prep_buffer(int id, char *uuid_buffer, size_t uuid_len, char *tx_buffer, size_t tx_size) {
size_t i = 2;
tx_buffer[0] = '0' + id;
tx_buffer[1] = ' ';
for (; i<uuid_len + 2; ++i) {
tx_buffer[i] = uuid_buffer[i - 2];
}
tx_buffer[i++] = ' ';
for (; i<tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0'; tx_buffer[i] = (rand() % 10) + '0';
} }
} }
@ -44,15 +56,21 @@ private:
UDPSocket sock; UDPSocket sock;
Thread thread; Thread thread;
bool result;
int id;
char *uuid_buffer;
size_t uuid_len;
public: public:
// Limiting stack size to 1k // Limiting stack size to 1k
Echo(): thread(osPriorityNormal, 1024) { Echo(): thread(osPriorityNormal, 1024), result(false) {
} }
void start() { void start(int id, char *uuid_buffer, size_t uuid_len) {
this->id = id;
this->uuid_buffer = uuid_buffer;
this->uuid_len = uuid_len;
osStatus status = thread.start(callback(this, &Echo::echo)); osStatus status = thread.start(callback(this, &Echo::echo));
TEST_ASSERT_EQUAL(osOK, status);
} }
void join() { void join() {
@ -68,69 +86,94 @@ public:
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT); sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
for (int i = 0; i < ECHO_LOOPS; i++) { int i = 0;
prep_buffer(tx_buffer, sizeof(tx_buffer)); while(success < ECHO_LOOPS) {
prep_buffer(id, uuid_buffer, uuid_len, tx_buffer, sizeof(tx_buffer));
const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer)); const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
iomutex.lock(); iomutex.lock();
printf("[%02d] sent...%d Bytes \n", i, ret); printf("[ID:%01d][%02d] sent %d Bytes - %.*s\n", id, i, ret, MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE, tx_buffer);
iomutex.unlock(); iomutex.unlock();
SocketAddress temp_addr; SocketAddress temp_addr;
const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer)); const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
iomutex.lock(); iomutex.lock();
printf("[%02d] recv...%d Bytes \n", i, n); printf("[ID:%01d][%02d] recv %d Bytes - %.*s\n", id, i, ret, MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE, rx_buffer);
iomutex.unlock(); iomutex.unlock();
if ((temp_addr == udp_addr && if ((temp_addr == udp_addr &&
n == sizeof(tx_buffer) && n == sizeof(tx_buffer) &&
memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) { memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
success += 1; success += 1;
iomutex.lock();
printf("[ID:%01d][%02d] success #%d\n", id, i, success);
iomutex.unlock();
} }
i++;
} }
result = success == ECHO_LOOPS;
err = sock.close(); err = sock.close();
TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_EQUAL(0, err);
if (err) {
result = false;
}
}
TEST_ASSERT(success > 3*ECHO_LOOPS/4); bool get_result() {
return result;
} }
}; };
int main() { int main() {
GREENTEA_SETUP(60, "udp_echo"); char uuid[48] = {0};
GREENTEA_SETUP_UUID(60, "udp_echo", uuid, 48);
printf("Got a uuid of %s\r\n", uuid);
size_t uuid_len = strlen(uuid);
Echo echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS]; Echo echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
int err = net.connect(); int err = net.connect();
TEST_ASSERT_EQUAL(0, err); TEST_ASSERT_EQUAL(0, err);
printf("UDP client IP Address is %s\n", net.get_ip_address());
greentea_send_kv("target_ip", net.get_ip_address()); if (err) {
printf("MBED: failed to connect with an error of %d\r\n", err);
GREENTEA_TESTSUITE_RESULT(false);
} else {
printf("UDP client IP Address is %s\n", net.get_ip_address());
char recv_key[] = "host_port"; greentea_send_kv("target_ip", net.get_ip_address());
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("host_ip", " "); char recv_key[] = "host_port";
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf)); char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("host_port", " "); greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf)); greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port); greentea_send_kv("host_port", " ");
udp_addr.set_ip_address(ipbuf); greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
udp_addr.set_port(port); sscanf(portbuf, "%u", &port);
// Startup echo threads in parallel printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) { udp_addr.set_ip_address(ipbuf);
echoers[i].start(); udp_addr.set_port(port);
// Startup echo threads in parallel
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i].start(i, uuid, uuid_len);
}
bool result = true;
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i].join();
result = result && echoers[i].get_result();
}
net.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
} }
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i].join();
}
net.disconnect();
GREENTEA_TESTSUITE_RESULT(true);
} }