use mempill_core::application::IngestClaimRequest;
use mempill_sqlite::open_default_in_memory;
use mempill_types::{AgentId, Cardinality, Confidence, Criticality, ExternalKind, ProvenanceLabel};
fn make_req(agent_id: &str, subject: &str, predicate: &str, value: &str) -> IngestClaimRequest {
IngestClaimRequest {
agent_id: AgentId(agent_id.into()),
subject: subject.into(),
predicate: predicate.into(),
value: serde_json::json!(value),
provenance: ProvenanceLabel::External(ExternalKind::UserAsserted),
cardinality: Cardinality::Functional,
valid_time: None,
confidence: Confidence {
value_confidence: 0.9,
valid_time_confidence: 0.0,
},
criticality: Criticality::Medium,
derived_from: vec![],
}
}
#[tokio::test]
async fn concurrent_writes_different_agent_ids_succeed() {
let engine = open_default_in_memory().expect("in-memory engine must open");
let engine_a = engine.clone();
let engine_b = engine.clone();
let req_a = make_req("agent-alpha", "user:alice", "city", "Berlin");
let req_b = make_req("agent-beta", "user:bob", "city", "Tokyo");
let (res_a, res_b) = tokio::join!(
engine_a.ingest_claim(req_a),
engine_b.ingest_claim(req_b),
);
assert!(
res_a.is_ok(),
"agent-alpha write must succeed, got: {res_a:?}"
);
assert!(
res_b.is_ok(),
"agent-beta write must succeed (was TxnAlreadyOpen before fix), got: {res_b:?}"
);
}
#[tokio::test]
async fn concurrent_writes_same_agent_id_succeed() {
let engine = open_default_in_memory().expect("in-memory engine must open");
let engine_a = engine.clone();
let engine_b = engine.clone();
let req_a = make_req("agent-same", "user:carol", "city", "Paris");
let req_b = make_req("agent-same", "user:carol", "score", "42");
let (res_a, res_b) = tokio::join!(
engine_a.ingest_claim(req_a),
engine_b.ingest_claim(req_b),
);
assert!(res_a.is_ok(), "same-agent write A must succeed, got: {res_a:?}");
assert!(res_b.is_ok(), "same-agent write B must succeed, got: {res_b:?}");
}