test(chat): exercise channel deletion from a topology notification
This commit is contained in:
1 parent
189ae43a7c
commit
33556fefea
1 file changed
+29
-3
@@ -21,6 +21,9 @@ static int argument, last_target;
|
||||
static sqlite3* reader;
|
||||
static struct nodeinfo_cbk_entry* preserved_callback;
|
||||
static unsigned ready;
|
||||
static uint64_t route_group;
|
||||
static int route_delete, route_inspect;
|
||||
static unsigned route_seen, route_events;
|
||||
extern int __real_member_sync_add_props_cbk(struct UTUN_INSTANCE*, node_props_changed_fn, void*);
|
||||
int __wrap_member_sync_add_props_cbk(struct UTUN_INSTANCE* inst, node_props_changed_fn callback, void* arg) {
|
||||
if (fail_props) { fail_props = 0; fail_malloc = 1; }
|
||||
@@ -97,7 +100,13 @@ static void snapshot(sqlite3* db, uint8_t out[32]) {
|
||||
}
|
||||
|
||||
static void event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int bytes) {
|
||||
(void)data; (void)bytes;
|
||||
if (type == CHAT_EVT_MEMBER_UPDATED && route_group && bytes > 0 && data[0] < 21 && bytes > data[0]) {
|
||||
char ch[21]; memcpy(ch, data + 1, data[0]); ch[data[0]] = 0;
|
||||
if (strtoull(ch, NULL, 10) == route_group) {
|
||||
route_events++;
|
||||
if (route_delete) { route_delete = 0; chat_core_delete_channel(inst, ch); }
|
||||
}
|
||||
}
|
||||
if (type != CHAT_EVT_DB_READY && type != CHAT_EVT_MY_NODE_ID) return;
|
||||
assert(chat_core_is_initialized(inst) && sqlite3_get_autocommit(inst->topo_sqlite_db));
|
||||
sqlite3_stmt* st = NULL;
|
||||
@@ -129,7 +138,11 @@ static int deny_accounts(void* arg, int action, const char* name, const char* a,
|
||||
}
|
||||
|
||||
static int veto(void* arg) { (*(unsigned*)arg)++; return 1; }
|
||||
static void preserved(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* node, void* arg) { (void)group; (void)node; (void)arg; }
|
||||
static void preserved(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* node, void* arg) {
|
||||
if (route_inspect) {
|
||||
assert(group->group_id == route_group && node->node_id == ((struct UTUN_INSTANCE*)arg)->node_id); route_seen++;
|
||||
}
|
||||
}
|
||||
|
||||
static void sql_faults(struct UTUN_INSTANCE* inst, const char* path) {
|
||||
const char* queries[] = {"INSERT OR REPLACE INTO local_identity", "SELECT value FROM ui_state WHERE key='media_base'"}; unsigned cases = 0;
|
||||
@@ -205,6 +218,19 @@ static void activation(struct UTUN_INSTANCE* inst, const char* path) {
|
||||
puts("PASS lifecycle:corrupt catalog rejected;second channel activation failure cleans all runtime,keeps data,and retries without false ready");
|
||||
}
|
||||
|
||||
static void route_notifications(struct UTUN_INSTANCE* inst, struct UASYNC* ua) {
|
||||
ready = 0; assert(!chat_service_start(inst) && ready == 2);
|
||||
route_group = chat_core_create_channel_auto(inst, "delete after route dispatch"); assert(route_group); uasync_poll(ua, 0);
|
||||
struct TOPO_GROUP* group = topo_groups_find(inst->topo_groups, route_group); assert(group && group->local_node);
|
||||
route_seen = route_events = 0; route_inspect = route_delete = 1;
|
||||
topo_fire_nodeinfo_cbk(inst, group, group->local_node);
|
||||
assert(group->local_node->node_id == inst->node_id && route_seen == 1 && route_delete && !route_events);
|
||||
route_inspect = 0; uasync_poll(ua, 0);
|
||||
assert(!route_delete && route_events == 1 && !topo_groups_find(inst->topo_groups, route_group));
|
||||
route_group = 0; chat_service_stop(inst);
|
||||
puts("PASS lifecycle:route observers and caller retain live group/node until dispatch returns;deferred event may delete channel");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); size_t baseline = u_get_allocated_count();
|
||||
utun_instance_set_tun_init_enabled(0); struct UASYNC* ua = uasync_create(); assert(ua);
|
||||
@@ -217,7 +243,7 @@ int main(void) {
|
||||
assert(!utun_add_nodeinfo_cbk(inst, preserved, inst)); preserved_callback = inst->nodeinfo_cbks;
|
||||
unsigned denied = 0; assert(sqlite3_set_authorizer(inst->topo_sqlite_db, deny_accounts, &denied) == SQLITE_OK);
|
||||
refused(inst, database); assert(denied == 1); assert(sqlite3_set_authorizer(inst->topo_sqlite_db, NULL, NULL) == SQLITE_OK);
|
||||
retry(inst, database); sql_faults(inst, database); validation(inst, database); activation(inst, database);
|
||||
retry(inst, database); sql_faults(inst, database); validation(inst, database); activation(inst, database); route_notifications(inst, ua);
|
||||
uint8_t before[32], after[32]; snapshot(reader, before); ready = 0;
|
||||
target = "COMMIT /* chat init */"; fault = F_EXEC; fail_rollback = 1; inst->running = 1;
|
||||
assert(chat_core_init(inst, database) < 0 && fault == F_NONE && !fail_rollback && !inst->running && !inst->chat_core);
|
||||
|
||||
Reference in new issue
Block a user