Makes Greentea TCP test cases to timeout less in connection errors

Made to prevent timeout if a single test case fails. The goal is that
each test case might wait only half of the remaining time reserved for
running TCP test cases.
pull/7578/head
Veijo Pesonen 2018-07-23 12:12:19 +03:00
parent be215a310d
commit dd6ec037d7
10 changed files with 174 additions and 44 deletions

View File

@ -32,6 +32,7 @@ using namespace utest::v1;
namespace
{
NetworkInterface* net;
Timer tc_bucket; // Timer to limit a test cases run time
}
char tcp_global::rx_buffer[RX_BUFF_SIZE];
@ -66,24 +67,32 @@ static void _ifdown() {
printf("MBED: ifdown\n");
}
void tcpsocket_connect_to_echo_srv(TCPSocket& sock) {
nsapi_error_t tcpsocket_connect_to_echo_srv(TCPSocket& sock) {
SocketAddress tcp_addr;
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr));
nsapi_error_t err = sock.open(get_interface());
if (err != NSAPI_ERROR_OK) {
return err;
}
return sock.connect(tcp_addr);
}
void tcpsocket_connect_to_discard_srv(TCPSocket& sock) {
nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket& sock) {
SocketAddress tcp_addr;
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
tcp_addr.set_port(9);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr));
nsapi_error_t err = sock.open(get_interface());
if (err != NSAPI_ERROR_OK) {
return err;
}
return sock.connect(tcp_addr);
}
void fill_tx_buffer_ascii(char *buff, size_t len)
@ -93,16 +102,23 @@ void fill_tx_buffer_ascii(char *buff, size_t len)
}
}
int split2half_rmng_tcp_test_time()
{
return (tcp_global::TESTS_TIMEOUT-tc_bucket.read())/2;
}
// Test setup
utest::v1::status_t greentea_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(480, "default_auto");
GREENTEA_SETUP(tcp_global::TESTS_TIMEOUT, "default_auto");
_ifup();
tc_bucket.start();
return greentea_test_setup_handler(number_of_cases);
}
void greentea_teardown(const size_t passed, const size_t failed, const failure_t failure)
{
tc_bucket.stop();
_ifdown();
return greentea_test_teardown_handler(passed, failed, failure);
}

View File

@ -21,11 +21,17 @@
NetworkInterface* get_interface();
void drop_bad_packets(TCPSocket& sock, int orig_timeout);
void fill_tx_buffer_ascii(char *buff, size_t len);
void tcpsocket_connect_to_echo_srv(TCPSocket& sock);
void tcpsocket_connect_to_discard_srv(TCPSocket& sock);
nsapi_error_t tcpsocket_connect_to_echo_srv(TCPSocket& sock);
nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket& sock);
/**
* Single testcase might take only half of the remaining execution time
*/
int split2half_rmng_tcp_test_time(); // [s]
namespace tcp_global
{
static const int TESTS_TIMEOUT = 480;
static const int TCP_OS_STACK_SIZE = 1024;
static const int RX_BUFF_SIZE = 1220;

View File

@ -37,6 +37,9 @@ namespace
1100,1200};
TCPSocket sock;
Semaphore tx_sem(0, 1);
Timer tc_exec_time;
int time_allotted;
}
static void _sigio_handler(osThreadId id) {
@ -45,7 +48,10 @@ static void _sigio_handler(osThreadId id) {
void TCPSOCKET_ECHOTEST()
{
tcpsocket_connect_to_echo_srv(sock);
if (tcpsocket_connect_to_echo_srv(sock) != NSAPI_ERROR_OK) {
TEST_FAIL();
return;
}
int recvd;
int sent;
@ -57,6 +63,8 @@ void TCPSOCKET_ECHOTEST()
if (sent < 0) {
printf("[Round#%02d] network error %d\n", x, sent);
TEST_FAIL();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
return;
}
int bytes2recv = sent;
@ -65,6 +73,8 @@ void TCPSOCKET_ECHOTEST()
if (recvd < 0) {
printf("[Round#%02d] network error %d\n", x, recvd);
TEST_FAIL();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
return;
}
bytes2recv -= recvd;
}
@ -80,10 +90,15 @@ void tcpsocket_echotest_nonblock_receiver(void *receive_bytes)
while (bytes2recv) {
recvd = sock.recv(&(tcp_global::rx_buffer[*(int*)receive_bytes-bytes2recv]), bytes2recv);
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
if (tc_exec_time.read() >= time_allotted) {
TEST_FAIL();
break;
}
wait(1);
continue;
} else if (recvd < 0) {
TEST_FAIL();
break;
}
bytes2recv -= recvd;
}
@ -99,6 +114,9 @@ void tcpsocket_echotest_nonblock_receiver(void *receive_bytes)
void TCPSOCKET_ECHOTEST_NONBLOCK()
{
tc_exec_time.start();
time_allotted = split2half_rmng_tcp_test_time(); // [s]
tcpsocket_connect_to_echo_srv(sock);
sock.set_blocking(false);
sock.sigio(callback(_sigio_handler, Thread::gettid()));
@ -124,19 +142,30 @@ void TCPSOCKET_ECHOTEST_NONBLOCK()
while (bytes2send > 0) {
sent = sock.send(&(tcp_global::tx_buffer[pkt_s-bytes2send]), bytes2send);
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
TEST_ASSERT_NOT_EQUAL(osEventTimeout, osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status);
if (tc_exec_time.read() >= time_allotted ||
osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
thread->terminate();
delete thread;
TEST_FAIL();
goto END;
}
continue;
} else if (sent <= 0) {
printf("[Sender#%02d] network error %d\n", s_idx, sent);
thread->terminate();
delete thread;
TEST_FAIL();
goto END;
}
bytes2send -= sent;
}
printf("[Sender#%02d] bytes sent: %d\n", s_idx, pkt_s);
tx_sem.wait();
tx_sem.wait(split2half_rmng_tcp_test_time());
thread->join();
delete thread;
}
END:
tc_exec_time.stop();
free(stack_mem);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}

