183 lines
5.3 KiB
C++
183 lines
5.3 KiB
C++
// Catch2 tests for VectorDatabase smoke tests
|
|
// Migrated from GTest: vector_smoke_test.cpp
|
|
// PBI-040: Minimal vector smoke test (conditional on sqlite-vec availability)
|
|
|
|
#include <catch2/catch_test_macros.hpp>
|
|
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <string>
|
|
#include <yams/vector/vector_database.h>
|
|
|
|
using namespace yams::vector;
|
|
|
|
namespace {
|
|
|
|
struct VectorSmokeFixture {
|
|
VectorSmokeFixture() {
|
|
// Check if sqlite-vec is available by attempting to load it
|
|
// If YAMS_SQLITE_VEC_SKIP_INIT=1 or YAMS_DISABLE_VECTORS=1, skip these tests
|
|
if (const char* skipEnv = std::getenv("YAMS_SQLITE_VEC_SKIP_INIT")) {
|
|
std::string v(skipEnv);
|
|
if (v == "1" || v == "true") {
|
|
skipReason = "Skipping vector smoke test (YAMS_SQLITE_VEC_SKIP_INIT=1)";
|
|
}
|
|
}
|
|
if (const char* disableEnv = std::getenv("YAMS_DISABLE_VECTORS")) {
|
|
std::string v(disableEnv);
|
|
if (v == "1" || v == "true") {
|
|
skipReason = "Skipping vector smoke test (YAMS_DISABLE_VECTORS=1)";
|
|
}
|
|
}
|
|
}
|
|
|
|
void skipIfNeeded() {
|
|
if (!skipReason.empty()) {
|
|
SKIP(skipReason);
|
|
}
|
|
}
|
|
|
|
std::string skipReason;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
TEST_CASE_METHOD(VectorSmokeFixture, "VectorSmoke initialize in-memory database",
|
|
"[vector][smoke][catch2]") {
|
|
skipIfNeeded();
|
|
|
|
VectorDatabaseConfig config;
|
|
config.database_path = ":memory:";
|
|
config.embedding_dim = 128;
|
|
config.create_if_missing = true;
|
|
config.use_in_memory = true;
|
|
|
|
VectorDatabase db(config);
|
|
REQUIRE(db.initialize());
|
|
INFO("Failed to initialize in-memory vector DB");
|
|
}
|
|
|
|
TEST_CASE_METHOD(VectorSmokeFixture, "VectorSmoke insert and search basic",
|
|
"[vector][smoke][catch2]") {
|
|
skipIfNeeded();
|
|
|
|
VectorDatabaseConfig config;
|
|
config.database_path = ":memory:";
|
|
config.embedding_dim = 4; // Small dimension for speed
|
|
config.create_if_missing = true;
|
|
config.use_in_memory = true;
|
|
|
|
VectorDatabase db(config);
|
|
REQUIRE(db.initialize());
|
|
|
|
// Insert a simple vector
|
|
std::vector<float> embedding = {1.0f, 0.0f, 0.0f, 0.0f};
|
|
VectorRecord rec;
|
|
rec.chunk_id = "test_hash_001";
|
|
rec.document_hash = "test_doc_001";
|
|
rec.embedding = embedding;
|
|
rec.content = "Test content";
|
|
rec.start_offset = 0;
|
|
rec.end_offset = 12;
|
|
REQUIRE(db.insertVector(rec));
|
|
|
|
// Search for it
|
|
VectorSearchParams params;
|
|
params.k = 1;
|
|
auto results = db.search(embedding, params);
|
|
REQUIRE(results.size() == 1);
|
|
CHECK(results[0].chunk_id == "test_hash_001");
|
|
}
|
|
|
|
TEST_CASE_METHOD(VectorSmokeFixture, "VectorSmoke insert and search with vec0 engine",
|
|
"[vector][smoke][vec0][catch2]") {
|
|
skipIfNeeded();
|
|
|
|
VectorDatabaseConfig config;
|
|
config.database_path = ":memory:";
|
|
config.embedding_dim = 4;
|
|
config.create_if_missing = true;
|
|
config.use_in_memory = true;
|
|
config.search_engine = VectorSearchEngine::Vec0L2;
|
|
|
|
VectorDatabase db(config);
|
|
REQUIRE(db.initialize());
|
|
|
|
std::vector<float> embedding = {1.0f, 0.0f, 0.0f, 0.0f};
|
|
VectorRecord rec;
|
|
rec.chunk_id = "vec0_hash_001";
|
|
rec.document_hash = "vec0_doc_001";
|
|
rec.embedding = embedding;
|
|
rec.content = "Vec0 test content";
|
|
rec.start_offset = 0;
|
|
rec.end_offset = 17;
|
|
REQUIRE(db.insertVector(rec));
|
|
|
|
VectorSearchParams params;
|
|
params.k = 1;
|
|
auto results = db.search(embedding, params);
|
|
REQUIRE(results.size() == 1);
|
|
CHECK(results[0].chunk_id == "vec0_hash_001");
|
|
}
|
|
|
|
TEST_CASE_METHOD(VectorSmokeFixture, "VectorSmoke insert and search with Simeon PQ engine",
|
|
"[vector][smoke][spq][catch2]") {
|
|
skipIfNeeded();
|
|
|
|
VectorDatabaseConfig config;
|
|
config.database_path = ":memory:";
|
|
config.embedding_dim = 4;
|
|
config.create_if_missing = true;
|
|
config.use_in_memory = true;
|
|
config.search_engine = VectorSearchEngine::SimeonPqAdc;
|
|
|
|
VectorDatabase db(config);
|
|
REQUIRE(db.initialize());
|
|
|
|
std::vector<float> embedding = {1.0f, 0.0f, 0.0f, 0.0f};
|
|
VectorRecord rec;
|
|
rec.chunk_id = "spq_hash_001";
|
|
rec.document_hash = "spq_doc_001";
|
|
rec.embedding = embedding;
|
|
rec.content = "Simeon PQ test content";
|
|
rec.start_offset = 0;
|
|
rec.end_offset = 27;
|
|
REQUIRE(db.insertVector(rec));
|
|
REQUIRE(db.buildIndex());
|
|
|
|
VectorSearchParams params;
|
|
params.k = 1;
|
|
auto results = db.search(embedding, params);
|
|
REQUIRE(results.size() == 1);
|
|
CHECK(results[0].chunk_id == "spq_hash_001");
|
|
}
|
|
|
|
TEST_CASE_METHOD(VectorSmokeFixture, "VectorSmoke get vector count", "[vector][smoke][catch2]") {
|
|
skipIfNeeded();
|
|
|
|
VectorDatabaseConfig config;
|
|
config.database_path = ":memory:";
|
|
config.embedding_dim = 4;
|
|
config.create_if_missing = true;
|
|
config.use_in_memory = true;
|
|
|
|
VectorDatabase db(config);
|
|
REQUIRE(db.initialize());
|
|
|
|
size_t count = db.getVectorCount();
|
|
CHECK(count == 0);
|
|
|
|
// Add a vector
|
|
std::vector<float> embedding = {1.0f, 0.0f, 0.0f, 0.0f};
|
|
VectorRecord rec;
|
|
rec.chunk_id = "test_hash_002";
|
|
rec.document_hash = "test_doc_002";
|
|
rec.embedding = embedding;
|
|
rec.content = "Test content";
|
|
rec.start_offset = 0;
|
|
rec.end_offset = 12;
|
|
REQUIRE(db.insertVector(rec));
|
|
|
|
count = db.getVectorCount();
|
|
CHECK(count == 1);
|
|
}
|