test(member-files): preserve unowned download temp on refusal
This commit is contained in:
1 parent
8185b83eba
commit
27dd9e7b60
1 file changed
+33
@@ -49,6 +49,8 @@ struct network_test {
|
||||
int (*server_receive_ready)(struct UTUN_INSTANCE*, uint64_t, uint64_t, const uint8_t*, size_t);
|
||||
int (*saved_receive_ready)(struct UTUN_INSTANCE*, uint64_t, uint64_t, const uint8_t*, size_t);
|
||||
unsigned restart_tick;
|
||||
unsigned preservation_case;
|
||||
char preserved_temp[864];
|
||||
struct api_case api[8];
|
||||
void* timer;
|
||||
};
|
||||
@@ -124,6 +126,27 @@ static int check_file(const char* path, unsigned size) {
|
||||
fclose(file); return ok;
|
||||
}
|
||||
|
||||
/* Чужой temp и прежнее назначение должны пережить отказ до создания своего файла. */
|
||||
static void preservation_start(struct network_test* t) {
|
||||
struct api_case* c = &t->api[7]; memset(c, 0, sizeof(*c)); c->id = 207 + t->preservation_case;
|
||||
snprintf(c->local, sizeof(c->local), "%s/preserved.bin", t->dir);
|
||||
snprintf(t->preserved_temp, sizeof(t->preserved_temp), "%s.utun-%016llx.part", c->local, (unsigned long long)c->id);
|
||||
const char* paths[] = { c->local, t->preserved_temp };
|
||||
for (unsigned n = 0; n < 2; n++) {
|
||||
FILE* file = fopen(paths[n], "wb");
|
||||
if (!file) { fail(t, "preservation fixture open"); return; }
|
||||
int error = 0;
|
||||
for (unsigned i = 0; i < 37; i++) if (fputc((i * 73 + 19) & 255, file) == EOF) error = 1;
|
||||
if (fclose(file) || error) { fail(t, "preservation fixture write/close"); return; }
|
||||
}
|
||||
struct mf_transfer_request q = { .inst = t->nodes[READER], .id = c->id, .group = GROUP,
|
||||
.server = t->ids[SERVER], .owner = t->ids[AUTHOR], .max_bytes = t->preservation_case == 1 ? BYTES - 1 : 0 };
|
||||
snprintf(q.remote, sizeof(q.remote), "file.bin"); snprintf(q.local, sizeof(q.local), "%s", c->local);
|
||||
c->handle = member_files_transfer_start(&q, api_event, c);
|
||||
if (!c->handle) { fail(t, "preservation transfer start"); return; }
|
||||
if (t->preservation_case == 2) member_files_transfer_cancel(c->handle);
|
||||
}
|
||||
|
||||
static int hold_receive(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer, const uint8_t* payload, size_t bytes) {
|
||||
(void)inst; (void)group; (void)peer; (void)payload; (void)bytes; return 0;
|
||||
}
|
||||
@@ -298,6 +321,16 @@ static void tick(void* arg) {
|
||||
if (t->api[7].status != MF_STALE || !check_file(t->api[7].local, 0)) {
|
||||
fail(t, "stale download changed existing destination"); return;
|
||||
}
|
||||
t->phase = 23; preservation_start(t);
|
||||
} else if (t->phase == 23 && t->api[7].finished) {
|
||||
const int expected[] = { MF_EXISTS, MF_INVALID_RANGE, MF_CANCELLED };
|
||||
int target_ok = check_file(t->api[7].local, 37), temp_ok = check_file(t->preserved_temp, 37);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "member_files: preservation case=%u status=%s expected=%s target=%d foreign_temp=%d",
|
||||
t->preservation_case, mf_status_text(t->api[7].status), mf_status_text(expected[t->preservation_case]), target_ok, temp_ok);
|
||||
if (t->api[7].status != expected[t->preservation_case] || !target_ok || !temp_ok) {
|
||||
fail(t, "download refusal/cancel removed unowned temp or changed target"); return;
|
||||
}
|
||||
if (++t->preservation_case < 3) { preservation_start(t); goto again; }
|
||||
t->phase = 10; t->answered = 0;
|
||||
struct mf_message q = { .command = MF_STAT, .owner = t->ids[AUTHOR] }; snprintf(q.path, sizeof(q.path), "cancelled.bin");
|
||||
if (!member_files_request(t->nodes[READER], GROUP, t->ids[SERVER], &q, response, t)) { fail(t, "cancelled STAT"); return; }
|
||||
|
||||
Reference in new issue
Block a user