View File

@ -57,11 +57,13 @@ void TCPSOCKET_ECHOTEST_BURST()
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
TEST_FAIL();
goto END;
}
continue;
} else if (sent < 0) {
printf("[%02d] network error %d\n", i, sent);
TEST_FAIL();
goto END;
}
bt_left -= sent;
}
@ -79,10 +81,12 @@ void TCPSOCKET_ECHOTEST_BURST()
if (bt_left != 0) {
drop_bad_packets(sock, 0);
TEST_FAIL();
goto END;
}
TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, BURST_SIZE));
}
END:
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}
@ -106,15 +110,20 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK()
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
TEST_FAIL();
goto END;
}
continue;
} else if (sent < 0) {
printf("[%02d] network error %d\n", i, sent);
TEST_FAIL();
goto END;
}
bt_left -= sent;
}
TEST_ASSERT_EQUAL(0, bt_left);
if (bt_left != 0) {
TEST_FAIL();
goto END;
}
bt_left = BURST_SIZE;
while (bt_left > 0) {
@ -136,9 +145,11 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK()
printf("network error %d, missing %d bytes from a burst\n", recvd, bt_left);
drop_bad_packets(sock, -1);
TEST_FAIL();
goto END;
}
TEST_ASSERT_EQUAL(0, memcmp(tcp_global::tx_buffer, tcp_global::rx_buffer, BURST_SIZE));
}
END:
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}

View File

@ -35,14 +35,18 @@ static void _sigio_handler(osThreadId id) {
osSignalSet(id, SIGNAL_SIGIO);
}
static void _tcpsocket_connect_to_daytime_srv(TCPSocket& sock) {
static nsapi_error_t _tcpsocket_connect_to_daytime_srv(TCPSocket& sock) {
SocketAddress tcp_addr;
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
tcp_addr.set_port(13);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr));
nsapi_error_t err = sock.open(get_interface());
if (err != NSAPI_ERROR_OK) {
return err;
}
return sock.connect(tcp_addr);
}
@ -50,9 +54,15 @@ void TCPSOCKET_ENDPOINT_CLOSE()
{
static const int MORE_THAN_AVAILABLE = 30;
char buff[MORE_THAN_AVAILABLE];
int time_allotted = split2half_rmng_tcp_test_time(); // [s]
Timer tc_exec_time;
tc_exec_time.start();
TCPSocket sock;
_tcpsocket_connect_to_daytime_srv(sock);
if (_tcpsocket_connect_to_daytime_srv(sock) != NSAPI_ERROR_OK) {
TEST_FAIL();
return;
}
sock.sigio(callback(_sigio_handler, Thread::gettid()));
int recvd = 0;
@ -61,16 +71,20 @@ void TCPSOCKET_ENDPOINT_CLOSE()
recvd = sock.recv(&(buff[recvd_total]), MORE_THAN_AVAILABLE);
if (recvd_total > 0 && recvd == 0) {
break; // Endpoint closed socket, success
} else if (recvd == 0) {
} else if (recvd <= 0) {
TEST_FAIL();
break;
} else if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
if(tc_exec_time.read() >= time_allotted ||
osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
TEST_FAIL();
break;
}
continue;
}
recvd_total += recvd;
TEST_ASSERT(recvd_total < MORE_THAN_AVAILABLE);
}
tc_exec_time.stop();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}

