1 changed files with 107 additions and 0 deletions
@ -0,0 +1,107 @@
|
||||
// test_etcp_ping.c - unit test for etcp_send_ping with callback on PONG/timeout
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <stdint.h> |
||||
#include "../src/etcp_connections.h" |
||||
#include "../src/utun_instance.h" |
||||
#include "../lib/u_async.h" |
||||
#include "../lib/debug_config.h" |
||||
#include "../lib/mem.h" |
||||
#include "../src/secure_channel.h" |
||||
|
||||
#define TEST_TIMEOUT_MS 500 |
||||
static int test_completed = 0; |
||||
static int cb_called = 0; |
||||
static int cb_success = -1; |
||||
static uint64_t test_nonce = 0; |
||||
|
||||
static void ping_test_callback(int success, void* arg, uint64_t nonce) { |
||||
(void)arg; |
||||
cb_called++; |
||||
cb_success = success; |
||||
test_nonce = nonce; |
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "ping_test_callback: success=%d nonce=%016llx", success, (unsigned long long)nonce); |
||||
test_completed = 1; |
||||
} |
||||
|
||||
int main(void) { |
||||
debug_config_init(); |
||||
debug_set_level(DEBUG_LEVEL_TRACE); |
||||
debug_set_categories(DEBUG_CATEGORY_ALL); |
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "=== ETCP Ping Test ==="); |
||||
|
||||
struct UASYNC* ua = uasync_create(); |
||||
if (!ua) { |
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "uasync_create failed"); |
||||
return 1; |
||||
} |
||||
|
||||
struct UTUN_INSTANCE* instance = u_calloc(1, sizeof(struct UTUN_INSTANCE)); |
||||
if (!instance) { |
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "instance alloc failed"); |
||||
uasync_destroy(ua, 0); |
||||
return 1; |
||||
} |
||||
instance->ua = ua; |
||||
instance->node_id = 0x1234567890ABCDEFULL; |
||||
// dummy keys for test (full init in production)
|
||||
for (int i = 0; i < SC_PRIVKEY_SIZE; i++) { |
||||
instance->my_keys.private_key[i] = i; |
||||
instance->my_keys.public_key[i] = i + 64; |
||||
} |
||||
|
||||
struct ETCP_SOCKET* dummy_sock = u_calloc(1, sizeof(struct ETCP_SOCKET)); |
||||
if (!dummy_sock) { |
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "dummy sock alloc failed"); |
||||
utun_instance_destroy(instance); |
||||
uasync_destroy(ua, 0); |
||||
return 1; |
||||
} |
||||
dummy_sock->instance = instance; |
||||
dummy_sock->fd = socket(AF_INET, SOCK_DGRAM, 0); |
||||
dummy_sock->local_addr.ss_family = AF_INET; |
||||
instance->etcp_sockets = dummy_sock; |
||||
|
||||
// dummy pubkey
|
||||
uint8_t dummy_pubkey[SC_PUBKEY_SIZE]; |
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) dummy_pubkey[i] = i; |
||||
|
||||
struct sockaddr_storage test_addr; |
||||
memset(&test_addr, 0, sizeof(test_addr)); |
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&test_addr; |
||||
sin->sin_family = AF_INET; |
||||
sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
||||
sin->sin_port = htons(12345); |
||||
|
||||
// test timeout path (no receiver, expect success=0)
|
||||
int ret = etcp_send_ping(instance, dummy_pubkey, &test_addr, 100, ping_test_callback, NULL); |
||||
if (ret != 0) { |
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_send_ping failed ret=%d", ret); |
||||
utun_instance_destroy(instance); |
||||
uasync_destroy(ua, 0); |
||||
return 1; |
||||
} |
||||
|
||||
// run uasync to trigger timeout cb
|
||||
for (int i = 0; i < 20 && !test_completed; i++) { |
||||
uasync_poll(ua, 50); |
||||
} |
||||
|
||||
if (cb_called != 1 || cb_success != 0) { |
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "callback not triggered correctly: called=%d success=%d", cb_called, cb_success); |
||||
utun_instance_destroy(instance); |
||||
uasync_destroy(ua, 0); |
||||
return 1; |
||||
} |
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Ping timeout test PASSED (cb called with success=0)"); |
||||
|
||||
// cleanup
|
||||
utun_instance_destroy(instance); |
||||
uasync_destroy(ua, 0); |
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "ETCP ping unit test PASSED"); |
||||
return 0; |
||||
} |
||||
Loading…
Reference in new issue