test(chat): verify invalid requests and diagnostic name lookup failures

This commit is contained in:
evgeny committed 2026-10-27 05:39:05 +01:00
1 parent 618c68268c
commit 5af4572ae1
2 files changed
+30 -5

No files matched your search

+8 -4
View File
@@ -258,18 +258,21 @@ struct voice_played_req {
uint64_t author_node_id;
};
// Сбор статуса (NTP + connections) и отправка в GUI. arg = struct UTUN_INSTANCE* (inst)
/* Снять текстовый статус NTP/connections:arg — заимствованный inst,ответ STATUS_REFRESH без конечного NUL.
* Динамический буфер живёт до возврата обработчика;отказ памяти/форматирования логируется без частичного события. */
void chat_core_collect_status_trampoline(void* arg);
// Лёгкий запрос нагрузки uasync для GUI. arg = inst, ответ CHAT_EVT_CPU_LOAD.
void chat_core_collect_cpu_load_trampoline(void* arg);
// Сбор списка ETCP-соединений и отправка в GUI (binary packet). arg = inst
/* Список до250 ETCP-соединений:arg — заимствованный inst,ответ CONN_LIST [count:u16 native][entry:46]*.
* Entry:peer:u64,flags:u8,links:u8,rtt:u16,inflight_KiB:u16,name:32;числа native,links/inflight насыщаются. */
void chat_core_collect_conn_list_trampoline(void* arg);
struct chat_node_arg { struct UTUN_INSTANCE* inst; uint64_t node_id; };
// Сбор полных метрик одного соединения (arg = u_malloc struct chat_node_arg)
/* Снять текстовые метрики соединения:arg — u_malloc chat_node_arg,забирается/освобождается,inst заимствован.
* Ответ CONN_METRICS без NUL,динамический буфер только до возврата обработчика;при OOM нет частичного события. */
void chat_core_collect_conn_metrics_trampoline(void* arg);
/* Диагностика карточки участника: запрос/codec находятся в chat_member.h. */
@@ -288,7 +291,8 @@ int chat_core_get_messages_json(struct UTUN_INSTANCE* inst, const char* ch_id, i
* connected означает наличие транспорта в реестре, а не его UP или готовность группы. */
int chat_core_get_members_json(struct UTUN_INSTANCE* inst, const char* ch_id, char* buf, size_t buf_size, size_t* out_len);
// Имя узла из таблицы nodes
/* Имя nodes с NUL,при необходимости обрезанное до sz-1 байт:0 — прочитано/узел отсутствует,-1 — ошибка.
* out/sz>0 обязательны;отсутствие узла и ошибка оставляют пустую строку (если буфер допустим). */
int chat_core_get_node_name(struct UTUN_INSTANCE* inst, uint64_t node_id, char* out, size_t sz);
// Ссылка на описание avatars/<sha256>.json внутри дерева своего UID/канала. server=0 удаляет ссылку.
+22 -1
View File
@@ -150,6 +150,15 @@ static void snapshots(struct UTUN_INSTANCE* inst) {
}
uint8_t* wire = NULL; int count = 0; assert(chat_core_get_member_list(NULL, channel, &wire, &count) < 0 && !wire && !count);
assert(!chat_core_member_online(NULL, channel, 7));
for (int rtt = 0; rtt < 2; rtt++) {
struct chat_member_list_req* req = u_calloc(1, sizeof(*req)); assert(req); strcpy(req->ch_id, channel);
if (rtt) chat_core_request_member_rtt_trampoline(req); else chat_core_request_member_list_trampoline(req);
req = u_malloc(sizeof(*req)); assert(req); req->inst = inst; memset(req->ch_id, '1', sizeof(req->ch_id));
if (rtt) chat_core_request_member_rtt_trampoline(req); else chat_core_request_member_list_trampoline(req);
}
struct chat_member_radio_mute_req* mute_req = u_malloc(sizeof(*mute_req)); assert(mute_req);
mute_req->inst = inst; mute_req->node_id = 7; memset(mute_req->ch_id, '1', sizeof(mute_req->ch_id));
chat_core_toggle_member_radio_mute_trampoline(mute_req);
on_member_props_changed(7, NULL, channel, inst); unsigned before = member_events;
target = "SELECT p.node_id"; fault = F_FINALIZE; on_member_props_changed(7, NULL, channel, inst);
assert(fault == F_NONE && before == member_events); on_member_props_changed(7, NULL, channel, inst); assert(member_events == before + 1);
@@ -211,6 +220,18 @@ static void details(struct UTUN_INSTANCE* inst) {
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "PASS member detail:4 SQL faults,complete addressed error replies and invalid request codec");
}
static void node_names(struct UTUN_INSTANCE* inst) {
target = "SELECT name FROM nodes"; char out[128];
for (enum fault point = F_PREPARE; point <= F_FINALIZE; point++) {
if (point == F_CHANGES) continue;
strcpy(out, "previous"); bind_index = 1; fault = point;
assert(chat_core_get_node_name(inst, inst->node_id, out, sizeof(out)) < 0 && !out[0] && fault == F_NONE);
assert(!chat_core_get_node_name(inst, inst->node_id, out, sizeof(out)) && !strcmp(out, inst->name));
}
out[0] = 'x'; assert(chat_core_get_node_name(inst, inst->node_id, out, 0) < 0 && out[0] == 'x');
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "PASS node names:4 SQL faults/retries,cleared failure output and zero-size guard");
}
static void diagnostics(struct UTUN_INSTANCE* inst) {
struct ETCP_CONN connection = {.instance = inst, .peer_node_id = 9, .unacked_bytes = UINT32_MAX};
struct ETCP_LINK* links = u_calloc(300, sizeof(*links)); assert(links); connection.links = links;
@@ -274,7 +295,7 @@ int main(void) {
inst->my_keys.public_key, inst->my_ed25519_pubkey));
snprintf(database, sizeof(database), "%s/chats.db", directory); assert(sqlite3_open_v2(database, &reader, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK);
chat_event_set_handler(inst, event); radio_set_mute_cb(inst, mute, NULL);
snapshots(inst); mutes(inst); details(inst); diagnostics(inst); member_limit(inst);
snapshots(inst); mutes(inst); details(inst); node_names(inst); diagnostics(inst); member_limit(inst);
assert(!radio_set_member_muted(inst, group_id, 7, 0)); unsigned display = member_events, audio = mute_events;
target = "COMMIT /* radio mute */"; fault = F_EXEC; fail_rollback = 1; inst->running = 1;
assert(chat_core_toggle_member_radio_mute(inst, channel, 7) < 0 && fault == F_NONE && !fail_rollback && !inst->running);