#include #include #include "compiler.h" #include #include #include "icmp.h" #include "internal/ping/send.h" #include "internal/ping/ping_state.h" #include "internal/ping/tracker.h" #include "ping/ping.h" /* Controllable mock state */ int g_mock_send_ret; int g_mock_retry_ret; int __wrap_icmp_send_echo(icmp_handle_t *h __unused, struct in_addr dest __unused, uint16_t id __unused, uint16_t seq __unused, uint8_t ttl __unused, const void *payload __unused, size_t len __unused) { return g_mock_send_ret; } int __wrap_icmp_should_retry(const icmp_handle_t *h __unused) { return g_mock_retry_ret; } const char *__wrap_icmp_strerror(const icmp_handle_t *h __unused) { return "mock error"; } int __wrap_ping_scheduler_arm(const struct ping_config *c __unused) { return 0; } static struct ping_config g_config; static struct ping_tracker g_tracker; static struct ping_state g_state; static void setup(void) { g_config = (struct ping_config){0}; g_state = (struct ping_state){ .handle = NULL, .config = &g_config, .tracker = &g_tracker, .seq = 0, }; ping_tracker_init(&g_tracker); g_mock_send_ret = 0; g_mock_retry_ret = 0; } Test(do_send, success_increments_seq, .init = setup) { g_mock_send_ret = 0; do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)1); cr_assert_eq(g_tracker.nb_sent, (size_t)1); } Test(do_send, eagain_does_not_consume_seq, .init = setup) { g_mock_send_ret = 1; g_mock_retry_ret = 1; do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)0); cr_assert_eq(g_tracker.nb_sent, (size_t)0); } Test(do_send, hard_error_does_not_consume_seq, .init = setup) { g_mock_send_ret = -1; g_mock_retry_ret = 0; do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)0); cr_assert_eq(g_tracker.nb_sent, (size_t)0); } Test(do_send, multiple_success_increments_seq, .init = setup) { g_mock_send_ret = 0; do_send(&g_state, 16); do_send(&g_state, 16); do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)3); cr_assert_eq(g_tracker.nb_sent, (size_t)3); } Test(do_send, eagain_then_success_uses_same_seq, .init = setup) { g_mock_send_ret = 1; g_mock_retry_ret = 1; do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)0); g_mock_send_ret = 0; g_mock_retry_ret = 0; do_send(&g_state, 16); cr_assert_eq(g_state.seq, (uint16_t)1); cr_assert_eq(g_tracker.nb_sent, (size_t)1); }