stemedb/crates/stemedb-query/src/engine/tests/mod.rs
jordan 3320c24afa feat: WAL hardening (Phase 5B) - CRC32C, crash recovery, group commit, log rotation
Add CRC32C checksums to WAL record format (v2), implement crash recovery
with automatic truncation of corrupt records, add feature-gated group commit
buffer for batched fsync under concurrent load, and implement log rotation
via segment files with global offset addressing.

Key changes:
- Record format v2: [len:u32][crc32c:u32][blake3:32][payload:N]
- recover_file() scans and truncates corrupt tail records
- GroupCommitBuffer batches fsync via MPSC channel (tokio feature gate)
- SegmentManager with binary search resolution and cursor-based cleanup
- Journal::read() auto-refreshes segments on miss for writer/reader split
- Split recovery.rs and key_codec.rs into directory modules for 500-line max

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 12:36:35 -07:00

81 lines
2.4 KiB
Rust

//! Test suite for QueryEngine.
use std::sync::Arc;
use stemedb_core::testing::AssertionBuilder;
use stemedb_core::types::{Assertion, LifecycleStage, MaterializedView};
use stemedb_storage::{key_codec, GenericIndexStore, HybridStore, IndexStore, KVStore};
use super::QueryEngine;
mod basic;
mod changelog;
mod conflict_score;
mod indexes;
mod materialized_views;
mod similarity;
mod time_travel;
/// Helper to create a test assertion with standard values.
pub(super) fn create_test_assertion(
subject: &str,
predicate: &str,
lifecycle: LifecycleStage,
) -> Assertion {
AssertionBuilder::new()
.subject(subject)
.predicate(predicate)
.confidence(0.95)
.lifecycle(lifecycle)
.build()
}
/// Helper to store an assertion in the KV store and update indexes.
pub(super) async fn store_assertion(store: &Arc<HybridStore>, assertion: &Assertion) {
let bytes = stemedb_core::serde::serialize(assertion).expect("serialize");
let hash = blake3::hash(&bytes);
let key = key_codec::assertion_key(&assertion.subject, &hash.to_hex());
store.put(&key, &bytes).await.expect("put");
// Update indexes using IndexStore
let index_store = GenericIndexStore::new(store.clone());
let assertion_hash: [u8; 32] = *hash.as_bytes();
index_store
.add_to_indexes(&assertion.subject, &assertion.predicate, &assertion_hash)
.await
.expect("add to indexes");
}
/// Helper to store a materialized view directly in the KV store.
pub(super) async fn store_materialized_view(
store: &Arc<HybridStore>,
subject: &str,
predicate: &str,
winner: &Assertion,
) {
store_materialized_view_with_time(store, subject, predicate, winner, 1000).await;
}
/// Helper to store a materialized view with a custom materialized_at timestamp.
pub(super) async fn store_materialized_view_with_time(
store: &Arc<HybridStore>,
subject: &str,
predicate: &str,
winner: &Assertion,
materialized_at: u64,
) {
let view = MaterializedView {
winner: winner.clone(),
lens_name: "VoteAwareConsensus".to_string(),
resolution_confidence: 0.95,
candidates_count: 3,
materialized_at,
conflict_score: 0.1,
};
let key = key_codec::mv_key(subject, predicate);
let bytes = stemedb_core::serde::serialize(&view).expect("serialize MV");
store.put(&key, &bytes).await.expect("put MV");
}