/* Проверяем настоящую схему media_delivery: restart, сброс старого кеша и сохранность media_files. */ #include "media_delivery_fixture.h" static void sql(sqlite3* db, const char* command) { REQUIRE(sqlite3_exec(db, command, NULL, NULL, NULL) == SQLITE_OK); } static sqlite3_int64 scalar(sqlite3* db, const char* command) { sqlite3_stmt* st = NULL; REQUIRE(sqlite3_prepare_v2(db, command, -1, &st, NULL) == SQLITE_OK && sqlite3_step(st) == SQLITE_ROW); sqlite3_int64 value = sqlite3_column_int64(st, 0); REQUIRE(sqlite3_finalize(st) == SQLITE_OK); return value; } int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_DEBUG, DEBUG_LEVEL_INFO); ua = uasync_create(); REQUIRE(ua); struct UTUN_INSTANCE* a = instance(SERVER); uint8_t epoch[16]; memcpy(epoch, a->md.source_epoch, 16); sql(a->md.db, "INSERT INTO block_availability(block_uuid,group_id,node_id,chunk,timestamp,status)" " VALUES(zeroblob(16),111,256,0,1,1),(zeroblob(16),222,256,0,1,1);" "INSERT INTO super_sync VALUES(111,512,zeroblob(16),4294967297),(222,512,zeroblob(16),8)"); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM block_availability") == 2); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM super_sync") == 2); media_delivery_destroy(a); REQUIRE(!media_delivery_init(a) && !memcmp(epoch, a->md.source_epoch, 16)); REQUIRE(scalar(a->md.db, "SELECT last_recv_id FROM super_sync WHERE group_id=111") == 4294967297LL); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM block_availability") == 2); /* Настоящая регистрация остаётся целой при пересоздании вспомогательного каталога. */ REQUIRE(!media_index_set_base(a->md.db, "/tmp")); uint8_t media[16] = {1}, block[16] = {2}, hash[32] = {0}; REQUIRE(!media_index_register_downloaded(a->md.db, media, block, hash, "111", "media-repl-preserved.bin", SERVER, 1, 1, 0, 0)); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM media_files") == 1); media_delivery_destroy(a); sql(a->topo_sqlite_db, "DROP TABLE block_availability"); REQUIRE(!media_delivery_init(a) && memcmp(epoch, a->md.source_epoch, 16)); REQUIRE(!scalar(a->md.db, "SELECT COUNT(*) FROM super_sync")); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM media_files") == 1); memcpy(epoch, a->md.source_epoch, 16); media_delivery_announce_media(a, GROUP, media, block, 1); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM block_availability") == 1); sqlite3_int64 high = scalar(a->md.db, "SELECT seq FROM sqlite_sequence WHERE name='block_availability'"); media_delivery_announce_media(a, GROUP, media, block, 1); REQUIRE(scalar(a->md.db, "SELECT seq FROM sqlite_sequence WHERE name='block_availability'") == high); /* Старая схема и её курсоры сбрасываются одной транзакцией, epoch меняется. */ media_delivery_destroy(a); sql(a->topo_sqlite_db, "DROP TABLE media_replication_meta; DROP TABLE block_availability; DROP TABLE super_sync;" "CREATE TABLE block_availability(id INTEGER PRIMARY KEY,block_uuid BLOB);" "CREATE TABLE super_sync(peer_node_id INTEGER PRIMARY KEY,last_recv_id INTEGER);" "INSERT INTO super_sync VALUES(512,99)"); REQUIRE(!media_delivery_init(a) && memcmp(epoch, a->md.source_epoch, 16)); REQUIRE(!scalar(a->md.db, "SELECT COUNT(*) FROM super_sync")); REQUIRE(scalar(a->md.db, "SELECT COUNT(*) FROM media_files") == 1); destroy(a); uasync_destroy(ua, 0); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "media catalog SQL restart/reset/preservation: PASS"); return 0; }