mirror of https://github.com/ARMmbed/mbed-os.git
Starts adding more TCP and UDP performance tests
Starts splitting Greentea test suites to TCP and UDP suites and adds more test cases like tcpsocket_echotest_burst tcpsocket_echotest_burst_nonblock tcpsocket_endpoint_close tcpsocket_recv_100k tcpsocket_recv_100k tcpsocket_recv_timeout tcpsocket_send_timeout tcpsocket_thread_per_socket_safety udpsocket_echotest_burst udpsocket_echotest_burst_nonblock udpsocket_recv_timeout udpsocket_sendto_timeoutpull/6665/head
parent
2f410b0ce2
commit
f04f7c1773
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
|
||||
#error [NOT_SUPPORTED] No network configuration found for this target.
|
||||
#endif
|
||||
|
||||
#ifndef MBED_EXTENDED_TESTS
|
||||
#error [NOT_SUPPORTED] Pressure tests are not supported by default
|
||||
#endif
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "utest/utest_stack_trace.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
#ifndef MBED_CFG_TCP_CLIENT_ECHO_TIMEOUT
|
||||
#define MBED_CFG_TCP_CLIENT_ECHO_TIMEOUT 500 //[ms]
|
||||
#endif
|
||||
|
||||
static NetworkInterface* net;
|
||||
|
||||
NetworkInterface* get_interface()
|
||||
{
|
||||
return net;
|
||||
}
|
||||
|
||||
void drop_bad_packets(TCPSocket& sock) {
|
||||
nsapi_error_t err;
|
||||
sock.set_timeout(0);
|
||||
while (true) {
|
||||
err = sock.recv(NULL, 0);
|
||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sock.set_timeout(MBED_CFG_TCP_CLIENT_ECHO_TIMEOUT);
|
||||
}
|
||||
|
||||
static void _ifup() {
|
||||
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
|
||||
nsapi_error_t err = MBED_CONF_APP_CONNECT_STATEMENT;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
|
||||
printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address());
|
||||
}
|
||||
|
||||
static void _ifdown() {
|
||||
net->disconnect();
|
||||
printf("MBED: ifdown\n");
|
||||
}
|
||||
|
||||
void fill_tx_buffer_ascii(char *buff, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i<len; ++i) {
|
||||
buff[i] = (rand() % 43) + '0';
|
||||
}
|
||||
}
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(240, "default_auto");
|
||||
_ifup();
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
void greentea_teardown(const size_t passed, const size_t failed, const failure_t failure)
|
||||
{
|
||||
_ifdown();
|
||||
return greentea_test_teardown_handler(passed, failed, failure);
|
||||
}
|
||||
|
||||
|
||||
Case cases[] = {
|
||||
Case("Echo burst", test_tcpsocket_echotest_burst),
|
||||
Case("Echo burst non-block", test_tcpsocket_echotest_burst_nonblock),
|
||||
Case("Receive 100k from CHARGEN service", test_tcpsocket_recv_100k),
|
||||
Case("Receive 100k from CHARGEN service non-block", test_tcpsocket_recv_100k_nonblock),
|
||||
Case("Receive in given time", test_tcpsocket_recv_timeout),
|
||||
Case("Sending shall not take too long", test_tcpsocket_send_timeout),
|
||||
Case("Parallel socket thread safety", test_tcpsocket_thread_per_socket_safety),
|
||||
Case("Endpoint initiated close", test_tcpsocket_endpoint_close),
|
||||
};
|
||||
|
||||
Specification specification(greentea_setup, cases, greentea_teardown);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !Harness::run(specification);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TCP_TESTS_H
|
||||
#define TCP_TESTS_H
|
||||
|
||||
NetworkInterface* get_interface();
|
||||
void drop_bad_packets(TCPSocket& sock);
|
||||
void fill_tx_buffer_ascii(char *buff, size_t len);
|
||||
|
||||
/*
|
||||
* Test cases
|
||||
*/
|
||||
void test_tcpsocket_echotest_burst();
|
||||
void test_tcpsocket_echotest_burst_nonblock();
|
||||
void test_tcpsocket_endpoint_close();
|
||||
void test_tcpsocket_recv_100k();
|
||||
void test_tcpsocket_recv_100k_nonblock();
|
||||
void test_tcpsocket_recv_timeout();
|
||||
void test_tcpsocket_send_timeout();
|
||||
void test_tcpsocket_thread_per_socket_safety();
|
||||
|
||||
#endif //TCP_TESTS_H
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
#define SIGNAL_SIGIO 0x1
|
||||
#define SIGIO_TIMEOUT 5000 //[ms]
|
||||
|
||||
namespace
|
||||
{
|
||||
static const int BURST_CNT = 100;
|
||||
static const int BURST_SIZE = 1220;
|
||||
char rx_buffer[BURST_SIZE] = {0};
|
||||
char tx_buffer[BURST_SIZE] = {0};
|
||||
}
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
void test_tcpsocket_echotest_burst()
|
||||
{
|
||||
SocketAddress tcp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
|
||||
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
TCPSocket sock;
|
||||
sock.open(get_interface());
|
||||
sock.connect(tcp_addr);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
// TX buffer to be preserved for comparison
|
||||
fill_tx_buffer_ascii(tx_buffer, BURST_SIZE);
|
||||
|
||||
int recvd;
|
||||
int bt_left;
|
||||
int sent;
|
||||
for (int i = 0; i < BURST_CNT; i++) {
|
||||
bt_left = BURST_SIZE;
|
||||
while (bt_left > 0) {
|
||||
sent = sock.send(&(tx_buffer[BURST_SIZE-bt_left]), bt_left);
|
||||
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
continue;
|
||||
} else if (sent < 0) {
|
||||
printf("[%02d] network error %d\n", i, sent);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bt_left -= sent;
|
||||
}
|
||||
|
||||
bt_left = BURST_SIZE;
|
||||
while (bt_left > 0) {
|
||||
recvd = sock.recv(&(rx_buffer[BURST_SIZE-bt_left]), BURST_SIZE);
|
||||
if (recvd < 0) {
|
||||
printf("[%02d] network error %d\n", i, recvd);
|
||||
break;
|
||||
}
|
||||
bt_left -= recvd;
|
||||
}
|
||||
|
||||
if (bt_left != 0) {
|
||||
drop_bad_packets(sock);
|
||||
TEST_FAIL();
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, memcmp(tx_buffer, rx_buffer, BURST_SIZE));
|
||||
}
|
||||
sock.close();
|
||||
}
|
||||
|
||||
void test_tcpsocket_echotest_burst_nonblock()
|
||||
{
|
||||
SocketAddress tcp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
|
||||
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
TCPSocket sock;
|
||||
sock.open(get_interface());
|
||||
sock.connect(tcp_addr);
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
// TX buffer to be preserved for comparison
|
||||
fill_tx_buffer_ascii(tx_buffer, BURST_SIZE);
|
||||
|
||||
int sent;
|
||||
int recvd;
|
||||
int bt_left = 0;
|
||||
for (int i = 0; i < BURST_CNT; i++) {
|
||||
bt_left = BURST_SIZE;
|
||||
while (bt_left > 0) {
|
||||
sent = sock.send(&(tx_buffer[BURST_SIZE-bt_left]), bt_left);
|
||||
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
continue;
|
||||
} else if (sent < 0) {
|
||||
printf("[%02d] network error %d\n", i, sent);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bt_left -= sent;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, bt_left);
|
||||
|
||||
bt_left = BURST_SIZE;
|
||||
while (bt_left > 0) {
|
||||
recvd = sock.recv(&(rx_buffer[BURST_SIZE-bt_left]), BURST_SIZE);
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
printf("[bt#%02d] packet timeout...", i);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
printf("[%02d] network error %d\n", i, recvd);
|
||||
break;
|
||||
}
|
||||
bt_left -= recvd;
|
||||
}
|
||||
|
||||
if (bt_left != 0) {
|
||||
printf("network error %d, missing %d bytes from a burst\n", recvd, bt_left);
|
||||
drop_bad_packets(sock);
|
||||
TEST_FAIL();
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(0, memcmp(tx_buffer, rx_buffer, BURST_SIZE));
|
||||
}
|
||||
sock.close();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace
|
||||
{
|
||||
static const int SIGNAL_SIGIO = 0x1;
|
||||
static const int SIGIO_TIMEOUT = 5000; //[ms]
|
||||
}
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
static void _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));
|
||||
}
|
||||
|
||||
|
||||
void test_tcpsocket_endpoint_close()
|
||||
{
|
||||
static const int MORE_THAN_AVAILABLE = 30;
|
||||
char buff[MORE_THAN_AVAILABLE];
|
||||
|
||||
TCPSocket sock;
|
||||
_tcpsocket_connect_to_daytime_srv(sock);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
int recvd = 0;
|
||||
int recvd_total = 0;
|
||||
while (true) {
|
||||
recvd = sock.recv(&(buff[recvd_total]), MORE_THAN_AVAILABLE);
|
||||
if (recvd_total > 0 && recvd == 0) {
|
||||
break; // Endpoint closed socket, success
|
||||
} else if (recvd == 0) {
|
||||
TEST_FAIL();
|
||||
} else if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
recvd_total += recvd;
|
||||
TEST_ASSERT(recvd_total < MORE_THAN_AVAILABLE);
|
||||
}
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
#define SIGNAL_SIGIO 0x1
|
||||
#define SIGIO_TIMEOUT 20000 //[ms]
|
||||
|
||||
static void _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));
|
||||
}
|
||||
|
||||
/** Generate RFC 864 example pattern.
|
||||
*
|
||||
* Pattern is 72 character lines of the ASCII printing characters ending with "\r\n".
|
||||
* There are 95 printing characters in the ASCII character set.
|
||||
* Example: `nc echo.mbedcloudtesting.com 19 | dd bs=1 count=222`
|
||||
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg
|
||||
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgh
|
||||
* "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghi
|
||||
*
|
||||
* NOTE: Pattern starts with space, not !
|
||||
*
|
||||
* \param offset Start pattern from offset
|
||||
* \param len Length of pattern to generate.
|
||||
*/
|
||||
static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len)
|
||||
{
|
||||
while (len--) {
|
||||
if (offset % 74 == 72)
|
||||
*buf++ = '\r';
|
||||
else if (offset % 74 == 73)
|
||||
*buf++ = '\n';
|
||||
else
|
||||
*buf++ = ' ' + (offset%74 + offset/74) % 95 ;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
static void check_RFC_864_pattern(void *rx_buff, const size_t len, const size_t offset)
|
||||
{
|
||||
void *ref_buff = malloc(len);
|
||||
TEST_ASSERT_NOT_NULL(ref_buff);
|
||||
|
||||
generate_RFC_864_pattern(offset, (uint8_t*)ref_buff, len);
|
||||
bool match = memcmp(ref_buff, rx_buff, len) == 0;
|
||||
|
||||
free(ref_buff);
|
||||
TEST_ASSERT(match);
|
||||
}
|
||||
|
||||
void rcv_n_chk_against_rfc864_pattern(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;
|
||||
|
||||
// Verify received data
|
||||
while (recvd_size < total_size) {
|
||||
int rd = sock.recv(buff, buff_size);
|
||||
TEST_ASSERT(rd > 0);
|
||||
check_RFC_864_pattern(buff, rd, recvd_size);
|
||||
recvd_size += rd;
|
||||
}
|
||||
}
|
||||
|
||||
void test_tcpsocket_recv_100k()
|
||||
{
|
||||
TCPSocket sock;
|
||||
_tcpsocket_connect_to_chargen_srv(sock);
|
||||
|
||||
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) {
|
||||
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;
|
||||
|
||||
// Verify received data
|
||||
while (recvd_size < total_size) {
|
||||
int rd = sock.recv(buff, buff_size);
|
||||
TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
|
||||
if (rd > 0) {
|
||||
check_RFC_864_pattern(buff, rd, recvd_size);
|
||||
recvd_size += rd;
|
||||
} else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
TEST_ASSERT_NOT_EQUAL(osEventTimeout, osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
void test_tcpsocket_recv_100k_nonblock()
|
||||
{
|
||||
TCPSocket sock;
|
||||
_tcpsocket_connect_to_chargen_srv(sock);
|
||||
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());
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
#define SIGNAL_SIGIO 0x1
|
||||
#define SIGIO_TIMEOUT 5000 //[ms]
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
void test_tcpsocket_recv_timeout()
|
||||
{
|
||||
SocketAddress tcp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &tcp_addr);
|
||||
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
static const int DATA_LEN = 100;
|
||||
char buff[DATA_LEN] = {0};
|
||||
|
||||
TCPSocket sock;
|
||||
sock.open(get_interface());
|
||||
sock.connect(tcp_addr);
|
||||
sock.set_timeout(100);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
int recvd = 0;
|
||||
int pkt_unrecvd;
|
||||
Timer timer;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
pkt_unrecvd = DATA_LEN;
|
||||
TEST_ASSERT_EQUAL(DATA_LEN, sock.send(buff, DATA_LEN));
|
||||
|
||||
while (pkt_unrecvd) {
|
||||
timer.reset();
|
||||
timer.start();
|
||||
recvd = sock.recv(&(buff[DATA_LEN-pkt_unrecvd]), pkt_unrecvd);
|
||||
timer.stop();
|
||||
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
printf("MBED: recv() took: %dms\n", timer.read_ms());
|
||||
TEST_ASSERT_INT_WITHIN(50, (100+200)/2, timer.read_ms());
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
printf("[pkt#%02d] network error %d\n", i, recvd);
|
||||
TEST_FAIL();
|
||||
}
|
||||
pkt_unrecvd -= recvd;
|
||||
}
|
||||
}
|
||||
sock.close();
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
void test_tcpsocket_send_timeout()
|
||||
{
|
||||
TCPSocket sock;
|
||||
sock.open(get_interface());
|
||||
sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, 9);
|
||||
|
||||
int err;
|
||||
Timer timer;
|
||||
static const char tx_buffer[] = {'h','e','l','l','o'};
|
||||
for (int i = 0; i < 10; i++) {
|
||||
timer.reset();
|
||||
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);
|
||||
}
|
||||
sock.close();
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "TCPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "tcp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
#define SIGNAL_SIGIO1 0x1
|
||||
#define SIGNAL_SIGIO2 0x2
|
||||
#define SIGIO_TIMEOUT 5000 //[ms]
|
||||
|
||||
Thread thread;
|
||||
static volatile bool running = true;
|
||||
|
||||
static void _sigio_handler1(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO1);
|
||||
}
|
||||
|
||||
static void _sigio_handler2(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO2);
|
||||
}
|
||||
|
||||
static void check_const_len_rand_sequence()
|
||||
{
|
||||
TCPSocket sock;
|
||||
sock.open(get_interface());
|
||||
sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
sock.sigio(callback(_sigio_handler1, Thread::gettid()));
|
||||
|
||||
static const int BUFF_SIZE = 10;
|
||||
char rx_buff[BUFF_SIZE] = {0};
|
||||
char tx_buff[BUFF_SIZE] = {0};
|
||||
|
||||
|
||||
int bytes2process;
|
||||
int recvd;
|
||||
int sent;
|
||||
while (running) {
|
||||
fill_tx_buffer_ascii(tx_buff, BUFF_SIZE);
|
||||
bytes2process = BUFF_SIZE;
|
||||
while (bytes2process > 0) {
|
||||
sent = sock.send(&(tx_buff[BUFF_SIZE-bytes2process]), bytes2process);
|
||||
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO1, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
continue;
|
||||
} else if (sent < 0) {
|
||||
printf("network error %d\n", sent);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bytes2process -= sent;
|
||||
}
|
||||
|
||||
bytes2process = BUFF_SIZE;
|
||||
while (bytes2process > 0) {
|
||||
recvd = sock.recv(&(rx_buff[BUFF_SIZE-bytes2process]), bytes2process);
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
printf("network error %d\n", recvd);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bytes2process -= recvd;
|
||||
}
|
||||
|
||||
if (bytes2process != 0) {
|
||||
drop_bad_packets(sock);
|
||||
TEST_FAIL();
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, BUFF_SIZE));
|
||||
}
|
||||
sock.close();
|
||||
}
|
||||
|
||||
static void check_var_len_rand_sequence()
|
||||
{
|
||||
TCPSocket sock;
|
||||
|
||||
sock.open(get_interface());
|
||||
sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
sock.sigio(callback(_sigio_handler2, Thread::gettid()));
|
||||
|
||||
static const int BUFF_SIZE = 1001;
|
||||
char rx_buff[BUFF_SIZE];
|
||||
char tx_buff[BUFF_SIZE];
|
||||
static const int pkt_size_diff = 100;
|
||||
|
||||
int bytes2process;
|
||||
int recvd;
|
||||
int sent;
|
||||
for (int i = BUFF_SIZE; i > 0; i -= pkt_size_diff) {
|
||||
fill_tx_buffer_ascii(tx_buff, i);
|
||||
bytes2process = i;
|
||||
while (bytes2process > 0) {
|
||||
sent = sock.send(&(tx_buff[i-bytes2process]), bytes2process);
|
||||
if (sent == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO2, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
TEST_FAIL();
|
||||
}
|
||||
continue;
|
||||
} else if (sent < 0) {
|
||||
printf("[%02d] network error %d\n", i, sent);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bytes2process -= sent;
|
||||
}
|
||||
|
||||
bytes2process = i;
|
||||
while (bytes2process > 0) {
|
||||
recvd = sock.recv(&(rx_buff[i-bytes2process]), bytes2process);
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
printf("[%02d] network error %d\n", i, recvd);
|
||||
TEST_FAIL();
|
||||
}
|
||||
bytes2process -= recvd;
|
||||
}
|
||||
|
||||
if (bytes2process != 0) {
|
||||
drop_bad_packets(sock);
|
||||
TEST_FAIL();
|
||||
}
|
||||
TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, i));
|
||||
}
|
||||
|
||||
sock.close();
|
||||
}
|
||||
|
||||
void test_tcpsocket_thread_per_socket_safety()
|
||||
{
|
||||
thread.start(callback(check_const_len_rand_sequence));
|
||||
|
||||
check_var_len_rand_sequence();
|
||||
|
||||
running = false;
|
||||
thread.join();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
|
||||
#error [NOT_SUPPORTED] No network configuration found for this target.
|
||||
#endif
|
||||
|
||||
#ifndef MBED_EXTENDED_TESTS
|
||||
#error [NOT_SUPPORTED] Pressure tests are not supported by default
|
||||
#endif
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "utest/utest_stack_trace.h"
|
||||
#include "udp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace
|
||||
{
|
||||
NetworkInterface* net;
|
||||
}
|
||||
|
||||
NetworkInterface* get_interface()
|
||||
{
|
||||
return net;
|
||||
}
|
||||
|
||||
static void _ifup() {
|
||||
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
|
||||
nsapi_error_t err = MBED_CONF_APP_CONNECT_STATEMENT;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
|
||||
printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address());
|
||||
}
|
||||
|
||||
static void _ifdown() {
|
||||
net->disconnect();
|
||||
printf("MBED: ifdown\n");
|
||||
}
|
||||
|
||||
void fill_tx_buffer_ascii(char *buff, size_t len)
|
||||
{
|
||||
for (size_t i = 0; i<len; ++i) {
|
||||
buff[i] = (rand() % 43) + '0';
|
||||
}
|
||||
}
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(120, "default_auto");
|
||||
_ifup();
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
void greentea_teardown(const size_t passed, const size_t failed, const failure_t failure)
|
||||
{
|
||||
_ifdown();
|
||||
return greentea_test_teardown_handler(passed, failed, failure);
|
||||
}
|
||||
|
||||
|
||||
Case cases[] = {
|
||||
Case("Echo burst", test_udpsocket_echotest_burst),
|
||||
Case("Echo burst non-block", test_udpsocket_echotest_burst_nonblock),
|
||||
Case("Receive in given time", test_udpsocket_recv_timeout),
|
||||
Case("Send in given time", test_udpsocket_sendto_timeout),
|
||||
|
||||
};
|
||||
|
||||
Specification specification(greentea_setup, cases, greentea_teardown);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !Harness::run(specification);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef UDP_TESTS_H
|
||||
#define UDP_TESTS_H
|
||||
|
||||
NetworkInterface* get_interface();
|
||||
void fill_tx_buffer_ascii(char *buff, size_t len);
|
||||
|
||||
/*
|
||||
* Test cases
|
||||
*/
|
||||
void test_udpsocket_echotest_burst();
|
||||
void test_udpsocket_echotest_burst_nonblock();
|
||||
void test_udpsocket_recv_timeout();
|
||||
void test_udpsocket_sendto_timeout();
|
||||
|
||||
#endif //UDP_TESTS_H
|
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "UDPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "udp_tests.h"
|
||||
|
||||
#define SIGNAL_SIGIO 0x1
|
||||
#define SIGIO_TIMEOUT 5000 //[ms]
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef struct pkg {
|
||||
int len;
|
||||
char *payload;
|
||||
} pkg_t;
|
||||
static const int BURST_CNT = 100;
|
||||
static const int BURST_PKTS = 5;
|
||||
static const int PKG_SIZES[BURST_PKTS] = {100, 200, 300, 120, 500};
|
||||
static const int RECV_TOTAL = 1220;
|
||||
pkg_t tx_buffers[BURST_PKTS];
|
||||
char rx_buffer[500] = {0};
|
||||
}
|
||||
|
||||
void prepare_tx_buffers() {
|
||||
// TX buffers to be preserved for comparison
|
||||
for (int x = 0; x < BURST_PKTS; x++) {
|
||||
tx_buffers[x].len = PKG_SIZES[x];
|
||||
tx_buffers[x].payload = (char*) (malloc(PKG_SIZES[x]));
|
||||
TEST_ASSERT_NOT_NULL(tx_buffers[x].payload);
|
||||
fill_tx_buffer_ascii(tx_buffers[x].payload, tx_buffers[x].len);
|
||||
}
|
||||
}
|
||||
|
||||
void free_tx_buffers() {
|
||||
for (int x = 0; x < BURST_PKTS; x++) {
|
||||
free(tx_buffers[x].payload);
|
||||
}
|
||||
}
|
||||
|
||||
void drop_bad_packets(UDPSocket& sock) {
|
||||
nsapi_error_t err;
|
||||
sock.set_timeout(0);
|
||||
while (true) {
|
||||
err = sock.recvfrom(NULL, NULL, 0);
|
||||
if (err == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
|
||||
}
|
||||
|
||||
void test_udpsocket_echotest_burst()
|
||||
{
|
||||
SocketAddress udp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
||||
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_timeout(5000);
|
||||
|
||||
// TX buffers to be preserved for comparison
|
||||
prepare_tx_buffers();
|
||||
|
||||
int ok_bursts = 0;
|
||||
int pkg_fail = 0;
|
||||
SocketAddress temp_addr;
|
||||
int recvd = 0;
|
||||
int bt_total = 0;
|
||||
for (int i = 0; i < BURST_CNT; i++) {
|
||||
for (int x = 0; x < BURST_PKTS; x++) {
|
||||
TEST_ASSERT_EQUAL(tx_buffers[x].len, sock.sendto(udp_addr, tx_buffers[x].payload, tx_buffers[x].len));
|
||||
}
|
||||
|
||||
recvd = 0;
|
||||
bt_total = 0;
|
||||
for (int j = 0; j < BURST_PKTS; j++) {
|
||||
recvd = sock.recvfrom(&temp_addr, rx_buffer, 500);
|
||||
if (recvd < 0) {
|
||||
pkg_fail++;
|
||||
printf("[%02d] network error %d\n", i, recvd);
|
||||
continue;
|
||||
} else if (temp_addr != udp_addr) {
|
||||
printf("[%02d] packet from wrong address\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Packets might arrive unordered
|
||||
for (int k = 0; k < BURST_PKTS; k++) {
|
||||
if (tx_buffers[k].len == recvd &&
|
||||
(memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) {
|
||||
bt_total += recvd;
|
||||
goto PKT_OK;
|
||||
}
|
||||
}
|
||||
pkg_fail++;
|
||||
break;
|
||||
PKT_OK:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bt_total == RECV_TOTAL) {
|
||||
ok_bursts++;
|
||||
} else {
|
||||
drop_bad_packets(sock);
|
||||
printf("[%02d] burst failure\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
free_tx_buffers();
|
||||
|
||||
// Packet loss up to 10% tolerated
|
||||
TEST_ASSERT_INT_WITHIN((BURST_CNT*BURST_PKTS/10), BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail);
|
||||
// 90% of the bursts need to be successful
|
||||
TEST_ASSERT_INT_WITHIN((BURST_CNT/10), BURST_CNT, ok_bursts);
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
}
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
void test_udpsocket_echotest_burst_nonblock()
|
||||
{
|
||||
SocketAddress udp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
||||
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
// TX buffers to be preserved for comparison
|
||||
prepare_tx_buffers();
|
||||
|
||||
int ok_bursts = 0;
|
||||
int pkg_fail = 0;
|
||||
SocketAddress temp_addr;
|
||||
int recvd = 0;
|
||||
int bt_total = 0;
|
||||
for (int i = 0; i < BURST_CNT; i++) {
|
||||
for (int x = 0; x < BURST_PKTS; x++) {
|
||||
TEST_ASSERT_EQUAL(tx_buffers[x].len, sock.sendto(udp_addr, tx_buffers[x].payload, tx_buffers[x].len));
|
||||
}
|
||||
|
||||
recvd = 0;
|
||||
bt_total = 0;
|
||||
for (int j = 0; j < BURST_PKTS; j++) {
|
||||
recvd = sock.recvfrom(&temp_addr, rx_buffer, 500);
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
if(osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT).status == osEventTimeout) {
|
||||
pkg_fail += BURST_PKTS-j;
|
||||
break;
|
||||
}
|
||||
--j;
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
pkg_fail++;
|
||||
continue;
|
||||
} else if (temp_addr != udp_addr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Packets might arrive unordered
|
||||
for (int k = 0; k < BURST_PKTS; k++) {
|
||||
if (tx_buffers[k].len == recvd &&
|
||||
(memcmp(tx_buffers[k].payload, rx_buffer, recvd) == 0)) {
|
||||
bt_total += recvd;
|
||||
goto PKT_OK;
|
||||
}
|
||||
}
|
||||
printf("[bt#%02d] corrupted packet...", i);
|
||||
pkg_fail++;
|
||||
break;
|
||||
PKT_OK:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bt_total == RECV_TOTAL) {
|
||||
ok_bursts++;
|
||||
} else {
|
||||
drop_bad_packets(sock);
|
||||
sock.set_blocking(false);
|
||||
}
|
||||
}
|
||||
|
||||
free_tx_buffers();
|
||||
|
||||
// Packet loss up to 10% tolerated
|
||||
TEST_ASSERT_INT_WITHIN((BURST_CNT*BURST_PKTS/10), BURST_CNT*BURST_PKTS, BURST_CNT*BURST_PKTS-pkg_fail);
|
||||
// 90% of the bursts need to be successful
|
||||
TEST_ASSERT_INT_WITHIN((BURST_CNT/10), BURST_CNT, ok_bursts);
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "UDPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "udp_tests.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace
|
||||
{
|
||||
static const int SIGNAL_SIGIO = 0x1;
|
||||
static const int SIGIO_TIMEOUT = 5000; //[ms]
|
||||
}
|
||||
|
||||
static void _sigio_handler(osThreadId id) {
|
||||
osSignalSet(id, SIGNAL_SIGIO);
|
||||
}
|
||||
|
||||
void test_udpsocket_recv_timeout()
|
||||
{
|
||||
SocketAddress udp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
||||
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||
|
||||
static const int DATA_LEN = 100;
|
||||
char buff[DATA_LEN] = {0};
|
||||
|
||||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_timeout(100);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
|
||||
int recvd;
|
||||
Timer timer;
|
||||
SocketAddress temp_addr;
|
||||
int pkt_success = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TEST_ASSERT_EQUAL(DATA_LEN, sock.sendto(udp_addr, buff, DATA_LEN));
|
||||
timer.reset();
|
||||
timer.start();
|
||||
recvd = sock.recvfrom(&temp_addr, buff, sizeof(buff));
|
||||
timer.stop();
|
||||
|
||||
if (recvd == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
osSignalWait(SIGNAL_SIGIO, SIGIO_TIMEOUT);
|
||||
printf("MBED: recvfrom() took: %dms\n", timer.read_ms());
|
||||
TEST_ASSERT_INT_WITHIN(50, (100+200)/2, timer.read_ms());
|
||||
continue;
|
||||
} else if (recvd < 0) {
|
||||
printf("[bt#%02d] network error %d\n", i, recvd);
|
||||
continue;
|
||||
} else if (temp_addr != udp_addr) {
|
||||
printf("[bt#%02d] packet from wrong address\n", i);
|
||||
continue;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(DATA_LEN, recvd);
|
||||
pkt_success++;
|
||||
}
|
||||
|
||||
TEST_ASSERT(pkt_success >= 5);
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "mbed.h"
|
||||
#include MBED_CONF_APP_HEADER_FILE
|
||||
#include "UDPSocket.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest.h"
|
||||
#include "udp_tests.h"
|
||||
|
||||
void test_udpsocket_sendto_timeout()
|
||||
{
|
||||
char tx_buffer[100];
|
||||
fill_tx_buffer_ascii(tx_buffer, sizeof(tx_buffer));
|
||||
|
||||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
|
||||
SocketAddress udp_addr;
|
||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
||||
udp_addr.set_port(9);
|
||||
|
||||
Timer timer;
|
||||
timer.start();
|
||||
int sent = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
|
||||
timer.stop();
|
||||
TEST_ASSERT_EQUAL(sizeof(tx_buffer), sent);
|
||||
TEST_ASSERT(timer.read_ms() <= 100);
|
||||
|
||||
timer.reset();
|
||||
timer.start();
|
||||
sent = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
|
||||
timer.stop();
|
||||
TEST_ASSERT_EQUAL(sizeof(tx_buffer), sent);
|
||||
TEST_ASSERT(timer.read_ms() <= 100);
|
||||
printf("MBED: Time taken: %fs\n", timer.read());
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
}
|
Loading…
Reference in New Issue