use serde_json::{Value, json};
use std::{fs, process::Command};
#[path = "../../artifactize-core/tests/support/mod.rs"]
mod support;
use support::runs::RecordOutput;
#[path = "support/run.rs"]
mod owned_run;
#[test]
fn ordinary_verify_reuses_graph_results_until_structure_changes() {
let root = owned_run::Root::from(support::os::tempdir());
let repo = root.path().join("repo");
let state = root.path().join("state");
root.track(&state, &repo);
fs::create_dir(&repo).unwrap();
let graph = json!({
"name": "project-graph",
"evals": [{"id":"check", "title":"Check project structure", "profile":{"kind":"runtime","command":support::os::true_program(),"args":[]}, "payload":{"instruction":"Check the graph."}}],
});
fs::write(
repo.join(".artf"),
support::declaration::to_toml(graph).unwrap(),
)
.unwrap();
fs::write(repo.join("index.artf"), "name = 'app'\nbasis = true\n").unwrap();
fs::write(repo.join("data.txt"), "first contents").unwrap();
let invoke = |args: &[&str], code: i32| -> Value {
let output = Command::new(support::os::cli())
.arg("--repo")
.arg(&repo)
.arg("--state-dir")
.arg(&state)
.args(args)
.arg("--json")
.env("ARTIFACTIZE_REMOTE", "off")
.record_output()
.unwrap();
assert_eq!(
output.status.code(),
Some(code),
"{}{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
serde_json::from_slice(&output.stdout).unwrap()
};
let first = invoke(&["verify", "--wait", "project-graph"], 0);
assert_eq!(first["executionsStarted"], 1);
let fingerprint = first["requests"][0]["key"].clone();
assert!(fingerprint.as_str().is_some());
let unchanged = invoke(&["verify", "--wait", "project-graph"], 0);
assert_eq!(unchanged["executionsStarted"], 0);
assert_eq!(
first["requests"][0]["executionId"],
unchanged["requests"][0]["executionId"]
);
fs::write(repo.join("data.txt"), "unrelated changed contents").unwrap();
fs::write(
repo.join("index.artf"),
"name = 'app'\nbasis = true\ntags = ['new-tag']\n",
)
.unwrap();
let content_only = invoke(
&[
"verify",
"--wait",
"project-graph",
"--reuse-only",
"runtime",
],
0,
);
assert_eq!(content_only["executionsStarted"], 0);
assert_eq!(content_only["requests"][0]["key"], fingerprint);
assert_eq!(
content_only["requests"][0]["executionId"],
first["requests"][0]["executionId"]
);
fs::write(
repo.join("index.artf"),
"name = 'renamed-app'\nbasis = true\n",
)
.unwrap();
let stale = invoke(
&[
"verify",
"--wait",
"project-graph",
"--reuse-only",
"runtime",
],
4,
);
assert_eq!(stale["executionsStarted"], 0);
let changed = invoke(&["verify", "--wait", "--all"], 0);
assert_eq!(changed["executionsStarted"], 1);
assert_ne!(changed["requests"][0]["key"], fingerprint);
let status = invoke(&["status", "--all"], 0);
assert_eq!(status["satisfied"], true);
assert!(status["evals"].as_array().unwrap().iter().any(|eval| {
eval["id"] == "project-graph/check" && eval["key"] == changed["requests"][0]["key"]
}));
fs::write(repo.join(".artf"), "name = 'project-graph'\nbasis = true\n").unwrap();
let basis = invoke(&["verify", "--wait", "--all"], 0);
assert_eq!(basis["validation"]["satisfied"], true);
assert_eq!(basis["executionsStarted"], 0);
}