mirror of
https://github.com/block/buzz.git
synced 2026-11-12 12:22:06 +00:00
test(desktop): cover apply_workspace activation orchestration
Drive plan_workspace_activation across the cross-community switch sequence (apply A, switch to B, switch back to A), asserting the observable spawn plan at each step. The existing restore tests exercise begin_relay_activation and record_activates_on_relay as isolated predicates; these close the coverage gap by proving the composition: a later apply must not re-spawn A, stop A to serve B, or let a blank-pinned record float from A to B. Both core invariants are verified load-bearing by mutation: removing the already_running exclusion double-spawns a live agent; neutering the relay filter leaks B's agent into A's plan. Test-only; no production lines touched. Co-authored-by: npub1jmc9dt2lyvzu3h0kxlwxt5zg4fxp9476awyxw6gwxn72g6cw7exqs64whm <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1jmc9dt2lyvzu3h0kxlwxt5zg4fxp9476awyxw6gwxn72g6cw7exqs64whm <96f056ad5f2305c8ddf637dc65d048aa4c12d7daeb8867690e34fca46b0ef64c@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
committed by
npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757
parent
2cd376b535
commit
6d5c1ea85e
@@ -624,3 +624,238 @@ mod tests {
|
||||
assert!(!record_activates_on_relay(&record, "wss://relay-a.example"));
|
||||
}
|
||||
}
|
||||
|
||||
/// Orchestration-level coverage of the `apply_workspace` → activation decision.
|
||||
///
|
||||
/// The tests above exercise `begin_relay_activation` and
|
||||
/// `record_activates_on_relay` as isolated predicates. These drive the full
|
||||
/// cross-community *sequence* through [`plan_workspace_activation`] — apply A,
|
||||
/// switch to B, switch back to A — asserting the spawn decision (and the
|
||||
/// blank-pin migration that gates it) at each step. That composition is what
|
||||
/// the fast-switch defect regresses: an isolated predicate can stay correct
|
||||
/// while a later apply wrongly re-spawns A, stops A to serve B, or lets a
|
||||
/// blank-pinned record float from A to B. Assertions are on the observable
|
||||
/// plan (`spawn_pubkeys`, `run_boot_sweeps`, `None`), not the predicates.
|
||||
#[cfg(test)]
|
||||
mod orchestration_tests {
|
||||
use super::{plan_workspace_activation, ManagedAgentRecord};
|
||||
use crate::managed_agents::stamp_blank_agent_relay_urls;
|
||||
use std::collections::HashSet;
|
||||
|
||||
const RELAY_A: &str = "wss://relay-a.example";
|
||||
const RELAY_B: &str = "wss://relay-b.example";
|
||||
|
||||
/// A local start-on-launch record with an explicit pubkey and pin. Distinct
|
||||
/// pubkeys let a single record set model several agents across the switch
|
||||
/// sequence.
|
||||
fn agent(pubkey: &str, relay_url: &str) -> ManagedAgentRecord {
|
||||
serde_json::from_str(&format!(
|
||||
r#"{{
|
||||
"pubkey": "{pubkey}",
|
||||
"name": "{pubkey}",
|
||||
"private_key_nsec": "nsec1fake",
|
||||
"relay_url": "{relay_url}",
|
||||
"acp_command": "buzz-acp",
|
||||
"agent_command": "goose",
|
||||
"agent_args": [],
|
||||
"mcp_command": "",
|
||||
"turn_timeout_seconds": 320,
|
||||
"created_at": "2026-01-01T00:00:00Z",
|
||||
"updated_at": "2026-01-01T00:00:00Z"
|
||||
}}"#
|
||||
))
|
||||
.expect("sample record")
|
||||
}
|
||||
|
||||
fn spawn_set(
|
||||
records: &[ManagedAgentRecord],
|
||||
relay: &str,
|
||||
activated: &mut HashSet<String>,
|
||||
) -> Option<Vec<String>> {
|
||||
let running = HashSet::new();
|
||||
plan_workspace_activation(records, &running, activated, relay)
|
||||
.map(|plan| plan.spawn_pubkeys)
|
||||
}
|
||||
|
||||
/// Applying community A starts only A's agent — B's pinned agent is not
|
||||
/// spawned by A's activation.
|
||||
#[test]
|
||||
fn apply_a_spawns_only_a() {
|
||||
let records = vec![agent("agent-a", RELAY_A), agent("agent-b", RELAY_B)];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
let plan = plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A)
|
||||
.expect("first apply activates");
|
||||
|
||||
assert_eq!(plan.spawn_pubkeys, vec!["agent-a".to_string()]);
|
||||
assert!(
|
||||
plan.run_boot_sweeps,
|
||||
"first activation of the session sweeps"
|
||||
);
|
||||
}
|
||||
|
||||
/// Fast-switch A→B starts only B and never stops or restarts A: A is already
|
||||
/// running, the plan carries no stop channel, and B's plan omits A.
|
||||
#[test]
|
||||
fn switch_to_b_spawns_only_b_and_leaves_a_running() {
|
||||
let records = vec![agent("agent-a", RELAY_A), agent("agent-b", RELAY_B)];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
// Apply A first (consumes the session boot sweep), then switch to B with
|
||||
// A's process live.
|
||||
plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A)
|
||||
.expect("apply A");
|
||||
let mut running = HashSet::new();
|
||||
running.insert("agent-a".to_string());
|
||||
|
||||
let plan = plan_workspace_activation(&records, &running, &mut activated, RELAY_B)
|
||||
.expect("switching to a new workspace activates it");
|
||||
|
||||
assert_eq!(
|
||||
plan.spawn_pubkeys,
|
||||
vec!["agent-b".to_string()],
|
||||
"B activation spawns only B's agent"
|
||||
);
|
||||
assert!(
|
||||
!plan.run_boot_sweeps,
|
||||
"a later activation must not re-run the one-shot boot sweeps"
|
||||
);
|
||||
// Nothing in the plan can stop A: the type has no stop channel, and A
|
||||
// remains in the running set the caller holds across the switch.
|
||||
assert!(
|
||||
running.contains("agent-a"),
|
||||
"A stays running across the switch"
|
||||
);
|
||||
}
|
||||
|
||||
/// Switching back to a workspace already activated this session is a no-op:
|
||||
/// A→B→A must not resurrect an agent the user stopped in A.
|
||||
#[test]
|
||||
fn revisiting_a_does_not_respawn() {
|
||||
let records = vec![agent("agent-a", RELAY_A), agent("agent-b", RELAY_B)];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A)
|
||||
.expect("apply A");
|
||||
plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_B)
|
||||
.expect("apply B");
|
||||
|
||||
// A user who stopped agent-a in A leaves it not-running; revisiting A
|
||||
// must still decline to plan, so the stop is honored.
|
||||
assert!(
|
||||
plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A).is_none(),
|
||||
"a re-activated relay yields no plan, so no agent is respawned"
|
||||
);
|
||||
}
|
||||
|
||||
/// Home pins and agent keys are stable across the whole switch sequence: the
|
||||
/// planner reads records immutably, so a switch can never rewrite an agent's
|
||||
/// identity or move its pin.
|
||||
#[test]
|
||||
fn keys_and_pins_are_stable_across_the_sequence() {
|
||||
let records = vec![agent("agent-a", RELAY_A), agent("agent-b", RELAY_B)];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
for relay in [RELAY_A, RELAY_B, RELAY_A, RELAY_B] {
|
||||
let _ = spawn_set(&records, relay, &mut activated);
|
||||
}
|
||||
|
||||
assert_eq!(records[0].pubkey, "agent-a");
|
||||
assert_eq!(records[0].relay_url, RELAY_A);
|
||||
assert_eq!(records[1].pubkey, "agent-b");
|
||||
assert_eq!(records[1].relay_url, RELAY_B);
|
||||
}
|
||||
|
||||
/// A legacy blank-pinned record is stamped to the first workspace applied,
|
||||
/// then never floats to a later workspace switch. This is the composition of
|
||||
/// the one-shot stamp migration (before activation) with the relay-filtered
|
||||
/// planner: on plain main the same record would spawn against whichever
|
||||
/// workspace was visited, because a blank pin matches every relay.
|
||||
#[test]
|
||||
fn blank_record_stamps_to_first_workspace_and_never_floats() {
|
||||
let mut records = vec![agent("agent-blank", "")];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
// Before stamping, a blank pin matches any relay — proving the float
|
||||
// hazard the migration closes.
|
||||
assert!(
|
||||
plan_workspace_activation(&records, &HashSet::new(), &mut HashSet::new(), RELAY_B)
|
||||
.expect("blank pin activates on any relay")
|
||||
.spawn_pubkeys
|
||||
== vec!["agent-blank".to_string()],
|
||||
"a blank pin would otherwise activate on B too — this is the float"
|
||||
);
|
||||
|
||||
// Apply A: the one-shot migration stamps the blank record to A, then A's
|
||||
// activation spawns it.
|
||||
let stamped = stamp_blank_agent_relay_urls(&mut records, RELAY_A);
|
||||
assert_eq!(stamped, 1, "the blank record is stamped on the first apply");
|
||||
assert_eq!(
|
||||
records[0].relay_url, RELAY_A,
|
||||
"stamped to the first workspace"
|
||||
);
|
||||
|
||||
let plan_a = plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A)
|
||||
.expect("apply A");
|
||||
assert_eq!(plan_a.spawn_pubkeys, vec!["agent-blank".to_string()]);
|
||||
|
||||
// Switch to B: the now-A-pinned record is filtered out — it does not
|
||||
// float to B.
|
||||
let mut running = HashSet::new();
|
||||
running.insert("agent-blank".to_string());
|
||||
let plan_b = plan_workspace_activation(&records, &running, &mut activated, RELAY_B)
|
||||
.expect("apply B");
|
||||
assert!(
|
||||
plan_b.spawn_pubkeys.is_empty(),
|
||||
"a stamped record must not float to a later workspace"
|
||||
);
|
||||
}
|
||||
|
||||
/// Within a single activation, a record already running on the *same* relay
|
||||
/// is not spawned again — the `already_running` exclusion, not just the
|
||||
/// relay filter, keeps the plan idempotent. Two agents share relay A; one is
|
||||
/// live when A is applied, so only the down one is planned.
|
||||
#[test]
|
||||
fn a_running_agent_on_the_active_relay_is_not_respawned() {
|
||||
let records = vec![agent("agent-a1", RELAY_A), agent("agent-a2", RELAY_A)];
|
||||
let mut activated = HashSet::new();
|
||||
let mut running = HashSet::new();
|
||||
running.insert("agent-a1".to_string()); // a1 already up on A
|
||||
|
||||
let plan = plan_workspace_activation(&records, &running, &mut activated, RELAY_A)
|
||||
.expect("apply A");
|
||||
|
||||
assert_eq!(
|
||||
plan.spawn_pubkeys,
|
||||
vec!["agent-a2".to_string()],
|
||||
"only the not-running A agent is spawned; a1 is not double-spawned"
|
||||
);
|
||||
}
|
||||
|
||||
/// A failed spawn in A must not cause B's activation to adopt A's record.
|
||||
/// A claimed its relay activation even though its process never came up, so
|
||||
/// it is absent from `already_running`; B's relay-filtered plan still omits
|
||||
/// A's A-pinned record.
|
||||
#[test]
|
||||
fn failed_spawn_in_a_does_not_leak_into_b() {
|
||||
let records = vec![agent("agent-a", RELAY_A), agent("agent-b", RELAY_B)];
|
||||
let mut activated = HashSet::new();
|
||||
|
||||
// Apply A: A is planned for spawn, but model the spawn as having failed —
|
||||
// A never enters the running set.
|
||||
let plan_a = plan_workspace_activation(&records, &HashSet::new(), &mut activated, RELAY_A)
|
||||
.expect("apply A");
|
||||
assert_eq!(plan_a.spawn_pubkeys, vec!["agent-a".to_string()]);
|
||||
let running = HashSet::new(); // A's spawn failed: not running.
|
||||
|
||||
// Switch to B: only B is planned. A's A-pinned record is not selected on
|
||||
// B even though it is neither running nor successfully started.
|
||||
let plan_b = plan_workspace_activation(&records, &running, &mut activated, RELAY_B)
|
||||
.expect("apply B");
|
||||
assert_eq!(
|
||||
plan_b.spawn_pubkeys,
|
||||
vec!["agent-b".to_string()],
|
||||
"a failed A spawn must not make B adopt A's record"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user