ntptun/tests/test_replay.cpp
2026-07-24 21:05:01 +02:00

69 lines
2.2 KiB
C++

#include "ntptun/ReplayWindow.hpp"
#include "TestUtil.hpp"
using namespace ntptun;
void run_tests() {
// Strictly increasing timestamps are all accepted.
{
ReplayWindow w;
for (std::uint64_t t = 1; t <= 100; ++t) {
CHECK(w.accept(t, 16));
}
}
// An exact replay of an in-window timestamp is rejected.
{
ReplayWindow w;
CHECK(w.accept(10, 16));
CHECK(w.accept(11, 16));
CHECK(!w.accept(10, 16)); // replay
CHECK(!w.accept(11, 16)); // replay
CHECK(w.accept(12, 16)); // fresh again
}
// Reordering within the window is tolerated (out-of-order but unseen).
{
ReplayWindow w;
CHECK(w.accept(100, 16));
CHECK(w.accept(105, 16));
CHECK(w.accept(102, 16)); // arrived late but never seen -> accept
CHECK(!w.accept(102, 16)); // now a replay
CHECK(!w.accept(105, 16)); // replay
}
// Timestamps older than the retained window are rejected once it is full.
{
ReplayWindow w;
const std::size_t cap = 8;
for (std::uint64_t t = 100; t < 100 + cap; ++t) {
CHECK(w.accept(t, cap)); // fills [100..107]
}
// Advancing evicts the smallest; 100 falls out of the window.
CHECK(w.accept(200, cap)); // window now drops its floor
CHECK(!w.accept(100, cap)); // below floor -> rejected (replay/too-old)
CHECK(!w.accept(50, cap)); // far too old -> rejected
}
// capacity 0 disables the check: everything, including duplicates, passes.
{
ReplayWindow w;
CHECK(w.accept(5, 0));
CHECK(w.accept(5, 0)); // duplicate still accepted when disabled
CHECK(w.accept(1, 0));
}
// A smaller capacity retains only the largest timestamps.
{
ReplayWindow w;
for (std::uint64_t t = 1; t <= 10; ++t) {
CHECK(w.accept(t, 10)); // set = {1..10}
}
CHECK(w.accept(11, 3)); // shrink to the 3 largest: {9, 10, 11}
CHECK(!w.accept(8, 3)); // below the floor (9) -> rejected
CHECK(!w.accept(9, 3)); // still retained -> replay rejected
CHECK(w.accept(12, 3)); // fresh -> accepted
}
}
TEST_MAIN()