test(aura-cli): RED for self-identifying RunManifest.commit
RunManifest.commit comes from option_env!("AURA_COMMIT") defaulting to
"unknown", so the C18 manifest's identity field -- which code produced
this run -- is a bare placeholder in a normal build. C8's audit-trail
invariant (this run = this commit) needs the manifest to point back at
its source once runs are archived.
This RED pins the desired contract structurally: a normal `aura run`'s
manifest.commit CONTAINS the current git HEAD sha (obtained in-test via
`git rev-parse HEAD`) and is NOT the bare "unknown" literal. Structural
(contains, not equals) on purpose: the working tree may be dirty when
the test runs (this test file itself was uncommitted at author time), so
a build that appends a "-dirty" suffix must still pass. GREEN is a
build.rs in aura-cli capturing HEAD at compile time, "unknown" retained
only for the no-git case.
refs #15
This commit is contained in:
@@ -26,6 +26,53 @@ fn run_prints_json_and_exits_zero() {
|
||||
assert!(line.ends_with("\"exposure_sign_flips\":1}}"), "got: {line}");
|
||||
}
|
||||
|
||||
/// Property: the RunManifest is self-identifying — its `commit` carries the
|
||||
/// real code identity that produced the run, not a placeholder. C8/C18 audit
|
||||
/// trail (this run = this commit): once runs are archived, `manifest.commit`
|
||||
/// must point back at the source. The build captures the current git HEAD at
|
||||
/// compile time; the `"unknown"` literal survives only when there is no git.
|
||||
///
|
||||
/// Structural assertion (not exact-equality) on purpose: the working tree may
|
||||
/// be dirty when this runs (e.g. this very test file uncommitted), so a build
|
||||
/// that appends a `-dirty` suffix would not equal `rev-parse HEAD` verbatim.
|
||||
/// The honest contract is: the field CONTAINS the current HEAD sha AND is not
|
||||
/// the bare `"unknown"` placeholder — true regardless of dirtiness/suffix.
|
||||
#[test]
|
||||
fn run_manifest_commit_carries_real_git_head() {
|
||||
// The current HEAD sha, obtained the same way the build is expected to.
|
||||
let head = Command::new("git")
|
||||
.args(["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.expect("spawn git rev-parse HEAD");
|
||||
assert!(head.status.success(), "git rev-parse HEAD failed");
|
||||
let head_sha = String::from_utf8(head.stdout).expect("utf-8 sha");
|
||||
let head_sha = head_sha.trim();
|
||||
assert!(!head_sha.is_empty(), "empty HEAD sha");
|
||||
|
||||
// Drive the binary and pull `manifest.commit` out of the single JSON line.
|
||||
let out = Command::new(BIN).arg("run").output().expect("spawn aura run");
|
||||
assert!(out.status.success(), "exit status: {:?}", out.status);
|
||||
let stdout = String::from_utf8(out.stdout).expect("utf-8 stdout");
|
||||
let line = stdout.trim_end();
|
||||
|
||||
// Locate the `"commit":"<value>"` value without a JSON dependency (the
|
||||
// sibling tests parse this output by substring too).
|
||||
let key = "\"commit\":\"";
|
||||
let start = line.find(key).expect("manifest has a commit field") + key.len();
|
||||
let rest = &line[start..];
|
||||
let end = rest.find('"').expect("commit field is a closed string");
|
||||
let commit = &rest[..end];
|
||||
|
||||
assert_ne!(
|
||||
commit, "unknown",
|
||||
"manifest.commit is still the placeholder: {line}"
|
||||
);
|
||||
assert!(
|
||||
commit.contains(head_sha),
|
||||
"manifest.commit {commit:?} should contain the current HEAD sha {head_sha:?}; line: {line}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_args_prints_usage_and_exits_two() {
|
||||
let out = Command::new(BIN).output().expect("spawn aura");
|
||||
|
||||
Reference in New Issue
Block a user