Menu
AkurAI-Build
publicLatest change fe39ce51fc9c202d5411f39fd9a8a2feeca4a85e - Harden test suite: 16→179 hermetic tests, race-free integration harness by Ólafur Búi Ólafsson
use std::{fs, path::Path, process::Command};
use anyhow::{Context, Result, ensure};
use serde_json::Value;
/// Verify the CLI produces a valid JSON envelope for every command.
#[test]
fn cli_json_contract_across_lifecycle() -> Result<()> {
let work = tempfile::tempdir()?;
let data = work.path().join("data");
let key = work.path().join("key.bin");
let repo = work.path().join("repo");
fs::create_dir(&repo)?;
// init a bare git repo
let init = Command::new("git")
.arg("init")
.args(["-b", "main"])
.arg(&repo)
.output()?;
ensure!(init.status.success(), "git init failed");
// keygen
let out = cli_raw(&data, &key, &["keygen", "--out", path(&key)?])?;
assert!(out["ok"] == true, "keygen envelope: {out}");
assert!(out["data"]["created"] == true, "key should be created");
// migrate
let out = cli_raw(&data, &key, &["migrate"])?;
assert!(out["ok"] == true, "migrate envelope: {out}");
assert!(
out["data"]["migrations_applied"]
.as_i64()
.is_some_and(|n| n >= 0),
"migrate should report applied count"
);
// repo add
let out = cli_raw(
&data,
&key,
&["repo", "add", "test-app", path(&repo)?, "--branch", "main"],
)?;
assert!(out["ok"] == true, "repo add envelope: {out}");
assert_eq!(out["data"]["name"], "test-app");
// repo list
let out = cli_raw(&data, &key, &["repo", "list"])?;
assert!(out["ok"] == true, "repo list envelope: {out}");
let repos = out["data"]
.as_array()
.context("repo list should be array")?;
assert_eq!(repos.len(), 1);
// workers (empty)
let out = cli_raw(&data, &key, &["workers"])?;
assert!(out["ok"] == true, "workers envelope: {out}");
let workers = out["data"].as_array().context("workers should be array")?;
assert!(workers.is_empty(), "no workers registered yet");
// runs (empty)
let out = cli_raw(&data, &key, &["runs"])?;
assert!(out["ok"] == true, "runs envelope: {out}");
let runs = out["data"].as_array().context("runs should be array")?;
assert!(runs.is_empty(), "no runs executed yet");
Ok(())
}
/// Run the CLI expecting success and return parsed JSON.
fn cli_raw(data: &Path, key: &Path, arguments: &[&str]) -> Result<Value> {
let output = Command::new(env!("CARGO_BIN_EXE_akurai"))
.args(["--data", path(data)?, "--key-file", path(key)?])
.args(arguments)
.output()?;
let value: Value = serde_json::from_slice(&output.stdout).with_context(|| {
format!(
"invalid CLI JSON: {}",
String::from_utf8_lossy(&output.stdout)
)
})?;
ensure!(
output.status.success(),
"CLI failed ({value}): {}",
String::from_utf8_lossy(&output.stderr)
);
Ok(value)
}
fn path(path: &Path) -> Result<&str> {
path.to_str().context("test path is not UTF-8")
}