Browse Source

Test incremental counts, empty replacements and startup-only scans

master
evgeny 6 days ago
parent
commit
9a06d19984
  1. 75
      tests/test_member_files.c

75
tests/test_member_files.c

@ -177,6 +177,79 @@ static void quota_commit(struct mf_storage* s, uint64_t group) {
q.data_len = 0; run(s, group, q.owner, MF_COMMIT, MF_OK);
}
static void check_counts(struct mf_storage* s, uint64_t group, uint64_t owner, uint64_t files, uint64_t directories) {
struct mf_message request = { .command = MF_QUOTA, .kind = MF_REQUEST, .owner = owner, .request_id = ++sequence }, response;
mf_storage_execute(s, group, owner, &request, &response);
EXPECT(response.status == MF_OK && response.data_len == MF_QUOTA_BYTES, "count snapshot response");
EXPECT(mf_get64(response.data + 24) == files && mf_get64(response.data + 32) == directories, "file/directory counters");
}
static void count_mutation(struct mf_storage* s, uint64_t group, uint64_t owner, const char* path,
const char* target, int command, int status) {
memset(&q, 0, sizeof(q)); q.owner = owner; snprintf(q.path, sizeof(q.path), "%s", path);
if (command != MF_MKDIR) { run(s, group, owner, MF_STAT, MF_OK); memcpy(q.version, r.version, 16); }
if (target) snprintf(q.target, sizeof(q.target), "%s", target);
run(s, group, owner, command, status);
}
static void count_test(const char* directory) {
char root[1200]; snprintf(root, sizeof(root), "%s/counts", directory);
struct mf_storage* s = mf_storage_create(root, 40, 200000);
EXPECT(s && !mf_storage_initialize(s), "count storage startup"); if (!s) return;
check_counts(s, 10, 101, 0, 0);
count_mutation(s, 10, 101, "folder", NULL, MF_MKDIR, MF_OK);
check_counts(s, 20, 101, 0, 1);
mf_storage_execute(s, 10, 101, &q, &r); EXPECT(r.status == MF_OK, "mkdir replay");
run(s, 10, 101, MF_MKDIR, MF_EXISTS); check_counts(s, 10, 101, 0, 1);
count_mutation(s, 10, 101, "folder/sub", NULL, MF_MKDIR, MF_OK);
check_counts(s, 10, 101, 0, 2);
quota_begin(s, 10, 101, "folder/zero", 0, 61, NULL, MF_OK);
check_counts(s, 10, 101, 0, 2); quota_commit(s, 10); check_counts(s, 10, 101, 1, 2);
uint8_t version[16]; memcpy(version, r.version, 16);
quota_begin(s, 10, 101, "folder/zero", 0, 62, version, MF_OK); quota_commit(s, 10);
memcpy(version, r.version, 16); check_counts(s, 10, 101, 1, 2);
quota_begin(s, 10, 101, "folder/zero", 2, 63, version, MF_OK); quota_commit(s, 10);
mf_storage_execute(s, 10, 101, &q, &r); EXPECT(r.status == MF_OK, "replacement replay");
check_counts(s, 20, 101, 1, 2);
quota_begin(s, 20, 101, "other", 3, 64, NULL, MF_OK); quota_commit(s, 20);
check_counts(s, 10, 101, 2, 2); check_quota(s, 10, 101, 5, 0, 40);
quota_begin(s, 10, 202, "other-user", 3, 65, NULL, MF_OK); quota_commit(s, 10);
check_counts(s, 10, 101, 2, 2); check_counts(s, 10, 202, 1, 0);
count_mutation(s, 10, 101, "folder", "moved", MF_RENAME, MF_OK);
check_counts(s, 10, 101, 2, 2);
count_mutation(s, 10, 101, "moved", NULL, MF_REMOVE, MF_IO_ERROR);
check_counts(s, 10, 101, 2, 2);
count_mutation(s, 10, 101, "moved/zero", NULL, MF_REMOVE, MF_OK);
mf_storage_execute(s, 10, 101, &q, &r); EXPECT(r.status == MF_OK, "file remove replay");
check_counts(s, 20, 101, 1, 2); check_quota(s, 20, 101, 3, 0, 40);
count_mutation(s, 10, 101, "moved/sub", NULL, MF_REMOVE, MF_OK);
mf_storage_execute(s, 10, 101, &q, &r); EXPECT(r.status == MF_OK, "directory remove replay");
check_counts(s, 20, 101, 1, 1);
count_mutation(s, 10, 101, "moved", NULL, MF_REMOVE, MF_OK); check_counts(s, 10, 101, 1, 0);
quota_begin(s, 10, 101, "aborted", 4, 66, NULL, MF_OK);
check_counts(s, 10, 101, 1, 0); run(s, 10, 101, MF_ABORT, MF_OK); check_counts(s, 10, 101, 1, 0);
quota_begin(s, 10, 101, "expired", 4, 67, NULL, MF_OK);
mf_storage_sweep(s, get_time_tb() + 200001); check_counts(s, 20, 101, 1, 0);
// Внешние изменения появляются в статистике только после нового старта, не после мутации/QUOTA.
char external[1400], folder[1400];
snprintf(external, sizeof(external), "%s/10/101/external.bin", root);
FILE* file = fopen(external, "wb"); EXPECT(file != NULL, "external file fixture");
if (file) { fputs("extra", file); fclose(file); }
snprintf(folder, sizeof(folder), "10/101/external-dir");
struct mf_disk_root disk; EXPECT(!mf_disk_root_open(&disk, root), "external directory fixture root");
int created = 0; EXPECT(!mf_disk_mkdir(&disk, folder, &created) && created, "mkdir reports creation");
created = 1; EXPECT(mf_disk_mkdir(&disk, folder, &created) == MF_EXISTS && !created, "existing mkdir reports no creation");
mf_disk_root_close(&disk);
count_mutation(s, 10, 101, "api-dir", NULL, MF_MKDIR, MF_OK);
check_counts(s, 10, 101, 1, 1); check_quota(s, 20, 101, 3, 0, 40);
quota_begin(s, 10, 101, "api-file", 1, 68, NULL, MF_OK); quota_commit(s, 10);
check_counts(s, 20, 101, 2, 1); check_quota(s, 10, 101, 4, 0, 40);
mf_storage_destroy(s); s = mf_storage_create(root, 40, 200000);
EXPECT(s && !mf_storage_initialize(s), "count restart scan"); if (!s) return;
check_counts(s, 20, 101, 3, 2); check_quota(s, 10, 101, 9, 0, 40);
check_counts(s, 10, 202, 1, 0); mf_storage_destroy(s);
}
static void quota_test(const char* directory) {
char root[1200]; snprintf(root, sizeof(root), "%s/quota", directory);
struct mf_storage* s = mf_storage_create(root, 40, 200000);
@ -273,7 +346,7 @@ int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); debug_set_category_level(DEBUG_CATEGORY_MEDIA, DEBUG_LEVEL_DEBUG);
char directory[1024] = "/tmp/utun_member_files_XXXXXX";
if (test_mkdtemp(directory)) return 1;
protocol_test(); storage_test(directory); quota_test(directory); quota_scan_failure_test(directory); worker_test();
protocol_test(); storage_test(directory); quota_test(directory); count_test(directory); quota_scan_failure_test(directory); worker_test();
#ifndef _WIN32
large_offset_test(directory);
#endif

Loading…
Cancel
Save