Commit 6d1ed8f7 authored by jan.koester's avatar jan.koester
Browse files

import test

parent c46f9cdb
Loading
Loading
Loading
Loading
+150 −0
Original line number Diff line number Diff line
@@ -871,6 +871,156 @@ TEST(preview_generate_and_cache) {
    }
}

// ═══════════════════════════════════════════════════════════
//  11. Cluster import: export → import → verify fetch + sync
// ═══════════════════════════════════════════════════════════

TEST(cluster_import_roundtrip) {
    auto tc = makeCluster();
    auto& node = *tc->nodes[0];

    BlobCache cache1(64 * 1024 * 1024, blob_value_size);
    ClusterMediaBackend src(node, cache1);

    // --- Step 1: create data on src backend ---
    auto store = src.create_store("import_test");
    ASSERT_TRUE(!store.id.empty());
    auto album = src.create_album(store.id, "album1");
    ASSERT_TRUE(album.has_value());

    constexpr size_t NUM_MEDIA = 5;
    constexpr size_t MEDIA_SIZE = 2048;
    std::vector<std::string> media_ids;
    for (size_t i = 0; i < NUM_MEDIA; i++) {
        auto data = makeTestData(MEDIA_SIZE, static_cast<uint8_t>(i));
        auto m = src.add_media(album->id,
            "file_" + std::to_string(i) + ".bin",
            "application/octet-stream", std::move(data));
        ASSERT_TRUE(m.has_value());
        media_ids.push_back(m->id);
    }

    std::string store_id = store.id;
    std::string album_id = album->id;

    // --- Step 2: export from src ---
    auto exported = src.export_db_to_buffer();
    ASSERT_TRUE(exported.size() > 0);
    std::cout << "  exported " << exported.size() << " bytes\n";

    // --- Step 3: verify raw cluster fetch BEFORE import on fresh backend ---
    // The src backend already replicated everything. Check keys are reachable.
    {
        std::vector<uint8_t> idx_data;
        bool idx_ok = node.fetch("index", idx_data);
        std::cout << "  fetch(index) before import: ok=" << idx_ok
                  << " size=" << idx_data.size() << "\n";
        ASSERT_TRUE(idx_ok);
        ASSERT_TRUE(idx_data.size() > 0);

        std::vector<uint8_t> store_data;
        bool store_ok = node.fetch("store:" + store_id, store_data);
        std::cout << "  fetch(store:" << store_id << ") before import: ok=" << store_ok
                  << " size=" << store_data.size() << "\n";
        ASSERT_TRUE(store_ok);
        ASSERT_TRUE(store_data.size() > 0);

        for (const auto& mid : media_ids) {
            std::vector<uint8_t> media_data;
            bool media_ok = node.fetch("media:" + mid, media_data);
            std::cout << "  fetch(media:" << mid << ") = ok=" << media_ok
                      << " size=" << media_data.size() << "\n";
            ASSERT_TRUE(media_ok);
            ASSERT_EQ(media_data.size(), MEDIA_SIZE);
        }
    }

    // --- Step 4: check group_id mapping ---
    {
        uint64_t idx_gid = cluster_group_id("index");
        uint64_t store_gid = cluster_group_id("store:" + store_id);
        std::cout << "  group_id(index) = " << idx_gid << "\n";
        std::cout << "  group_id(store:" << store_id << ") = " << store_gid << "\n";

        auto peer_groups = node.list_peer_groups();
        std::cout << "  " << peer_groups.size() << " peers:\n";
        for (const auto& pg : peer_groups) {
            std::cout << "    node[" << pg.index << "] " << pg.address << ":"
                      << pg.port << " online=" << pg.online
                      << " groups=" << pg.groups.size() << "\n";
            bool has_idx = std::find(pg.groups.begin(), pg.groups.end(), idx_gid) != pg.groups.end();
            bool has_store = std::find(pg.groups.begin(), pg.groups.end(), store_gid) != pg.groups.end();
            std::cout << "      has index_gid=" << has_idx
                      << " has store_gid=" << has_store << "\n";
        }
    }

    // --- Step 5: fresh backend, import, verify ---
    {
        BlobCache cache2(64 * 1024 * 1024, blob_value_size);
        ClusterMediaBackend dst(node, cache2);

        bool import_ok = dst.import_db_from_buffer(exported);
        std::cout << "  import_db_from_buffer: ok=" << import_ok << "\n";
        ASSERT_TRUE(import_ok);

        // Check stores are visible
        auto stores = dst.list_stores();
        std::cout << "  dst.list_stores() = " << stores.size() << "\n";
        ASSERT_EQ(stores.size(), 1u);
        ASSERT_EQ(stores[0].id, store_id);

        // Check albums
        auto albums = dst.list_albums(store_id);
        std::cout << "  dst.list_albums() = " << albums.size() << "\n";
        ASSERT_EQ(albums.size(), 1u);

        // Check media
        auto media = dst.list_media(album_id);
        std::cout << "  dst.list_media() = " << media.size() << "\n";
        ASSERT_EQ(media.size(), NUM_MEDIA);

        // Read media data
        for (size_t i = 0; i < NUM_MEDIA; i++) {
            auto raw = dst.read_media_data(media_ids[i]);
            std::cout << "  dst.read_media_data(" << media_ids[i] << ") = "
                      << raw.size() << " bytes\n";
            ASSERT_EQ(raw.size(), MEDIA_SIZE);
        }
    }

    // --- Step 6: fresh backend, sync_from_cluster, verify ---
    {
        BlobCache cache3(64 * 1024 * 1024, blob_value_size);
        ClusterMediaBackend sync_dst(node, cache3);

        std::cout << "  sync_from_cluster...\n";
        sync_dst.sync_from_cluster();

        auto stores = sync_dst.list_stores();
        std::cout << "  sync_dst.list_stores() = " << stores.size() << "\n";
        ASSERT_EQ(stores.size(), 1u);

        auto albums = sync_dst.list_albums(store_id);
        std::cout << "  sync_dst.list_albums() = " << albums.size() << "\n";
        ASSERT_EQ(albums.size(), 1u);

        auto media = sync_dst.list_media(album_id);
        std::cout << "  sync_dst.list_media() = " << media.size() << "\n";
        ASSERT_EQ(media.size(), NUM_MEDIA);

        // Read media data via cluster fetch
        for (size_t i = 0; i < NUM_MEDIA; i++) {
            auto raw = sync_dst.read_media_data(media_ids[i]);
            std::cout << "  sync_dst.read_media_data(" << media_ids[i] << ") = "
                      << raw.size() << " bytes\n";
            ASSERT_EQ(raw.size(), MEDIA_SIZE);
        }
    }

    std::cout << "  cluster_import_roundtrip: all checks passed\n";
}

// ═══════════════════════════════════════════════════════════
//  main
// ═══════════════════════════════════════════════════════════