pub mod common;
use nodedb_array::types::cell_value::value::CellValue;
use nodedb_lite::sync::array::inbound::outcome::InboundOutcome;
#[tokio::test(flavor = "multi_thread")]
async fn two_writes_same_coord_bitemporal_as_of() {
let harness = common::SyncHarness::new_in_memory().await;
harness.create_array("bt").await;
let schema_hlc = harness.schema_hlc("bt");
let rep = common::replica(1);
let op1 = common::put_op("bt", 1, 10.0, 100, schema_hlc, rep);
let op2 = common::put_op("bt", 1, 20.0, 200, schema_hlc, rep);
let o1 = harness.deliver(&op1);
let o2 = harness.deliver(&op2);
assert_eq!(o1, InboundOutcome::Applied);
assert_eq!(o2, InboundOutcome::Applied);
harness.flush("bt").await;
let val_150 = harness.read_coord("bt", 1, 150).await;
assert!(val_150.is_some(), "expected a cell AS-OF 150");
assert_eq!(
val_150.unwrap(),
CellValue::Float64(10.0),
"AS-OF 150 must see v1 (10.0)"
);
let val_max = harness.read_coord("bt", 1, i64::MAX).await;
assert!(val_max.is_some(), "expected a cell AS-OF MAX");
assert_eq!(
val_max.unwrap(),
CellValue::Float64(20.0),
"AS-OF MAX must see v2 (20.0)"
);
}
#[tokio::test(flavor = "multi_thread")]
async fn out_of_order_delivery_still_correct() {
let harness = common::SyncHarness::new_in_memory().await;
harness.create_array("oo").await;
let schema_hlc = harness.schema_hlc("oo");
let rep = common::replica(1);
let op_late = common::put_op("oo", 2, 200.0, 200, schema_hlc, rep);
let op_early = common::put_op("oo", 2, 100.0, 100, schema_hlc, rep);
let rl = harness.deliver(&op_late);
let re = harness.deliver(&op_early);
assert_eq!(rl, InboundOutcome::Applied);
assert!(
matches!(re, InboundOutcome::Applied | InboundOutcome::Idempotent),
"early op must be Applied or Idempotent, got: {re:?}"
);
harness.flush("oo").await;
let val = harness.read_coord("oo", 2, 150).await;
let val_max = harness.read_coord("oo", 2, i64::MAX).await;
assert!(val_max.is_some(), "latest value must be readable");
assert_eq!(val_max.unwrap(), CellValue::Float64(200.0));
let _ = val; }
#[tokio::test(flavor = "multi_thread")]
async fn hlc_order_is_strictly_monotonic() {
let harness = common::SyncHarness::new_in_memory().await;
harness.create_array("mono").await;
let schema_hlc = harness.schema_hlc("mono");
let rep = common::replica(42);
let h1 = common::hlc(1000, rep);
let h2 = common::hlc(2000, rep);
let h3 = common::hlc(3000, rep);
assert!(h1 < h2, "HLC 1000 < 2000");
assert!(h2 < h3, "HLC 2000 < 3000");
let op1 = common::put_op("mono", 0, 1.0, 1000, schema_hlc, rep);
let op2 = common::put_op("mono", 0, 2.0, 2000, schema_hlc, rep);
let op3 = common::put_op("mono", 0, 3.0, 3000, schema_hlc, rep);
assert_eq!(harness.deliver(&op1), InboundOutcome::Applied);
assert_eq!(harness.deliver(&op2), InboundOutcome::Applied);
assert_eq!(harness.deliver(&op3), InboundOutcome::Applied);
harness.flush("mono").await;
let latest = harness.read_coord("mono", 0, i64::MAX).await;
assert!(latest.is_some());
assert_eq!(latest.unwrap(), CellValue::Float64(3.0));
}