use std::collections::BTreeMap;
use std::fs;
use std::path::{Path, PathBuf};
use serde_json::{json, Value};
use supercode_harness::harness_service::HARNESS_SERVICE_METHODS;
use supercode_harness::{HarnessSessionService, SdkOperation};
fn fixture() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/hermes_home")
.canonicalize()
.unwrap()
}
fn scratch(tag: &str) -> PathBuf {
let root = std::env::temp_dir().join(format!(
"supercode-ont4-{tag}-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
fs::create_dir_all(&root).unwrap();
root.canonicalize().unwrap()
}
fn call(service: &mut HarnessSessionService, method: &str, params: Value) -> Value {
let response = service.handle(json!({
"jsonrpc": "2.0", "id": 1, "method": method, "params": params
}));
assert!(response.get("error").is_none(), "{method}: {response}");
response["result"].clone()
}
fn files_under(root: &Path) -> BTreeMap<String, Vec<u8>> {
fn walk(base: &Path, dir: &Path, out: &mut BTreeMap<String, Vec<u8>>) {
for entry in fs::read_dir(dir).unwrap().flatten() {
let path = entry.path();
if path.is_dir() {
walk(base, &path, out);
} else if path.is_file() {
out.insert(
path.strip_prefix(base)
.unwrap()
.to_string_lossy()
.into_owned(),
fs::read(&path).unwrap(),
);
}
}
}
let mut out = BTreeMap::new();
walk(root, root, &mut out);
out
}
fn fixture_vault() -> BTreeMap<String, String> {
supercode_harness::orchestration::codec::from_hermes(&fixture())
.unwrap()
.vault
}
#[test]
fn the_world_methods_are_published_and_have_operations() {
for method in [
"harness.v1.orchestration.load",
"harness.v1.orchestration.save",
"harness.v1.orchestration.compile",
"harness.v1.orchestration.decompile",
"harness.v1.orchestration.import",
"harness.v1.orchestration.export",
] {
assert!(
HARNESS_SERVICE_METHODS.contains(&method),
"`{method}` is not published"
);
assert!(
SdkOperation::from_method(method).is_some(),
"`{method}` has no SDK operation"
);
}
for action in [
"orchestration_load",
"orchestration_save",
"orchestration_compile",
"orchestration_decompile",
"orchestration_import",
"orchestration_export",
"workflow_load",
] {
assert!(
SdkOperation::from_action_name(action).is_some(),
"`{action}` is not a stable action spelling"
);
}
}
#[test]
fn compile_from_hermes_answers_the_world_and_the_vault_key_names_only() {
let mut service = HarnessSessionService::new();
let result = call(
&mut service,
"harness.v1.orchestration.compile",
json!({"from": "hermes", "home": fixture()}),
);
let names: Vec<&str> = result["orchestration"]["profiles"]
.as_object()
.expect("the orchestration carries its profiles")
.keys()
.map(String::as_str)
.collect();
assert_eq!(names, vec!["coder", "default", "ops"]);
let keys: Vec<&str> = result["vault_keys"]
.as_array()
.unwrap()
.iter()
.map(|k| k.as_str().unwrap())
.collect();
assert!(
keys.contains(&"TELEGRAM_TOKEN"),
"the vault's key names come back: {keys:?}"
);
let wire = serde_json::to_string(&result).unwrap();
assert!(
!wire.contains("FAKE-TOKEN-DO-NOT-EMIT"),
"the fixture's telegram token was emitted"
);
let vault = fixture_vault();
assert!(!vault.is_empty(), "the fixture has secrets to keep");
for (key, value) in &vault {
assert!(
!wire.contains(value.as_str()),
"`{key}`'s value crossed the wire"
);
}
}
#[test]
fn decompile_to_hermes_of_an_unchanged_world_reuses_the_store_and_refuses_nothing() {
let mut service = HarnessSessionService::new();
let compiled = call(
&mut service,
"harness.v1.orchestration.compile",
json!({"from": "hermes", "home": fixture()}),
);
let dest = scratch("hermes-back");
let report = call(
&mut service,
"harness.v1.orchestration.decompile",
json!({
"to": "hermes",
"orchestration": compiled["orchestration"],
"source": fixture(),
"dest": dest,
}),
);
assert_eq!(
report["refused"].as_array().unwrap(),
&Vec::<Value>::new(),
"nothing changed, so nothing is refused"
);
let byte: Vec<&str> = report["written"]
.as_array()
.unwrap()
.iter()
.filter(|a| a["fidelity"] == "byte_lossless")
.map(|a| a["path"].as_str().unwrap())
.collect();
assert!(
byte.iter().any(|path| path.ends_with("state.db")),
"an unchanged state.db is reused byte for byte: {byte:?}"
);
for path in &byte {
assert_eq!(
fs::read(dest.join(path)).unwrap(),
fs::read(fixture().join(path)).unwrap(),
"{path} byte for byte"
);
}
}
#[test]
fn load_and_save_round_trip_our_folder_byte_for_byte() {
let mut service = HarnessSessionService::new();
let compiled = call(
&mut service,
"harness.v1.orchestration.compile",
json!({"from": "hermes", "home": fixture()}),
);
let root = scratch("our-folder");
let saved = call(
&mut service,
"harness.v1.orchestration.save",
json!({"root": root, "orchestration": compiled["orchestration"], "vault": fixture_vault()}),
);
assert_eq!(saved["written"], json!(true));
assert_eq!(saved["root"], json!(root));
let before = files_under(&root);
assert!(
before.contains_key("config.yaml") && before.contains_key(".env"),
"the home was written: {:?}",
before.keys().collect::<Vec<_>>()
);
assert!(
String::from_utf8_lossy(&before[".env"]).contains("TELEGRAM_TOKEN="),
"secrets land in .env, never in the orchestration"
);
let read = call(
&mut service,
"harness.v1.orchestration.load",
json!({"root": root}),
);
assert_eq!(
read["orchestration"]["root"],
json!(root),
"the orchestration names the folder it was read from"
);
let keys: Vec<&str> = read["vault_keys"]
.as_array()
.unwrap()
.iter()
.map(|k| k.as_str().unwrap())
.collect();
assert!(keys.contains(&"TELEGRAM_TOKEN"), "{keys:?}");
let wire = serde_json::to_string(&read).unwrap();
for (key, value) in fixture_vault() {
assert!(
!wire.contains(value.as_str()),
"`{key}`'s value was read out"
);
}
call(
&mut service,
"harness.v1.orchestration.save",
json!({"root": root, "orchestration": read["orchestration"]}),
);
let after = files_under(&root);
assert_eq!(
after.keys().collect::<Vec<_>>(),
before.keys().collect::<Vec<_>>(),
"save(load(root)) writes the same files"
);
assert!(
after == before,
"save(load(root)) == root byte for byte; first difference: {:?}",
before
.iter()
.find(|(name, bytes)| after.get(*name) != Some(*bytes))
.map(|(name, _)| name)
);
}
#[test]
fn import_then_export_move_the_credential_without_it_crossing_the_wire() {
let mut service = HarnessSessionService::new();
let vault = fixture_vault();
let token = vault["TELEGRAM_TOKEN"].clone();
let into = scratch("import-into");
let imported = call(
&mut service,
"harness.v1.orchestration.import",
json!({"from": "hermes", "home": fixture(), "into": into}),
);
assert!(
!imported.to_string().contains(&token),
"the answer carries no secret value"
);
assert!(imported["vault_keys"]
.as_array()
.unwrap()
.iter()
.any(|k| k == "TELEGRAM_TOKEN"));
assert_eq!(imported["root"], json!(into));
let env = fs::read_to_string(into.join(".env")).unwrap();
assert!(env.contains(&token), ".env holds the value");
let config = fs::read_to_string(into.join("config.yaml")).unwrap();
assert!(
config.contains("dotenv") && !config.contains(&token),
"config.yaml holds a ref, never the value: {config}"
);
let carried: Vec<&str> = imported["carried"]
.as_array()
.unwrap()
.iter()
.map(|c| c.as_str().unwrap())
.collect();
for rel in &carried {
assert_eq!(
fs::read(into.join(rel)).unwrap(),
fs::read(fixture().join(rel)).unwrap(),
"{rel} carried byte for byte"
);
}
let dest = scratch("export-dest");
let report = call(
&mut service,
"harness.v1.orchestration.export",
json!({"to": "hermes", "root": into, "dest": dest}),
);
let out = fs::read_to_string(dest.join("config.yaml")).unwrap();
assert!(
out.contains(&token) && !out.contains("dotenv"),
"Hermes reads the value from config.yaml: {out}"
);
assert!(
report["refused"]
.as_array()
.unwrap()
.iter()
.any(|r| r["file"] == "state.db" && r["reason"].as_str().unwrap().contains("UNI-22")),
"our state.db is never written as Hermes's: {}",
report["refused"]
);
}