test: identify custody replies and force storage-mediated file delivery
This commit is contained in:
1 parent
13d838988e
commit
b1bfb94f1f
2 files changed
+25
-15
No files matched your search
@@ -166,6 +166,8 @@ static int run(void) {
|
||||
REQUIRE(!member(A, 0, A, "admitted", 1));
|
||||
/* Отдельная A/B-группа нужна только для начала беседы, затем прямого маршрута нет. */
|
||||
REQUIRE(!member(A, 6, B, "admitted", 0) && !member(B, 6, A, "admitted", 0));
|
||||
/* Синхронизация подписанного состава не должна восстановить прямой путь в этом сценарии. */
|
||||
f.group[A][6]->stopping = f.group[B][6]->stopping = 1;
|
||||
topo_group_revalidate_members(f.group[A][6]); topo_group_revalidate_members(f.group[B][6]);
|
||||
REQUIRE(!dm_send(f.node[A], f.conv, "text", (const uint8_t*)"pairwise mailbox", 16));
|
||||
uint8_t packet[2048] = {1};
|
||||
@@ -214,7 +216,8 @@ static int file_delivery(void) {
|
||||
REQUIRE(sqlite3_finalize(st) == SQLITE_OK);
|
||||
REQUIRE(!dm_mailbox_store_file(f.node[A], f.node[B]->node_id, body, bytes));
|
||||
uint64_t end = get_time_tb() + 250000;
|
||||
while (value(B, "SELECT count(*) FROM dm_files WHERE ready=1") != 1 && get_time_tb() < end) uasync_poll(f.ua, 1);
|
||||
while ((value(B, "SELECT count(*) FROM dm_files WHERE ready=1") != 1 ||
|
||||
value(M, "SELECT count(*) FROM dm_custody WHERE ready=1") != 1) && get_time_tb() < end) uasync_poll(f.ua, 1);
|
||||
REQUIRE(value(B, "SELECT count(*) FROM dm_files WHERE ready=1") == 1);
|
||||
REQUIRE(sqlite3_prepare_v2(f.node[B]->topo_sqlite_db, "SELECT local_path FROM dm_files WHERE ready=1", -1, &st, NULL) == SQLITE_OK);
|
||||
REQUIRE(sqlite3_step(st) == SQLITE_ROW); snprintf(path, sizeof(path), "%s", sqlite3_column_text(st, 0));
|
||||
|
||||
@@ -21,7 +21,7 @@ static const uint8_t id[16] = {1};
|
||||
static uint8_t receipt[DM_MEDIA_RECEIPT_SIZE];
|
||||
|
||||
static int inject(enum operation op, const char* sql) {
|
||||
const char* prefixes[] = { "SELECT node_id FROM dm_media_holders", "UPDATE dm_media_holders SET released=1",
|
||||
const char* prefixes[] = { "SELECT node_id,assignment_id FROM dm_media_holders", "UPDATE dm_media_holders SET released=1",
|
||||
"UPDATE dm_media_jobs SET body=NULL" };
|
||||
if (fault != op || !sql || strncmp(sql, prefixes[target], strlen(prefixes[target]))) return 0;
|
||||
fault = NO_FAULT; hits++;
|
||||
@@ -55,9 +55,8 @@ int __wrap_sqlite3_finalize(sqlite3_stmt* st) {
|
||||
int __wrap_dm_media_send(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer,
|
||||
uint8_t cmd, const uint8_t* body, size_t len) {
|
||||
(void)inst; (void)group;
|
||||
assert(len == sizeof(receipt) && !memcmp(body, receipt, len));
|
||||
if (cmd == DM_MEDIA_RECEIPT) { assert(peer == 11); return -1; }
|
||||
assert(cmd == DM_MEDIA_DELETE);
|
||||
if (cmd == DM_MEDIA_RECEIPT) { assert(peer == 11 && len == sizeof(receipt) && !memcmp(body, receipt, len)); return -1; }
|
||||
assert(cmd == DM_MEDIA_DELETE && len == 16 + sizeof(receipt) && body[0] == (uint8_t)peer && !memcmp(body + 16, receipt, sizeof(receipt)));
|
||||
deletes++; last_peer = peer; return 0;
|
||||
}
|
||||
int __wrap_dm_route_group(struct UTUN_INSTANCE* inst, uint64_t peer, uint64_t preferred, uint64_t* group) {
|
||||
@@ -75,18 +74,26 @@ static void fixture(sqlite3* db, int pending) {
|
||||
exec_sql(db, "DELETE FROM dm_media_holders; DELETE FROM dm_media_jobs; DELETE FROM dm_file_targets");
|
||||
sqlite3_stmt* st = NULL;
|
||||
assert(sqlite3_prepare_v2(db, "INSERT INTO dm_media_jobs(id,author,recipient,seq,body,body_hash,holder,stored,receipt)"
|
||||
" VALUES(?,11,12,1,x'01020304',zeroblob(32),102,1,?)", -1, &st, NULL) == SQLITE_OK);
|
||||
" VALUES(?,11,12,1,x'01020304',zeroblob(32),101,1,?)", -1, &st, NULL) == SQLITE_OK);
|
||||
assert(sqlite3_bind_blob(st, 1, id, sizeof(id), SQLITE_STATIC) == SQLITE_OK);
|
||||
assert(sqlite3_bind_blob(st, 2, receipt, sizeof(receipt), SQLITE_STATIC) == SQLITE_OK);
|
||||
assert(sqlite3_step(st) == SQLITE_DONE && sqlite3_finalize(st) == SQLITE_OK);
|
||||
exec_sql(db, "INSERT INTO dm_file_targets SELECT id,12,1,receipt,NULL FROM dm_media_jobs");
|
||||
assert(sqlite3_prepare_v2(db, "INSERT INTO dm_media_holders(id,node_id,released) VALUES(?,101,?)",
|
||||
assert(sqlite3_prepare_v2(db, "INSERT INTO dm_media_holders(id,node_id,assignment_id,released)"
|
||||
" VALUES(?,101,x'65000000000000000000000000000000',?)",
|
||||
-1, &st, NULL) == SQLITE_OK);
|
||||
assert(sqlite3_bind_blob(st, 1, id, sizeof(id), SQLITE_STATIC) == SQLITE_OK);
|
||||
assert(sqlite3_bind_int(st, 2, !pending) == SQLITE_OK);
|
||||
assert(sqlite3_step(st) == SQLITE_DONE && sqlite3_finalize(st) == SQLITE_OK);
|
||||
}
|
||||
|
||||
/* Ответы привязаны к сохранённому назначению; номер группы не входит в его идентичность. */
|
||||
static void reply(struct dm_mb_media* media, uint64_t group, uint64_t peer, uint8_t cmd, const uint8_t* body, size_t len) {
|
||||
uint8_t packet[41] = {0}; packet[0] = (uint8_t)peer;
|
||||
assert(len + 16 <= sizeof(packet)); memcpy(packet + 16, body, len);
|
||||
dm_mailbox_media_recv(media, group, peer, cmd, packet, len + 16);
|
||||
}
|
||||
|
||||
static void check_receipt(sqlite3* db) {
|
||||
sqlite3_stmt* st = NULL;
|
||||
assert(sqlite3_prepare_v2(db, "SELECT receipt FROM dm_media_jobs", -1, &st, NULL) == SQLITE_OK);
|
||||
@@ -120,12 +127,12 @@ static void write_failures(struct UTUN_INSTANCE* inst, struct dm_mb_media* media
|
||||
if (target == BODY && op == BIND_INT) continue;
|
||||
fixture(inst->topo_sqlite_db, target == ACK);
|
||||
fault = op; hits = 0;
|
||||
if (target == ACK) dm_mailbox_media_recv(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
if (target == ACK) reply(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
else test_clock_next_timer(inst->ua);
|
||||
assert(hits == 1);
|
||||
if (target == ACK) {
|
||||
assert(scalar(inst->topo_sqlite_db, "SELECT released FROM dm_media_holders") == (op == FINALIZE));
|
||||
dm_mailbox_media_recv(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
reply(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
} else {
|
||||
assert(scalar(inst->topo_sqlite_db, "SELECT body IS NULL FROM dm_media_jobs") == (op == FINALIZE));
|
||||
}
|
||||
@@ -158,19 +165,19 @@ int main(void) {
|
||||
test_clock_next_timer(inst.ua); assert(deletes == sent + 1);
|
||||
assert(scalar(inst.topo_sqlite_db, "SELECT body IS NOT NULL FROM dm_media_jobs") == 1);
|
||||
check_receipt(inst.topo_sqlite_db);
|
||||
dm_mailbox_media_recv(media, 77, 999, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
reply(media, 77, 999, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
assert(scalar(inst.topo_sqlite_db, "SELECT released FROM dm_media_holders") == 0);
|
||||
exec_sql(inst.topo_sqlite_db, "INSERT INTO dm_media_holders SELECT id,102,0 FROM dm_media_jobs");
|
||||
dm_mailbox_media_recv(media, 78, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
exec_sql(inst.topo_sqlite_db, "INSERT INTO dm_media_holders SELECT id,102,x'66000000000000000000000000000000',0 FROM dm_media_jobs");
|
||||
reply(media, 78, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
assert(scalar(inst.topo_sqlite_db, "SELECT released FROM dm_media_holders WHERE node_id=101") == 1);
|
||||
dm_mailbox_media_recv(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
reply(media, 77, 101, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
exec_sql(inst.topo_sqlite_db, "UPDATE dm_media_jobs SET retry_at=0"); test_clock_next_timer(inst.ua);
|
||||
assert(last_peer == 102 && scalar(inst.topo_sqlite_db, "SELECT body IS NOT NULL FROM dm_media_jobs") == 1);
|
||||
dm_mailbox_media_recv(media, 77, 102, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
reply(media, 77, 102, DM_MEDIA_DELETE_ACK, id, sizeof(id));
|
||||
exec_sql(inst.topo_sqlite_db, "UPDATE dm_media_jobs SET retry_at=0"); test_clock_next_timer(inst.ua);
|
||||
assert(scalar(inst.topo_sqlite_db, "SELECT body IS NULL FROM dm_media_jobs") == 1);
|
||||
uint8_t stored[25] = {1};
|
||||
dm_mailbox_media_recv(media, 77, 101, DM_MEDIA_STORED, stored, sizeof(stored));
|
||||
reply(media, 77, 101, DM_MEDIA_STORED, stored, sizeof(stored));
|
||||
assert(last_peer == 101 && scalar(inst.topo_sqlite_db, "SELECT count(*) FROM dm_media_holders WHERE released=0") == 0);
|
||||
check_receipt(inst.topo_sqlite_db);
|
||||
dm_mailbox_media_destroy(media); assert(sqlite3_close(inst.topo_sqlite_db) == SQLITE_OK);
|
||||
|
||||
Reference in new issue
Block a user