Inject topology pool database registry and radio timer failures
This commit is contained in:
1 parent
d1562bdd0e
commit
56d513ed85
2 files changed
+68
-1
No files matched your search
+2
-1
@@ -732,7 +732,8 @@ test_node_snapshot_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
|
||||
test_topo_node_wire_SOURCES = test_topo_node_wire.c
|
||||
test_topo_node_wire_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
|
||||
if OS_LINUX
|
||||
test_topo_node_wire_LDFLAGS = -Wl,--wrap=u_malloc_impl -Wl,--wrap=u_calloc_impl -Wl,--wrap=memory_pool_alloc_impl
|
||||
test_topo_node_wire_LDFLAGS = -Wl,--wrap=u_malloc_impl -Wl,--wrap=u_calloc_impl -Wl,--wrap=memory_pool_alloc_impl \
|
||||
-Wl,--wrap=memory_pool_init -Wl,--wrap=topo_node_sqlite_init -Wl,--wrap=queue_entry_new -Wl,--wrap=uasync_set_timeout
|
||||
endif
|
||||
|
||||
test_ncd_config_SOURCES = test_ncd_config.c
|
||||
|
||||
@@ -28,6 +28,33 @@ struct wire_fixture {
|
||||
static unsigned fail_at, attempts, inside_pool;
|
||||
static int track_allocations;
|
||||
static int lifecycle_faults;
|
||||
static const char* fail_pool_name;
|
||||
static int fail_schema, fail_registry_entry;
|
||||
static const char* fail_timer_name;
|
||||
|
||||
struct memory_pool* __real_memory_pool_init(size_t, const char*);
|
||||
struct memory_pool* __wrap_memory_pool_init(size_t size, const char* name) {
|
||||
if (fail_pool_name && !strcmp(fail_pool_name, name)) return NULL;
|
||||
return __real_memory_pool_init(size, name);
|
||||
}
|
||||
|
||||
int __real_topo_node_sqlite_init(sqlite3*);
|
||||
int __wrap_topo_node_sqlite_init(sqlite3* db) {
|
||||
if (fail_schema) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "[fault] reject topology schema initialization"); return -1; }
|
||||
return __real_topo_node_sqlite_init(db);
|
||||
}
|
||||
|
||||
struct ll_entry* __real_queue_entry_new(size_t);
|
||||
struct ll_entry* __wrap_queue_entry_new(size_t size) {
|
||||
if (fail_registry_entry && size == 8 + sizeof(void*)) { fail_registry_entry = 0; return NULL; }
|
||||
return __real_queue_entry_new(size);
|
||||
}
|
||||
|
||||
void* __real_uasync_set_timeout(struct UASYNC*, int, void*, timeout_callback_t, const char*);
|
||||
void* __wrap_uasync_set_timeout(struct UASYNC* ua, int delay, void* arg, timeout_callback_t cb, const char* name) {
|
||||
if (fail_timer_name && !strcmp(fail_timer_name, name)) return NULL;
|
||||
return __real_uasync_set_timeout(ua, delay, arg, cb, name);
|
||||
}
|
||||
|
||||
static int allocation_fails(const char *where) {
|
||||
if (!track_allocations || (!strstr(where, "topo_node.c:") && !strstr(where, "topo_node_sqlite.c:") &&
|
||||
@@ -371,6 +398,9 @@ static void test_local_allocation_failures(struct wire_fixture *f) {
|
||||
assert(node->group_ref_count == before_refs && f->inst.rt->count == routes && live_allocations() == before);
|
||||
}
|
||||
lifecycle_faults = 0; fail_at = 0;
|
||||
fail_timer_name = "radio_talker";
|
||||
assert(!topo_groups_create_group(&f->groups, 43, TOPO_GROUP_TYPE_UTUN, NULL));
|
||||
fail_timer_name = NULL; uasync_poll(f->inst.ua, 0);
|
||||
queue_free(f->groups.group_list); f->groups.group_list = NULL;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "[PASS] group creation: %u allocation failures roll back all resources; radio retry preserved",
|
||||
creation_allocations);
|
||||
@@ -381,6 +411,41 @@ static void test_local_allocation_failures(struct wire_fixture *f) {
|
||||
uasync_destroy(f->inst.ua, 0); f->inst.ua = NULL; f->inst.config = NULL;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "[PASS] local group: %u allocation failures preserve identity, routes and ownership", total);
|
||||
}
|
||||
|
||||
/* Контейнер не может возвращать успех с отсутствующим пулом, БД или локальной записью. */
|
||||
static void test_registry_initialization(struct wire_fixture* f) {
|
||||
struct utun_config config = {0};
|
||||
struct UTUN_INSTANCE inst = {.config = &config, .node_id = f->inst.node_id};
|
||||
inst.my_keys = f->inst.my_keys;
|
||||
memcpy(inst.my_ed25519_pubkey, f->inst.my_ed25519_pubkey, 32);
|
||||
memcpy(inst.my_ed25519_privkey, f->inst.my_ed25519_privkey, 32);
|
||||
inst.ua = uasync_create(); assert(inst.ua);
|
||||
const char* pools[] = {"to_v4sock", "to_v4addr", "to_v6sock", "to_v6addr", "to_v4sub", "to_v6sub"};
|
||||
for (size_t i = 0; i < sizeof(pools) / sizeof(pools[0]); i++) {
|
||||
size_t before = live_allocations();
|
||||
fail_pool_name = pools[i];
|
||||
assert(!topo_groups_init(&inst) && !inst.topo_groups && !inst.topo_sqlite_db);
|
||||
fail_pool_name = NULL;
|
||||
assert(live_allocations() == before);
|
||||
}
|
||||
size_t before = live_allocations();
|
||||
snprintf(config.global.db_path, sizeof(config.global.db_path), "/dev/null");
|
||||
assert(!topo_groups_init(&inst) && !inst.topo_groups && !inst.topo_sqlite_db);
|
||||
assert(live_allocations() == before); config.global.db_path[0] = '\0';
|
||||
fail_schema = 1;
|
||||
assert(!topo_groups_init(&inst) && !inst.topo_groups && !inst.topo_sqlite_db);
|
||||
fail_schema = 0; assert(live_allocations() == before);
|
||||
fail_registry_entry = 1;
|
||||
assert(!topo_groups_init(&inst) && !fail_registry_entry && !inst.topo_groups && !inst.topo_sqlite_db);
|
||||
assert(live_allocations() == before);
|
||||
struct TOPO_GROUPS* registry = topo_groups_init(&inst); assert(registry);
|
||||
sqlite3* db = inst.topo_sqlite_db;
|
||||
assert(!topo_groups_init(&inst) && inst.topo_groups == registry && inst.topo_sqlite_db == db);
|
||||
topo_groups_destroy(&inst); sqlite3_close(db); inst.topo_sqlite_db = NULL;
|
||||
assert(live_allocations() == before);
|
||||
uasync_poll(inst.ua, 0); uasync_destroy(inst.ua, 0);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "[PASS] topology init: six pools, SQLite open/schema, registry OOM and duplicate initialization");
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void) {
|
||||
@@ -396,6 +461,7 @@ int main(void) {
|
||||
test_allocation_failures(&fixture);
|
||||
test_bootstrap_allocation_failures(&fixture);
|
||||
test_local_allocation_failures(&fixture);
|
||||
test_registry_initialization(&fixture);
|
||||
#endif
|
||||
fixture_destroy(&fixture);
|
||||
assert(u_get_allocated_count() == before);
|
||||
|
||||
Reference in new issue
Block a user