Run media integration replication in its actual CHAT group
This commit is contained in:
1 parent
00502bf4d4
commit
63c0b9a655
2 files changed
+18
-20
No files matched your search
@@ -4,7 +4,7 @@
|
||||
// Топология: цепь 0→1 1→2 2→3
|
||||
// Фазы:
|
||||
// P1: CHAT-группа (topo_groups_create_group + member_sync_put)
|
||||
// A1: SUPER_HELLO, HAVE_BLOCK, репликация
|
||||
// A1: роли CHAT, запросы страниц, HAVE_BLOCK, репликация
|
||||
// A2: admission control (OVERLOADED)
|
||||
// B1: n1 создаёт файл → n2 инициирует загрузку → стриминг → сборка → проверка
|
||||
|
||||
@@ -104,13 +104,13 @@ static void mon(void* arg) {
|
||||
if (!g_result) uasync_set_timeout(g_ua, 10, NULL, mon, "md_mon");
|
||||
}
|
||||
|
||||
static int msend(struct UTUN_INSTANCE* inst, uint64_t dst, const uint8_t* data, size_t len) {
|
||||
static int msend(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t dst, const uint8_t* data, size_t len) {
|
||||
struct ll_entry* e = queue_entry_new(0); if (!e) return -1;
|
||||
e->dgram = u_malloc(len + 1); if (!e->dgram) { queue_entry_free(e); return -1; }
|
||||
e->dgram[0] = ETCP_RT_ID_MEDIA_DELIVERY; memcpy(e->dgram + 1, data, len); e->len = (uint16_t)(len + 1);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[msend] 0x%016llx → 0x%016llx svc=0x%02x subcmd=0x%02x len=%zu",
|
||||
(unsigned long long)inst->node_id, (unsigned long long)dst, e->dgram[0], data[0], len);
|
||||
int rc = etcp_route_send(inst, TOPO_GROUP_UTUN, dst, e, 1, 0);
|
||||
int rc = etcp_route_send(inst, group, dst, e, 1, 0);
|
||||
if (rc != 0) DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "[msend] FAILED rc=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -175,19 +175,16 @@ static void setup_chat_group(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Phase A1: SUPER_HELLO ── */
|
||||
/* ── Phase A1: автоматический запуск по подписанным ролям CHAT ── */
|
||||
static void phase_a1_super_hello(void) {
|
||||
TEST("s1,s2 are supernodes"); {
|
||||
media_delivery_set_supernode(g_inst[2], 1);
|
||||
media_delivery_set_supernode(g_inst[3], 1);
|
||||
media_delivery_refresh_roles(g_inst[2]);
|
||||
media_delivery_refresh_roles(g_inst[3]);
|
||||
topo_node_sqlite_nodeinfo_updated(g_inst[2]->topo_sqlite_db, g_nid[2]);
|
||||
topo_node_sqlite_nodeinfo_updated(g_inst[3]->topo_sqlite_db, g_nid[3]);
|
||||
if (g_inst[2]->md.is_supernode && g_inst[3]->md.is_supernode) OK(); else FAIL();
|
||||
}
|
||||
TEST("SUPER_HELLO s1↔s2"); {
|
||||
struct media_pkt_super_hello h; h.subcmd = MEDIA_SUBCMD_SUPER_HELLO; h.last_recv_id = 0; h.group_id = TOPO_GROUP_UTUN;
|
||||
msend(g_inst[2], g_nid[3], (const uint8_t*)&h, sizeof(h));
|
||||
msend(g_inst[3], g_nid[2], (const uint8_t*)&h, sizeof(h));
|
||||
TEST("automatic CHAT replication s1↔s2"); {
|
||||
int a = 0; while (a < 500) { uasync_poll(g_ua, POLL_MS); a++; }
|
||||
int ok1 = g_inst[2]->md.super_peers && g_inst[2]->md.super_peers->head != NULL;
|
||||
int ok2 = g_inst[3]->md.super_peers && g_inst[3]->md.super_peers->head != NULL;
|
||||
@@ -203,18 +200,19 @@ static void phase_a2_have_block_replication(void) {
|
||||
hb.subcmd = MEDIA_SUBCMD_HAVE_BLOCK; hb.group_id = g_group_id;
|
||||
memcpy(hb.block_id, uuid, 16); memcpy(hb.media_id, uuid, 16);
|
||||
hb.chunk = 0; hb.timestamp = (int64_t)time(NULL);
|
||||
msend(g_inst[1], g_nid[2], (const uint8_t*)&hb, sizeof(hb));
|
||||
msend(g_inst[1], g_group_id, g_nid[2], (const uint8_t*)&hb, sizeof(hb));
|
||||
int a = 0; while (a < 500) { if (db_count(g_inst[2]->topo_sqlite_db, "block_availability", "node_id", g_nid[1]) >= 1) break; uasync_poll(g_ua, POLL_MS); a++; }
|
||||
if (db_count(g_inst[2]->topo_sqlite_db, "block_availability", "node_id", g_nid[1]) >= 1) OK(); else FAIL();
|
||||
}
|
||||
TEST("SUPER_REPL s1→s2"); {
|
||||
TEST("SYNC pages s1→s2"); {
|
||||
int a = 0; while (a < 500) { uasync_poll(g_ua, POLL_MS); a++; }
|
||||
if (db_count(g_inst[3]->topo_sqlite_db, "block_availability", NULL, 0) >= 1) OK(); else FAIL();
|
||||
}
|
||||
TEST("s2 super_sync updated"); {
|
||||
sqlite3_stmt* st = NULL; uint64_t lr = 0;
|
||||
sqlite3_prepare_v2(g_inst[3]->topo_sqlite_db, "SELECT last_recv_id FROM super_sync WHERE peer_node_id=?", -1, &st, NULL);
|
||||
sqlite3_bind_int64(st, 1, (sqlite3_int64)g_nid[2]);
|
||||
sqlite3_prepare_v2(g_inst[3]->topo_sqlite_db, "SELECT last_recv_id FROM super_sync WHERE group_id=? AND peer_node_id=?", -1, &st, NULL);
|
||||
sqlite3_bind_int64(st, 1, (sqlite3_int64)g_group_id);
|
||||
sqlite3_bind_int64(st, 2, (sqlite3_int64)g_nid[2]);
|
||||
if (sqlite3_step(st) == SQLITE_ROW) lr = (uint64_t)sqlite3_column_int64(st, 0);
|
||||
sqlite3_finalize(st);
|
||||
if (lr > 0) OK(); else FAIL();
|
||||
@@ -287,7 +285,7 @@ static void phase_a3_admission(void) {
|
||||
struct media_pkt_block_req req; memset(&req, 0, sizeof(req));
|
||||
req.subcmd = MEDIA_SUBCMD_BLOCK_REQ; assert(!media_index_generate_uuid(req.transfer_id));
|
||||
memcpy(req.media_id, g_test_mid, 16); memcpy(req.block_id, g_test_bid0, 16);
|
||||
msend(g_inst[1], g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
msend(g_inst[1], TOPO_GROUP_UTUN, g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
int a = 0; while (a < 500) { uasync_poll(g_ua, POLL_MS); a++; }
|
||||
if (g_inst[0]->md.streams_started >= 1) OK(); else FAIL("started=%d", g_inst[0]->md.streams_started);
|
||||
}
|
||||
@@ -297,7 +295,7 @@ static void phase_a3_admission(void) {
|
||||
struct media_pkt_block_req req; memset(&req, 0, sizeof(req));
|
||||
req.subcmd = MEDIA_SUBCMD_BLOCK_REQ; assert(!media_index_generate_uuid(req.transfer_id));
|
||||
memcpy(req.media_id, g_test_mid, 16); memcpy(req.block_id, g_test_bid0, 16);
|
||||
msend(g_inst[1], g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
msend(g_inst[1], TOPO_GROUP_UTUN, g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
}
|
||||
int a = 0; while (a < 500) { uasync_poll(g_ua, POLL_MS); a++; }
|
||||
int started = g_inst[0]->md.streams_started - before;
|
||||
@@ -316,7 +314,7 @@ static void phase_b1_stream_test(void) {
|
||||
memcpy(req.media_id, g_test_mid, 16); memcpy(req.block_id, g_test_bid1, 16);
|
||||
req.chunk = 1;
|
||||
g_inst[0]->md.stream_completed = 0;
|
||||
msend(g_inst[1], g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
msend(g_inst[1], TOPO_GROUP_UTUN, g_nid[0], (const uint8_t*)&req, sizeof(req));
|
||||
int a = 0;
|
||||
while (a < 3000 && !g_inst[0]->md.stream_completed) { uasync_poll(g_ua, POLL_MS); a++; }
|
||||
if (g_inst[0]->md.stream_completed) OK(); else FAIL("stream not completed after %dms", 3000 * POLL_MS);
|
||||
|
||||
@@ -28,9 +28,9 @@ int main(void) {
|
||||
|
||||
/* Настоящая регистрация остаётся целой при пересоздании вспомогательного каталога. */
|
||||
REQUIRE(!media_index_set_base(a->md.db, "/tmp"));
|
||||
uint8_t media[16] = {1}, block[16] = {2}, sig[64] = {0};
|
||||
REQUIRE(!media_index_register_downloaded(a->md.db, media, block, "111", "media-repl-preserved.bin",
|
||||
SERVER, sig, 1, 1, 1, 0, 0));
|
||||
uint8_t media[16] = {1}, block[16] = {2}, hash[32] = {0};
|
||||
REQUIRE(!media_index_register_downloaded(a->md.db, media, block, hash, "111", "media-repl-preserved.bin",
|
||||
SERVER, 1, 1, 0, 0));
|
||||
REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM media_files") == 1);
|
||||
media_delivery_destroy(a);
|
||||
sql(a->topo_sqlite_db, "DROP TABLE block_availability");
|
||||
|
||||
Reference in new issue
Block a user