mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-03 13:28:44 +00:00
fix tests
This commit is contained in:
1 parent
b95022a3b3
commit
a8c2ce544e
12 files changed
+107
-2183
No files matched your search
+46
-39
@@ -1,7 +1,7 @@
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||
|
||||
#include "mongoose.c"
|
||||
#include "mongoose.c" // order is important, this one first
|
||||
#include "driver_mock.c"
|
||||
|
||||
static int s_num_tests = 0;
|
||||
@@ -11,9 +11,9 @@ static int s_seg_sent = 0;
|
||||
#ifdef NO_SLEEP_ABORT
|
||||
#define ABORT() abort()
|
||||
#else
|
||||
#define ABORT() \
|
||||
sleep(2); /* 2s, GH print reason */ \
|
||||
abort();
|
||||
#define ABORT() \
|
||||
sleep(2); /* 2s, GH print reason */ \
|
||||
abort();
|
||||
#endif
|
||||
|
||||
#define ASSERT(expr) \
|
||||
@@ -48,18 +48,21 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
static void frag_recv_fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
if (ev == MG_EV_ERROR) {
|
||||
if (s_sent_fragment) {
|
||||
ASSERT(strcmp((char*) ev_data, "Received fragmented packet") == 0);
|
||||
ASSERT(strcmp((char *) ev_data, "Received fragmented packet") == 0);
|
||||
}
|
||||
}
|
||||
(void) c, (void) ev_data;
|
||||
}
|
||||
|
||||
// mock send to a non-existent peer using the listener connection
|
||||
static void frag_send_fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||
static bool s_sent;
|
||||
static int s_seg_sizes[] = {416, 416, 368};
|
||||
static int s_seg_sizes[] = {416, 416, 368}; // based on len=1200 and MTU=500
|
||||
if (ev == MG_EV_POLL) {
|
||||
if (!s_sent) {
|
||||
c->send.len = 1200; // setting TCP payload size
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
s->dmss = 1500; // mock set some destination MSS way larger
|
||||
c->send.len = 1200; // setting TCP payload size
|
||||
s_sent = true;
|
||||
}
|
||||
} else if (ev == MG_EV_WRITE) {
|
||||
@@ -88,7 +91,7 @@ static void test_poll(void) {
|
||||
struct driver_data {
|
||||
char buf[DRIVER_BUF_SIZE];
|
||||
size_t len;
|
||||
bool tx_ready; // data can be read from tx
|
||||
bool tx_ready; // data can be read from tx
|
||||
};
|
||||
|
||||
static struct driver_data s_driver_data;
|
||||
@@ -111,7 +114,7 @@ static size_t if_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (!driver_data->len) return 0;
|
||||
if (len > driver_data->len) len = driver_data->len;
|
||||
memcpy(buf, driver_data->buf, len);
|
||||
driver_data->len = 0; // cleaning up the buffer
|
||||
driver_data->len = 0; // cleaning up the buffer
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -132,8 +135,8 @@ static void create_tcp_pkt(struct eth *e, struct ip *ip, uint32_t seq,
|
||||
memcpy(s_driver_data.buf, e, sizeof(*e));
|
||||
memcpy(s_driver_data.buf + sizeof(*e), ip, sizeof(*ip));
|
||||
memcpy(s_driver_data.buf + sizeof(*e) + sizeof(*ip), &t, sizeof(struct tcp));
|
||||
s_driver_data.len = sizeof(*e) + sizeof(*ip)
|
||||
+ sizeof(struct tcp) + payload_len;
|
||||
s_driver_data.len =
|
||||
sizeof(*e) + sizeof(*ip) + sizeof(struct tcp) + payload_len;
|
||||
}
|
||||
|
||||
static void init_tcp_handshake(struct eth *e, struct ip *ip, struct tcp *tcp,
|
||||
@@ -143,9 +146,9 @@ static void init_tcp_handshake(struct eth *e, struct ip *ip, struct tcp *tcp,
|
||||
mg_mgr_poll(mgr, 0);
|
||||
|
||||
// SYN-ACK
|
||||
while(!received_response(&s_driver_data)) mg_mgr_poll(mgr, 0);
|
||||
while (!received_response(&s_driver_data)) mg_mgr_poll(mgr, 0);
|
||||
tcp = (struct tcp *) (s_driver_data.buf + sizeof(struct eth) +
|
||||
sizeof(struct ip));
|
||||
sizeof(struct ip));
|
||||
ASSERT((tcp->flags == (TH_SYN | TH_ACK)));
|
||||
ASSERT((tcp->ack == mg_htonl(1001)));
|
||||
|
||||
@@ -154,6 +157,9 @@ static void init_tcp_handshake(struct eth *e, struct ip *ip, struct tcp *tcp,
|
||||
mg_mgr_poll(mgr, 0);
|
||||
}
|
||||
|
||||
// NOTE: a 1-byte payload could be an erroneous Keep-Alive, keep length > 1 in
|
||||
// this operation, we're testing retransmissions and having len=1 won't work
|
||||
|
||||
static void test_retransmit(void) {
|
||||
struct mg_mgr mgr;
|
||||
struct eth e;
|
||||
@@ -167,12 +173,13 @@ static void test_retransmit(void) {
|
||||
mg_mgr_init(&mgr);
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
memset(&s_driver_data, 0, sizeof(struct driver_data));
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll, driver.rx = if_rx;
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll,
|
||||
driver.rx = if_rx;
|
||||
mif.driver = &driver;
|
||||
mif.driver_data = &s_driver_data;
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:0", fn, NULL);
|
||||
mgr.conns->pfn = NULL; // HTTP handler not needed
|
||||
mgr.conns->pfn = NULL; // HTTP handler not needed
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
|
||||
// setting the Ethernet header
|
||||
@@ -189,20 +196,20 @@ static void test_retransmit(void) {
|
||||
|
||||
// packet with seq_no = 1001
|
||||
ip.len =
|
||||
mg_htons(sizeof(struct ip) + sizeof(struct tcp) + /* TCP Payload */ 1);
|
||||
create_tcp_pkt(&e, &ip, 1001, 1, TH_PUSH | TH_ACK, 1);
|
||||
mg_htons(sizeof(struct ip) + sizeof(struct tcp) + /* TCP Payload */ 2);
|
||||
create_tcp_pkt(&e, &ip, 1001, 1, TH_PUSH | TH_ACK, 2);
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
while(!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0);
|
||||
while (!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0);
|
||||
t = (struct tcp *) (s_driver_data.buf + sizeof(struct eth) +
|
||||
sizeof(struct ip));
|
||||
ASSERT((t->flags == TH_ACK));
|
||||
ASSERT((t->ack == mg_htonl(1002))); // OK
|
||||
ASSERT((t->ack == mg_htonl(1003))); // OK
|
||||
|
||||
// resend packet with seq_no = 1001 (e.g.: MIP ACK lost)
|
||||
create_tcp_pkt(&e, &ip, 1001, 1, TH_PUSH | TH_ACK, 1);
|
||||
create_tcp_pkt(&e, &ip, 1001, 1, TH_PUSH | TH_ACK, 2);
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
start = mg_millis();
|
||||
while(!received_response(&s_driver_data)) {
|
||||
while (!received_response(&s_driver_data)) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
now = mg_millis() - start;
|
||||
// we wait enough time for a reply
|
||||
@@ -211,31 +218,31 @@ static void test_retransmit(void) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT((!response_recv)); // replies should not be sent for duplicate packets
|
||||
ASSERT((!response_recv)); // replies should not be sent for duplicate packets
|
||||
|
||||
// packet with seq_no = 1002 got lost/delayed, send seq_no = 1003
|
||||
create_tcp_pkt(&e, &ip, 1003, 1, TH_PUSH | TH_ACK, 1);
|
||||
// packet with seq_no = 1003 got lost/delayed, send seq_no = 1005
|
||||
create_tcp_pkt(&e, &ip, 1005, 1, TH_PUSH | TH_ACK, 2);
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
start = mg_millis();
|
||||
while(!received_response(&s_driver_data)) {
|
||||
while (!received_response(&s_driver_data)) {
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
now = mg_millis() - start;
|
||||
if (now > 2 * MIP_TCP_ACK_MS)
|
||||
ASSERT(0); // response should have been received by now
|
||||
ASSERT(0); // response should have been received by now
|
||||
}
|
||||
t = (struct tcp *) (s_driver_data.buf + sizeof(struct eth) +
|
||||
sizeof(struct ip));
|
||||
ASSERT((t->flags == TH_ACK));
|
||||
ASSERT((t->ack == mg_htonl(1002))); // dup ACK
|
||||
ASSERT((t->ack == mg_htonl(1003))); // dup ACK
|
||||
|
||||
// retransmitting packet with seq_no = 1002
|
||||
create_tcp_pkt(&e, &ip, 1002, 1, TH_PUSH | TH_ACK, 1);
|
||||
// retransmitting packet with seq_no = 1003
|
||||
create_tcp_pkt(&e, &ip, 1003, 1, TH_PUSH | TH_ACK, 2);
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
while(!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0);
|
||||
while (!received_response(&s_driver_data)) mg_mgr_poll(&mgr, 0);
|
||||
t = (struct tcp *) (s_driver_data.buf + sizeof(struct eth) +
|
||||
sizeof(struct ip));
|
||||
ASSERT((t->flags == TH_ACK));
|
||||
ASSERT((t->ack == mg_htonl(1003))); // OK
|
||||
ASSERT((t->ack == mg_htonl(1005))); // OK
|
||||
|
||||
s_driver_data.len = 0;
|
||||
mg_mgr_free(&mgr);
|
||||
@@ -252,7 +259,8 @@ static void test_frag_recv_path(void) {
|
||||
mg_mgr_init(&mgr);
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
memset(&s_driver_data, 0, sizeof(struct driver_data));
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll, driver.rx = if_rx;
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll,
|
||||
driver.rx = if_rx;
|
||||
mif.driver = &driver;
|
||||
mif.driver_data = &s_driver_data;
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
@@ -273,9 +281,8 @@ static void test_frag_recv_path(void) {
|
||||
init_tcp_handshake(&e, &ip, t, &mgr);
|
||||
|
||||
// send fragmented TCP packet
|
||||
ip.len =
|
||||
mg_htons(sizeof(struct ip) + sizeof(struct tcp) + 1000);
|
||||
ip.frag |= IP_MORE_FRAGS_MSK; // setting More Fragments bit to 1
|
||||
ip.len = mg_htons(sizeof(struct ip) + sizeof(struct tcp) + 1000);
|
||||
ip.frag |= IP_MORE_FRAGS_MSK; // setting More Fragments bit to 1
|
||||
create_tcp_pkt(&e, &ip, 1001, 1, TH_PUSH | TH_ACK, 1000);
|
||||
s_sent_fragment = true;
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
@@ -292,15 +299,15 @@ static void test_frag_send_path(void) {
|
||||
mg_mgr_init(&mgr);
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
memset(&s_driver_data, 0, sizeof(struct driver_data));
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll, driver.rx = if_rx;
|
||||
driver.init = NULL, driver.tx = if_tx, driver.poll = if_poll,
|
||||
driver.rx = if_rx;
|
||||
mif.driver = &driver;
|
||||
mif.driver_data = &s_driver_data;
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mif.mtu = 500;
|
||||
mif.mtu = 500; // force ad hoc small MTU to fragment IP
|
||||
mg_http_listen(&mgr, "http://0.0.0.0:0", frag_send_fn, NULL);
|
||||
mgr.conns->pfn = NULL;
|
||||
for (int i = 0; i < 10; i++)
|
||||
mg_mgr_poll(&mgr, 0);
|
||||
for (int i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0);
|
||||
ASSERT(s_seg_sent == 3);
|
||||
s_driver_data.len = 0;
|
||||
mg_mgr_free(&mgr);
|
||||
|
||||
Reference in new issue
Block a user