Verify old relay readers survive a new download generation independently
This commit is contained in:
1 parent
bd0260040c
commit
8f97cf8070
2 files changed
+46
-6
No files matched your search
@@ -389,6 +389,40 @@ static void test_relay_cancel(void) {
|
||||
puts("relay cancellation: exact attempt, idempotent request, sibling isolation and producer failure cleanup: PASS");
|
||||
}
|
||||
|
||||
static void test_relay_generation(void) {
|
||||
for (int cancel_new = 0; cancel_new < 2; cancel_new++) {
|
||||
struct fixture f = ready(1);
|
||||
struct media_download* dl = download(f.client);
|
||||
struct media_block_source* old_source = dl->blocks[0].source;
|
||||
char old_path[FILE_IO_PATH_MAX]; snprintf(old_path, sizeof(old_path), "%s", old_source->storage.temporary);
|
||||
struct packet request = request_packet(dl, 0x300); receive(f.client, &request);
|
||||
struct ETCP_ROUTER_CONN* slow = etcp_router_conn_get(f.client, GROUP, 0x300, ETCP_RT_ID_MEDIA_DELIVERY);
|
||||
queue_set_threshold(slow->send_q, -1, 0);
|
||||
struct packet old_chunk = chunk_packet(f.client, 0, 1), old_done = done_packet(f.client);
|
||||
receive(f.client, &old_chunk); receive(f.client, &old_done); poll_ready();
|
||||
REQUIRE(!download(f.client) && old_source->refs == 1 && old_source->verified && !access(old_path, F_OK));
|
||||
start(f.client, &f.metadata); struct packet response = answer(f.server); receive(f.client, &response);
|
||||
dl = download(f.client); struct media_block_source* new_source = dl->blocks[0].source;
|
||||
REQUIRE(new_source != old_source && !old_source->indexed && new_source->indexed && new_source->refs == 1);
|
||||
unchanged(f.client, &old_chunk); unchanged(f.client, &old_done);
|
||||
if (cancel_new) REQUIRE(!media_download_cancel(f.client, dl->media_id, NULL, 0));
|
||||
capture_blocks = 1; queue_set_threshold(slow->send_q, 0, 0); poll_ready();
|
||||
REQUIRE(access(old_path, F_OK) && !f.client->md.streams && packet_count == 2);
|
||||
REQUIRE(packets[0].data[0] == MEDIA_SUBCMD_BLOCK_CHUNK && packets[1].data[0] == MEDIA_SUBCMD_BLOCK_DONE);
|
||||
REQUIRE(!memcmp(((struct media_pkt_block_chunk*)packets[0].data)->transfer_id,
|
||||
((struct media_pkt_block_req*)request.data)->transfer_id, 16));
|
||||
REQUIRE(((struct media_pkt_block_done*)packets[1].data)->status == MEDIA_BLOCK_OK);
|
||||
if (!cancel_new) {
|
||||
REQUIRE(download(f.client) == dl && dl->blocks[0].source == new_source && new_source->indexed && !new_source->available);
|
||||
struct packet chunk = chunk_packet(f.client, 0, 1), done = done_packet(f.client);
|
||||
receive(f.client, &chunk); receive(f.client, &done);
|
||||
REQUIRE(done_count == 2 && !done_err && !download(f.client));
|
||||
} else REQUIRE(done_count == 2 && done_err == -2);
|
||||
finish(&f);
|
||||
}
|
||||
puts("relay across restart: old verified file drains independently of a new producer's success or cancellation: PASS");
|
||||
}
|
||||
|
||||
static void test_destinations(void) {
|
||||
struct fixture f = ready(1); struct media_download* dl = download(f.client);
|
||||
char alias[1024]; snprintf(alias, sizeof(alias), "%s/./result.bin", directory);
|
||||
@@ -509,7 +543,8 @@ int main(void) {
|
||||
ua = uasync_create(); REQUIRE(ua);
|
||||
snprintf(directory, sizeof(directory), "/tmp/utun-blocks-XXXXXX"); REQUIRE(!test_mkdtemp(directory));
|
||||
test_identity_and_bounds(); test_rejected_attempts(); test_io_failures(); test_reentrant_cancel();
|
||||
test_growing_relay(); test_relay_cancel(); test_destinations(); test_registration_failure_and_keys(); test_relay_limit_and_idle();
|
||||
test_growing_relay(); test_relay_cancel(); test_relay_generation(); test_destinations();
|
||||
test_registration_failure_and_keys(); test_relay_limit_and_idle();
|
||||
test_indexed_source();
|
||||
REQUIRE(!rmdir(directory)); uasync_destroy(ua, 0);
|
||||
puts("media block regressions: PASS"); return 0;
|
||||
|
||||
@@ -94,7 +94,15 @@ static struct UTUN_INSTANCE* make_minimal_instance(sqlite3* db) {
|
||||
inst->node_id = 0xDEADBEEFDEADBEEFULL;
|
||||
inst->topo_sqlite_db = db;
|
||||
for (int i = 0; i < 32; i++) inst->my_ed25519_privkey[i] = (uint8_t)(rand() & 0xFF);
|
||||
memset(inst->my_ed25519_pubkey, 0xDD, 32);
|
||||
EVP_PKEY* author = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, inst->my_ed25519_privkey, 32);
|
||||
size_t key_size = 32;
|
||||
if (!author || EVP_PKEY_get_raw_public_key(author, inst->my_ed25519_pubkey, &key_size) != 1) exit(1);
|
||||
EVP_PKEY_free(author);
|
||||
if (sqlite3_exec(db, "CREATE TABLE nodes(node_id INTEGER PRIMARY KEY,ed25519_pubkey BLOB)", NULL, NULL, NULL)) exit(1);
|
||||
sqlite3_stmt* row = NULL;
|
||||
if (sqlite3_prepare_v2(db, "INSERT INTO nodes VALUES(0xAAA,?)", -1, &row, NULL) != SQLITE_OK
|
||||
|| sqlite3_bind_blob(row, 1, inst->my_ed25519_pubkey, 32, SQLITE_STATIC) != SQLITE_OK
|
||||
|| sqlite3_step(row) != SQLITE_DONE || sqlite3_finalize(row) != SQLITE_OK) exit(1);
|
||||
|
||||
inst->md.inst = inst;
|
||||
inst->md.db = db;
|
||||
@@ -129,10 +137,7 @@ static struct media_download* make_test_dl(sqlite3* db, struct UTUN_INSTANCE* in
|
||||
dl->active = 1;
|
||||
dl->inst = inst;
|
||||
dl->author_node_id = 0xAAAA000000000001ULL;
|
||||
EVP_PKEY* author = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, inst->my_ed25519_privkey, 32);
|
||||
size_t key_size = 32;
|
||||
if (!author || EVP_PKEY_get_raw_public_key(author, dl->author_pubkey, &key_size) != 1) exit(1);
|
||||
EVP_PKEY_free(author);
|
||||
memcpy(dl->author_pubkey, inst->my_ed25519_pubkey, 32);
|
||||
|
||||
struct ll_entry* qe = queue_entry_new(sizeof(*dl));
|
||||
if (!qe) { u_free(dl->blocks); u_free(dl->block_sigs); u_free(dl); return NULL; }
|
||||
|
||||
Reference in new issue
Block a user