Commit 71c1592f authored by jan.koester's avatar jan.koester
Browse files

test

parent 178d0a4c
Loading
Loading
Loading
Loading
+117 −0
Original line number Diff line number Diff line
@@ -3,12 +3,15 @@
#include <paritypp/parity.h>
#include <paritypp/auth.h>
#include <paritypp/protocol.h>
#include <paritypp/server.h>

#include <iostream>
#include <cstring>
#include <cassert>
#include <vector>
#include <algorithm>
#include <filesystem>
#include <cstdlib>

using namespace paritypp;

@@ -340,6 +343,119 @@ static void test_auth_protocol() {
    std::cout << "  Auth protocol tests passed." << std::endl;
}

static void test_file_block_store() {
    std::cout << "=== File Block Store (write-hole protection) ===" << std::endl;

    std::string dir = "/tmp/paritypp_test_" + std::to_string(getpid());
    std::filesystem::remove_all(dir);

    // Test 1: basic store/fetch with CRC32
    {
        file_block_store store(dir, 0); // threshold=0: flush every write
        std::vector<uint8_t> data = {1, 2, 3, 4, 5, 6, 7, 8};
        assert(store.store(100, 0, data.data(), data.size()));

        std::vector<uint8_t> out;
        assert(store.fetch(100, 0, out));
        assert(out == data);
        assert(store.total_blocks() == 1);
        assert(store.total_groups() == 1);
    }

    // Test 2: reopen and verify data survives (CRC32 validated on scan)
    {
        file_block_store store(dir, 0);
        std::vector<uint8_t> out;
        assert(store.fetch(100, 0, out));
        std::vector<uint8_t> expected = {1, 2, 3, 4, 5, 6, 7, 8};
        assert(out == expected);
        assert(store.total_blocks() == 1);
    }

    // Test 3: overwrite + vacuum
    {
        file_block_store store(dir, 0);
        std::vector<uint8_t> data2 = {10, 20, 30};
        assert(store.store(100, 0, data2.data(), data2.size()));

        std::vector<uint8_t> out;
        assert(store.fetch(100, 0, out));
        assert(out == data2);

        assert(store.vacuum());
        out.clear();
        assert(store.fetch(100, 0, out));
        assert(out == data2);
    }

    // Test 4: multiple groups and blocks
    {
        file_block_store store(dir, 0);
        for (uint64_t g = 200; g < 205; ++g) {
            for (uint32_t b = 0; b < 4; ++b) {
                std::vector<uint8_t> d(64, static_cast<uint8_t>(g + b));
                store.store(g, b, d.data(), d.size());
            }
        }

        assert(store.total_groups() >= 5); // 200-204 + maybe 100 from above

        for (uint64_t g = 200; g < 205; ++g) {
            auto blocks = store.list_blocks(g);
            assert(blocks.size() == 4);
            for (uint32_t b = 0; b < 4; ++b) {
                std::vector<uint8_t> out;
                assert(store.fetch(g, b, out));
                assert(out.size() == 64);
                assert(out[0] == static_cast<uint8_t>(g + b));
            }
        }
    }

    // Test 5: remove group
    {
        file_block_store store(dir, 0);
        assert(store.remove_group(200));
        auto blocks = store.list_blocks(200);
        assert(blocks.empty());
    }

    // Test 6: WAL recovery — simulate crash by corrupting end of data file
    {
        // Write some data with buffering (threshold > 0)
        std::filesystem::remove_all(dir);
        {
            file_block_store store(dir, 0);
            std::vector<uint8_t> good = {0xAA, 0xBB, 0xCC, 0xDD};
            store.store(300, 0, good.data(), good.size());
        }

        // Append garbage to simulate a partial/corrupt write
        {
            std::string data_path = dir + "/blocks.bin";
            FILE* f = fopen(data_path.c_str(), "ab");
            assert(f);
            uint8_t garbage[10] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00,
                                    0x00, 0x01, 0x02, 0x03, 0x04};
            fwrite(garbage, 1, sizeof(garbage), f);
            fclose(f);
        }

        // Reopen — should detect corrupt trailing record via CRC and truncate
        {
            file_block_store store(dir, 0);
            std::vector<uint8_t> out;
            assert(store.fetch(300, 0, out));
            std::vector<uint8_t> expected = {0xAA, 0xBB, 0xCC, 0xDD};
            assert(out == expected);
            assert(store.total_blocks() == 1);
        }
    }

    std::filesystem::remove_all(dir);
    std::cout << "  File block store tests passed." << std::endl;
}

int main() {
    std::cout << "libparitypp Test Suite" << std::endl;
    std::cout << "=====================" << std::endl << std::endl;
@@ -354,6 +470,7 @@ int main() {
    test_auth_store();
    test_auth_hmac();
    test_auth_protocol();
    test_file_block_store();

    std::cout << std::endl << "All tests passed!" << std::endl;
    return 0;