use reifydb_sdk::{
operator::{FFIOperatorAdapter, windowed::rolling_incremental::RollingIncrementalDriver},
testing::chaos::{
ChaosHarness,
accumulator_oracle::rolling_incremental_accumulator_oracle,
config::{ChaosConfig, SupportedOps},
runner::ChaosOutcome,
schema::KeyStrategy,
strategy::{ColumnSampler, samplers},
},
};
use super::common::{self, VelocityIncremental};
const BASELINE_TOL: f64 = 1e-6;
fn group_key() -> Vec<String> {
vec!["group".to_string()]
}
fn value_sampler(none_values: bool) -> ColumnSampler {
if none_values {
common::maybe_none_f64(-50.0, 50.0)
} else {
samplers::f64_range(-50.0..50.0)
}
}
fn run(none_values: bool, cfg: ChaosConfig, seed: u64) -> ChaosOutcome {
ChaosHarness::<FFIOperatorAdapter<RollingIncrementalDriver<VelocityIncremental>>>::builder()
.with_input_shape(common::rolling_shape())
.with_output_shape(common::velocity_out_shape())
.with_key_strategy(KeyStrategy::Sequential)
.with_output_key(["group"])
.with_column("group", samplers::utf8_choices(&["BTC", "ETH", "SOL"]))
.with_column("window_start", samplers::u64_range(0..10))
.with_column("value", value_sampler(none_values))
.with_tolerance("baseline", BASELINE_TOL)
.with_chaos(cfg)
.with_oracle(|ctx, batches| {
rolling_incremental_accumulator_oracle(
&common::velocity_incremental(),
ctx,
batches,
&group_key(),
)
})
.seed(seed)
.build()
.expect("build incremental harness")
.run()
}
#[test]
fn velocity_matches_across_configs_and_seeds() {
for &seed in &common::SEEDS {
run(false, common::baseline(150, SupportedOps::insert_only()), seed).assert_matches();
run(false, common::baseline(150, SupportedOps::no_remove()), seed).assert_matches();
run(false, common::baseline(150, SupportedOps::no_update()), seed).assert_matches();
run(false, common::baseline(200, SupportedOps::all()), seed).assert_matches();
run(false, common::full_chaos(250), seed).assert_matches();
}
}
#[test]
fn velocity_handles_none_inputs() {
for &seed in &common::SEEDS {
run(true, common::full_chaos(200), seed).assert_matches();
}
}
#[test]
fn velocity_exercises_eviction_and_running_maintenance() {
let outcome = run(false, common::full_chaos(400), 12_345);
outcome.assert_matches();
assert!(!outcome.oracle_table.is_empty(), "expected velocity output rows");
}
#[test]
fn velocity_empty_stream_is_empty() {
let outcome = run(false, common::baseline(0, SupportedOps::all()), 0);
outcome.assert_matches();
assert!(outcome.operator_table.is_empty());
assert!(outcome.oracle_table.is_empty());
}