diff --git a/src/Makefile.am b/src/Makefile.am index 92ea30bb..e2f14968 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,6 +136,8 @@ utun_CORE_SOURCES = \ proxy/proxy_protocol.h \ proxy/tcp_proxy_client.c \ routing_layer/etcp_router.c \ + routing_layer/route_tx_stats.c \ + routing_layer/route_tx_stats.h \ routing_layer/route_crypto.c \ proxy/tcp_proxy_server.c \ proxy/udp_proxy.c \ @@ -286,6 +288,8 @@ libutun_a_SOURCES = \ proxy/proxy_protocol.h \ proxy/tcp_proxy_client.c \ routing_layer/etcp_router.c \ + routing_layer/route_tx_stats.c \ + routing_layer/route_tx_stats.h \ routing_layer/route_crypto.c \ proxy/tcp_proxy_server.c \ proxy/udp_proxy.c \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 80522f4e..5e96ee75 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -9,6 +9,7 @@ EXTRA_DIST = fixtures/reality_openssl_hello.hex data/silero_speech.pcm data/sile # Быстрые проверки (до 100мс). check_PROGRAMS = \ + test_route_tx_stats \ test_memory_pool_and_config \ test_serialize \ test_reed_solomon \ @@ -673,6 +674,8 @@ test_dm_worker_CFLAGS = $(test_dm_e2e_CFLAGS) test_dm_worker_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) test_call_SOURCES = test_call.c +test_route_tx_stats_SOURCES = test_route_tx_stats.c +test_route_tx_stats_LDADD = $(LIBUTUN) $(COMMON_LIBS) test_call_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/chat -I$(top_srcdir)/src/dm -I$(top_srcdir)/src/call -I$(top_srcdir)/src/routing_layer -I$(top_srcdir)/src/transport_layer -I$(top_srcdir)/lib test_call_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) diff --git a/tests/test_route_tx_stats.c b/tests/test_route_tx_stats.c new file mode 100644 index 00000000..ae6f495f --- /dev/null +++ b/tests/test_route_tx_stats.c @@ -0,0 +1,34 @@ +/* Границы 50мс, неполное окно, пачки ACK, простой и новая эпоха доставки. */ +#include +#include +#include "../src/routing_layer/route_tx_stats.h" +#include "../lib/debug_config.h" + +#define CHECK(x) do { if (!(x)) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "TX meter test line=%d: %s", __LINE__, #x); exit(1); } } while (0) + +int main(void) { + debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); + struct route_tx_meter meter; + struct route_tx_window out; + route_tx_meter_reset(&meter, 0); + for (unsigned i = 0; i < 10; i++) CHECK(route_tx_meter_ack(&meter, i * 50000 + 49999, i + 1) == 0); + CHECK(route_tx_meter_window(&meter, 499999, &out) == 0 && !out.valid && out.bytes == 45); + CHECK(route_tx_meter_window(&meter, 500000, &out) == 0 && out.valid && out.bytes == 55 && out.packets == 10); + CHECK(route_tx_meter_ack(&meter, 500000, 100) == 0); + CHECK(route_tx_meter_window(&meter, 549999, &out) == 0 && out.bytes == 55 && out.end_us == 500000); + CHECK(route_tx_meter_window(&meter, 550000, &out) == 0 && out.bytes == 154 && out.packets == 10); + CHECK(route_tx_meter_window(&meter, 1050000, &out) == 0 && out.bytes == 0 && meter.bytes == 155); + CHECK(route_tx_meter_ack(&meter, 2000000, 200) == 0); + CHECK(route_tx_meter_ack(&meter, 2000000, 300) == 0); + CHECK(route_tx_meter_window(&meter, 2050000, &out) == 0 && out.bytes == 500 && out.packets == 2); + route_tx_meter_reset(&meter, 2075000); + CHECK(route_tx_meter_window(&meter, 2550000, &out) == 0 && !out.valid && out.bytes == 0 && !meter.bytes); + CHECK(route_tx_meter_window(&meter, 2600000, &out) == 0 && out.valid && !out.packets); + CHECK(route_tx_meter_ack(&meter, 2600000, 123) == 0); + struct route_tx_meter saved = meter; + CHECK(route_tx_meter_ack(&meter, 2599999, 1) == -1 && memcmp(&saved, &meter, sizeof(meter)) == 0); + CHECK(route_tx_meter_ack(&meter, 2600000, UINT64_MAX) == -1 && memcmp(&saved, &meter, sizeof(meter)) == 0); + CHECK(route_tx_meter_window(&meter, 2650000, &out) == 0 && out.bytes == 123 && out.packets == 1); + DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "PASS TX meter: 500ms/50ms, boundary, ACK burst, idle, reset, invalid input"); + return 0; +}