

14 changed files with 1981 additions and 1 deletions
@ -0,0 +1,3 @@
|
||||
MODULE := lwip_sock_tcp
|
||||
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @{ |
||||
* |
||||
* @file |
||||
* @author Martine Lenders <m.lenders@fu-berlin.de> |
||||
*/ |
||||
|
||||
#include "mutex.h" |
||||
|
||||
#include "net/sock/tcp.h" |
||||
#include "timex.h" |
||||
|
||||
#include "lwip/sock_internal.h" |
||||
#include "lwip/api.h" |
||||
#include "lwip/opt.h" |
||||
|
||||
static inline void _tcp_sock_init(sock_tcp_t *sock, struct netconn *conn, |
||||
sock_tcp_queue_t *queue) |
||||
{ |
||||
mutex_init(&sock->mutex); |
||||
mutex_lock(&sock->mutex); |
||||
netconn_set_noautorecved(conn, 1); |
||||
sock->conn = conn; |
||||
sock->queue = queue; |
||||
sock->last_buf = NULL; |
||||
sock->last_offset = 0; |
||||
mutex_unlock(&sock->mutex); |
||||
} |
||||
|
||||
int sock_tcp_connect(sock_tcp_t *sock, const sock_tcp_ep_t *remote, |
||||
uint16_t local_port, uint16_t flags) |
||||
{ |
||||
assert(sock != NULL); |
||||
assert((remote != NULL) && (remote->port != 0)); |
||||
|
||||
int res; |
||||
struct netconn *tmp = NULL; |
||||
struct _sock_tl_ep local = { .family = remote->family, |
||||
.netif = remote->netif, |
||||
.port = local_port }; |
||||
|
||||
if ((res = lwip_sock_create(&tmp, &local, (struct _sock_tl_ep *)remote, 0, |
||||
flags, NETCONN_TCP)) == 0) { |
||||
_tcp_sock_init(sock, tmp, NULL); |
||||
} |
||||
return res; |
||||
} |
||||
|
||||
int sock_tcp_listen(sock_tcp_queue_t *queue, const sock_tcp_ep_t *local, |
||||
sock_tcp_t *queue_array, unsigned queue_len, |
||||
uint16_t flags) |
||||
{ |
||||
assert(queue != NULL); |
||||
assert((local != NULL) && (local->port != 0)); |
||||
assert((queue_array != NULL) && (queue_len != 0)); |
||||
|
||||
int res; |
||||
struct netconn *tmp = NULL; |
||||
|
||||
if (queue_len > USHRT_MAX) { |
||||
return -EFAULT; |
||||
} |
||||
if ((res = lwip_sock_create(&tmp, (struct _sock_tl_ep *)local, NULL, 0, |
||||
flags, NETCONN_TCP)) < 0) { |
||||
return res; |
||||
} |
||||
assert(tmp != NULL); /* just in case lwIP is trolling */ |
||||
mutex_init(&queue->mutex); |
||||
mutex_lock(&queue->mutex); |
||||
queue->conn = tmp; |
||||
queue->array = queue_array; |
||||
queue->len = queue_len; |
||||
queue->used = 0; |
||||
memset(queue->array, 0, sizeof(sock_tcp_t) * queue_len); |
||||
mutex_unlock(&queue->mutex); |
||||
switch (netconn_listen_with_backlog(queue->conn, queue->len)) { |
||||
case ERR_OK: |
||||
break; |
||||
case ERR_MEM: |
||||
return -ENOMEM; |
||||
case ERR_USE: |
||||
return -EADDRINUSE; |
||||
case ERR_VAL: |
||||
return -EINVAL; |
||||
default: |
||||
assert(false); /* should not happen since queue->conn is not closed
|
||||
* and we have a TCP conn */ |
||||
break; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
void sock_tcp_disconnect(sock_tcp_t *sock) |
||||
{ |
||||
assert(sock != NULL); |
||||
mutex_lock(&sock->mutex); |
||||
if (sock->conn != NULL) { |
||||
netconn_close(sock->conn); |
||||
netconn_delete(sock->conn); |
||||
sock->conn = NULL; |
||||
/* if sock came from a sock_tcp_queue_t: since sock is a pointer in it's
|
||||
* array it is also deleted from there, but we need to decrement the used |
||||
* counter */ |
||||
if (sock->queue != NULL) { |
||||
assert(sock->queue->used > 0); |
||||
sock->queue->used--; |
||||
sock->queue = NULL; |
||||
} |
||||
} |
||||
mutex_unlock(&sock->mutex); |
||||
memset(&sock->mutex, 0, sizeof(mutex_t)); |
||||
} |
||||
|
||||
void sock_tcp_stop_listen(sock_tcp_queue_t *queue) |
||||
{ |
||||
assert(queue != NULL); |
||||
mutex_lock(&queue->mutex); |
||||
if (queue->conn != NULL) { |
||||
netconn_close(queue->conn); |
||||
netconn_delete(queue->conn); |
||||
queue->conn = NULL; |
||||
/* sever connections established through this queue */ |
||||
for (unsigned i = 0; i < queue->len; i++) { |
||||
sock_tcp_disconnect(&queue->array[i]); |
||||
} |
||||
queue->array = NULL; |
||||
queue->len = 0; |
||||
queue->used = 0; |
||||
} |
||||
mutex_unlock(&queue->mutex); |
||||
memset(&queue->mutex, 0, sizeof(mutex_t)); |
||||
} |
||||
|
||||
int sock_tcp_get_local(sock_tcp_t *sock, sock_tcp_ep_t *ep) |
||||
{ |
||||
int res = 0; |
||||
assert(sock != NULL); |
||||
mutex_lock(&sock->mutex); |
||||
if ((sock->conn == NULL) || lwip_sock_get_addr(sock->conn, |
||||
(struct _sock_tl_ep *)ep, |
||||
1)) { |
||||
res = -EADDRNOTAVAIL; |
||||
} |
||||
mutex_unlock(&sock->mutex); |
||||
return res; |
||||
} |
||||
|
||||
int sock_tcp_get_remote(sock_tcp_t *sock, sock_tcp_ep_t *ep) |
||||
{ |
||||
int res = 0; |
||||
assert(sock != NULL); |
||||
mutex_lock(&sock->mutex); |
||||
if ((sock->conn == NULL) || lwip_sock_get_addr(sock->conn, |
||||
(struct _sock_tl_ep *)ep, |
||||
0)) { |
||||
res = -ENOTCONN; |
||||
} |
||||
mutex_unlock(&sock->mutex); |
||||
return res; |
||||
} |
||||
|
||||
int sock_tcp_queue_get_local(sock_tcp_queue_t *queue, sock_tcp_ep_t *ep) |
||||
{ |
||||
int res = 0; |
||||
|
||||
assert(queue != NULL); |
||||
mutex_lock(&queue->mutex); |
||||
if ((queue->conn == NULL) || lwip_sock_get_addr(queue->conn, |
||||
(struct _sock_tl_ep *)ep, |
||||
1)) { |
||||
res = -EADDRNOTAVAIL; |
||||
} |
||||
mutex_unlock(&queue->mutex); |
||||
return res; |
||||
} |
||||
|
||||
int sock_tcp_accept(sock_tcp_queue_t *queue, sock_tcp_t **sock, |
||||
uint32_t timeout) |
||||
{ |
||||
struct netconn *tmp = NULL; |
||||
int res = 0; |
||||
|
||||
assert((queue != NULL) && (sock != NULL)); |
||||
if (queue->conn == NULL) { |
||||
return -EINVAL; |
||||
} |
||||
if (timeout == 0) { |
||||
if (!mutex_trylock(&queue->mutex)) { |
||||
return -EAGAIN; |
||||
} |
||||
} |
||||
else if (timeout != 0) { |
||||
mutex_lock(&queue->mutex); |
||||
} |
||||
if (queue->used < queue->len) { |
||||
#if LWIP_SO_RCVTIMEO |
||||
if ((timeout != 0) && (timeout != SOCK_NO_TIMEOUT)) { |
||||
netconn_set_recvtimeout(queue->conn, timeout / US_PER_MS); |
||||
} |
||||
else |
||||
#endif |
||||
if ((timeout == 0) && !cib_avail(&queue->conn->acceptmbox.mbox.cib)) { |
||||
mutex_unlock(&queue->mutex); |
||||
return -EAGAIN; |
||||
} |
||||
switch (netconn_accept(queue->conn, &tmp)) { |
||||
case ERR_OK: |
||||
for (unsigned short i = 0; i < queue->len; i++) { |
||||
sock_tcp_t *s = &queue->array[i]; |
||||
if (s->conn == NULL) { |
||||
_tcp_sock_init(s, tmp, queue); |
||||
queue->used++; |
||||
assert(queue->used > 0); |
||||
*sock = s; |
||||
break; |
||||
} |
||||
} |
||||
break; |
||||
case ERR_ABRT: |
||||
res = -ECONNABORTED; |
||||
break; |
||||
case ERR_MEM: |
||||
res = -ENOMEM; |
||||
break; |
||||
#if LWIP_SO_RCVTIMEO |
||||
case ERR_TIMEOUT: |
||||
res = -ETIMEDOUT; |
||||
break; |
||||
#endif |
||||
default: |
||||
assert(false); |
||||
res = -1; |
||||
break; |
||||
} |
||||
} |
||||
else { |
||||
res = -ENOMEM; |
||||
} |
||||
#if LWIP_SO_RCVTIMEO |
||||
netconn_set_recvtimeout(queue->conn, 0); |
||||
#endif |
||||
mutex_unlock(&queue->mutex); |
||||
return res; |
||||
} |
||||
|
||||
ssize_t sock_tcp_read(sock_tcp_t *sock, void *data, size_t max_len, |
||||
uint32_t timeout) |
||||
{ |
||||
uint8_t *data_ptr = data; |
||||
struct pbuf *buf; |
||||
ssize_t offset = 0, res = 0; |
||||
bool done = false; |
||||
|
||||
assert((sock != NULL) && (data != NULL) && (max_len > 0)); |
||||
if (sock->conn == NULL) { |
||||
return -ENOTCONN; |
||||
} |
||||
if (timeout == 0) { |
||||
if (!mutex_trylock(&sock->mutex)) { |
||||
return -EAGAIN; |
||||
} |
||||
} |
||||
else { |
||||
mutex_lock(&sock->mutex); |
||||
} |
||||
#if LWIP_SO_RCVTIMEO |
||||
if ((timeout != 0) && (timeout != SOCK_NO_TIMEOUT)) { |
||||
netconn_set_recvtimeout(sock->conn, timeout / US_PER_MS); |
||||
} |
||||
else |
||||
#endif |
||||
if ((timeout == 0) && !cib_avail(&sock->conn->recvmbox.mbox.cib)) { |
||||
mutex_unlock(&sock->mutex); |
||||
return -EAGAIN; |
||||
} |
||||
while (!done) { |
||||
uint16_t copylen, buf_len; |
||||
if (sock->last_buf != NULL) { |
||||
buf = sock->last_buf; |
||||
} |
||||
else { |
||||
err_t err; |
||||
if ((err = netconn_recv_tcp_pbuf(sock->conn, &buf)) < 0) { |
||||
switch (err) { |
||||
case ERR_ABRT: |
||||
res = -ECONNABORTED; |
||||
break; |
||||
case ERR_CONN: |
||||
res = -EADDRNOTAVAIL; |
||||
break; |
||||
case ERR_RST: |
||||
case ERR_CLSD: |
||||
res = -ECONNRESET; |
||||
break; |
||||
case ERR_MEM: |
||||
res = -ENOMEM; |
||||
break; |
||||
#if LWIP_SO_RCVTIMEO |
||||
case ERR_TIMEOUT: |
||||
res = -ETIMEDOUT; |
||||
break; |
||||
#endif |
||||
default: |
||||
/* no applicable error */ |
||||
res = -1; |
||||
break; |
||||
} |
||||
break; |
||||
} |
||||
sock->last_buf = buf; |
||||
} |
||||
buf_len = buf->tot_len - sock->last_offset; |
||||
copylen = (buf_len > max_len) ? (uint16_t)max_len : buf_len; |
||||
pbuf_copy_partial(buf, data_ptr + offset, copylen, sock->last_offset); |
||||
offset += copylen; |
||||
max_len -= copylen; /* should be 0 at minimum due to copylen setting above */ |
||||
if (max_len == 0) { |
||||
done = true; |
||||
res = offset; /* in case offset == 0 */ |
||||
} |
||||
/* post-process buf */ |
||||
if (buf_len > copylen) { |
||||
/* there is still data in the buffer */ |
||||
sock->last_buf = buf; |
||||
sock->last_offset = copylen; |
||||
} |
||||
else { |
||||
sock->last_buf = NULL; |
||||
sock->last_offset = 0; |
||||
pbuf_free(buf); |
||||
break; |
||||
} |
||||
} |
||||
if (offset > 0) { |
||||
/* inform lwIP how much we receive*/ |
||||
netconn_recved(sock->conn, (u32_t)offset); |
||||
res = offset; /* we received data so return it */ |
||||
} |
||||
/* unset flags */ |
||||
#if LWIP_SO_RCVTIMEO |
||||
netconn_set_recvtimeout(sock->conn, 0); |
||||
#endif |
||||
netconn_set_nonblocking(sock->conn, false); |
||||
mutex_unlock(&sock->mutex); |
||||
return res; |
||||
} |
||||
|
||||
ssize_t sock_tcp_write(sock_tcp_t *sock, const void *data, size_t len) |
||||
{ |
||||
struct netconn *conn; |
||||
int res = 0; |
||||
|
||||
assert(sock != NULL); |
||||
assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */ |
||||
mutex_lock(&sock->mutex); |
||||
if (sock->conn == NULL) { |
||||
mutex_unlock(&sock->mutex); |
||||
return -ENOTCONN; |
||||
} |
||||
conn = sock->conn; |
||||
mutex_unlock(&sock->mutex); /* we won't change anything to sock here
|
||||
(lwip_sock_send neither, since it remote is |
||||
NULL) so we can leave the mutex */ |
||||
res = lwip_sock_send(&conn, data, len, 0, NULL, NETCONN_TCP); |
||||
return res; |
||||
} |
||||
|
||||
/** @} */ |
@ -0,0 +1,49 @@
|
||||
APPLICATION = lwip_sock_tcp
|
||||
|
||||
include ../Makefile.tests_common |
||||
|
||||
# lwIP's memory management doesn't seem to work on non 32-bit platforms at the
|
||||
# moment.
|
||||
BOARD_BLACKLIST := arduino-uno arduino-duemilanove arduino-mega2560 chronos \
|
||||
msb-430 msb-430h telosb waspmote-pro wsn430-v1_3b \
|
||||
wsn430-v1_4 z1
|
||||
BOARD_INSUFFICIENT_MEMORY = nucleo-f030 nucleo32-f042 nucleo-f334 \
|
||||
stm32f0discovery weio
|
||||
|
||||
LWIP_IPV4 ?= 0
|
||||
|
||||
ifneq (0, $(LWIP_IPV4)) |
||||
USEMODULE += ipv4_addr
|
||||
USEMODULE += lwip_arp
|
||||
USEMODULE += lwip_ipv4
|
||||
CFLAGS += -DETHARP_SUPPORT_STATIC_ENTRIES=1
|
||||
LWIP_IPV6 ?= 0
|
||||
else |
||||
LWIP_IPV6 ?= 1
|
||||
endif |
||||
|
||||
ifneq (0, $(LWIP_IPV6)) |
||||
USEMODULE += ipv6_addr
|
||||
USEMODULE += lwip_ipv6_autoconfig
|
||||
endif |
||||
|
||||
USEMODULE += inet_csum
|
||||
USEMODULE += lwip_ethernet lwip_netdev2
|
||||
USEMODULE += lwip_sock_tcp
|
||||
USEMODULE += netdev2_eth
|
||||
USEMODULE += netdev2_test
|
||||
USEMODULE += ps
|
||||
|
||||
DISABLE_MODULE += auto_init
|
||||
|
||||
CFLAGS += -DDEVELHELP
|
||||
CFLAGS += -DSO_REUSE
|
||||
CFLAGS += -DLWIP_SO_RCVTIMEO
|
||||
CFLAGS += -DLWIP_SOCK_TCP_ACCEPT_TIMEOUT=500
|
||||
CFLAGS += -DLWIP_NETIF_LOOPBACK=1
|
||||
CFLAGS += -DLWIP_HAVE_LOOPIF=1
|
||||
|
||||
include $(RIOTBASE)/Makefile.include |
||||
|
||||
test: |
||||
./tests/01-run.py
|
@ -0,0 +1,33 @@
|
||||
Tests for lwIP's sock_tcp port |
||||
============================== |
||||
|
||||
This tests the `sock_tcp` port of lwIP. There is no network device needed since |
||||
a [virtual device](http://doc.riot-os.org/group__sys__netdev2__test.html) is |
||||
provided at the backend. |
||||
|
||||
These tests test both IPv4 and IPv6 capabilities. They can be activated by |
||||
the `LWIP_IPV4` and `LWIP_IPV6` environment variables to a non-zero value. |
||||
IPv6 is activated by default: |
||||
|
||||
```sh |
||||
make all test |
||||
# or |
||||
LWIP_IPV6=1 make all test |
||||
``` |
||||
|
||||
To just test IPv4 set the `LWIP_IPV4` to a non-zero value (IPv6 will be |
||||
deactivated automatically): |
||||
|
||||
```sh |
||||
LWIP_IPV4=1 make all test |
||||
``` |
||||
|
||||
To test both set the `LWIP_IPV4` and `LWIP_IPV6` to a non-zero value: |
||||
|
||||
```sh |
||||
LWIP_IPV4=1 LWIP_IPV6=1 make all test |
||||
``` |
||||
|
||||
Since lwIP uses a lot of macro magic to activate/deactivate these capabilities |
||||
it is advisable to **test all three configurations individually** (just IPv4, |
||||
just IPv6, IPv4/IPv6 dual stack mode). |
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @defgroup |
||||
* @ingroup |
||||
* @brief |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief |
||||
* |
||||
* @author Martine Lenders <m.lenders@fu-berlin.de> |
||||
*/ |
||||
#ifndef CONSTANTS_H_ |
||||
#define CONSTANTS_H_ |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#define _TEST_PORT_LOCAL (0x2c94) |
||||
#define _TEST_PORT_REMOTE (0xa615) |
||||
#define _TEST_NETIF (1) |
||||
#define _TEST_TIMEOUT (1000000U) |
||||
#define _TEST_ADDR4_LOCAL (0xc0a84f96U) /* 192.168.79.150 */ |
||||
#define _TEST_ADDR4_REMOTE (0x7f000001U) /* 127.0.0.1 */ |
||||
#define _TEST_ADDR4_WRONG (0x254c6b4cU) |
||||
#define _TEST_ADDR4_MASK (0xffffff00U) /* 255.255.255.0 */ |
||||
#define _TEST_ADDR4_GW (0UL) /* so we can test unreachability */ |
||||
#define _TEST_ADDR6_LOCAL { 0x2f, 0xc4, 0x11, 0x5a, 0xe6, 0x91, 0x8d, 0x5d, \ |
||||
0x8c, 0xd1, 0x47, 0x07, 0xb7, 0x6f, 0x9b, 0x48 } |
||||
#define _TEST_ADDR6_REMOTE { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } |
||||
#define _TEST_ADDR6_WRONG { 0x2a, 0xce, 0x5d, 0x4e, 0xc8, 0xbf, 0x86, 0xf7, \ |
||||
0x85, 0x49, 0xb4, 0x19, 0xf2, 0x28, 0xde, 0x9b } |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* CONSTANTS_H_ */ |
||||
/** @} */ |
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @{ |
||||
* |
||||
* @file |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
|
||||
|
||||
#include "xtimer.h" |
||||
|
||||
#include "lwip.h" |
||||
#include "lwip/netif.h" |
||||
|
||||
#include "stack.h" |
||||
|
||||
void _net_init(void) |
||||
{ |
||||
xtimer_init(); |
||||
lwip_bootstrap(); |
||||
} |
||||
|
||||
/** @} */ |
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Freie Universität Berlin |
||||
* |
||||
* This file is subject to the terms and conditions of the GNU Lesser |
||||
* General Public License v2.1. See the file LICENSE in the top level |
||||
* directory for more details. |
||||
*/ |
||||
|
||||
/**
|
||||
* @defgroup |
||||
* @ingroup |
||||
* @brief |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief |
||||
* |
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> |
||||
*/ |
||||
#ifndef STACK_H_ |
||||
#define STACK_H_ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief Initializes networking for tests |
||||
*/ |
||||
void _net_init(void); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* STACK_H_ */ |
||||
/** @} */ |
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# Copyright (C) 2016 Freie Universität Berlin |
||||
# |
||||
# This file is subject to the terms and conditions of the GNU Lesser |
||||
# General Public License v2.1. See the file LICENSE in the top level |
||||
# directory for more details. |
||||
|
||||
import os |
||||
import sys |
||||
|
||||
from datetime import datetime |
||||
|
||||
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner')) |
||||
import testrunner |
||||
|
||||
class InvalidTimeout(Exception): |
||||
pass |
||||
|
||||
def _reuse_tests(code): |
||||
return code & 1 |
||||
|
||||
def _ipv6_tests(code): |
||||
return code & (1 << 6) |
||||
|
||||
def _ipv4_tests(code): |
||||
return code & (1 << 4) |
||||
|
||||
def testfunc(child): |
||||
child.expect(u"code (0x[0-9a-f]{2})") |
||||
code = int(child.match.group(1), base=16) |
||||
if _ipv4_tests(code): |
||||
if _reuse_tests(code): |
||||
child.expect_exact("Calling test_tcp_connect4__EADDRINUSE()") |
||||
child.expect_exact("Calling test_tcp_connect4__EAFNOSUPPORT()") |
||||
child.expect_exact("Calling test_tcp_connect4__EINVAL_addr()") |
||||
child.expect_exact("Calling test_tcp_connect4__EINVAL_netif()") |
||||
child.expect_exact("Calling test_tcp_connect4__success_without_port()") |
||||
child.expect_exact("Calling test_tcp_connect4__success_local_port()") |
||||
if _reuse_tests(code): |
||||
child.expect_exact("Calling test_tcp_listen4__EADDRINUSE()") |
||||
child.expect_exact("Calling test_tcp_listen4__EAFNOSUPPORT()") |
||||
child.expect_exact("Calling test_tcp_listen4__EINVAL()") |
||||
child.expect_exact("Calling test_tcp_listen4__success_any_netif()") |
||||
child.expect_exact("Calling test_tcp_listen4__success_spec_netif()") |
||||
child.expect_exact("Calling test_tcp_accept4__EAGAIN()") |
||||
child.expect_exact("Calling test_tcp_accept4__EINVAL()") |
||||
child.expect_exact("Calling test_tcp_accept4__ETIMEDOUT()") |
||||
start = datetime.now() |
||||
child.expect_exact(" * Calling sock_tcp_accept()") |
||||
child.expect(u" \\* \\(timed out with timeout (\\d+)\\)") |
||||
exp_diff = int(child.match.group(1)) |
||||
stop = datetime.now() |
||||
diff = (stop - start) |
||||
diff = (diff.seconds * 1000000) + diff.microseconds |
||||
# fail within 5% of expected |
||||
if diff > (exp_diff + (exp_diff * 0.05)) or \ |
||||
diff < (exp_diff - (exp_diff * 0.05)): |
||||
raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); |
||||
else: |
||||
print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) |
||||
child.expect_exact("Calling test_tcp_accept4__success()") |
||||
child.expect_exact("Calling test_tcp_read4__EAGAIN()") |
||||
child.expect_exact("Calling test_tcp_read4__ECONNRESET()") |
||||
child.expect_exact("Calling test_tcp_read4__ENOTCONN()") |
||||
child.expect_exact("Calling test_tcp_read4__ETIMEDOUT()") |
||||
start = datetime.now() |
||||
child.expect_exact(" * Calling sock_tcp_read()") |
||||
child.expect(u" \\* \\(timed out with timeout (\\d+)\\)") |
||||
exp_diff = int(child.match.group(1)) |
||||
stop = datetime.now() |
||||
diff = (stop - start) |
||||
diff = (diff.seconds * 1000000) + diff.microseconds |
||||
# fail within 5% of expected |
||||
if diff > (exp_diff + (exp_diff * 0.05)) or \ |
||||
diff < (exp_diff - (exp_diff * 0.05)): |
||||
raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); |
||||
else: |
||||
print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) |
||||
child.expect_exact("Calling test_tcp_read4__success()") |
||||
child.expect_exact("Calling test_tcp_read4__success_with_timeout()") |
||||
child.expect_exact("Calling test_tcp_read4__success_non_blocking()") |
||||
child.expect_exact("Calling test_tcp_write4__ENOTCONN()") |
||||
child.expect_exact("Calling test_tcp_write4__success()") |
||||
if _ipv6_tests(code): |
||||
if _reuse_tests(code): |
||||
child.expect_exact("Calling test_tcp_connect6__EADDRINUSE()") |
||||
child.expect_exact("Calling test_tcp_connect6__EAFNOSUPPORT()") |
||||
child.expect_exact("Calling test_tcp_connect6__EINVAL_addr()") |
||||
child.expect_exact("Calling test_tcp_connect6__EINVAL_netif()") |
||||
child.expect_exact("Calling test_tcp_connect6__success_without_port()") |
||||
child.expect_exact("Calling test_tcp_connect6__success_local_port()") |
||||
if _reuse_tests(code): |
||||
child.expect_exact("Calling test_tcp_listen6__EADDRINUSE()") |
||||
child.expect_exact("Calling test_tcp_listen6__EAFNOSUPPORT()") |
||||
child.expect_exact("Calling test_tcp_listen6__EINVAL()") |
||||
child.expect_exact("Calling test_tcp_listen6__success_any_netif()") |
||||
child.expect_exact("Calling test_tcp_listen6__success_spec_netif()") |
||||
child.expect_exact("Calling test_tcp_accept6__EAGAIN()") |
||||
child.expect_exact("Calling test_tcp_accept6__EINVAL()") |
||||
child.expect_exact("Calling test_tcp_accept6__ETIMEDOUT()") |
||||
start = datetime.now() |
||||
child.expect_exact(" * Calling sock_tcp_accept()") |
||||
child.expect(u" \\* \\(timed out with timeout (\\d+)\\)") |
||||
exp_diff = int(child.match.group(1)) |
||||
stop = datetime.now() |
||||
diff = (stop - start) |
||||
diff = (diff.seconds * 1000000) + diff.microseconds |
||||
# fail within 5% of expected |
||||
if diff > (exp_diff + (exp_diff * 0.05)) or \ |
||||
diff < (exp_diff - (exp_diff * 0.05)): |
||||
raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); |
||||
else: |
||||
print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) |
||||
child.expect_exact("Calling test_tcp_accept6__success()") |
||||
child.expect_exact("Calling test_tcp_read6__EAGAIN()") |
||||
child.expect_exact("Calling test_tcp_read6__ECONNRESET()") |
||||
child.expect_exact("Calling test_tcp_read6__ENOTCONN()") |
||||
child.expect_exact("Calling test_tcp_read6__ETIMEDOUT()") |
||||
start = datetime.now() |
||||
child.expect_exact(" * Calling sock_tcp_read()") |
||||
child.expect(u" \\* \\(timed out with timeout (\\d+)\\)") |
||||
exp_diff = int(child.match.group(1)) |
||||
stop = datetime.now() |
||||
diff = (stop - start) |
||||
diff = (diff.seconds * 1000000) + diff.microseconds |
||||
# fail within 5% of expected |
||||
if diff > (exp_diff + (exp_diff * 0.05)) or \ |
||||
diff < (exp_diff - (exp_diff * 0.05)): |
||||
raise InvalidTimeout("Invalid timeout %d (expected %d)" % (diff, exp_diff)); |
||||
else: |
||||
print("Timed out correctly: %d (expected %d)" % (diff, exp_diff)) |
||||
child.expect_exact("Calling test_tcp_read6__success()") |
||||
child.expect_exact("Calling test_tcp_read6__success_with_timeout()") |
||||
child.expect_exact("Calling test_tcp_read6__success_non_blocking()") |
||||
child.expect_exact("Calling test_tcp_write6__ENOTCONN()") |
||||
child.expect_exact("Calling test_tcp_write6__success()") |
||||
child.expect_exact(u"ALL TESTS SUCCESSFUL") |
||||
|
||||
if __name__ == "__main__": |
||||
sys.exit(testrunner.run(testfunc, timeout=60)) |
Loading…
Reference in new issue