diff options
Diffstat (limited to 'src/ipcpd/unicast/tests')
| -rw-r--r-- | src/ipcpd/unicast/tests/cap_test.c | 434 |
1 files changed, 9 insertions, 425 deletions
diff --git a/src/ipcpd/unicast/tests/cap_test.c b/src/ipcpd/unicast/tests/cap_test.c index 7867b490..e3c3f8b3 100644 --- a/src/ipcpd/unicast/tests/cap_test.c +++ b/src/ipcpd/unicast/tests/cap_test.c @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2026 * - * Unit tests for link capacity estimation + * Unit tests for link capacity codes * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -24,41 +24,6 @@ #include <test/test.h> -#define TICK (50 * 1000ULL) /* 50 us between packets */ -#define LEN 1000ULL /* default packet size (B) */ -#define QLEN 8 /* steady ring backlog */ -#define RATE (LEN * BILLION / TICK) /* LEN per TICK = 20 MB/s */ - -#define SHP_LEN 1250ULL /* shaped-link packet (B) */ -#define SHP_STEP 20 /* packets per shaped window */ -#define SHP_RATE (SHP_LEN * BILLION / (SHP_STEP * TICK)) - -static int test_cap_init_fini(void) -{ - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - if (cap_get(0) != 0 || cap_get(PROC_MAX_FLOWS - 1) != 0) { - printf("Fresh estimator not unknown.\n"); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - /* Exact roundtrip holds for codes >= 32 (rates >= 256 B/s). */ static int test_cap_codec_roundtrip(void) { @@ -152,28 +117,36 @@ static int test_cap_stamp(void) TEST_START(); pci = 42; + cap_stamp(&pci, 0); + if (pci != 42) { printf("Unknown own code overwrote the byte.\n"); goto fail; } pci = 0; + cap_stamp(&pci, 97); + if (pci != 97) { printf("Own code not written into unknown.\n"); goto fail; } pci = 97; + cap_stamp(&pci, 42); + if (pci != 42) { printf("Lower own code did not lower the byte.\n"); goto fail; } pci = 42; + cap_stamp(&pci, 97); + if (pci != 42) { printf("Higher own code raised the byte.\n"); goto fail; @@ -187,384 +160,6 @@ static int test_cap_stamp(void) return TEST_RC_FAIL; } -static int test_cap_est_busy_window(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - /* 1000 B every 50 us, ring steady at 8: drain = 20 MB/s. */ - for (i = 1; i <= 40; i++) - cap_update_at(0, QLEN, LEN, i * TICK); - - if (cap_get(0) != cap_enc(RATE)) { - printf("Estimated code: exp %u, got %u.\n", - cap_enc(RATE), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_idle_tolerated(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - for (i = 1; i <= 40; i++) - cap_update_at(0, i == 21 ? 0 : QLEN, LEN, i * TICK); - - if (cap_get(0) != cap_enc(RATE)) { - printf("Grazed window: exp %u, got %u.\n", - cap_enc(RATE), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_mostly_idle_rejects(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - for (i = 1; i <= 100; i++) - cap_update_at(0, 0, LEN, i * TICK); - - if (cap_get(0) != 0) { - printf("Idle ring estimated %u.\n", cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_slow_link_extends(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - /* 1000 B every 100 us: 10 slots/ms closes on a 2 ms window. */ - for (i = 1; i <= 30; i++) - cap_update_at(0, QLEN, LEN, i * 2 * TICK); - - if (cap_get(0) != cap_enc(RATE / 2)) { - printf("Slow link: exp %u, got %u.\n", - cap_enc(RATE / 2), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_shaped_link(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - /* 1250 B every ms; one empty observation per 20 packets. */ - for (i = 1; i <= 100; i++) - cap_update_at(0, i % SHP_STEP == 0 ? 0 : 6, SHP_LEN, - i * SHP_STEP * TICK); - - if (cap_get(0) != cap_enc(SHP_RATE)) { - printf("Shaped link: exp %u, got %u.\n", - cap_enc(SHP_RATE), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_stale_discard(void) -{ - uint64_t t; - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - /* Open a window, trickle 4 slots, then ~200 ms of silence. */ - for (i = 1; i <= 5; i++) - cap_update_at(0, QLEN, LEN, i * CAP_T_MIN); - - t = 205 * CAP_T_MIN; - - cap_update_at(0, QLEN, LEN, t); - - if (cap_get(0) != 0) { - printf("Gap window estimated %u.\n", cap_get(0)); - goto fail_init; - } - - for (i = 1; i <= 40; i++) - cap_update_at(0, QLEN, LEN, t + i * TICK); - - if (cap_get(0) != cap_enc(RATE)) { - printf("Post-gap: exp %u, got %u.\n", - cap_enc(RATE), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_est_empty_start_no_raise(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - cap_update_at(0, 0, LEN, CAP_T_MIN); - - for (i = 1; i <= 40; i++) - cap_update_at(0, QLEN, LEN, CAP_T_MIN + i * TICK); - - if (cap_get(0) != 0) { - printf("Empty-start window raised to %u.\n", - cap_get(0)); - goto fail_init; - } - - for (i = 41; i <= 60; i++) - cap_update_at(0, QLEN, LEN, CAP_T_MIN + i * TICK); - - if (cap_get(0) != cap_enc(RATE)) { - printf("Backlogged window: exp %u, got %u.\n", - cap_enc(RATE), cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -/* Max filter: fast attack on a high sample, slow release on lower. */ -static int test_cap_est_max_filter(void) -{ - uint8_t high; - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - for (i = 1; i <= 40; i++) - cap_update_at(0, QLEN, LEN, i * TICK); - - high = cap_get(0); - if (high != cap_enc(RATE)) { - printf("Attack missed: exp %u, got %u.\n", cap_enc(RATE), - high); - goto fail_init; - } - - /* Halved packet size: valid samples at 10 MB/s. */ - for (i = 41; i <= 80; i++) - cap_update_at(0, QLEN, LEN / 2, i * TICK); - - if (cap_get(0) >= high) { - printf("Release did not decay: %u.\n", cap_get(0)); - goto fail_init; - } - - if (cap_get(0) <= cap_enc(RATE / 2)) { - printf("Release collapsed to %u.\n", cap_get(0)); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -/* No fold within CAP_T_MIN of the previous one. */ -static int test_cap_est_gate(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - cap_update_at(0, QLEN, LEN, CAP_T_MIN); - - for (i = 0; i < 5; i++) - cap_update_at(0, QLEN, LEN, CAP_T_MIN + CAP_T_MIN / 2); - - if (cap.est[0].t_gate != CAP_T_MIN) { - printf("Fold ran inside the gate.\n"); - goto fail_init; - } - - if (LOAD_RELAXED(&cap.est[0].c_pkt) != 6) { - printf("Gated packets not counted.\n"); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - -static int test_cap_reset(void) -{ - size_t i; - - TEST_START(); - - if (cap_init() < 0) { - printf("Failed to init cap.\n"); - goto fail; - } - - for (i = 1; i <= 40; i++) - cap_update_at(0, QLEN, LEN, i * TICK); - - if (cap_get(0) == 0) { - printf("No estimate to reset.\n"); - goto fail_init; - } - - cap_reset(0); - - if (cap_get(0) != 0) { - printf("Reset did not clear the estimate.\n"); - goto fail_init; - } - - cap_fini(); - - TEST_SUCCESS(); - - return TEST_RC_SUCCESS; - fail_init: - cap_fini(); - fail: - TEST_FAIL(); - return TEST_RC_FAIL; -} - int cap_test(int argc, char ** argv) { @@ -573,21 +168,10 @@ int cap_test(int argc, (void) argc; (void) argv; - ret |= test_cap_init_fini(); ret |= test_cap_codec_roundtrip(); ret |= test_cap_codec_bounds(); ret |= test_cap_min(); ret |= test_cap_stamp(); - ret |= test_cap_est_busy_window(); - ret |= test_cap_est_idle_tolerated(); - ret |= test_cap_est_mostly_idle_rejects(); - ret |= test_cap_est_slow_link_extends(); - ret |= test_cap_est_shaped_link(); - ret |= test_cap_est_stale_discard(); - ret |= test_cap_est_empty_start_no_raise(); - ret |= test_cap_est_max_filter(); - ret |= test_cap_est_gate(); - ret |= test_cap_reset(); return ret; } |
