summaryrefslogtreecommitdiff
path: root/src/ipcpd/unicast/tests/cap_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/unicast/tests/cap_test.c')
-rw-r--r--src/ipcpd/unicast/tests/cap_test.c434
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;
}