165 lines
4 KiB
C
165 lines
4 KiB
C
#include <criterion/criterion.h>
|
|
#include <stdint.h>
|
|
#include "internal/ping/tracker.h"
|
|
|
|
static struct timespec
|
|
make_ts(long sec, long nsec)
|
|
{
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = sec;
|
|
ts.tv_nsec = nsec;
|
|
return (ts);
|
|
}
|
|
|
|
Test(ping_tracker, init)
|
|
{
|
|
struct ping_tracker t;
|
|
|
|
ping_tracker_init(&t);
|
|
cr_assert_eq(t.nb_sent, (size_t)0);
|
|
cr_assert_eq(t.nb_recv, (size_t)0);
|
|
}
|
|
|
|
Test(ping_tracker, basic_send_recv)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts_send;
|
|
struct timespec ts_recv;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts_send = make_ts(1, 0);
|
|
ts_recv = make_ts(1, 10000000); /* 10 ms later */
|
|
ping_tracker_record_send(&t, 1, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 1, &ts_recv);
|
|
cr_assert_eq(rtt, (int64_t)10000000, "Expected RTT of 10ms in ns");
|
|
cr_assert_eq(t.nb_sent, (size_t)1);
|
|
cr_assert_eq(t.nb_recv, (size_t)1);
|
|
}
|
|
|
|
Test(ping_tracker, double_recv_ignored)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts_send;
|
|
struct timespec ts_recv;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts_send = make_ts(0, 0);
|
|
ts_recv = make_ts(0, 5000000);
|
|
ping_tracker_record_send(&t, 5, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 5, &ts_recv);
|
|
cr_assert(rtt >= 0, "First recv should succeed");
|
|
rtt = ping_tracker_record_recv(&t, 5, &ts_recv);
|
|
cr_assert_eq(rtt, (int64_t)-1, "Duplicate recv should return -1");
|
|
cr_assert_eq(t.nb_recv, (size_t)1);
|
|
}
|
|
|
|
Test(ping_tracker, unknown_seq_returns_minus_one)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts = make_ts(0, 0);
|
|
rtt = ping_tracker_record_recv(&t, 42, &ts);
|
|
cr_assert_eq(rtt, (int64_t)-1);
|
|
}
|
|
|
|
Test(ping_tracker, wraparound_seq)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts_send;
|
|
struct timespec ts_recv;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts_send = make_ts(0, 0);
|
|
ts_recv = make_ts(0, 1000000);
|
|
/* seq 128 maps to slot 0 */
|
|
ping_tracker_record_send(&t, 128, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 128, &ts_recv);
|
|
cr_assert_eq(rtt, (int64_t)1000000);
|
|
}
|
|
|
|
Test(ping_tracker, lost_count)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts;
|
|
|
|
ping_tracker_init(&t);
|
|
ts = make_ts(0, 0);
|
|
ping_tracker_record_send(&t, 1, &ts);
|
|
ping_tracker_record_send(&t, 2, &ts);
|
|
ping_tracker_record_send(&t, 3, &ts);
|
|
ping_tracker_record_recv(&t, 2, &ts);
|
|
cr_assert_eq(t.nb_sent, (size_t)3);
|
|
cr_assert_eq(t.nb_recv, (size_t)1);
|
|
cr_assert_eq(t.nb_sent - t.nb_recv, (size_t)2);
|
|
}
|
|
|
|
Test(ping_tracker, sent_count_increments)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts;
|
|
|
|
ping_tracker_init(&t);
|
|
ts = make_ts(0, 0);
|
|
ping_tracker_record_send(&t, 1, &ts);
|
|
ping_tracker_record_send(&t, 2, &ts);
|
|
ping_tracker_record_send(&t, 3, &ts);
|
|
cr_assert_eq(t.nb_sent, (size_t)3);
|
|
}
|
|
|
|
Test(ping_tracker, recv_rtt_positive)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts_send;
|
|
struct timespec ts_recv;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts_send = make_ts(1, 0);
|
|
ts_recv = make_ts(1, 10000000); /* 10 ms later */
|
|
ping_tracker_record_send(&t, 7, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 7, &ts_recv);
|
|
cr_assert(rtt > 0, "RTT should be positive");
|
|
}
|
|
|
|
Test(ping_tracker, slot_reuse_after_wraparound)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts_send;
|
|
struct timespec ts_recv;
|
|
int64_t rtt;
|
|
|
|
ping_tracker_init(&t);
|
|
ts_send = make_ts(0, 0);
|
|
ts_recv = make_ts(0, 1000000);
|
|
/* seq=1 -> slot 1 */
|
|
ping_tracker_record_send(&t, 1, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 1, &ts_recv);
|
|
cr_assert(rtt >= 0, "First round RTT should be >= 0");
|
|
/* seq=129 -> slot 129 % 128 = 1, same slot */
|
|
ping_tracker_record_send(&t, 129, &ts_send);
|
|
rtt = ping_tracker_record_recv(&t, 129, &ts_recv);
|
|
cr_assert(rtt >= 0, "Second round RTT should be >= 0");
|
|
cr_assert_eq(t.nb_sent, (size_t)2);
|
|
cr_assert_eq(t.nb_recv, (size_t)2);
|
|
}
|
|
|
|
Test(ping_tracker, full_buffer)
|
|
{
|
|
struct ping_tracker t;
|
|
struct timespec ts;
|
|
uint16_t seq;
|
|
|
|
ping_tracker_init(&t);
|
|
ts = make_ts(0, 0);
|
|
for (seq = 1; seq <= 128; seq++)
|
|
ping_tracker_record_send(&t, seq, &ts);
|
|
cr_assert_eq(t.nb_sent, (size_t)128);
|
|
cr_assert_eq(t.nb_recv, (size_t)0);
|
|
}
|