# Tests for smartbotic-database # yyjson (v1.10+) — Phase A swaps nlohmann::json::parse for parse_to_nlohmann # at hot paths in wal.cpp, snapshot.cpp, history_store.cpp, etc. Any test # target that compiles those files now also needs json_parse.cpp linked and # yyjson linked. Resolve once at file scope so every test target below can # use ${yyjson_LIBRARIES} / ${yyjson_INCLUDE_DIRS}. if(NOT yyjson_FOUND) find_package(PkgConfig REQUIRED) pkg_check_modules(yyjson REQUIRED yyjson) endif() # LMDB (v2.0 storage substrate) — resolve once at file scope, mirroring the # yyjson pattern. liblmdb does not ship pkg-config on Debian 13, so use # find_path/find_library. Each test target that pulls in storage/ sources # adds ${LMDB_INCLUDE_DIR} / ${LMDB_LIBRARY} to its link/include flags. if(NOT LMDB_INCLUDE_DIR OR NOT LMDB_LIBRARY) find_path(LMDB_INCLUDE_DIR lmdb.h) find_library(LMDB_LIBRARY NAMES lmdb) if(NOT LMDB_INCLUDE_DIR OR NOT LMDB_LIBRARY) message(FATAL_ERROR "LMDB not found. Install liblmdb-dev.") endif() endif() # Vector storage integration test # Compiles memory_store.cpp directly — no dependency on the full service executable. set(TEST_VECTOR_SOURCES test_vector_storage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) add_executable(test_vector_storage ${TEST_VECTOR_SOURCES}) target_include_directories(test_vector_storage PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) # nlohmann/json if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_vector_storage PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_vector_storage PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() # spdlog if(TARGET spdlog::spdlog) target_link_libraries(test_vector_storage PRIVATE spdlog::spdlog) else() target_link_libraries(test_vector_storage PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_vector_storage PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() # Threads (required by MemoryStore background threads) find_package(Threads REQUIRED) target_link_libraries(test_vector_storage PRIVATE Threads::Threads) # yyjson (wal.cpp uses parse_to_nlohmann from v1.10+) target_link_libraries(test_vector_storage PRIVATE ${yyjson_LIBRARIES}) target_include_directories(test_vector_storage PRIVATE ${yyjson_INCLUDE_DIRS}) # View projection unit test set(TEST_VIEWS_SOURCES test_views.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/views/projection.cpp ) add_executable(test_views ${TEST_VIEWS_SOURCES}) target_include_directories(test_views PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) # nlohmann/json if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_views PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_views PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() # Per-collection timestamp precision test set(TEST_TIMESTAMP_PRECISION_SOURCES test_timestamp_precision.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) add_executable(test_timestamp_precision ${TEST_TIMESTAMP_PRECISION_SOURCES}) target_include_directories(test_timestamp_precision PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_timestamp_precision PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_timestamp_precision PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_timestamp_precision PRIVATE spdlog::spdlog) else() target_link_libraries(test_timestamp_precision PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_timestamp_precision PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() find_package(Threads REQUIRED) target_link_libraries(test_timestamp_precision PRIVATE Threads::Threads) # yyjson (wal.cpp uses parse_to_nlohmann from v1.10+) target_link_libraries(test_timestamp_precision PRIVATE ${yyjson_LIBRARIES}) target_include_directories(test_timestamp_precision PRIVATE ${yyjson_INCLUDE_DIRS}) # Snapshot durability + fallback integration test # Exercises SnapshotManager directly; pulls in memory_store.cpp, snapshot.cpp, # and wal.cpp (for the crc32 helpers used by snapshot.cpp). set(TEST_SNAPSHOT_DURABILITY_SOURCES test_snapshot_durability.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/snapshot.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) add_executable(test_snapshot_durability ${TEST_SNAPSHOT_DURABILITY_SOURCES}) target_include_directories(test_snapshot_durability PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_snapshot_durability PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_snapshot_durability PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_snapshot_durability PRIVATE spdlog::spdlog) else() target_link_libraries(test_snapshot_durability PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_snapshot_durability PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() find_package(Threads REQUIRED) target_link_libraries(test_snapshot_durability PRIVATE Threads::Threads) # yyjson (wal.cpp/snapshot.cpp use parse_to_nlohmann from v1.10+) target_link_libraries(test_snapshot_durability PRIVATE ${yyjson_LIBRARIES}) target_include_directories(test_snapshot_durability PRIVATE ${yyjson_INCLUDE_DIRS}) # LZ4 — snapshot.cpp #includes unless DISABLE_LZ4 is defined, so link it. find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) pkg_check_modules(TEST_LZ4 QUIET liblz4) endif() if(TEST_LZ4_FOUND) target_link_libraries(test_snapshot_durability PRIVATE ${TEST_LZ4_LIBRARIES}) target_include_directories(test_snapshot_durability PRIVATE ${TEST_LZ4_INCLUDE_DIRS}) else() # Fallback: assume liblz4 is installed at a standard location target_link_libraries(test_snapshot_durability PRIVATE lz4) endif() # Config drop-in loader test (v1.7.0 T1 → T12) # Exercises loadLayeredConfig() in isolation. set(TEST_CONFIG_DROPINS_SOURCES test_config_dropins.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/config_loader.cpp ) add_executable(test_config_dropins ${TEST_CONFIG_DROPINS_SOURCES}) target_include_directories(test_config_dropins PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_config_dropins PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_config_dropins PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_config_dropins PRIVATE spdlog::spdlog) else() target_link_libraries(test_config_dropins PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_config_dropins PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() # Eviction test (v1.7.0 T4+T5+T6 → T12) # Exercises chunked eviction, per-collection priorities, and the hot-write # floor directly through MemoryStore. Mirrors the link deps of test_timestamp_precision. set(TEST_EVICTION_SOURCES test_eviction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) add_executable(test_eviction ${TEST_EVICTION_SOURCES}) target_include_directories(test_eviction PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_eviction PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_eviction PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_eviction PRIVATE spdlog::spdlog) else() target_link_libraries(test_eviction PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_eviction PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() find_package(Threads REQUIRED) target_link_libraries(test_eviction PRIVATE Threads::Threads) # yyjson (wal.cpp uses parse_to_nlohmann from v1.10+) target_link_libraries(test_eviction PRIVATE ${yyjson_LIBRARIES}) target_include_directories(test_eviction PRIVATE ${yyjson_INCLUDE_DIRS}) # yyjson → nlohmann bridge helper test (v1.10 Phase A T2) # Exercises parse_to_nlohmann() in isolation against nlohmann::json::parse # for a corpus of production-shaped docs. yyjson is configured at the # service/ scope; re-resolve it here so the test target can find it # independently of the service build. if(NOT yyjson_FOUND) find_package(PkgConfig REQUIRED) pkg_check_modules(yyjson REQUIRED yyjson) endif() add_executable(test_json_parse test_json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ) target_include_directories(test_json_parse PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${yyjson_INCLUDE_DIRS} ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_json_parse PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_json_parse PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() target_link_libraries(test_json_parse PRIVATE ${yyjson_LIBRARIES}) # Binary doc encoder/decoder test (v1.11 Phase B T2) # Exercises doc_binary::Doc, encode, decode, get_field, to_json_text against # nlohmann::json round-trips. yyjson resolution is shared at file scope above. add_executable(test_doc_binary test_doc_binary.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) target_include_directories(test_doc_binary PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${yyjson_INCLUDE_DIRS} ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_doc_binary PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_doc_binary PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() target_link_libraries(test_doc_binary PRIVATE ${yyjson_LIBRARIES}) # Parse-time micro-benchmark (v1.10 Phase A T8) — manual bench, NOT # registered with CTest. Run as ./build/tests/bench_json_parse . add_executable(bench_json_parse bench_json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ) target_include_directories(bench_json_parse PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${yyjson_INCLUDE_DIRS} ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(bench_json_parse PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(bench_json_parse PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() target_link_libraries(bench_json_parse PRIVATE ${yyjson_LIBRARIES}) # RSS bench (v1.11 Phase B T8) — manual bench, NOT registered with CTest. # Run as ./build/tests/bench_doc_memory [N]. add_executable(bench_doc_memory bench_doc_memory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) target_include_directories(bench_doc_memory PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${yyjson_INCLUDE_DIRS} ) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(bench_doc_memory PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(bench_doc_memory PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() target_link_libraries(bench_doc_memory PRIVATE ${yyjson_LIBRARIES}) # LMDB environment unit test (v2.0 storage Phase C Stage 1, Tasks 1.2 / 1.3). # Compiles the storage/ sources directly — no dependency on the service # executable. add_executable(test_lmdb_env test_lmdb_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_txn.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_dbi.cpp ) target_include_directories(test_lmdb_env PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${LMDB_INCLUDE_DIR} ) target_link_libraries(test_lmdb_env PRIVATE ${LMDB_LIBRARY}) # DocumentStore + LmdbDocumentStore unit test (v2.0 storage Phase C Stage 2). # Same shape as test_lmdb_env: links the storage/ sources and a couple of # helpers (doc_binary, json_parse) directly. No dependency on the full # service executable. add_executable(test_document_store test_document_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_txn.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_dbi.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/document_store_lmdb.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ) target_include_directories(test_document_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${LMDB_INCLUDE_DIR} ${yyjson_INCLUDE_DIRS} ) target_link_libraries(test_document_store PRIVATE ${LMDB_LIBRARY}) target_link_libraries(test_document_store PRIVATE ${yyjson_LIBRARIES}) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_document_store PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_document_store PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() # v1.x → v2.0 migration tool unit test (v2.0 storage Phase C Stage 3). # Pulls in both the v1.x persistence stack (snapshot.cpp, wal.cpp, history_store.cpp, # memory_store.cpp) and the v2.0 storage stack (LMDB primitives + DocumentStore + # migrate_v1_to_v2). Each side is independent of the other at link time except # for the migration .cpp itself, which is the bridge. add_executable(test_migrate_v1_to_v2 test_migrate_v1_to_v2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/snapshot.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_txn.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_dbi.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/document_store_lmdb.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/migrate_v1_to_v2.cpp ) target_include_directories(test_migrate_v1_to_v2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${LMDB_INCLUDE_DIR} ${yyjson_INCLUDE_DIRS} ) target_link_libraries(test_migrate_v1_to_v2 PRIVATE ${LMDB_LIBRARY}) target_link_libraries(test_migrate_v1_to_v2 PRIVATE ${yyjson_LIBRARIES}) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_migrate_v1_to_v2 PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_migrate_v1_to_v2 PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_migrate_v1_to_v2 PRIVATE spdlog::spdlog) else() target_link_libraries(test_migrate_v1_to_v2 PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_migrate_v1_to_v2 PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() find_package(Threads REQUIRED) target_link_libraries(test_migrate_v1_to_v2 PRIVATE Threads::Threads) # LZ4 — snapshot.cpp uses LZ4 compression if(PKG_CONFIG_FOUND) pkg_check_modules(MIGRATE_LZ4 QUIET liblz4) endif() if(MIGRATE_LZ4_FOUND) target_link_libraries(test_migrate_v1_to_v2 PRIVATE ${MIGRATE_LZ4_LIBRARIES}) target_include_directories(test_migrate_v1_to_v2 PRIVATE ${MIGRATE_LZ4_INCLUDE_DIRS}) else() target_link_libraries(test_migrate_v1_to_v2 PRIVATE lz4) endif() # v2.0 Stage 4 — dual-write mirror unit + integration test. # Links the MemoryStore + LMDB substrate the same way test_migrate_v1_to_v2 does, # but skips persistence/snapshot/wal since the mirror helper does not touch them. add_executable(test_dual_write_mirror test_dual_write_mirror.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/memory_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/config/collection_config_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/history_store.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/persistence/wal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/json_parse.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/doc_binary.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_env.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_txn.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/lmdb_dbi.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../service/src/storage/document_store_lmdb.cpp ) target_include_directories(test_dual_write_mirror PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../service/src ${LMDB_INCLUDE_DIR} ${yyjson_INCLUDE_DIRS} ) target_link_libraries(test_dual_write_mirror PRIVATE ${LMDB_LIBRARY}) target_link_libraries(test_dual_write_mirror PRIVATE ${yyjson_LIBRARIES}) if(TARGET nlohmann_json::nlohmann_json) target_link_libraries(test_dual_write_mirror PRIVATE nlohmann_json::nlohmann_json) else() target_include_directories(test_dual_write_mirror PRIVATE ${NLOHMANN_JSON_INCLUDE_DIRS}) endif() if(TARGET spdlog::spdlog) target_link_libraries(test_dual_write_mirror PRIVATE spdlog::spdlog) else() target_link_libraries(test_dual_write_mirror PRIVATE ${SPDLOG_LIBRARIES}) target_include_directories(test_dual_write_mirror PRIVATE ${SPDLOG_INCLUDE_DIRS}) endif() find_package(Threads REQUIRED) target_link_libraries(test_dual_write_mirror PRIVATE Threads::Threads) # Register with CTest enable_testing() add_test(NAME vector_storage COMMAND test_vector_storage) add_test(NAME views COMMAND test_views) add_test(NAME timestamp_precision COMMAND test_timestamp_precision) add_test(NAME snapshot_durability COMMAND test_snapshot_durability) add_test(NAME config_dropins COMMAND test_config_dropins) add_test(NAME eviction COMMAND test_eviction) add_test(NAME json_parse COMMAND test_json_parse) add_test(NAME doc_binary COMMAND test_doc_binary) add_test(NAME lmdb_env COMMAND test_lmdb_env) add_test(NAME document_store COMMAND test_document_store) add_test(NAME migrate_v1_to_v2 COMMAND test_migrate_v1_to_v2) add_test(NAME dual_write_mirror COMMAND test_dual_write_mirror)