Assert media QUERY results and preserve transport ownership in tests

This commit is contained in:
evgeny committed 2026-10-22 18:31:12 +02:00
1 parent e02c9f7727
commit f47e80571d
2 files changed
+43 -17

No files matched your search

+8
View File
@@ -888,10 +888,18 @@ test_media_delivery_sql_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_media_delivery_download_SOURCES = test_media_delivery_download.c
test_media_delivery_download_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/media_delivery -I$(top_srcdir)/src/media_async -I$(top_srcdir)/lib -I$(top_srcdir)/src/transport_layer -I$(top_srcdir)/src/routing_layer -I$(top_srcdir)/src/chat
test_media_delivery_download_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_media_delivery_download_LDFLAGS = -Wl,--wrap=etcp_route_send
test_media_download_timeout_SOURCES = test_media_download_timeout.c
test_media_download_timeout_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/media_delivery -I$(top_srcdir)/src/media_async -I$(top_srcdir)/lib -I$(top_srcdir)/src/transport_layer -I$(top_srcdir)/src/routing_layer -I$(top_srcdir)/src/chat
test_media_download_timeout_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_media_download_timeout_LDFLAGS = -Wl,--wrap=etcp_route_send
check_PROGRAMS += test_media_query
test_media_query_SOURCES = test_media_query.c
test_media_query_CFLAGS = $(test_media_delivery_download_CFLAGS)
test_media_query_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_media_query_LDFLAGS = -Wl,--wrap=etcp_route_send -Wl,--wrap=RAND_bytes
test_media_delivery_integration_SOURCES = test_media_delivery_integration.c
test_media_delivery_integration_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/media_delivery -I$(top_srcdir)/src/media_async -I$(top_srcdir)/lib -I$(top_srcdir)/src/transport_layer -I$(top_srcdir)/src/routing_layer -I$(top_srcdir)/src/chat
+35 -17
View File
@@ -33,6 +33,13 @@
#include <unistd.h>
#include <sys/stat.h>
/* Доставка принята транспортом, ответа нет. Владение entry совпадает с реальным router во всех исходах. */
int __wrap_etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t dst,
struct ll_entry* entry, int force, int mode) {
(void)inst; (void)group; (void)dst; (void)force; (void)mode;
queue_dgram_free(entry); queue_entry_free(entry); return 0;
}
#define TEMP_DIR "/tmp/test_mdl_dl_XXXXXX"
#define CHUNK_SIZE 100
#define NUM_BLOCKS 3
@@ -135,6 +142,8 @@ static struct media_download* make_test_dl(sqlite3* db, struct UTUN_INSTANCE* in
static void free_test_dl(struct UTUN_INSTANCE* inst, struct media_download* dl) {
if (!dl) return;
if (dl->watchdog_timer) { uasync_cancel_timeout(inst->ua, dl->watchdog_timer); dl->watchdog_timer = NULL; }
if (dl->pump_timer) uasync_call_soon_cancel(inst->ua, dl->pump_timer);
for (int pi = 0; pi < dl->num_peers; pi++) if (dl->peers[pi].cm_handle) conn_mgr_close(dl->peers[pi].cm_handle);
u_free(dl->blocks);
u_free(dl->block_sigs);
if (inst->md.downloads) {
@@ -143,6 +152,17 @@ static void free_test_dl(struct UTUN_INSTANCE* inst, struct media_download* dl)
}
}
/* Полный ответ на текущую пачку; тесты задают только найденных держателей. */
static void query_response(struct media_download* dl, uint8_t* wire, int count) {
memset(wire, 0, MEDIA_QUERY_RESP_HDR_SIZE + (size_t)count * sizeof(struct media_pkt_query_resp_entry));
struct media_pkt_query_resp* r = (struct media_pkt_query_resp*)wire;
r->subcmd = MEDIA_SUBCMD_QUERY_RESP; r->num_blocks = (uint16_t)count;
memcpy(r->media_id, dl->media_id, 16); memset(r->request_id, 0xA5, 16); memcpy(dl->query_id, r->request_id, 16);
dl->query_node = 0x9001; dl->query_count = count; dl->query_deadline_tb = get_time_tb() + 20000;
struct media_pkt_query_resp_entry* entries = (struct media_pkt_query_resp_entry*)(wire + MEDIA_QUERY_RESP_HDR_SIZE);
for (int bi = 0; bi < count; bi++) { dl->query_blocks[bi] = bi; memcpy(entries[bi].block_id, dl->blocks[bi].block_id, 16); }
}
static void add_holder(struct media_download* dl, int bi, uint64_t node_id) {
struct media_download_block* b = &dl->blocks[bi];
if (b->num_holders < MD_MAX_HOLDERS_PER_BLOCK)
@@ -412,10 +432,12 @@ static void test_query_resp_empty(void) {
struct media_download* dl = make_test_dl(db, inst, 1);
if (!dl) { FAIL("make_test_dl"); sqlite3_close(db); u_free(inst); return; }
uint8_t pkt[MEDIA_QUERY_RESP_HDR_SIZE]; memset(pkt, 0, sizeof(pkt));
pkt[0] = MEDIA_SUBCMD_QUERY_RESP; /* num_entries = 0 */
media_download_handle_query_resp(inst, pkt, sizeof(pkt));
OK();
uint8_t pkt[MEDIA_QUERY_RESP_HDR_SIZE + sizeof(struct media_pkt_query_resp_entry)];
query_response(dl, pkt, 1);
media_download_handle_query_resp(inst, dl->group_id, dl->query_node, pkt, sizeof(pkt));
if (dl->blocks[0].num_holders == 1 && dl->blocks[0].holders[0] == dl->author_node_id
&& dl->blocks[0].state == MD_BLK_REQ && !dl->query_deadline_tb) OK();
else FAIL("empty result did not use author fallback");
free_test_dl(inst, dl);
sqlite3_close(db); u_free(inst);
@@ -433,17 +455,13 @@ static void test_query_resp_assign(void) {
/* 2 держателя на каждый блок */
uint64_t n1 = 0x1111, n2 = 0x2222;
struct media_pkt_query_resp_entry entries[6];
memset(entries, 0, sizeof(entries));
uint8_t pkt[MEDIA_QUERY_RESP_HDR_SIZE + 3 * sizeof(struct media_pkt_query_resp_entry)];
query_response(dl, pkt, 3);
struct media_pkt_query_resp_entry* entries = (struct media_pkt_query_resp_entry*)(pkt + MEDIA_QUERY_RESP_HDR_SIZE);
for (int i = 0; i < 3; i++) {
entries[i * 2 + 0].node_id = n1; memcpy(entries[i * 2 + 0].block_id, dl->blocks[i].block_id, 16);
entries[i * 2 + 1].node_id = n2; memcpy(entries[i * 2 + 1].block_id, dl->blocks[i].block_id, 16);
entries[i].num_holders = 2; entries[i].holders[0] = n1; entries[i].holders[1] = n2;
}
uint8_t pkt[3 + sizeof(entries)];
pkt[0] = MEDIA_SUBCMD_QUERY_RESP;
uint16_t ne = 6; memcpy(pkt + 1, &ne, 2);
memcpy(pkt + 3, entries, sizeof(entries));
media_download_handle_query_resp(inst, pkt, sizeof(pkt));
media_download_handle_query_resp(inst, dl->group_id, dl->query_node, pkt, sizeof(pkt));
/* блоки разложены: holder_idx = i % num_holders (стартовый разброс) */
int ok = 1;
@@ -498,11 +516,11 @@ static void test_cm_handle_lifetime(void) {
h->ua = g_ua; h->deliver_up_token = uasync_call_soon(g_ua, &late, late_up);
dl->num_peers = 1; dl->peers[0].node_id = 0x1111; dl->peers[0].cm_handle = h;
uint8_t wire[MEDIA_QUERY_RESP_HDR_SIZE + 2 * sizeof(struct media_pkt_query_resp_entry)] = {MEDIA_SUBCMD_QUERY_RESP};
uint16_t count = 2; memcpy(wire + 1, &count, 2);
query_response(dl, wire, 2);
struct media_pkt_query_resp_entry* entries = (struct media_pkt_query_resp_entry*)(wire + MEDIA_QUERY_RESP_HDR_SIZE);
for (int bi = 0; bi < 2; bi++) { entries[bi].node_id = 0x1111; memcpy(entries[bi].block_id, dl->blocks[bi].block_id, 16); }
media_download_handle_query_resp(inst, wire, sizeof(wire));
media_download_handle_query_resp(inst, wire, sizeof(wire));
for (int bi = 0; bi < 2; bi++) { entries[bi].num_holders = 1; entries[bi].holders[0] = 0x1111; }
media_download_handle_query_resp(inst, dl->group_id, dl->query_node, wire, sizeof(wire));
media_download_handle_query_resp(inst, dl->group_id, dl->query_node, wire, sizeof(wire));
int retained = dl->num_peers == 1 && dl->peers[0].cm_handle == h && dl->blocks[0].state == MD_BLK_CONN
&& dl->blocks[1].state == MD_BLK_CONN && dl->blocks[0].holder_idx == 0 && dl->blocks[1].holder_idx == 0;
md_dl_conn_cb(h, 0x1111, dl->group_id, CONN_EVENT_TIMEOUT, dl);