Merge pull request #6093 from jeromecoutant/PR_IP_PRESSURE

NETSOCKET MBED_EXTENDED_TESTS json configuration
pull/6162/head
Cruz Monrreal 2018-02-20 13:27:31 -06:00 committed by GitHub
commit 45b4062f8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 428 additions and 244 deletions

View File

@ -16,7 +16,7 @@
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#include "mbed.h"
@ -32,18 +32,21 @@ using namespace utest::v1;
#define MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE 256
#endif
namespace {
char tx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
char rx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
namespace
{
char tx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
char rx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0};
}
void prep_buffer(char *tx_buffer, size_t tx_size) {
for (size_t i=0; i<tx_size; ++i) {
void prep_buffer(char *tx_buffer, size_t tx_size)
{
for (size_t i = 0; i < tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0';
}
}
void test_tcp_echo() {
void test_tcp_echo()
{
int n = 0;
NetworkInterface* net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
int err = MBED_CONF_APP_CONNECT_STATEMENT;
@ -119,7 +122,8 @@ void test_tcp_echo() {
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(240, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -130,6 +134,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_EXTENDED_TESTS
#error [NOT_SUPPORTED] Parallel tests are not supported by default
#error [NOT_SUPPORTED] Parallel tests are not supported by default
#endif
#include "mbed.h"
@ -33,12 +33,12 @@
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE 64
#ifndef MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE 64
#endif
#ifndef MBED_CFG_TCP_CLIENT_ECHO_THREADS
#define MBED_CFG_TCP_CLIENT_ECHO_THREADS 3
#ifndef MBED_CONF_APP_TCP_CLIENT_ECHO_THREADS
#define MBED_CONF_APP_TCP_CLIENT_ECHO_THREADS 3
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -49,51 +49,59 @@ NetworkInterface* net;
SocketAddress tcp_addr;
Mutex iomutex;
void prep_buffer(char *tx_buffer, size_t tx_size) {
for (size_t i=0; i<tx_size; ++i) {
void prep_buffer(char *tx_buffer, size_t tx_size)
{
for (size_t i = 0; i < tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0';
}
}
// Each echo class is in charge of one parallel transaction
class Echo {
class Echo
{
private:
char tx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE];
char rx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE];
char tx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE];
char rx_buffer[MBED_CONF_APP_TCP_CLIENT_ECHO_BUFFER_SIZE];
TCPSocket sock;
Thread thread;
public:
// Limiting stack size to 1k
Echo(): thread(osPriorityNormal, 1024) {
Echo(): thread(osPriorityNormal, 1024)
{
}
void start() {
void start()
{
osStatus status = thread.start(callback(this, &Echo::echo));
TEST_ASSERT_EQUAL(osOK, status);
}
void join() {
void join()
{
osStatus status = thread.join();
TEST_ASSERT_EQUAL(osOK, status);
}
void echo() {
void echo()
{
int err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
err = sock.connect(tcp_addr);
TEST_ASSERT_EQUAL(0, err);
#if defined(MBED_CONF_APP_TCP_ECHO_PREFIX)
//recv connection prefix message
sock.recv(rx_buffer, sizeof(MBED_CONF_APP_TCP_ECHO_PREFIX));
#endif /* MBED_CONF_APP_TCP_ECHO_PREFIX */
memset(rx_buffer, 0, sizeof(rx_buffer));
iomutex.lock();
printf("HTTP: Connected to %s:%d\r\n",
tcp_addr.get_ip_address(), tcp_addr.get_port());
tcp_addr.get_ip_address(), tcp_addr.get_port());
printf("tx_buffer buffer size: %u\r\n", sizeof(tx_buffer));
printf("rx_buffer buffer size: %u\r\n", sizeof(rx_buffer));
iomutex.unlock();
@ -112,26 +120,45 @@ public:
}
};
Echo *echoers[MBED_CFG_TCP_CLIENT_ECHO_THREADS];
Echo *echoers[MBED_CONF_APP_TCP_CLIENT_ECHO_THREADS];
void test_tcp_echo_parallel() {
void test_tcp_echo_parallel()
{
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
int err = MBED_CONF_APP_CONNECT_STATEMENT;
TEST_ASSERT_EQUAL(0, err);
printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address());
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
tcp_addr.set_ip_address(MBED_CONF_APP_ECHO_SERVER_ADDR);
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
tcp_addr.set_ip_address(ipbuf);
tcp_addr.set_port(port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
// Startup echo threads in parallel
for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_TCP_CLIENT_ECHO_THREADS; i++) {
echoers[i] = new Echo;
echoers[i]->start();
}
for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_TCP_CLIENT_ECHO_THREADS; i++) {
echoers[i]->join();
delete echoers[i];
}
@ -140,7 +167,8 @@ void test_tcp_echo_parallel() {
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -151,6 +179,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#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
#error [NOT_SUPPORTED] Pressure tests are not supported by default
#endif
#include "mbed.h"
@ -33,20 +33,20 @@
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN 64
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN 64
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -54,7 +54,8 @@ using namespace utest::v1;
// Simple xorshift pseudorandom number generator
class RandSeq {
class RandSeq
{
private:
uint32_t x;
uint32_t y;
@ -63,23 +64,26 @@ private:
static const int C = 11;
public:
RandSeq(uint32_t seed=MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED)
RandSeq(uint32_t seed = MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED)
: x(seed), y(seed) {}
uint32_t next(void) {
uint32_t next(void)
{
x ^= x << A;
x ^= x >> B;
x ^= y ^ (y >> C);
return x + y;
}
void skip(size_t size) {
void skip(size_t size)
{
for (size_t i = 0; i < size; i++) {
next();
}
}
void buffer(uint8_t *buffer, size_t size) {
void buffer(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -87,7 +91,8 @@ public:
}
}
int cmp(uint8_t *buffer, size_t size) {
int cmp(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -107,7 +112,8 @@ size_t buffer_size;
// Tries to get the biggest buffer possible on the device. Exponentially
// grows a buffer until heap runs out of space, and uses half to leave
// space for the rest of the program
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max)
{
size_t i = min;
while (i < max) {
void *b = malloc(i);
@ -128,10 +134,11 @@ void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
}
void test_tcp_packet_pressure() {
void test_tcp_packet_pressure()
{
generate_buffer(&buffer, &buffer_size,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX);
printf("MBED: Generated buffer %d\r\n", buffer_size);
NetworkInterface* net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
@ -141,24 +148,43 @@ void test_tcp_packet_pressure() {
printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address());
TCPSocket sock;
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
SocketAddress tcp_addr(MBED_CONF_APP_ECHO_SERVER_ADDR, MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
SocketAddress tcp_addr(ipbuf, port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
Timer timer;
timer.start();
// Tests exponentially growing sequences
for (size_t size = MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
for (size_t size = MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
err = sock.connect(tcp_addr);
TEST_ASSERT_EQUAL(0, err);
printf("TCP: %s:%d streaming %d bytes\r\n",
tcp_addr.get_ip_address(), tcp_addr.get_port(), size);
tcp_addr.get_ip_address(), tcp_addr.get_port(), size);
#if defined(MBED_CONF_APP_TCP_ECHO_PREFIX)
//recv connection prefix message
sock.recv(buffer, sizeof(MBED_CONF_APP_TCP_ECHO_PREFIX));
#endif /* MBED_CONF_APP_TCP_ECHO_PREFIX */
memset(buffer, 0, sizeof(buffer));
sock.set_blocking(false);
@ -182,7 +208,7 @@ void test_tcp_packet_pressure() {
int td = sock.send(buffer, chunk_size);
if (td > 0) {
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("TCP: tx -> %d\r\n", td);
}
tx_seq.skip(td);
@ -190,11 +216,11 @@ void test_tcp_packet_pressure() {
} else if (td != NSAPI_ERROR_WOULD_BLOCK) {
// We may fail to send because of buffering issues,
// cut buffer in half
if (window > MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("TCP: Not sent (%d), window = %d\r\n", td, window);
}
}
@ -205,7 +231,7 @@ void test_tcp_packet_pressure() {
int rd = sock.recv(buffer, buffer_size);
TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
if (rd > 0) {
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("TCP: rx <- %d\r\n", rd);
}
int diff = rx_seq.cmp(buffer, rd);
@ -225,15 +251,16 @@ void test_tcp_packet_pressure() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
8 * (2 * MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000 * timer.read()));
net->disconnect();
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -244,6 +271,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_EXTENDED_TESTS
#error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
#error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
#endif
#include "mbed.h"
@ -33,24 +33,24 @@
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN 64
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN 64
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS 3
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS 3
#endif
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
#ifndef MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG false
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -58,7 +58,8 @@ using namespace utest::v1;
// Simple xorshift pseudorandom number generator
class RandSeq {
class RandSeq
{
private:
uint32_t x;
uint32_t y;
@ -67,23 +68,26 @@ private:
static const int C = 11;
public:
RandSeq(uint32_t seed=MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_SEED)
RandSeq(uint32_t seed = MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_SEED)
: x(seed), y(seed) {}
uint32_t next(void) {
uint32_t next(void)
{
x ^= x << A;
x ^= x >> B;
x ^= y ^ (y >> C);
return x + y;
}
void skip(size_t size) {
void skip(size_t size)
{
for (size_t i = 0; i < size; i++) {
next();
}
}
void buffer(uint8_t *buffer, size_t size) {
void buffer(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -91,7 +95,8 @@ public:
}
}
int cmp(uint8_t *buffer, size_t size) {
int cmp(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -108,7 +113,8 @@ public:
// Tries to get the biggest buffer possible on the device. Exponentially
// grows a buffer until heap runs out of space, and uses half to leave
// space for the rest of the program
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max)
{
size_t i = min;
while (i < max) {
void *b = malloc(i);
@ -136,7 +142,8 @@ Timer timer;
Mutex iomutex;
// Single instance of a pressure test
class PressureTest {
class PressureTest
{
private:
uint8_t *buffer;
size_t buffer_size;
@ -146,33 +153,40 @@ private:
public:
PressureTest(uint8_t *buffer, size_t buffer_size)
: buffer(buffer), buffer_size(buffer_size) {
: buffer(buffer), buffer_size(buffer_size)
{
}
void start() {
void start()
{
osStatus status = thread.start(callback(this, &PressureTest::run));
TEST_ASSERT_EQUAL(osOK, status);
}
void join() {
void join()
{
osStatus status = thread.join();
TEST_ASSERT_EQUAL(osOK, status);
}
void run() {
void run()
{
// Tests exponentially growing sequences
for (size_t size = MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
for (size_t size = MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
int err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
err = sock.connect(tcp_addr);
TEST_ASSERT_EQUAL(0, err);
#if defined(MBED_CONF_APP_TCP_ECHO_PREFIX)
sock.recv(buffer, sizeof(MBED_CONF_APP_TCP_ECHO_PREFIX));
#endif /* MBED_CONF_APP_TCP_ECHO_PREFIX */
iomutex.lock();
printf("TCP: %s:%d streaming %d bytes\r\n",
tcp_addr.get_ip_address(), tcp_addr.get_port(), size);
tcp_addr.get_ip_address(), tcp_addr.get_port(), size);
iomutex.unlock();
sock.set_blocking(false);
@ -196,7 +210,7 @@ public:
int td = sock.send(buffer, chunk_size);
if (td > 0) {
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("TCP: tx -> %d\r\n", td);
iomutex.unlock();
@ -206,11 +220,11 @@ public:
} else if (td != NSAPI_ERROR_WOULD_BLOCK) {
// We may fail to send because of buffering issues,
// cut buffer in half
if (window > MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("TCP: Not sent (%d), window = %d\r\n", td, window);
iomutex.unlock();
@ -223,7 +237,7 @@ public:
int rd = sock.recv(buffer, buffer_size);
TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
if (rd > 0) {
if (MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("TCP: rx <- %d\r\n", rd);
iomutex.unlock();
@ -244,21 +258,22 @@ public:
}
};
PressureTest *pressure_tests[MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS];
PressureTest *pressure_tests[MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS];
void test_tcp_packet_pressure_parallel() {
void test_tcp_packet_pressure_parallel()
{
uint8_t *buffer;
size_t buffer_size;
generate_buffer(&buffer, &buffer_size,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX);
size_t buffer_subsize = buffer_size / MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS;
size_t buffer_subsize = buffer_size / MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS;
printf("MBED: Generated buffer %d\r\n", buffer_size);
printf("MBED: Split into %d buffers %d\r\n",
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS,
buffer_subsize);
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS,
buffer_subsize);
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
int err = MBED_CONF_APP_CONNECT_STATEMENT;
@ -266,18 +281,36 @@ void test_tcp_packet_pressure_parallel() {
printf("MBED: TCPClient IP address is '%s'\n", net->get_ip_address());
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
tcp_addr.set_ip_address(MBED_CONF_APP_ECHO_SERVER_ADDR);
tcp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
tcp_addr.set_ip_address(ipbuf);
tcp_addr.set_port(port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
timer.start();
// Startup pressure tests in parallel
for (int i = 0; i < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i] = new PressureTest(&buffer[i*buffer_subsize], buffer_subsize);
for (int i = 0; i < MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i] = new PressureTest(&buffer[i * buffer_subsize], buffer_subsize);
pressure_tests[i]->start();
}
for (int i = 0; i < MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i]->join();
delete pressure_tests[i];
}
@ -285,16 +318,17 @@ void test_tcp_packet_pressure_parallel() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS*
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_THREADS *
8 * (2 * MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CONF_APP_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000 * timer.read()));
net->disconnect();
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -305,6 +339,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_EXTENDED_TESTS
#error [NOT_SUPPORTED] Parallel tests are not supported by default
#error [NOT_SUPPORTED] Parallel tests are not supported by default
#endif
#include "mbed.h"
@ -33,16 +33,16 @@
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
#ifndef MBED_CONF_APP_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CONF_APP_UDP_CLIENT_ECHO_BUFFER_SIZE 64
#endif
#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
#define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
#ifndef MBED_CONF_APP_UDP_CLIENT_ECHO_TIMEOUT
#define MBED_CONF_APP_UDP_CLIENT_ECHO_TIMEOUT 500
#endif
#ifndef MBED_CFG_UDP_CLIENT_ECHO_THREADS
#define MBED_CFG_UDP_CLIENT_ECHO_THREADS 3
#ifndef MBED_CONF_APP_UDP_CLIENT_ECHO_THREADS
#define MBED_CONF_APP_UDP_CLIENT_ECHO_THREADS 3
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -56,28 +56,30 @@ Mutex iomutex;
char uuid[48] = {0};
// NOTE: assuming that "id" stays in the single digits
void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size) {
void prep_buffer(int id, char *uuid, char *tx_buffer, size_t tx_size)
{
size_t i = 0;
tx_buffer[i++] = '0' + id;
tx_buffer[i++] = ' ';
memcpy(tx_buffer+i, uuid, strlen(uuid));
memcpy(tx_buffer + i, uuid, strlen(uuid));
i += strlen(uuid);
tx_buffer[i++] = ' ';
for (; i<tx_size; ++i) {
for (; i < tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0';
}
}
// Each echo class is in charge of one parallel transaction
class Echo {
class Echo
{
private:
char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE];
char tx_buffer[MBED_CONF_APP_UDP_CLIENT_ECHO_BUFFER_SIZE];
char rx_buffer[MBED_CONF_APP_UDP_CLIENT_ECHO_BUFFER_SIZE];
UDPSocket sock;
Thread thread;
@ -87,27 +89,31 @@ private:
public:
// Limiting stack size to 1k
Echo(): thread(osPriorityNormal, 1024), result(false) {
Echo(): thread(osPriorityNormal, 1024), result(false)
{
}
void start(int id, char *uuid) {
void start(int id, char *uuid)
{
this->id = id;
this->uuid = uuid;
osStatus status = thread.start(callback(this, &Echo::echo));
}
void join() {
void join()
{
osStatus status = thread.join();
TEST_ASSERT_EQUAL(osOK, status);
}
void echo() {
void echo()
{
int success = 0;
int err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
sock.set_timeout(MBED_CONF_APP_UDP_CLIENT_ECHO_TIMEOUT);
for (int i = 0; success < ECHO_LOOPS; i++) {
prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer));
@ -137,8 +143,8 @@ public:
}
if ((temp_addr == udp_addr &&
n == sizeof(tx_buffer) &&
memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
n == sizeof(tx_buffer) &&
memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
success += 1;
iomutex.lock();
printf("[ID:%01d][%02d] success #%d\n", id, i, success);
@ -154,7 +160,7 @@ public:
break;
}
}
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
sock.set_timeout(MBED_CONF_APP_UDP_CLIENT_ECHO_TIMEOUT);
}
result = success == ECHO_LOOPS;
@ -166,15 +172,17 @@ public:
}
}
bool get_result() {
bool get_result()
{
return result;
}
};
Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
Echo *echoers[MBED_CONF_APP_UDP_CLIENT_ECHO_THREADS];
void test_udp_echo_parallel() {
void test_udp_echo_parallel()
{
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
int err = MBED_CONF_APP_CONNECT_STATEMENT;
TEST_ASSERT_EQUAL(0, err);
@ -185,18 +193,37 @@ void test_udp_echo_parallel() {
} else {
printf("UDP client IP Address is %s\n", net->get_ip_address());
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
udp_addr.set_ip_address(MBED_CONF_APP_ECHO_SERVER_ADDR);
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
printf("UDP Connect to %s:%d\r\n", ipbuf, port);
udp_addr.set_ip_address(ipbuf);
udp_addr.set_port(port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
// Startup echo threads in parallel
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i] = new Echo;
echoers[i]->start(i, uuid);
}
bool result = true;
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i]->join();
result = result && echoers[i]->get_result();
delete echoers[i];
@ -209,7 +236,8 @@ void test_udp_echo_parallel() {
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "udp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -220,6 +248,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#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
#error [NOT_SUPPORTED] Pressure tests are not supported by default
#endif
#include "mbed.h"
@ -33,24 +33,24 @@
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN 64
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN 64
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -58,7 +58,8 @@ using namespace utest::v1;
// Simple xorshift pseudorandom number generator
class RandSeq {
class RandSeq
{
private:
uint32_t x;
uint32_t y;
@ -67,23 +68,26 @@ private:
static const int C = 11;
public:
RandSeq(uint32_t seed=MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED)
RandSeq(uint32_t seed = MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED)
: x(seed), y(seed) {}
uint32_t next(void) {
uint32_t next(void)
{
x ^= x << A;
x ^= x >> B;
x ^= y ^ (y >> C);
return x + y;
}
void skip(size_t size) {
void skip(size_t size)
{
for (size_t i = 0; i < size; i++) {
next();
}
}
void buffer(uint8_t *buffer, size_t size) {
void buffer(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -91,7 +95,8 @@ public:
}
}
int cmp(uint8_t *buffer, size_t size) {
int cmp(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -111,7 +116,8 @@ size_t buffer_size;
// Tries to get the biggest buffer possible on the device. Exponentially
// grows a buffer until heap runs out of space, and uses half to leave
// space for the rest of the program
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max)
{
size_t i = min;
while (i < max) {
void *b = malloc(i);
@ -131,10 +137,11 @@ void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
TEST_ASSERT(buffer);
}
void test_udp_packet_pressure() {
void test_udp_packet_pressure()
{
generate_buffer(&buffer, &buffer_size,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX);
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX);
printf("MBED: Generated buffer %d\r\n", buffer_size);
NetworkInterface* net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
@ -144,19 +151,36 @@ void test_udp_packet_pressure() {
printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address());
UDPSocket sock;
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
SocketAddress udp_addr(MBED_CONF_APP_ECHO_SERVER_ADDR, MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
SocketAddress udp_addr(ipbuf, port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
Timer timer;
timer.start();
// Tests exponentially growing sequences
for (size_t size = MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
for (size_t size = MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
printf("UDP: %s:%d streaming %d bytes\r\n",
udp_addr.get_ip_address(), udp_addr.get_port(), size);
udp_addr.get_ip_address(), udp_addr.get_port(), size);
sock.set_blocking(false);
@ -180,7 +204,7 @@ void test_udp_packet_pressure() {
int td = sock.sendto(udp_addr, buffer, chunk_size);
if (td > 0) {
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("UDP: tx -> %d\r\n", td);
}
tx_seq.skip(td);
@ -188,11 +212,11 @@ void test_udp_packet_pressure() {
} else if (td != NSAPI_ERROR_WOULD_BLOCK) {
// We may fail to send because of buffering issues, revert to
// last good sequence and cut buffer in half
if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("UDP: Not sent (%d), window = %d\r\n", td, window);
}
}
@ -205,7 +229,7 @@ void test_udp_packet_pressure() {
TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
if (rd > 0) {
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("UDP: rx <- %d\r\n", rd);
}
@ -213,22 +237,22 @@ void test_udp_packet_pressure() {
rx_seq.skip(rd);
rx_count += rd;
known_time = timer.read_ms();
if (window < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX) {
window += MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
if (window < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX) {
window += MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN;
}
}
} else if (timer.read_ms() - known_time >
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
// Dropped packet or out of order, revert to last good sequence
// and cut buffer in half
tx_seq = rx_seq;
tx_count = rx_count;
known_time = timer.read_ms();
if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
printf("UDP: Dropped, window = %d\r\n", window);
}
} else if (rd == NSAPI_ERROR_WOULD_BLOCK) {
@ -244,15 +268,16 @@ void test_udp_packet_pressure() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
8 * (2 * MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000 * timer.read()));
net->disconnect();
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "udp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -263,6 +288,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}

View File

@ -15,12 +15,12 @@
* limitations under the License.
*/
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_CONF_APP_CONNECT_STATEMENT
#error [NOT_SUPPORTED] No network configuration found for this target.
#endif
#ifndef MBED_EXTENDED_TESTS
#error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
#error [NOT_SUPPORTED] Parallel pressure tests are not supported by default
#endif
#include "mbed.h"
@ -33,28 +33,28 @@
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN 64
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN 64
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX 0x80000
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT 100
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED 0x6d626564
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS 3
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS 3
#endif
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
#ifndef MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG
#define MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG false
#endif
#define STRINGIZE(x) STRINGIZE2(x)
@ -62,7 +62,8 @@ using namespace utest::v1;
// Simple xorshift pseudorandom number generator
class RandSeq {
class RandSeq
{
private:
uint32_t x;
uint32_t y;
@ -71,23 +72,26 @@ private:
static const int C = 11;
public:
RandSeq(uint32_t seed=MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_SEED)
RandSeq(uint32_t seed = MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_SEED)
: x(seed), y(seed) {}
uint32_t next(void) {
uint32_t next(void)
{
x ^= x << A;
x ^= x >> B;
x ^= y ^ (y >> C);
return x + y;
}
void skip(size_t size) {
void skip(size_t size)
{
for (size_t i = 0; i < size; i++) {
next();
}
}
void buffer(uint8_t *buffer, size_t size) {
void buffer(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -95,7 +99,8 @@ public:
}
}
int cmp(uint8_t *buffer, size_t size) {
int cmp(uint8_t *buffer, size_t size)
{
RandSeq lookahead = *this;
for (size_t i = 0; i < size; i++) {
@ -111,7 +116,8 @@ public:
// Tries to get the biggest buffer possible on the device. Exponentially
// grows a buffer until heap runs out of space, and uses half to leave
// space for the rest of the program
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max)
{
size_t i = min;
while (i < max) {
void *b = malloc(i);
@ -139,7 +145,8 @@ Timer timer;
Mutex iomutex;
// Single instance of a pressure test
class PressureTest {
class PressureTest
{
private:
uint8_t *buffer;
size_t buffer_size;
@ -149,29 +156,33 @@ private:
public:
PressureTest(uint8_t *buffer, size_t buffer_size)
: buffer(buffer), buffer_size(buffer_size) {
: buffer(buffer), buffer_size(buffer_size)
{
}
void start() {
void start()
{
osStatus status = thread.start(callback(this, &PressureTest::run));
TEST_ASSERT_EQUAL(osOK, status);
}
void join() {
void join()
{
osStatus status = thread.join();
TEST_ASSERT_EQUAL(osOK, status);
}
void run() {
void run()
{
// Tests exponentially growing sequences
for (size_t size = MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
for (size_t size = MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN;
size < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX;
size *= 2) {
int err = sock.open(net);
TEST_ASSERT_EQUAL(0, err);
iomutex.lock();
printf("UDP: %s:%d streaming %d bytes\r\n",
udp_addr.get_ip_address(), udp_addr.get_port(), size);
udp_addr.get_ip_address(), udp_addr.get_port(), size);
iomutex.unlock();
sock.set_blocking(false);
@ -196,7 +207,7 @@ public:
int td = sock.sendto(udp_addr, buffer, chunk_size);
if (td > 0) {
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("UDP: tx -> %d\r\n", td);
iomutex.unlock();
@ -206,11 +217,11 @@ public:
} else if (td != NSAPI_ERROR_WOULD_BLOCK) {
// We may fail to send because of buffering issues, revert to
// last good sequence and cut buffer in half
if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("UDP: Not sent (%d), window = %d\r\n", td, window);
iomutex.unlock();
@ -225,7 +236,7 @@ public:
TEST_ASSERT(rd > 0 || rd == NSAPI_ERROR_WOULD_BLOCK);
if (rd > 0) {
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("UDP: rx <- %d\r\n", rd);
iomutex.unlock();
@ -235,22 +246,22 @@ public:
rx_seq.skip(rd);
rx_count += rd;
known_time = timer.read_ms();
if (window < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX) {
window += MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN;
if (window < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX) {
window += MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN;
}
}
} else if (timer.read_ms() - known_time >
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_TIMEOUT) {
// Dropped packet or out of order, revert to last good sequence
// and cut buffer in half
tx_seq = rx_seq;
tx_count = rx_count;
known_time = timer.read_ms();
if (window > MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) {
if (window > MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) {
window /= 2;
}
if (MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
if (MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_DEBUG) {
iomutex.lock();
printf("UDP: Dropped, window = %d\r\n", window);
iomutex.unlock();
@ -267,21 +278,22 @@ public:
}
};
PressureTest *pressure_tests[MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS];
PressureTest *pressure_tests[MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS];
void test_udp_packet_pressure_parallel() {
void test_udp_packet_pressure_parallel()
{
uint8_t *buffer;
size_t buffer_size;
generate_buffer(&buffer, &buffer_size,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX);
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX);
size_t buffer_subsize = buffer_size / MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS;
size_t buffer_subsize = buffer_size / MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS;
printf("MBED: Generated buffer %d\r\n", buffer_size);
printf("MBED: Split into %d buffers %d\r\n",
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS,
buffer_subsize);
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS,
buffer_subsize);
net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
int err = MBED_CONF_APP_CONNECT_STATEMENT;
@ -289,18 +301,36 @@ void test_udp_packet_pressure_parallel() {
printf("MBED: UDPClient IP address is '%s'\n", net->get_ip_address());
#if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
udp_addr.set_ip_address(MBED_CONF_APP_ECHO_SERVER_ADDR);
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
#else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
unsigned int port = 0;
greentea_send_kv("target_ip", net->get_ip_address());
greentea_send_kv("host_ip", " ");
greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
greentea_send_kv("host_port", " ");
greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
sscanf(portbuf, "%u", &port);
udp_addr.set_ip_address(ipbuf);
udp_addr.set_port(port);
#endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
timer.start();
// Startup pressure tests in parallel
for (int i = 0; i < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i] = new PressureTest(&buffer[i*buffer_subsize], buffer_subsize);
for (int i = 0; i < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i] = new PressureTest(&buffer[i * buffer_subsize], buffer_subsize);
pressure_tests[i]->start();
}
for (int i = 0; i < MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
for (int i = 0; i < MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS; i++) {
pressure_tests[i]->join();
delete pressure_tests[i];
}
@ -308,16 +338,17 @@ void test_udp_packet_pressure_parallel() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS*
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_THREADS *
8 * (2 * MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CONF_APP_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000 * timer.read()));
net->disconnect();
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(120, "udp_echo");
return verbose_test_setup_handler(number_of_cases);
}
@ -328,6 +359,7 @@ Case cases[] = {
Specification specification(test_setup, cases);
int main() {
int main()
{
return !Harness::run(specification);
}