use super::records::{AgentEvent, AgentHarness, AgentSpec};
use super::test_support::{Fixture, TestResult, approved};
#[test]
fn an_approved_create_and_every_transition_survive_reopen_in_one_batch() -> TestResult {
let fixture = Fixture::new()?;
let registry = fixture.registry()?;
let draft = approved(
"draft-create",
"assistant",
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Coordinate the service builders.".into(),
service: None,
}),
)?;
let before = fixture.counts.snapshot();
registry.execute_approved_at(&draft, 1)?;
let counts = fixture.counts.snapshot().since(&before);
assert_eq!(counts.append_all_calls, 1);
assert_eq!(counts.append_calls, 0);
assert_eq!(counts.flushes, 1);
registry.observe(
"assistant",
super::records::AgentTransition {
holder: "assistant".into(),
at_ms: 2,
change: AgentEvent::Present { connection: 7 },
},
)?;
registry.observe(
"assistant",
super::records::AgentTransition {
holder: "server".into(),
at_ms: 3,
change: AgentEvent::Gone {
connection: 7,
reason: "transport_eof".into(),
},
},
)?;
let counts = fixture.counts.snapshot().since(&before);
assert_eq!((counts.append_all_calls, counts.flushes), (3, 3));
let record = registry.record("assistant")?;
assert_eq!(record.owner, "owner");
assert_eq!(record.transitions[0].holder, "owner");
assert_eq!(record.transitions[0].at_ms, 1);
registry.execute_approved(&draft)?;
assert_eq!(fixture.counts.snapshot().since(&before).append_all_calls, 3);
drop(registry);
let fixture = Fixture::at(fixture.close())?;
let reopened = fixture.registry()?;
assert_eq!(reopened.record("assistant")?, record);
assert!(reopened.receipt(&draft.id)?.is_some());
Ok(())
}
#[test]
fn malformed_or_oversized_creation_never_lands_a_record() -> TestResult {
let fixture = Fixture::new()?;
let registry = fixture.registry()?;
let before = fixture.counts.snapshot();
for (id, name, purpose) in [
("bad-name", "a.b", "One sentence.".to_owned()),
(
"large",
"large",
"x".repeat(super::config::AgentsConfig::default().max_field_bytes + 1),
),
] {
let draft = approved(
id,
name,
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose,
service: None,
}),
)?;
assert!(registry.execute_approved(&draft).is_err());
}
assert_eq!(fixture.counts.snapshot().since(&before).append_all_calls, 0);
assert!(registry.records()?.is_empty());
Ok(())
}
#[test]
fn an_old_store_with_no_agents_keeps_its_existing_rows_and_needs_no_migration() -> TestResult {
use liminal::durability::{DurableStore, bridge::block_on};
let fixture = Fixture::new()?;
block_on(
fixture
.counts
.append_all("old/service", vec![b"old-record".to_vec()], 0),
)??;
block_on(fixture.counts.flush())??;
let registry = fixture.registry()?;
assert!(registry.records()?.is_empty());
assert_eq!(
block_on(
fixture
.counts
.read_stream_next_seq(super::registry::REGISTRY_STREAM)
)??,
None
);
assert_eq!(
block_on(fixture.counts.read_from("old/service", 0, 1))??[0].payload,
b"old-record"
);
Ok(())
}
#[test]
fn create_needs_a_draft_and_reusing_its_id_cannot_change_its_words() -> TestResult {
let fixture = Fixture::new()?;
let registry = fixture.registry()?;
assert_eq!(
registry.held("create_agent", "draft-1").to_string(),
"create_agent is deliberate: held by draft draft-1"
);
let original = approved(
"draft-1",
"a",
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build one service.".into(),
service: None,
}),
)?;
registry.execute_approved(&original)?;
let changed = approved(
"draft-1",
"b",
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build another service.".into(),
service: None,
}),
)?;
assert_eq!(
registry
.execute_approved(&changed)
.err()
.ok_or("accepted changed draft")?
.to_string(),
"agent_draft_digest_mismatch"
);
assert!(registry.record("b").is_err());
Ok(())
}
#[test]
fn configured_owner_and_exchange_bounds_count_active_agents_and_retirement_frees_one() -> TestResult
{
let fixture = Fixture::new()?;
let registry = fixture.registry()?;
for n in 0..8 {
registry.execute_approved(&approved(
&format!("create-{n}"),
&format!("a{n}"),
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build one service.".into(),
service: None,
}),
)?)?;
}
let ninth = approved(
"ninth",
"a8",
"owner",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build one service.".into(),
service: None,
}),
)?;
assert_eq!(
registry
.execute_approved(&ninth)
.err()
.ok_or("ninth admitted")?
.to_string(),
"auth.lys.agents.max_per_owner: limit 8, count 8"
);
registry.execute_approved(&approved("retire", "a0", "owner", AgentEvent::Retire)?)?;
registry.execute_approved(&ninth)?;
for n in 9..65 {
registry.execute_approved(&approved(
&format!("create-{n}"),
&format!("a{n}"),
&format!("owner{n}"),
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build one service.".into(),
service: None,
}),
)?)?;
}
let last = approved(
"last",
"last",
"other",
AgentEvent::Create(AgentSpec {
harness: AgentHarness::Cdx,
purpose: "Build one service.".into(),
service: None,
}),
)?;
assert_eq!(
registry
.execute_approved(&last)
.err()
.ok_or("sixty-fifth admitted")?
.to_string(),
"auth.lys.agents.max_per_exchange: limit 64, count 64"
);
Ok(())
}