Files
utun2/tests/test_media_delivery_sql.c
T
evgeny 326dfd7e2c media_delivery: маршрутизация всегда через CHAT-группу
media_download/медиа-ответы и суперузловая репликация теперь берут группу
из контекста (dl->group_id, group_id из пакета, peer->group_id) вместо
хардкода TOPO_GROUP_UTUN. node_props_changed получает channel_id.
SUPER_HELLO несёт group_id.
2026-09-03 23:24:50 +03:00

470 lines
21 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// test_media_delivery_sql.c — SQL-таблицы + протокольные структуры media_delivery
//
// Покрытие:
// 1. Создание таблиц block_availability + super_sync + индексов
// 2. INSERT OR REPLACE (upsert) — дубликат не создаёт вторую строку
// 3. SELECT с фильтром по block_uuid, сортировка timestamp DESC
// 4. SELECT с id > N, сортировка ASC, LIMIT
// 5. super_sync: INSERT OR REPLACE + SELECT (дефолт 0)
// 6. DELETE WHERE node_id=?
// 7. DELETE WHERE node_id!=? (чистка чужих при выключении суперузла)
// 8. Размеры packed-структур
// 9. Проверка полей packed-структур (нет padding-сюрпризов)
// 10. Построение/разбор MEDIA_QUERY
// 11. Построение/разбор MEDIA_HAVE_BLOCK
// 12. Построение/разбор MEDIA_SUPER_HELLO
#include "../src/media_delivery/media_delivery_proto.h"
#include "../lib/debug_config.h"
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
static int g_passed = 0, g_failed = 0, g_total = 0;
#define TEST(name) do { g_total++; printf(" %-50s", name); } while(0)
#define OK() do { g_passed++; printf("OK\n"); } while(0)
#define FAIL(fmt, ...) do { g_failed++; printf("FAIL: " fmt "\n", ##__VA_ARGS__); } while(0)
static void make_uuid(uint8_t buf[16]) {
for (int i = 0; i < 16; i++) buf[i] = (uint8_t)(rand() & 0xFF);
}
static sqlite3* make_db(void) {
sqlite3* db = NULL;
sqlite3_open(":memory:", &db);
sqlite3_exec(db, "PRAGMA journal_mode=memory", NULL, NULL, NULL);
return db;
}
static int create_tables(sqlite3* db) {
const char* sql_ba =
"CREATE TABLE IF NOT EXISTS block_availability ("
" id INTEGER PRIMARY KEY AUTOINCREMENT,"
" block_uuid BLOB NOT NULL,"
" group_id INTEGER NOT NULL,"
" node_id INTEGER NOT NULL,"
" chunk INTEGER NOT NULL,"
" timestamp INTEGER NOT NULL,"
" status INTEGER NOT NULL DEFAULT 1)"; // 0=processing, 1=completed
int rc = sqlite3_exec(db, sql_ba, NULL, NULL, NULL);
if (rc != SQLITE_OK) return -1;
sqlite3_exec(db, "CREATE UNIQUE INDEX IF NOT EXISTS idx_ba_uuid_node ON block_availability(block_uuid, node_id)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS idx_ba_id ON block_availability(id)", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE INDEX IF NOT EXISTS idx_ba_node_id ON block_availability(node_id)", NULL, NULL, NULL);
const char* sql_ss =
"CREATE TABLE IF NOT EXISTS super_sync ("
" peer_node_id INTEGER PRIMARY KEY,"
" last_recv_id INTEGER NOT NULL DEFAULT 0)";
rc = sqlite3_exec(db, sql_ss, NULL, NULL, NULL);
return (rc == SQLITE_OK) ? 0 : -1;
}
static int table_exists(sqlite3* db, const char* name) {
sqlite3_stmt* s = NULL;
int ok = 0;
if (sqlite3_prepare_v2(db, "SELECT name FROM sqlite_master WHERE type='table' AND name=?", -1, &s, NULL) == SQLITE_OK) {
sqlite3_bind_text(s, 1, name, -1, SQLITE_STATIC);
ok = (sqlite3_step(s) == SQLITE_ROW);
sqlite3_finalize(s);
}
return ok;
}
static int index_exists(sqlite3* db, const char* name) {
sqlite3_stmt* s = NULL;
int ok = 0;
if (sqlite3_prepare_v2(db, "SELECT name FROM sqlite_master WHERE type='index' AND name=?", -1, &s, NULL) == SQLITE_OK) {
sqlite3_bind_text(s, 1, name, -1, SQLITE_STATIC);
ok = (sqlite3_step(s) == SQLITE_ROW);
sqlite3_finalize(s);
}
return ok;
}
static int count_rows(sqlite3* db, const char* table) {
char sql[128]; snprintf(sql, sizeof(sql), "SELECT COUNT(*) FROM %s", table);
sqlite3_stmt* s = NULL;
int n = -1;
if (sqlite3_prepare_v2(db, sql, -1, &s, NULL) == SQLITE_OK) {
if (sqlite3_step(s) == SQLITE_ROW) n = sqlite3_column_int(s, 0);
sqlite3_finalize(s);
}
return n;
}
/* ── test cases ── */
static void test_tables(void) {
TEST("create tables exist"); {
sqlite3* db = make_db();
if (create_tables(db) != 0) { FAIL("create_tables failed"); sqlite3_close(db); return; }
int ba = table_exists(db, "block_availability");
int ss = table_exists(db, "super_sync");
if (ba && ss) OK(); else FAIL("ba=%d ss=%d", ba, ss);
sqlite3_close(db);
}
TEST("create tables idempotent"); {
sqlite3* db = make_db();
if (create_tables(db) != 0) { FAIL("first create"); sqlite3_close(db); return; }
if (create_tables(db) != 0) { FAIL("second create"); sqlite3_close(db); return; }
OK();
sqlite3_close(db);
}
TEST("indices exist"); {
sqlite3* db = make_db();
create_tables(db);
int i1 = index_exists(db, "idx_ba_uuid_node");
int i2 = index_exists(db, "idx_ba_id");
int i3 = index_exists(db, "idx_ba_node_id");
if (i1 && i2 && i3) OK(); else FAIL("i1=%d i2=%d i3=%d", i1, i2, i3);
sqlite3_close(db);
}
}
static void test_ba_insert(void) {
TEST("ba_insert basic"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
uint64_t gid = 0x100, nid = 0x200;
const char* sql = "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
for (int i = 0; i < 3; i++) {
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, sql, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_bind_int64(s, 2, (sqlite3_int64)gid);
sqlite3_bind_int64(s, 3, (sqlite3_int64)(nid + (uint64_t)i));
sqlite3_bind_int(s, 4, i);
sqlite3_bind_int64(s, 5, (sqlite3_int64)time(NULL));
sqlite3_step(s); sqlite3_finalize(s);
}
int n = count_rows(db, "block_availability");
if (n == 3) OK(); else FAIL("expected 3 rows got %d", n);
sqlite3_close(db);
}
TEST("ba_insert upsert (unique uuid+node)"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
const char* sql = "INSERT OR REPLACE INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
for (int pass = 0; pass < 2; pass++) {
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, sql, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_bind_int64(s, 2, (sqlite3_int64)1);
sqlite3_bind_int64(s, 3, (sqlite3_int64)0x300);
sqlite3_bind_int(s, 4, 0);
sqlite3_bind_int64(s, 5, (sqlite3_int64)(pass + 100));
sqlite3_step(s); sqlite3_finalize(s);
}
int n = count_rows(db, "block_availability");
if (n == 1) OK(); else FAIL("expected 1 row (upsert) got %d", n);
sqlite3_close(db);
}
}
static void test_ba_find(void) {
TEST("ba_find nodes by uuid"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
const char* ins = "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
for (int i = 0; i < 5; i++) {
sqlite3_stmt* s = NULL; sqlite3_prepare_v2(db, ins, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_bind_int64(s, 2, (sqlite3_int64)1);
sqlite3_bind_int64(s, 3, (sqlite3_int64)(0x10 + i));
sqlite3_bind_int(s, 4, i);
sqlite3_bind_int64(s, 5, (sqlite3_int64)(2000 - i));
sqlite3_step(s); sqlite3_finalize(s);
}
const char* q = "SELECT node_id FROM block_availability WHERE block_uuid=? ORDER BY timestamp DESC LIMIT 3";
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, q, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
int count = 0, first_node = -1;
while (sqlite3_step(s) == SQLITE_ROW) { if (count == 0) first_node = sqlite3_column_int(s, 0); count++; }
sqlite3_finalize(s);
if (count == 3 && first_node == 0x10) OK(); else FAIL("count=%d first_node=0x%x", count, first_node);
sqlite3_close(db);
}
}
static void test_ba_get_since(void) {
TEST("ba_get_since id > N"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
const char* ins = "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
for (int i = 0; i < 6; i++) {
sqlite3_stmt* s = NULL; sqlite3_prepare_v2(db, ins, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_bind_int64(s, 2, (sqlite3_int64)1);
sqlite3_bind_int64(s, 3, (sqlite3_int64)(0x20 + i));
sqlite3_bind_int(s, 4, i);
sqlite3_bind_int64(s, 5, (sqlite3_int64)1000);
sqlite3_step(s); sqlite3_finalize(s);
}
const char* q = "SELECT id FROM block_availability WHERE id > ? ORDER BY id ASC LIMIT 4";
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, q, -1, &s, NULL);
sqlite3_bind_int64(s, 1, 1);
int count = 0;
while (sqlite3_step(s) == SQLITE_ROW) count++;
sqlite3_finalize(s);
if (count == 4) OK(); else FAIL("expected 4 rows got %d", count);
sqlite3_close(db);
}
}
/* ── status column tests ── */
static void test_ba_status(void) {
/* processing→completed: DELETE old + INSERT new, ids don't reuse */
TEST("ba_complete: new id > processing id"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; for (int i = 0; i < 16; i++) uuid[i] = (uint8_t)(0xAA + i);
sqlite3_stmt* s = NULL;
/* 1. INSERT processing (status=0) */
sqlite3_prepare_v2(db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status) VALUES(?,1,0xAA,0,100,0)", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_step(s); sqlite3_finalize(s);
/* 2. get processing id */
int64_t pid = -1;
sqlite3_prepare_v2(db, "SELECT id FROM block_availability WHERE node_id=0xAA AND status=0", -1, &s, NULL);
if (sqlite3_step(s) == SQLITE_ROW) pid = sqlite3_column_int64(s, 0);
sqlite3_finalize(s);
/* 3. DELETE processing + INSERT completed (new id) */
sqlite3_exec(db, "DELETE FROM block_availability WHERE block_uuid=x'AAABACADAEAFB0B1B2B3B4B5B6B7B8B9' AND node_id=0xAA AND status=0", NULL, NULL, NULL);
sqlite3_prepare_v2(db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status) VALUES(?,1,0xAA,0,200,1)", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_step(s); sqlite3_finalize(s);
/* 4. get completed id */
int64_t cid = -1;
sqlite3_prepare_v2(db, "SELECT id,status FROM block_availability WHERE node_id=0xAA", -1, &s, NULL);
int st = -1;
if (sqlite3_step(s) == SQLITE_ROW) { cid = sqlite3_column_int64(s, 0); st = sqlite3_column_int(s, 1); }
sqlite3_finalize(s);
int n = count_rows(db, "block_availability");
if (n == 1 && st == 1 && cid > pid) OK(); else FAIL("rows=%d status=%d pid=%lld cid=%lld (expected 1 row, status=1, cid>pid)", n, st, (long long)pid, (long long)cid);
sqlite3_close(db);
}
/* completed already exists → no-op, no duplicate */
TEST("ba_complete: no-op when completed exists"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; for (int i = 0; i < 16; i++) uuid[i] = (uint8_t)(0xBB + i);
sqlite3_stmt* s = NULL;
/* 1. INSERT completed */
sqlite3_prepare_v2(db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status) VALUES(?,1,0xBB,0,300,1)", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_step(s); sqlite3_finalize(s);
int64_t id1 = -1;
sqlite3_prepare_v2(db, "SELECT id FROM block_availability WHERE node_id=0xBB", -1, &s, NULL);
if (sqlite3_step(s) == SQLITE_ROW) id1 = sqlite3_column_int64(s, 0);
sqlite3_finalize(s);
/* 2. DELETE processing (none) + check completed exists + skip INSERT */
sqlite3_exec(db, "DELETE FROM block_availability WHERE block_uuid=x'BBBCBDBEBFC0C1C2C3C4C5C6C7C8C9' AND node_id=0xBB AND status=0", NULL, NULL, NULL);
int exists = 0;
sqlite3_prepare_v2(db, "SELECT 1 FROM block_availability WHERE block_uuid=? AND node_id=0xBB AND status=1", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
exists = (sqlite3_step(s) == SQLITE_ROW);
sqlite3_finalize(s);
/* 3. Don't insert if exists */
int64_t id2 = -1;
sqlite3_prepare_v2(db, "SELECT id FROM block_availability WHERE node_id=0xBB", -1, &s, NULL);
if (sqlite3_step(s) == SQLITE_ROW) id2 = sqlite3_column_int64(s, 0);
sqlite3_finalize(s);
int n = count_rows(db, "block_availability");
if (n == 1 && exists && id2 == id1) OK(); else FAIL("rows=%d exists=%d id1=%lld id2=%lld (expected 1 row, same id)", n, exists, (long long)id1, (long long)id2);
sqlite3_close(db);
}
/* processing after completed INSERT → CONSTRAINT violation */
TEST("ba_processing after completed: constraint violation"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; for (int i = 0; i < 16; i++) uuid[i] = (uint8_t)(0xCC + i);
sqlite3_stmt* s = NULL;
/* 1. INSERT completed */
sqlite3_prepare_v2(db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status) VALUES(?,1,0xCC,0,400,1)", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
sqlite3_step(s); sqlite3_finalize(s);
/* 2. try INSERT processing (same uuid+node) → must fail with unique constraint */
int rc = SQLITE_OK;
sqlite3_prepare_v2(db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status) VALUES(?,1,0xCC,0,500,0)", -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC);
rc = sqlite3_step(s);
sqlite3_finalize(s);
/* 3. completed is still there, unchanged */
int n = count_rows(db, "block_availability");
int64_t ts_check = -1;
sqlite3_prepare_v2(db, "SELECT timestamp FROM block_availability WHERE node_id=0xCC", -1, &s, NULL);
if (sqlite3_step(s) == SQLITE_ROW) ts_check = sqlite3_column_int64(s, 0);
sqlite3_finalize(s);
if (n == 1 && rc == SQLITE_CONSTRAINT && ts_check == 400) OK();
else FAIL("rows=%d rc=%d ts=%lld (expected 1 row, CONSTRAINT, ts=400)", n, rc, (long long)ts_check);
sqlite3_close(db);
}
}
static void test_ss_ops(void) {
TEST("super_sync insert+select"); {
sqlite3* db = make_db(); create_tables(db);
sqlite3_exec(db, "INSERT OR REPLACE INTO super_sync(peer_node_id,last_recv_id) VALUES(0xAA, 42)", NULL, NULL, NULL);
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, "SELECT last_recv_id FROM super_sync WHERE peer_node_id=?", -1, &s, NULL);
sqlite3_bind_int64(s, 1, 0xAA);
int v = -1;
if (sqlite3_step(s) == SQLITE_ROW) v = sqlite3_column_int(s, 0);
sqlite3_finalize(s);
if (v == 42) OK(); else FAIL("expected 42 got %d", v);
sqlite3_close(db);
}
TEST("super_sync default 0"); {
sqlite3* db = make_db(); create_tables(db);
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, "SELECT last_recv_id FROM super_sync WHERE peer_node_id=?", -1, &s, NULL);
sqlite3_bind_int64(s, 1, 0xCC);
int v = -1;
if (sqlite3_step(s) == SQLITE_ROW) v = sqlite3_column_int(s, 0);
else v = 0; /* no row = default */
sqlite3_finalize(s);
if (v == 0) OK(); else FAIL("expected 0 got %d", v);
sqlite3_close(db);
}
}
static void test_ba_delete(void) {
TEST("ba_delete by node_id"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
const char* ins = "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
sqlite3_stmt* s = NULL;
sqlite3_prepare_v2(db, ins, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC); sqlite3_bind_int64(s, 2, 1);
sqlite3_bind_int64(s, 3, 0x500); sqlite3_bind_int(s, 4, 0);
sqlite3_bind_int64(s, 5, 100); sqlite3_step(s); sqlite3_finalize(s);
sqlite3_prepare_v2(db, ins, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC); sqlite3_bind_int64(s, 2, 1);
sqlite3_bind_int64(s, 3, 0x600); sqlite3_bind_int(s, 4, 0);
sqlite3_bind_int64(s, 5, 100); sqlite3_step(s); sqlite3_finalize(s);
if (count_rows(db, "block_availability") != 2) { FAIL("setup failed"); sqlite3_close(db); return; }
sqlite3_exec(db, "DELETE FROM block_availability WHERE node_id=0x500", NULL, NULL, NULL);
int n = count_rows(db, "block_availability");
if (n == 1) OK(); else FAIL("expected 1 got %d", n);
sqlite3_close(db);
}
TEST("ba_delete foreign (node_id != self)"); {
sqlite3* db = make_db(); create_tables(db);
uint8_t uuid[16]; make_uuid(uuid);
const char* ins = "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp) VALUES(?,?,?,?,?)";
sqlite3_stmt* s = NULL;
for (int i = 0; i < 3; i++) {
sqlite3_prepare_v2(db, ins, -1, &s, NULL);
sqlite3_bind_blob(s, 1, uuid, 16, SQLITE_STATIC); sqlite3_bind_int64(s, 2, 1);
sqlite3_bind_int64(s, 3, (sqlite3_int64)(0x700 + i)); sqlite3_bind_int(s, 4, i);
sqlite3_bind_int64(s, 5, 100); sqlite3_step(s); sqlite3_finalize(s);
}
char buf[128]; snprintf(buf, sizeof(buf), "DELETE FROM block_availability WHERE node_id!=0x700");
sqlite3_exec(db, buf, NULL, NULL, NULL);
int n = count_rows(db, "block_availability");
if (n == 1) OK(); else FAIL("expected 1 (self) got %d", n);
sqlite3_close(db);
}
}
static void test_proto_sizes(void) {
TEST("packed struct sizes"); {
int ok = 1;
if (sizeof(struct media_pkt_query) != 27) { FAIL("query: %zu != 27", sizeof(struct media_pkt_query)); ok = 0; }
if (sizeof(struct media_pkt_have_block) != 117) { FAIL("have_block: %zu != 117", sizeof(struct media_pkt_have_block)); ok = 0; }
if (sizeof(struct media_pkt_super_hello) != 17) { FAIL("super_hello: %zu != 17", sizeof(struct media_pkt_super_hello)); ok = 0; }
if (sizeof(struct media_pkt_super_ack) != 5) { FAIL("super_ack: %zu != 5", sizeof(struct media_pkt_super_ack)); ok = 0; }
if (sizeof(struct media_pkt_block_req) != 53) { FAIL("block_req: %zu != 53", sizeof(struct media_pkt_block_req)); ok = 0; }
if (sizeof(struct media_pkt_cancel) != 37) { FAIL("cancel: %zu != 37", sizeof(struct media_pkt_cancel)); ok = 0; }
if (sizeof(struct media_pkt_block_done) != 105) { FAIL("block_done: %zu != 105", sizeof(struct media_pkt_block_done)); ok = 0; }
if (sizeof(struct media_pkt_query_resp_entry) != 30) { FAIL("query_resp_entry: %zu != 30", sizeof(struct media_pkt_query_resp_entry)); ok = 0; }
if (ok) OK();
/* continue running even if sizes mismatch */
}
}
static void test_proto_build(void) {
TEST("build MEDIA_QUERY"); {
uint8_t mid[16]; memset(mid, 0xAB, 16);
uint8_t bids[32]; memset(bids, 0xCD, 32);
uint8_t pkt[256];
struct media_pkt_query* q = (struct media_pkt_query*)pkt;
q->subcmd = MEDIA_SUBCMD_QUERY;
q->group_id = 0x12345678;
memcpy(q->media_id, mid, 16);
q->num_blocks = 2;
memcpy(pkt + MEDIA_QUERY_HDR_SIZE, bids, 32);
if (q->subcmd == MEDIA_SUBCMD_QUERY && q->group_id == 0x12345678 &&
q->num_blocks == 2 && memcmp(q->media_id, mid, 16) == 0 &&
memcmp(pkt + MEDIA_QUERY_HDR_SIZE, bids, 32) == 0) OK();
else FAIL();
}
TEST("build MEDIA_HAVE_BLOCK"); {
struct media_pkt_have_block hb;
memset(&hb, 0, sizeof(hb));
hb.subcmd = MEDIA_SUBCMD_HAVE_BLOCK;
hb.group_id = 0xAA;
hb.chunk = 5;
hb.timestamp = 999;
if (hb.subcmd == MEDIA_SUBCMD_HAVE_BLOCK && hb.group_id == 0xAA &&
hb.chunk == 5 && hb.timestamp == 999) OK();
else FAIL();
}
TEST("build MEDIA_SUPER_HELLO"); {
struct media_pkt_super_hello sh;
sh.subcmd = MEDIA_SUBCMD_SUPER_HELLO;
sh.last_recv_id = 12345;
sh.group_id = 0x11223344;
if (sh.subcmd == MEDIA_SUBCMD_SUPER_HELLO && sh.last_recv_id == 12345 && sh.group_id == 0x11223344) OK();
else FAIL();
}
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR);
srand((unsigned)time(NULL));
printf("=== test_media_delivery_sql ===\n");
test_tables();
test_ba_insert();
test_ba_find();
test_ba_get_since();
test_ba_status();
test_ss_ops();
test_ba_delete();
test_proto_sizes();
test_proto_build();
printf("\n%d/%d passed, %d failed\n", g_passed, g_total, g_failed);
return g_failed > 0 ? 1 : 0;
}