mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
198 lines
5.9 KiB
Rust
198 lines
5.9 KiB
Rust
use fabro_test::{fabro_snapshot, test_context};
|
|
use httpmock::MockServer;
|
|
use serde_json::Value;
|
|
|
|
use super::support::{mock_resolved_run, remote_run_summary_json};
|
|
use crate::support::unique_run_id;
|
|
|
|
#[test]
|
|
fn help() {
|
|
let context = test_context!();
|
|
let mut cmd = context.command();
|
|
cmd.args(["parent", "--help"]);
|
|
fabro_snapshot!(context.filters(), cmd, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
Manage run parent links
|
|
|
|
Usage: fabro parent [OPTIONS] <COMMAND>
|
|
|
|
Commands:
|
|
link Link or replace a run's orchestration parent
|
|
unlink Unlink a run from its orchestration parent
|
|
help Print this message or the help of the given subcommand(s)
|
|
|
|
Options:
|
|
--json Output as JSON [env: FABRO_JSON=]
|
|
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
|
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
|
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
|
--verbose Enable verbose output [env: FABRO_VERBOSE=]
|
|
-h, --help Print help
|
|
----- stderr -----
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn parent_link_resolves_selectors_calls_endpoint_and_prints_link() {
|
|
let context = test_context!();
|
|
let server = MockServer::start();
|
|
let child_id = unique_run_id();
|
|
let parent_id = unique_run_id();
|
|
|
|
let child_resolve = mock_resolved_run(&server, "child-build", &child_id);
|
|
let parent_resolve = mock_resolved_run(&server, "parent-build", &parent_id);
|
|
let link_mock = server.mock(|when, then| {
|
|
when.method("PUT")
|
|
.path(format!("/api/v1/runs/{child_id}/parent"))
|
|
.header("content-type", "application/json")
|
|
.json_body(serde_json::json!({
|
|
"parent_id": parent_id
|
|
}));
|
|
let mut summary = remote_run_summary_json(
|
|
&child_id,
|
|
"Nightly Build",
|
|
"nightly-build",
|
|
"Nightly run",
|
|
&serde_json::json!({
|
|
"kind": "succeeded",
|
|
"reason": "completed"
|
|
}),
|
|
"2026-04-05T12:00:00Z",
|
|
);
|
|
summary["parent_id"] = serde_json::json!(parent_id);
|
|
then.status(200)
|
|
.header("Content-Type", "application/json")
|
|
.json_body(summary);
|
|
});
|
|
|
|
let mut cmd = context.command();
|
|
cmd.args([
|
|
"parent",
|
|
"link",
|
|
"--server",
|
|
&server.base_url(),
|
|
"child-build",
|
|
"parent-build",
|
|
]);
|
|
|
|
fabro_snapshot!(context.filters(), cmd, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
Linked parent: [ULID] -> [ULID]
|
|
----- stderr -----
|
|
");
|
|
|
|
child_resolve.assert();
|
|
parent_resolve.assert();
|
|
link_mock.assert();
|
|
}
|
|
|
|
#[test]
|
|
fn parent_link_json_prints_updated_run_summary() {
|
|
let context = test_context!();
|
|
let server = MockServer::start();
|
|
let child_id = unique_run_id();
|
|
let parent_id = unique_run_id();
|
|
|
|
let child_resolve = mock_resolved_run(&server, "child-build", &child_id);
|
|
let parent_resolve = mock_resolved_run(&server, "parent-build", &parent_id);
|
|
let link_mock = server.mock(|when, then| {
|
|
when.method("PUT")
|
|
.path(format!("/api/v1/runs/{child_id}/parent"))
|
|
.json_body(serde_json::json!({
|
|
"parent_id": parent_id
|
|
}));
|
|
let mut summary = remote_run_summary_json(
|
|
&child_id,
|
|
"Nightly Build",
|
|
"nightly-build",
|
|
"Nightly run",
|
|
&serde_json::json!({
|
|
"kind": "succeeded",
|
|
"reason": "completed"
|
|
}),
|
|
"2026-04-05T12:00:00Z",
|
|
);
|
|
summary["parent_id"] = serde_json::json!(parent_id);
|
|
then.status(200)
|
|
.header("Content-Type", "application/json")
|
|
.json_body(summary);
|
|
});
|
|
|
|
let output = context
|
|
.command()
|
|
.args([
|
|
"--json",
|
|
"parent",
|
|
"link",
|
|
"--server",
|
|
&server.base_url(),
|
|
"child-build",
|
|
"parent-build",
|
|
])
|
|
.output()
|
|
.expect("parent link should execute");
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"parent link failed:\nstdout:\n{}\nstderr:\n{}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
let summary: Value = serde_json::from_slice(&output.stdout).expect("JSON should parse");
|
|
assert_eq!(summary["id"], child_id);
|
|
assert_eq!(summary["parent_id"], parent_id);
|
|
|
|
child_resolve.assert();
|
|
parent_resolve.assert();
|
|
link_mock.assert();
|
|
}
|
|
|
|
#[test]
|
|
fn parent_unlink_resolves_selector_calls_endpoint_and_prints_unlinked_child() {
|
|
let context = test_context!();
|
|
let server = MockServer::start();
|
|
let child_id = unique_run_id();
|
|
|
|
let child_resolve = mock_resolved_run(&server, "child-build", &child_id);
|
|
let unlink_mock = server.mock(|when, then| {
|
|
when.method("DELETE")
|
|
.path(format!("/api/v1/runs/{child_id}/parent"));
|
|
then.status(200)
|
|
.header("Content-Type", "application/json")
|
|
.json_body(remote_run_summary_json(
|
|
&child_id,
|
|
"Nightly Build",
|
|
"nightly-build",
|
|
"Nightly run",
|
|
&serde_json::json!({
|
|
"kind": "succeeded",
|
|
"reason": "completed"
|
|
}),
|
|
"2026-04-05T12:00:00Z",
|
|
));
|
|
});
|
|
|
|
let mut cmd = context.command();
|
|
cmd.args([
|
|
"parent",
|
|
"unlink",
|
|
"--server",
|
|
&server.base_url(),
|
|
"child-build",
|
|
]);
|
|
|
|
fabro_snapshot!(context.filters(), cmd, @"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
Unlinked parent: [ULID]
|
|
----- stderr -----
|
|
");
|
|
|
|
child_resolve.assert();
|
|
unlink_mock.assert();
|
|
}
|