View File

@ -31,14 +31,19 @@ namespace
static const int SIGIO_TIMEOUT = 20000; //[ms]
}
static void _tcpsocket_connect_to_chargen_srv(TCPSocket& sock) {
static nsapi_error_t _tcpsocket_connect_to_chargen_srv(TCPSocket& sock)
{
SocketAddress tcp_addr;
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
tcp_addr.set_port(19);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(tcp_addr));
nsapi_error_t err = sock.open(get_interface());
if (err != NSAPI_ERROR_OK) {
return err;
}
return sock.connect(tcp_addr);
}
/** Generate RFC 864 example pattern.
@ -86,35 +91,46 @@ void rcv_n_chk_against_rfc864_pattern(TCPSocket& sock) {
uint8_t buff[buff_size];
size_t recvd_size = 0;
Timer timer;
timer.start();
// Verify received data
while (recvd_size < total_size) {
int rd = sock.recv(buff, buff_size);
TEST_ASSERT(rd > 0);
if (rd < 0) {
break;
}
check_RFC_864_pattern(buff, rd, recvd_size);
recvd_size += rd;
}
timer.stop();
printf("MBED: Time taken: %fs\n", timer.read());
}
void TCPSOCKET_RECV_100K()
{
TCPSocket sock;
_tcpsocket_connect_to_chargen_srv(sock);
if (_tcpsocket_connect_to_chargen_srv(sock) != NSAPI_ERROR_OK) {
TEST_FAIL();
return;
}
Timer timer;
timer.start();
rcv_n_chk_against_rfc864_pattern(sock);
timer.stop();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
printf("MBED: Time taken: %fs\n", timer.read());
}
void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket& sock) {
void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket& sock)
{
static const size_t total_size = 1024 * 100;
static const size_t buff_size = 1220;
uint8_t buff[buff_size];
size_t recvd_size = 0;
int time_allotted = split2half_rmng_tcp_test_time(); // [s]
Timer timer;
timer.start();
// Verify received data
while (recvd_size < total_size) {
@ -124,9 +140,18 @@ void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket& sock) {
check_RFC_864_pattern(buff, rd, recvd_size);
recvd_size += rd;
} else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
if (timer.read() >= time_allotted) {
TEST_FAIL();
break;
}
TEST_ASSERT_NOT_EQUAL(osEventTimeout, osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status);
} else {
TEST_FAIL();
break;
}
}
timer.stop();
printf("MBED: Time taken: %fs\n", timer.read());
}
static void _sigio_handler(osThreadId id) {
@ -135,17 +160,18 @@ static void _sigio_handler(osThreadId id) {
void TCPSOCKET_RECV_100K_NONBLOCK()
{
TCPSocket sock;
_tcpsocket_connect_to_chargen_srv(sock);
TCPSocket sock;
nsapi_error_t err = _tcpsocket_connect_to_chargen_srv(sock);
if (err != NSAPI_ERROR_OK) {
TEST_FAIL();
return;
}
sock.set_blocking(false);
sock.sigio(callback(_sigio_handler, Thread::gettid()));
Timer timer;
timer.start();
rcv_n_chk_against_rfc864_pattern_nonblock(sock);
timer.stop();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
printf("MBED: Time taken: %fs\n", timer.read());
}

View File

@ -39,6 +39,9 @@ void TCPSOCKET_RECV_TIMEOUT()
{
static const int DATA_LEN = 100;
char buff[DATA_LEN] = {0};
int time_allotted = split2half_rmng_tcp_test_time(); // [s]
Timer tc_exec_time;
tc_exec_time.start();
TCPSocket sock;
tcpsocket_connect_to_echo_srv(sock);
@ -59,8 +62,10 @@ void TCPSOCKET_RECV_TIMEOUT()
timer.stop();
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
if (tc_exec_time.read() >= time_allotted ||
(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout)) {
TEST_FAIL();
goto CLEANUP;
}
printf("MBED: recv() took: %dms\n", timer.read_ms());
TEST_ASSERT_INT_WITHIN(50, 150, timer.read_ms());
@ -68,9 +73,13 @@ void TCPSOCKET_RECV_TIMEOUT()
} else if (recvd < 0) {
printf("[pkt#%02d] network error %d\n", i, recvd);
TEST_FAIL();
goto CLEANUP;
}
pkt_unrecvd -= recvd;
}
}
CLEANUP:
tc_exec_time.stop();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}

View File

@ -30,12 +30,15 @@ void TCPSOCKET_SEND_REPEAT()
TCPSocket sock;
tcpsocket_connect_to_discard_srv(sock);
int err;
int snd;
Timer timer;
static const char tx_buffer[] = {'h','e','l','l','o'};
for (int i = 0; i < 1000; i++) {
err = sock.send(tx_buffer, sizeof(tx_buffer));
TEST_ASSERT_EQUAL(sizeof(tx_buffer), err);
snd = sock.send(tx_buffer, sizeof(tx_buffer));
if (snd != sizeof(tx_buffer)) {
TEST_FAIL();
break;
}
}
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());

View File

@ -28,7 +28,10 @@ using namespace utest::v1;
void TCPSOCKET_SEND_TIMEOUT()
{
TCPSocket sock;
tcpsocket_connect_to_discard_srv(sock);
if (tcpsocket_connect_to_discard_srv(sock) != NSAPI_ERROR_OK) {
TEST_FAIL();
return;
}
int err;
Timer timer;
@ -38,8 +41,12 @@ void TCPSOCKET_SEND_TIMEOUT()
timer.start();
err = sock.send(tx_buffer, sizeof(tx_buffer));
timer.stop();
TEST_ASSERT_EQUAL(sizeof(tx_buffer), err);
TEST_ASSERT(timer.read_ms() <= 800);
if ((err == sizeof(tx_buffer)) &&
(timer.read_ms() <= 800)) {
continue;
}
TEST_FAIL();
break;
}
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());

View File

@ -65,11 +65,13 @@ static void check_const_len_rand_sequence()
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO1, SIGIO_TIMEOUT).status == osEventTimeout) {
TEST_FAIL();
goto END;
}
continue;
} else if (sent < 0) {
printf("network error %d\n", sent);
TEST_FAIL();
goto END;
}
bytes2process -= sent;
}
@ -82,6 +84,7 @@ static void check_const_len_rand_sequence()
} else if (recvd < 0) {
printf("network error %d\n", recvd);
TEST_FAIL();
goto END;
}
bytes2process -= recvd;
}
@ -89,9 +92,11 @@ static void check_const_len_rand_sequence()
if (bytes2process != 0) {
drop_bad_packets(sock, 0);
TEST_FAIL();
goto END;
}
TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, BUFF_SIZE));
}
END:
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}
@ -117,11 +122,13 @@ static void check_var_len_rand_sequence()
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
if(osSignalWait(SIGNAL_SIGIO2, SIGIO_TIMEOUT).status == osEventTimeout) {
TEST_FAIL();
goto END;
}
continue;
} else if (sent < 0) {
printf("[%02d] network error %d\n", i, sent);
TEST_FAIL();
goto END;
}
bytes2process -= sent;
}
@ -134,6 +141,7 @@ static void check_var_len_rand_sequence()
} else if (recvd < 0) {
printf("[%02d] network error %d\n", i, recvd);
TEST_FAIL();
goto END;
}
bytes2process -= recvd;
}
@ -141,10 +149,11 @@ static void check_var_len_rand_sequence()
if (bytes2process != 0) {
drop_bad_packets(sock, 0);
TEST_FAIL();
goto END;
}
TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, i));
}
END:
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}