use super::*;
#[test]
fn test_parses_routes_json() {
let cli = Cli::parse_from(["harn", "routes", "fixtures/project", "--json"]);
let Command::Routes(args) = cli.command.unwrap() else {
panic!("expected routes command");
};
assert_eq!(args.root, PathBuf::from("fixtures/project"));
assert!(args.json);
}
#[test]
fn test_parses_graph_json_and_module_filter() {
let cli = Cli::parse_from([
"harn",
"graph",
"fixtures/project",
"--json",
"--module",
"main",
]);
let Command::Graph(args) = cli.command.unwrap() else {
panic!("expected graph command");
};
assert_eq!(args.root, PathBuf::from("fixtures/project"));
assert!(args.json);
assert_eq!(args.module.as_deref(), Some("main"));
}
#[test]
fn test_parses_runs_inspect_compare() {
let cli = Cli::parse_from([
"harn",
"runs",
"inspect",
"run.json",
"--compare",
"baseline.json",
]);
let Command::Runs(args) = cli.command.unwrap() else {
panic!("expected runs command");
};
let RunsCommand::Inspect(inspect) = args.command;
assert_eq!(inspect.path, "run.json");
assert_eq!(inspect.compare.as_deref(), Some("baseline.json"));
}
#[test]
fn test_parses_replay_sources_and_runs() {
let cli = Cli::parse_from(["harn", "replay", "run.json", "--json"]);
let Command::Replay(replay) = cli.command.unwrap() else {
panic!("expected replay command");
};
assert_eq!(replay.path.as_deref(), Some("run.json"));
assert!(replay.fixture.is_none());
assert!(replay.session_id.is_none());
assert_eq!(replay.runs, 1);
assert!(replay.json);
let cli = Cli::parse_from([
"harn",
"replay",
"--fixture",
"trace.json",
"--runs",
"3",
"--json",
]);
let Command::Replay(replay) = cli.command.unwrap() else {
panic!("expected replay command");
};
assert!(replay.path.is_none());
assert_eq!(replay.fixture.as_deref(), Some("trace.json"));
assert_eq!(replay.runs, 3);
assert!(replay.json);
let cli = Cli::parse_from([
"harn",
"replay",
"--session-id",
"session-123",
"--events-db",
".harn/events.sqlite",
"--runs",
"2",
]);
let Command::Replay(replay) = cli.command.unwrap() else {
panic!("expected replay command");
};
assert_eq!(replay.session_id.as_deref(), Some("session-123"));
assert_eq!(replay.events_db.as_deref(), Some(".harn/events.sqlite"));
assert_eq!(replay.runs, 2);
assert!(replay.counterfactual.is_empty());
let cli = Cli::parse_from([
"harn",
"replay",
"--session-id",
"session-123",
"--events-db",
".harn/events.sqlite",
"--at",
"7",
"--counterfactual",
"first.harn",
"--counterfactual",
"second.harn",
]);
let Command::Replay(replay) = cli.command.unwrap() else {
panic!("expected replay command");
};
assert_eq!(replay.at, Some(7));
assert_eq!(replay.counterfactual, vec!["first.harn", "second.harn"]);
}
#[test]
fn test_parses_session_bundle_commands() {
let cli = Cli::parse_from([
"harn",
"session",
"export",
"run.json",
"--out",
"bundle.json",
"--include-attachments",
]);
let Command::Session(args) = cli.command.unwrap() else {
panic!("expected session command");
};
let SessionCommand::Export(export) = args.command else {
panic!("expected session export");
};
assert_eq!(export.run_record, "run.json");
assert_eq!(export.out.as_deref(), Some("bundle.json"));
assert!(export.include_attachments);
let cli = Cli::parse_from([
"harn",
"session",
"import",
"bundle.json",
"--out",
"imported.json",
"--allow-unsafe-secret-markers",
]);
let Command::Session(args) = cli.command.unwrap() else {
panic!("expected session command");
};
let SessionCommand::Import(import) = args.command else {
panic!("expected session import");
};
assert_eq!(import.bundle, "bundle.json");
assert_eq!(import.out.as_deref(), Some("imported.json"));
assert!(import.allow_unsafe_secret_markers);
let cli = Cli::parse_from(["harn", "session", "validate", "bundle.json", "--json"]);
let Command::Session(args) = cli.command.unwrap() else {
panic!("expected session command");
};
let SessionCommand::Validate(validate) = args.command else {
panic!("expected session validate");
};
assert_eq!(validate.bundle, "bundle.json");
assert!(validate.json);
let cli = Cli::parse_from(["harn", "session", "schema", "--check"]);
let Command::Session(args) = cli.command.unwrap() else {
panic!("expected session command");
};
let SessionCommand::Schema(schema) = args.command else {
panic!("expected session schema");
};
assert!(schema.check);
}
#[test]
fn test_parses_trace_import_args() {
let cli = Cli::parse_from([
"harn",
"trace",
"import",
"--trace-file",
"langfuse.jsonl",
"--trace-id",
"trace_123",
"--output",
"fixtures/imported.jsonl",
]);
let Command::Trace(args) = cli.command.unwrap() else {
panic!("expected trace command");
};
let TraceCommand::Import(import) = args.command;
assert_eq!(import.trace_file, "langfuse.jsonl");
assert_eq!(import.trace_id.as_deref(), Some("trace_123"));
assert_eq!(import.output, "fixtures/imported.jsonl");
}
#[test]
fn test_parses_merge_captain_ladder_args() {
let cli = Cli::parse_from([
"harn",
"merge-captain",
"ladder",
"personas/merge_captain/harn.eval.toml",
"--report-out",
"ladder-report.json",
"--format",
"json",
]);
let Command::MergeCaptain(args) = cli.command.unwrap() else {
panic!("expected merge-captain command");
};
let MergeCaptainCommand::Ladder(ladder) = args.command else {
panic!("expected merge-captain ladder command");
};
assert_eq!(ladder.manifest, "personas/merge_captain/harn.eval.toml");
assert_eq!(ladder.report_out.as_deref(), Some("ladder-report.json"));
assert!(!ladder.json);
assert!(matches!(
ladder.format,
crate::cli::MergeCaptainLadderFormat::Json
));
}
#[test]
fn test_parses_merge_captain_ladder_json_alias() {
let cli = Cli::parse_from([
"harn",
"merge-captain",
"ladder",
"personas/merge_captain/harn.eval.toml",
"--json",
]);
let Command::MergeCaptain(args) = cli.command.unwrap() else {
panic!("expected merge-captain command");
};
let MergeCaptainCommand::Ladder(ladder) = args.command else {
panic!("expected merge-captain ladder command");
};
assert!(ladder.json);
assert!(matches!(
ladder.format,
crate::cli::MergeCaptainLadderFormat::Text
));
}
#[test]
fn test_parses_merge_captain_iterate_args() {
let cli = Cli::parse_from([
"harn",
"merge-captain",
"iterate",
"examples/personas/merge_captain/iterations/smoke.toml",
"--report-out",
"iteration-report.json",
"--markdown-out",
"iteration.md",
"--format",
"json",
]);
let Command::MergeCaptain(args) = cli.command.unwrap() else {
panic!("expected merge-captain command");
};
let MergeCaptainCommand::Iterate(iterate) = args.command else {
panic!("expected merge-captain iterate command");
};
assert_eq!(
iterate.manifest.as_deref(),
Some("examples/personas/merge_captain/iterations/smoke.toml")
);
assert_eq!(iterate.report_out.as_deref(), Some("iteration-report.json"));
assert_eq!(iterate.markdown_out.as_deref(), Some("iteration.md"));
assert!(!iterate.json);
assert!(matches!(
iterate.format,
crate::cli::MergeCaptainIterateFormat::Json
));
}
#[test]
fn test_parses_merge_captain_iterate_diff_args() {
let cli = Cli::parse_from([
"harn",
"merge-captain",
"iterate",
"--diff",
"baseline",
"candidate",
]);
let Command::MergeCaptain(args) = cli.command.unwrap() else {
panic!("expected merge-captain command");
};
let MergeCaptainCommand::Iterate(iterate) = args.command else {
panic!("expected merge-captain iterate command");
};
assert_eq!(iterate.diff, vec!["baseline", "candidate"]);
assert!(iterate.manifest.is_none());
}
#[test]
fn test_parses_trigger_replay_flags() {
let cli = Cli::parse_from([
"harn",
"trigger",
"replay",
"trigger_evt_123",
"--diff",
"--as-of",
"2026-04-19T18:00:00Z",
]);
let Command::Trigger(args) = cli.command.unwrap() else {
panic!("expected trigger command");
};
let TriggerCommand::Replay(replay) = args.command else {
panic!("expected trigger replay");
};
assert_eq!(replay.event_id.as_deref(), Some("trigger_evt_123"));
assert!(replay.diff);
assert_eq!(replay.as_of.as_deref(), Some("2026-04-19T18:00:00Z"));
assert!(replay.where_expr.is_none());
}
#[test]
fn test_parses_trigger_replay_steering_flags() {
let cli = Cli::parse_from([
"harn",
"trigger",
"replay",
"trigger_evt_123",
"--steer-from",
"outcome",
"--to-decision",
r#"{"status":"skipped"}"#,
"--reason",
"human corrected routing",
"--applied-by",
"alice",
"--scope",
"this_persona",
]);
let Command::Trigger(args) = cli.command.unwrap() else {
panic!("expected trigger command");
};
let TriggerCommand::Replay(replay) = args.command else {
panic!("expected trigger replay");
};
assert_eq!(replay.event_id.as_deref(), Some("trigger_evt_123"));
assert_eq!(replay.steer_from.as_deref(), Some("outcome"));
assert_eq!(
replay.to_decision.as_deref(),
Some(r#"{"status":"skipped"}"#)
);
assert_eq!(replay.reason.as_deref(), Some("human corrected routing"));
assert_eq!(replay.applied_by.as_deref(), Some("alice"));
assert_eq!(replay.scope.as_deref(), Some("this_persona"));
}
#[test]
fn test_parses_flow_replay_audit_flags() {
let cli = Cli::parse_from([
"harn",
"flow",
"replay-audit",
"--store",
".harn/flow.sqlite",
"--predicate-root",
".",
"--touched-dir",
"crates/harn-vm",
"--since",
"2026-04-26",
"--fail-on-drift",
"--json",
]);
let Command::Flow(args) = cli.command.unwrap() else {
panic!("expected flow command");
};
let FlowCommand::ReplayAudit(audit) = args.command else {
panic!("expected replay-audit command");
};
assert_eq!(audit.store, PathBuf::from(".harn/flow.sqlite"));
assert_eq!(audit.predicate_root, PathBuf::from("."));
assert_eq!(audit.touched_dirs, vec![PathBuf::from("crates/harn-vm")]);
assert_eq!(audit.since.as_deref(), Some("2026-04-26"));
assert!(audit.fail_on_drift);
assert!(audit.json);
}
#[test]
fn test_parses_flow_archivist_scan_flags() {
let cli = Cli::parse_from([
"harn",
"flow",
"archivist",
"scan",
".",
"--manifest",
"examples/personas/flow.harn.toml",
"--store",
".harn/flow.sqlite",
"--shadow-days",
"14",
"--out",
".harn/archivist/proposals.json",
"--json",
]);
let Command::Flow(args) = cli.command.unwrap() else {
panic!("expected flow command");
};
let FlowCommand::Archivist(archivist) = args.command else {
panic!("expected archivist command");
};
let FlowArchivistCommand::Scan(scan) = archivist.command;
assert_eq!(scan.repo, PathBuf::from("."));
assert_eq!(
scan.manifest,
Some(PathBuf::from("examples/personas/flow.harn.toml"))
);
assert_eq!(scan.store, PathBuf::from(".harn/flow.sqlite"));
assert_eq!(scan.shadow_days, 14);
assert_eq!(
scan.out,
Some(PathBuf::from(".harn/archivist/proposals.json"))
);
assert!(scan.json);
}
#[test]
fn test_parses_persona_check_flags() {
let cli = Cli::parse_from([
"harn",
"persona",
"--manifest",
"examples/personas/harn.toml",
"check",
"personas/ship_captain/harn.toml",
"--json",
]);
let Command::Persona(args) = cli.command.unwrap() else {
panic!("expected persona command");
};
assert_eq!(
args.manifest,
Some(PathBuf::from("examples/personas/harn.toml"))
);
let PersonaCommand::Check(check) = args.command else {
panic!("expected persona check command");
};
assert_eq!(
check.path,
Some(PathBuf::from("personas/ship_captain/harn.toml"))
);
assert!(check.json);
}
#[test]
fn test_parses_trigger_bulk_cancel_flags() {
let cli = Cli::parse_from([
"harn",
"trigger",
"cancel",
"--where",
"event.payload.tenant == 'acme' AND attempt.handler == 'handlers::risky'",
"--dry-run",
"--progress",
"--rate-limit",
"4",
]);
let Command::Trigger(args) = cli.command.unwrap() else {
panic!("expected trigger command");
};
let TriggerCommand::Cancel(cancel) = args.command else {
panic!("expected trigger cancel");
};
assert!(cancel.event_id.is_none());
assert_eq!(
cancel.where_expr.as_deref(),
Some("event.payload.tenant == 'acme' AND attempt.handler == 'handlers::risky'")
);
assert!(cancel.dry_run);
assert!(cancel.progress);
assert_eq!(cancel.rate_limit, Some(4.0));
}
#[test]
fn test_parses_orchestrator_serve_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"serve",
"--config",
"workspace/harn.toml",
"--state-dir",
"state/orchestrator",
"--bind",
"0.0.0.0:8080",
"--cert",
"tls/cert.pem",
"--key",
"tls/key.pem",
"--shutdown-timeout",
"45",
"--drain-max-items",
"256",
"--drain-deadline",
"9",
"--pump-max-outstanding",
"4",
"--mcp",
"--mcp-path",
"/ops/mcp",
"--mcp-sse-path",
"/ops/sse",
"--mcp-messages-path",
"/ops/messages",
"--log-format",
"json",
"--role",
"single-tenant",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Serve(serve) = args.command else {
panic!("expected orchestrator serve");
};
assert_eq!(serve.local.config, PathBuf::from("workspace/harn.toml"));
assert_eq!(serve.local.state_dir, PathBuf::from("state/orchestrator"));
assert_eq!(serve.bind.to_string(), "0.0.0.0:8080");
assert_eq!(serve.cert, Some(PathBuf::from("tls/cert.pem")));
assert_eq!(serve.key, Some(PathBuf::from("tls/key.pem")));
assert_eq!(serve.shutdown_timeout, 45);
assert_eq!(serve.drain_max_items, Some(256));
assert_eq!(serve.drain_deadline, Some(9));
assert_eq!(serve.pump_max_outstanding, Some(4));
assert!(serve.mcp);
assert_eq!(serve.mcp_path, "/ops/mcp");
assert_eq!(serve.mcp_sse_path, "/ops/sse");
assert_eq!(serve.mcp_messages_path, "/ops/messages");
assert_eq!(serve.log_format, OrchestratorLogFormat::Json);
assert_eq!(
serve.role,
crate::commands::orchestrator::role::OrchestratorRole::SingleTenant
);
}
#[test]
fn test_parses_orchestrator_serve_container_aliases() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"serve",
"--manifest",
"/etc/harn/triggers.toml",
"--state-dir",
"/var/lib/harn/state",
"--listen",
"0.0.0.0:8080",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Serve(serve) = args.command else {
panic!("expected orchestrator serve");
};
assert_eq!(serve.local.config, PathBuf::from("/etc/harn/triggers.toml"));
assert_eq!(serve.local.state_dir, PathBuf::from("/var/lib/harn/state"));
assert_eq!(serve.bind.to_string(), "0.0.0.0:8080");
}
#[test]
fn test_parses_orchestrator_deploy_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"deploy",
"--provider",
"fly",
"--manifest",
"workspace/harn.toml",
"--name",
"harn-prod",
"--image",
"ghcr.io/acme/harn-prod:latest",
"--deploy-dir",
"ops/deploy",
"--port",
"8443",
"--data-dir",
"/data",
"--disk-size-gb",
"20",
"--shutdown-timeout",
"60",
"--region",
"sjc",
"--fly-api-token",
"fly-token",
"--build",
"--env",
"RUST_LOG=debug",
"--secret",
"OPENAI_API_KEY=sk-test",
"--dry-run",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Deploy(deploy) = args.command else {
panic!("expected orchestrator deploy");
};
assert_eq!(deploy.provider, OrchestratorDeployProvider::Fly);
assert_eq!(deploy.manifest, PathBuf::from("workspace/harn.toml"));
assert_eq!(deploy.name, "harn-prod");
assert_eq!(deploy.image, "ghcr.io/acme/harn-prod:latest");
assert_eq!(deploy.deploy_dir, PathBuf::from("ops/deploy"));
assert_eq!(deploy.port, 8443);
assert_eq!(deploy.data_dir, "/data");
assert_eq!(deploy.disk_size_gb, 20);
assert_eq!(deploy.shutdown_timeout, 60);
assert_eq!(deploy.region.as_deref(), Some("sjc"));
assert_eq!(deploy.fly_api_token.as_deref(), Some("fly-token"));
assert!(deploy.build);
assert_eq!(deploy.env, vec!["RUST_LOG=debug".to_string()]);
assert_eq!(deploy.secret, vec!["OPENAI_API_KEY=sk-test".to_string()]);
assert!(deploy.dry_run);
}
#[test]
fn test_parses_orchestrator_inspect_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"inspect",
"--config",
"workspace/harn.toml",
"--state-dir",
"state/orchestrator",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Inspect(inspect) = args.command else {
panic!("expected orchestrator inspect");
};
assert_eq!(inspect.local.config, PathBuf::from("workspace/harn.toml"));
assert_eq!(inspect.local.state_dir, PathBuf::from("state/orchestrator"));
assert!(!inspect.json);
}
#[test]
fn test_parses_orchestrator_fire_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"fire",
"github-new-issue",
"--config",
"workspace/harn.toml",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Fire(fire) = args.command else {
panic!("expected orchestrator fire");
};
assert_eq!(fire.binding_id, "github-new-issue");
assert_eq!(fire.local.config, PathBuf::from("workspace/harn.toml"));
}
#[test]
fn test_parses_orchestrator_replay_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"replay",
"trigger_evt_123",
"--state-dir",
"state/orchestrator",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Replay(replay) = args.command else {
panic!("expected orchestrator replay");
};
assert_eq!(replay.event_id, "trigger_evt_123");
assert_eq!(replay.local.state_dir, PathBuf::from("state/orchestrator"));
assert!(!replay.json);
}
#[test]
fn test_parses_orchestrator_dlq_replay_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"dlq",
"--replay",
"dlq_123",
"--config",
"workspace/harn.toml",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Dlq(dlq) = args.command else {
panic!("expected orchestrator dlq");
};
assert_eq!(dlq.replay.as_deref(), Some("dlq_123"));
assert!(dlq.discard.is_none());
assert!(!dlq.list);
assert_eq!(dlq.local.config, PathBuf::from("workspace/harn.toml"));
assert!(!dlq.json);
}
#[test]
fn test_parses_orchestrator_json_flags() {
let inspect_cli = Cli::parse_from(["harn", "orchestrator", "inspect", "--json"]);
let Command::Orchestrator(inspect_args) = inspect_cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Inspect(inspect) = inspect_args.command else {
panic!("expected orchestrator inspect");
};
assert!(inspect.json);
let replay_cli = Cli::parse_from([
"harn",
"orchestrator",
"replay",
"trigger_evt_123",
"--json",
]);
let Command::Orchestrator(replay_args) = replay_cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Replay(replay) = replay_args.command else {
panic!("expected orchestrator replay");
};
assert!(replay.json);
let dlq_cli = Cli::parse_from(["harn", "orchestrator", "dlq", "--json", "--list"]);
let Command::Orchestrator(dlq_args) = dlq_cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Dlq(dlq) = dlq_args.command else {
panic!("expected orchestrator dlq");
};
assert!(dlq.json);
assert!(dlq.list);
}
#[test]
fn test_parses_orchestrator_resume_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"resume",
"hitl_escalation_trigger_evt_123_1",
"--reviewer",
"ops-lead",
"--reason",
"manual escalation ack",
"--json",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Resume(resume) = args.command else {
panic!("expected orchestrator resume");
};
assert_eq!(resume.event_id, "hitl_escalation_trigger_evt_123_1");
assert_eq!(resume.reviewer, "ops-lead");
assert_eq!(resume.reason.as_deref(), Some("manual escalation ack"));
assert!(resume.json);
}
#[test]
fn test_parses_orchestrator_queue_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"queue",
"--state-dir",
"state/orchestrator",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Queue(queue) = args.command else {
panic!("expected orchestrator queue");
};
assert_eq!(queue.local.state_dir, PathBuf::from("state/orchestrator"));
assert!(queue.command.is_none());
}
#[test]
fn test_parses_orchestrator_queue_drain_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"queue",
"--state-dir",
"state/orchestrator",
"drain",
"triage",
"--consumer-id",
"worker-a",
"--claim-ttl",
"30s",
"--json",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Queue(queue) = args.command else {
panic!("expected orchestrator queue");
};
let Some(OrchestratorQueueCommand::Drain(drain)) = queue.command else {
panic!("expected orchestrator queue drain");
};
assert_eq!(queue.local.state_dir, PathBuf::from("state/orchestrator"));
assert_eq!(drain.queue, "triage");
assert_eq!(drain.consumer_id.as_deref(), Some("worker-a"));
assert_eq!(drain.claim_ttl, StdDuration::from_secs(30));
assert!(drain.json);
}
#[test]
fn test_parses_orchestrator_queue_purge_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"queue",
"--state-dir",
"state/orchestrator",
"purge",
"triage",
"--confirm",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Queue(queue) = args.command else {
panic!("expected orchestrator queue");
};
let Some(OrchestratorQueueCommand::Purge(purge)) = queue.command else {
panic!("expected orchestrator queue purge");
};
assert_eq!(queue.local.state_dir, PathBuf::from("state/orchestrator"));
assert_eq!(purge.queue, "triage");
assert!(purge.confirm);
}
#[test]
fn test_parses_orchestrator_recover_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"recover",
"--config",
"workspace/harn.toml",
"--state-dir",
"state/orchestrator",
"--envelope-age",
"15m",
"--dry-run",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Recover(recover) = args.command else {
panic!("expected orchestrator recover");
};
assert_eq!(recover.local.config, PathBuf::from("workspace/harn.toml"));
assert_eq!(recover.local.state_dir, PathBuf::from("state/orchestrator"));
assert_eq!(recover.envelope_age, StdDuration::from_mins(15));
assert!(recover.dry_run);
assert!(!recover.yes);
}
#[test]
fn test_parses_orchestrator_tenant_create_args() {
let cli = Cli::parse_from([
"harn",
"orchestrator",
"tenant",
"--state-dir",
"state/orchestrator",
"create",
"acme",
"--daily-cost-usd",
"25.5",
"--ingest-per-minute",
"120",
"--json",
]);
let Command::Orchestrator(args) = cli.command.unwrap() else {
panic!("expected orchestrator command");
};
let OrchestratorCommand::Tenant(tenant) = args.command else {
panic!("expected orchestrator tenant");
};
let OrchestratorTenantCommand::Create(create) = tenant.command else {
panic!("expected orchestrator tenant create");
};
assert_eq!(tenant.local.state_dir, PathBuf::from("state/orchestrator"));
assert_eq!(create.id, "acme");
assert_eq!(create.daily_cost_usd, Some(25.5));
assert_eq!(create.ingest_per_minute, Some(120));
assert!(create.json);
}