From 3309bee7eb4b41ce73f887e49be427e4534375de Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 03:24:22 +0100 Subject: [PATCH] Compare attachment SQL timestamps using the SQLite clock --- tests/test_attachment_requests.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/test_attachment_requests.c b/tests/test_attachment_requests.c index 55843be6..b4af7d11 100644 --- a/tests/test_attachment_requests.c +++ b/tests/test_attachment_requests.c @@ -144,6 +144,14 @@ static void sql(struct fixture* f, const char* query) { assert(rc == SQLITE_OK); } +/* Проверяем SQLite timestamps её же часами: libc time() может отставать у границы секунды. */ +static int64_t database_time(struct fixture* f) { + sqlite3_stmt* st = NULL; + assert(sqlite3_prepare_v2(f->reader, "SELECT unixepoch()", -1, &st, NULL) == SQLITE_OK && sqlite3_step(st) == SQLITE_ROW); + int64_t now = sqlite3_column_int64(st, 0); + assert(sqlite3_step(st) == SQLITE_DONE && sqlite3_finalize(st) == SQLITE_OK); return now; +} + static struct snapshot snapshot(struct fixture* f) { sqlite3_stmt* st = NULL; struct snapshot result = {0}; assert(sqlite3_prepare_v2(f->reader, "SELECT a.key,a.error,r.message_id IS NOT NULL,coalesce(r.incoming,-1),coalesce(r.state,-1)," @@ -166,7 +174,11 @@ static struct snapshot snapshot(struct fixture* f) { static void equal(struct fixture* f) { struct snapshot current = snapshot(f); if (f->expected.created < 0) { - assert(current.created >= f->started && current.created <= (int64_t)time(NULL)); f->expected.created = current.created; + int64_t now = database_time(f); + if (current.created < f->started || current.created > now) + DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "request test: created=%lld outside SQLite bounds=%lld..%lld", + (long long)current.created, (long long)f->started, (long long)now); + assert(current.created >= f->started && current.created <= now); f->expected.created = current.created; } assert(current.key_bytes == f->expected.key_bytes && !memcmp(current.key, f->expected.key, 32)); assert(current.error == f->expected.error && current.exists == f->expected.exists); @@ -207,7 +219,7 @@ int __wrap_etcp_router_conn_send(struct ETCP_ROUTER_CONN* conn, const uint8_t* d assert(!memcmp(data + 5, active->message, 32) && !memcmp(data + 37, active->id, 16) && !memcmp(data + 53, active->hash, 32)); if (active->outgoing) { active->expected.retry = snapshot(active).retry; - assert(active->expected.retry >= active->started + 5 && active->expected.retry <= (int64_t)time(NULL) + 5); + assert(active->expected.retry >= active->started + 5 && active->expected.retry <= database_time(active) + 5); } equal(active); active->acks++; return active->send_rc; } @@ -226,7 +238,7 @@ static void event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int } static void receive(struct fixture* f, int success) { - f->expected = snapshot(f); f->allow_result = success; f->acks = f->events = 0; f->started = (int64_t)time(NULL); + f->expected = snapshot(f); f->allow_result = success; f->acks = f->events = 0; f->started = database_time(f); if (success) { if (!f->expected.exists) { f->expected.exists = 1; f->expected.incoming = 1; f->expected.state = 0; f->expected.created = -1; } if (f->expected.state) { f->expected.command = f->expected.state == 3 ? 4 : 3; f->expected.retry = 0; } @@ -411,7 +423,7 @@ static void outgoing_reset(struct fixture* f, int queued) { } static void outgoing_tick(struct fixture* f, int create, int sends) { - f->expected = snapshot(f); f->allow_result = create || sends; f->acks = f->events = 0; f->started = (int64_t)time(NULL); + f->expected = snapshot(f); f->allow_result = create || sends; f->acks = f->events = 0; f->started = database_time(f); if (create) { f->expected.exists = 1; f->expected.incoming = 0; f->expected.state = 0; f->expected.created = -1; f->expected.command = 1; f->expected.retry = 0; @@ -420,7 +432,7 @@ static void outgoing_tick(struct fixture* f, int create, int sends) { uasync_cancel_timeout(f->ua, CC(f->inst)->attachment_timer); attachment_tick(f->inst); if (sends || (create && (!f->route_up || !f->room))) { f->expected.retry = snapshot(f).retry; - assert(f->expected.retry >= f->started + 5 && f->expected.retry <= (int64_t)time(NULL) + 5); + assert(f->expected.retry >= f->started + 5 && f->expected.retry <= database_time(f) + 5); } equal(f); assert(f->events == (unsigned)create && f->acks == (unsigned)sends); }