Public dry run dryrun-dece97efaef9
This commit is contained in:
parent
7c05d077a1
commit
13d4d524c4
3 changed files with 158 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"kind": "disasmer-filtered-public-tree",
|
"kind": "disasmer-filtered-public-tree",
|
||||||
"source_commit": "01b2c7b06dd306582f1a83dce6d6646658854db7",
|
"source_commit": "dece97efaef95e21b322410d4ae5dd8ad7824df6",
|
||||||
"release_name": "dryrun-01b2c7b06dd3",
|
"release_name": "dryrun-dece97efaef9",
|
||||||
"filtered_out": [
|
"filtered_out": [
|
||||||
"private/**",
|
"private/**",
|
||||||
"experiments/**",
|
"experiments/**",
|
||||||
|
|
|
||||||
|
|
@ -1122,10 +1122,13 @@ fn process_restart_report(args: ProcessRestartArgs) -> Result<Value> {
|
||||||
"project": args.scope.project,
|
"project": args.scope.project,
|
||||||
"process": args.process,
|
"process": args.process,
|
||||||
}))?;
|
}))?;
|
||||||
|
let restart_request = process_restart_request_summary(&response, !args.yes);
|
||||||
return Ok(json!({
|
return Ok(json!({
|
||||||
"command": "process restart",
|
"command": "process restart",
|
||||||
"coordinator": coordinator,
|
"coordinator": coordinator,
|
||||||
|
"process": args.process,
|
||||||
"requires_confirmation": !args.yes,
|
"requires_confirmation": !args.yes,
|
||||||
|
"restart_request": restart_request,
|
||||||
"response": response,
|
"response": response,
|
||||||
"coordinator_session_requests": session.requests(),
|
"coordinator_session_requests": session.requests(),
|
||||||
}));
|
}));
|
||||||
|
|
@ -1135,6 +1138,11 @@ fn process_restart_report(args: ProcessRestartArgs) -> Result<Value> {
|
||||||
"status": "requires_coordinator",
|
"status": "requires_coordinator",
|
||||||
"requires_confirmation": !args.yes,
|
"requires_confirmation": !args.yes,
|
||||||
"process": args.process,
|
"process": args.process,
|
||||||
|
"restart_request": {
|
||||||
|
"status": "requires_coordinator",
|
||||||
|
"operation": "restart_virtual_process",
|
||||||
|
"explicit_user_action": true,
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1149,10 +1157,15 @@ fn process_cancel_report(args: ProcessCancelArgs) -> Result<Value> {
|
||||||
"node": args.node,
|
"node": args.node,
|
||||||
"task": args.task,
|
"task": args.task,
|
||||||
}))?;
|
}))?;
|
||||||
|
let cancel_request = process_cancel_request_summary(&response, !args.yes);
|
||||||
return Ok(json!({
|
return Ok(json!({
|
||||||
"command": "process cancel",
|
"command": "process cancel",
|
||||||
"coordinator": coordinator,
|
"coordinator": coordinator,
|
||||||
"requires_confirmation": !args.yes,
|
"requires_confirmation": !args.yes,
|
||||||
|
"process": args.process,
|
||||||
|
"node": args.node,
|
||||||
|
"task": args.task,
|
||||||
|
"cancel_request": cancel_request,
|
||||||
"response": response,
|
"response": response,
|
||||||
"coordinator_session_requests": session.requests(),
|
"coordinator_session_requests": session.requests(),
|
||||||
}));
|
}));
|
||||||
|
|
@ -1164,6 +1177,12 @@ fn process_cancel_report(args: ProcessCancelArgs) -> Result<Value> {
|
||||||
"process": args.process,
|
"process": args.process,
|
||||||
"node": args.node,
|
"node": args.node,
|
||||||
"task": args.task,
|
"task": args.task,
|
||||||
|
"cancel_request": {
|
||||||
|
"status": "requires_coordinator",
|
||||||
|
"operation": "task_scoped_cancel",
|
||||||
|
"whole_process_cancel_available": false,
|
||||||
|
"explicit_user_action": true,
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2348,6 +2367,60 @@ fn artifact_name_from_path(path: &str) -> String {
|
||||||
path.rsplit('/').next().unwrap_or(path).to_owned()
|
path.rsplit('/').next().unwrap_or(path).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn process_restart_request_summary(response: &Value, requires_confirmation: bool) -> Value {
|
||||||
|
if response.get("type").and_then(Value::as_str) != Some("process_started") {
|
||||||
|
return json!({
|
||||||
|
"status": response.get("type").and_then(Value::as_str).unwrap_or("coordinator_response"),
|
||||||
|
"operation": "restart_virtual_process",
|
||||||
|
"accepted": false,
|
||||||
|
"requires_confirmation": requires_confirmation,
|
||||||
|
"explicit_user_action": true,
|
||||||
|
"error": response.get("message").cloned().unwrap_or(Value::Null),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
json!({
|
||||||
|
"status": "process_started",
|
||||||
|
"operation": "restart_virtual_process",
|
||||||
|
"accepted": true,
|
||||||
|
"process": response.get("process").cloned().unwrap_or(Value::Null),
|
||||||
|
"coordinator_epoch": response.get("epoch").cloned().unwrap_or(Value::Null),
|
||||||
|
"requires_confirmation": requires_confirmation,
|
||||||
|
"explicit_user_action": true,
|
||||||
|
"website_required": false,
|
||||||
|
"single_active_process_boundary": true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_cancel_request_summary(response: &Value, requires_confirmation: bool) -> Value {
|
||||||
|
if response.get("type").and_then(Value::as_str) != Some("task_cancellation_requested") {
|
||||||
|
return json!({
|
||||||
|
"status": response.get("type").and_then(Value::as_str).unwrap_or("coordinator_response"),
|
||||||
|
"operation": "task_scoped_cancel",
|
||||||
|
"accepted": false,
|
||||||
|
"requires_confirmation": requires_confirmation,
|
||||||
|
"explicit_user_action": true,
|
||||||
|
"whole_process_cancel_available": false,
|
||||||
|
"error": response.get("message").cloned().unwrap_or(Value::Null),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
json!({
|
||||||
|
"status": "task_cancellation_requested",
|
||||||
|
"operation": "task_scoped_cancel",
|
||||||
|
"accepted": true,
|
||||||
|
"process": response.get("process").cloned().unwrap_or(Value::Null),
|
||||||
|
"task": response.get("task").cloned().unwrap_or(Value::Null),
|
||||||
|
"node": response.get("node").cloned().unwrap_or(Value::Null),
|
||||||
|
"requires_confirmation": requires_confirmation,
|
||||||
|
"explicit_user_action": true,
|
||||||
|
"website_required": false,
|
||||||
|
"whole_process_cancel_available": false,
|
||||||
|
"node_must_poll_task_control": true,
|
||||||
|
"surviving_state_visibility": "task and artifact state remains visible after terminal task events are reported",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn artifact_download_session_summary(response: &Value) -> Value {
|
fn artifact_download_session_summary(response: &Value) -> Value {
|
||||||
if response.get("type").and_then(Value::as_str) != Some("artifact_download_link") {
|
if response.get("type").and_then(Value::as_str) != Some("artifact_download_link") {
|
||||||
return json!({
|
return json!({
|
||||||
|
|
@ -4426,6 +4499,88 @@ mod tests {
|
||||||
assert_eq!(export["export_plan"]["authorization_digest_present"], true);
|
assert_eq!(export["export_plan"]["authorization_digest_present"], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn process_restart_and_cancel_reports_expose_control_boundaries() {
|
||||||
|
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||||
|
let addr = listener.local_addr().unwrap().to_string();
|
||||||
|
let server = std::thread::spawn(move || {
|
||||||
|
let restart_response = r#"{"type":"process_started","process":"vp","epoch":42}"#;
|
||||||
|
let cancel_response = r#"{"type":"task_cancellation_requested","process":"vp","task":"compile-linux","node":"node-a"}"#;
|
||||||
|
for expected in ["start_process", "cancel_task"] {
|
||||||
|
let (mut stream, _) = listener.accept().unwrap();
|
||||||
|
let mut reader = BufReader::new(stream.try_clone().unwrap());
|
||||||
|
let mut line = String::new();
|
||||||
|
reader.read_line(&mut line).unwrap();
|
||||||
|
assert!(line.contains(&format!(r#""type":"{expected}""#)));
|
||||||
|
assert!(line.contains(r#""tenant":"tenant""#));
|
||||||
|
assert!(line.contains(r#""project":"project""#));
|
||||||
|
assert!(line.contains(r#""process":"vp""#));
|
||||||
|
if expected == "start_process" {
|
||||||
|
stream.write_all(restart_response.as_bytes()).unwrap();
|
||||||
|
} else {
|
||||||
|
assert!(line.contains(r#""node":"node-a""#));
|
||||||
|
assert!(line.contains(r#""task":"compile-linux""#));
|
||||||
|
stream.write_all(cancel_response.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
stream.write_all(b"\n").unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let scope = CliScopeArgs {
|
||||||
|
coordinator: Some(addr),
|
||||||
|
tenant: "tenant".to_owned(),
|
||||||
|
project: "project".to_owned(),
|
||||||
|
user: "user".to_owned(),
|
||||||
|
json: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let restart = process_restart_report(ProcessRestartArgs {
|
||||||
|
scope: scope.clone(),
|
||||||
|
process: "vp".to_owned(),
|
||||||
|
yes: true,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
let cancel = process_cancel_report(ProcessCancelArgs {
|
||||||
|
scope,
|
||||||
|
process: "vp".to_owned(),
|
||||||
|
node: "node-a".to_owned(),
|
||||||
|
task: "compile-linux".to_owned(),
|
||||||
|
yes: false,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
server.join().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(restart["restart_request"]["status"], "process_started");
|
||||||
|
assert_eq!(
|
||||||
|
restart["restart_request"]["operation"],
|
||||||
|
"restart_virtual_process"
|
||||||
|
);
|
||||||
|
assert_eq!(restart["restart_request"]["accepted"], true);
|
||||||
|
assert_eq!(restart["restart_request"]["process"], "vp");
|
||||||
|
assert_eq!(restart["restart_request"]["coordinator_epoch"], 42);
|
||||||
|
assert_eq!(restart["restart_request"]["requires_confirmation"], false);
|
||||||
|
assert_eq!(restart["restart_request"]["website_required"], false);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
cancel["cancel_request"]["status"],
|
||||||
|
"task_cancellation_requested"
|
||||||
|
);
|
||||||
|
assert_eq!(cancel["cancel_request"]["operation"], "task_scoped_cancel");
|
||||||
|
assert_eq!(cancel["cancel_request"]["accepted"], true);
|
||||||
|
assert_eq!(cancel["cancel_request"]["process"], "vp");
|
||||||
|
assert_eq!(cancel["cancel_request"]["task"], "compile-linux");
|
||||||
|
assert_eq!(cancel["cancel_request"]["node"], "node-a");
|
||||||
|
assert_eq!(cancel["cancel_request"]["requires_confirmation"], true);
|
||||||
|
assert_eq!(cancel["cancel_request"]["website_required"], false);
|
||||||
|
assert_eq!(
|
||||||
|
cancel["cancel_request"]["whole_process_cancel_available"],
|
||||||
|
false
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
cancel["cancel_request"]["node_must_poll_task_control"],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_command_reuses_bundle_inspection_without_full_repo_upload() {
|
fn build_command_reuses_bundle_inspection_without_full_repo_upload() {
|
||||||
let temp = tempfile::tempdir().unwrap();
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ for (const [name, pattern] of [
|
||||||
["quota coordinator usage coverage", /fn quota_status_queries_public_coordinator_usage\(\)/],
|
["quota coordinator usage coverage", /fn quota_status_queries_public_coordinator_usage\(\)/],
|
||||||
["task event summary coverage", /fn process_task_log_and_artifact_reports_summarize_task_events\(\)/],
|
["task event summary coverage", /fn process_task_log_and_artifact_reports_summarize_task_events\(\)/],
|
||||||
["artifact download/export report coverage", /fn artifact_download_and_export_reports_expose_safe_session_boundaries\(\)/],
|
["artifact download/export report coverage", /fn artifact_download_and_export_reports_expose_safe_session_boundaries\(\)/],
|
||||||
|
["process control report coverage", /fn process_restart_and_cancel_reports_expose_control_boundaries\(\)/],
|
||||||
["build no full repo upload coverage", /fn build_command_reuses_bundle_inspection_without_full_repo_upload\(\)/],
|
["build no full repo upload coverage", /fn build_command_reuses_bundle_inspection_without_full_repo_upload\(\)/],
|
||||||
["safe coordinator-required plans", /fn node_enroll_and_process_commands_have_safe_plan_without_coordinator\(\)/],
|
["safe coordinator-required plans", /fn node_enroll_and_process_commands_have_safe_plan_without_coordinator\(\)/],
|
||||||
]) {
|
]) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue