Skip to content

Commit

Permalink
test: Add tcp-pcb recycle test
Browse files Browse the repository at this point in the history
  • Loading branch information
david-cermak authored and David Čermák committed Nov 13, 2024
1 parent 3bfc85d commit a587d92
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 24 deletions.
93 changes: 71 additions & 22 deletions test/apps/tcp_socket_reuse/test_sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,6 @@ test_sockets_get_used_count(void)
return used;
}

#if 0
static int
wait_for_pcbs_to_cleanup(void)
{
struct tcp_pcb *pcb = tcp_active_pcbs;
while (pcb != NULL) {
if (pcb->state == TIME_WAIT || pcb->state == LAST_ACK) {
return -1;
}
pcb = pcb->next;
}
return 0;
}
#endif
/* Setups/teardown functions */
static void
sockets_setup(void)
Expand Down Expand Up @@ -75,12 +61,12 @@ START_TEST(test_tcp_active_socket_limit)
}
END_TEST

START_TEST(test_tcp_new_max_num)
static void create_tcp_pcbs_and_kill_state(u8_t recycle_test, enum tcp_state state)
{
struct tcp_pcb* pcb[MEMP_NUM_TCP_PCB + 1];
int i;
err_t err;
mem_size_t prev_used, one_pcb_size;
LWIP_UNUSED_ARG(_i);

prev_used = lwip_stats.mem.used;
pcb[0] = tcp_new();
Expand All @@ -92,19 +78,77 @@ START_TEST(test_tcp_new_max_num)
pcb[i] = tcp_new();
fail_unless(pcb[i] != NULL);
fail_unless(one_pcb_size == lwip_stats.mem.used - prev_used);
/* bind the pcb, so lwip expects they're active */
err = tcp_bind(pcb[i], &test_local_ip, 3333+i);
fail_unless(err == ERR_OK);
}
/* Trying to remove the oldest pcb in TIME_WAIT,LAST_ACK,CLOSING state when pcb full */
pcb[MEMP_NUM_TCP_PCB] = tcp_new();
fail_unless(pcb[MEMP_NUM_TCP_PCB] == NULL);
tcp_set_state(pcb[0], TIME_WAIT, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
pcb[MEMP_NUM_TCP_PCB] = tcp_new();
fail_unless(pcb[MEMP_NUM_TCP_PCB] != NULL);

for (i = 1; i <= MEMP_NUM_TCP_PCB; i++)
if (recycle_test) {
/* Trying to remove the oldest pcb in TIME_WAIT,LAST_ACK,CLOSING state when pcb full */
if (state == TIME_WAIT) {
tcp_set_state(pcb[0], TIME_WAIT, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
} else {
tcp_set_state(pcb[0], ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
pcb[0]->state = state;
}
fail_unless(pcb[0]->state == state);

pcb[MEMP_NUM_TCP_PCB] = tcp_new();
fail_unless(pcb[MEMP_NUM_TCP_PCB] != NULL);
pcb[0] = tcp_new();
fail_unless(pcb[0] == NULL);
}

for (i = 0; i <= MEMP_NUM_TCP_PCB; i++)
{
tcp_abort(pcb[i]);
if (pcb[i]) {
tcp_abort(pcb[i]);
}
}
}

START_TEST(test_tcp_new_max_num)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(0, /* N/A */ CLOSED);
}
END_TEST

START_TEST(test_tcp_pcb_recycle_TIME_WAIT)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(1, TIME_WAIT);
}
END_TEST

START_TEST(test_tcp_pcb_recycle_LAST_ACK)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(1, LAST_ACK);
}
END_TEST

START_TEST(test_tcp_pcb_recycle_CLOSING)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(1, CLOSING);
}
END_TEST

START_TEST(test_tcp_pcb_recycle_FIN_WAIT_1)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(1, FIN_WAIT_1);
}
END_TEST

START_TEST(test_tcp_pcb_recycle_FIN_WAIT_2)
{
LWIP_UNUSED_ARG(_i);
create_tcp_pcbs_and_kill_state(1, FIN_WAIT_2);
}
END_TEST

/** Create the suite including all tests for this module */
Expand All @@ -114,6 +158,11 @@ sockets_suite(void)
testfunc tests[] = {
TESTFUNC(test_tcp_active_socket_limit),
TESTFUNC(test_tcp_new_max_num),
TESTFUNC(test_tcp_pcb_recycle_TIME_WAIT),
TESTFUNC(test_tcp_pcb_recycle_LAST_ACK),
TESTFUNC(test_tcp_pcb_recycle_CLOSING),
TESTFUNC(test_tcp_pcb_recycle_FIN_WAIT_1),
TESTFUNC(test_tcp_pcb_recycle_FIN_WAIT_2),
};
return create_suite("TCP_ACTIVE_SOCKETS", tests, sizeof(tests)/sizeof(testfunc), sockets_setup, sockets_teardown);
}
5 changes: 3 additions & 2 deletions test/ci/test_apps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ for app in $TEST_APPS; do
cmake -DCI_BUILD=1 -DTEST_APP=${app} -B ${app} -G Ninja .
cmake --build ${app}/
timeout 10 ./${app}/lwip_test_apps
[ -f check2junit.py ] &&
[ -f ${LWIP_DIR}/check2junit.py ] &&
python ${LWIP_DIR}/check2junit.py lwip_test_apps.xml > ${LWIP_DIR}/${app}.xml
done
# Run the lingering test multiple times

# Run the stress test(s) multiple times
for stress_cfg in $STRESS_TEST_APPS; do
for run in {1..1000}; do ( timeout 10 ./$stress_cfg/lwip_test_apps ) || exit 1 ; done;
done
Expand Down
53 changes: 53 additions & 0 deletions test/unit/tcp/test_tcp_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,56 @@ START_TEST(test_tcp_new_max_num_remove_TIME_WAIT)
}
END_TEST

#if ESP_LWIP
/*
* ESP_LWIP:
* If pcb lists are full when allocating a new pcb,
* try to remove one pcb in TIME_WAIT,LAST_ACK, FIN_WAIT_1,CLOSING,FIN_WAIT_1 state.
*/
START_TEST(test_tcp_new_max_num_remove_FIN_WAIT_1)
{
struct tcp_pcb* pcb;
struct tcp_pcb* pcb_list[MEMP_NUM_TCP_PCB + 1];
err_t err;
int i;
uint16_t base_bind_port = 2222;
LWIP_UNUSED_ARG(_i);

/* create a pcb in FIN_WAIT_1 state */
pcb = tcp_new();
EXPECT_RET(pcb != NULL);
tcp_set_state(pcb, ESTABLISHED, &test_local_ip, &test_remote_ip, TEST_LOCAL_PORT, TEST_REMOTE_PORT);
EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);
err = tcp_close(pcb);
EXPECT_RET(err == ERR_OK);
EXPECT_RET(pcb->state == FIN_WAIT_1);
EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 1);

/* Create max number pcbs */
for(i = 0;i < MEMP_NUM_TCP_PCB-1; i++) {
pcb_list[i] = tcp_new();
EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == (i + 2));
/* must bind pcb, otherwise, it will not be calculated in tcp_active_pcbs */
err = tcp_bind(pcb_list[i], &test_netif.ip_addr, base_bind_port+i);
EXPECT(err == ERR_OK);
}
EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == MEMP_NUM_TCP_PCB);
/* Create one more pcb */
pcb_list[MEMP_NUM_TCP_PCB-1] = tcp_new();

/* the FIN_WAIT_1 pcb was removed */
EXPECT_RET(pcb_list[MEMP_NUM_TCP_PCB-1] != NULL);
EXPECT_RET(MEMP_STATS_GET(used, MEMP_TCP_PCB) == MEMP_NUM_TCP_PCB);

for (i = 0; i <= MEMP_NUM_TCP_PCB-1; i++)
{
tcp_abort(pcb_list[i]);
}
EXPECT(MEMP_STATS_GET(used, MEMP_TCP_PCB) == 0);

}
END_TEST
#endif /* ESP_LWIP */

/* Call tcp_connect to check active open */
START_TEST(test_tcp_connect_active_open)
Expand Down Expand Up @@ -649,6 +699,9 @@ tcp_state_suite(void)
testfunc tests[] = {
TESTFUNC(test_tcp_new_max_num),
TESTFUNC(test_tcp_new_max_num_remove_TIME_WAIT),
#if ESP_LWIP
TESTFUNC(test_tcp_new_max_num_remove_FIN_WAIT_1),
#endif
TESTFUNC(test_tcp_connect_active_open),
TESTFUNC(test_tcp_active_close),
TESTFUNC(test_tcp_imultaneous_close),
Expand Down

0 comments on commit a587d92

Please sign in to comment.