use super::*;
#[tokio::test]
async fn no_log_timestamps_on_a_sheep_named_by_the_token_writes_the_field_first() {
use shep_client::testing::fake_client_answering;
use shep_core::status::ProcStatus;
let dir = tempfile::tempdir().unwrap();
let sock = shep_client::testing::control_address(dir.path());
let flock = vec![ProcessInfo::builder(0, "rotating", ProcStatus::Stopped).build()];
let (client, mut envelopes) =
fake_client_answering(&sock, move |request: &Request| match request {
Request::ListFlock => Response::Flock(flock.clone()),
Request::SetSheepField { name, key, .. } => Response::SheepFieldSet {
name: name.clone(),
key: key.clone(),
pending: true,
warning: None,
},
Request::Restart { .. } => Response::Restarted {
accepted: vec![ProcessInfo::builder(0, "rotating", ProcStatus::Online).build()],
refused: Vec::new(),
},
_ => Response::Pong,
})
.await;
let mut args = start_args("rotating");
args.no_log_timestamps = true;
let (code, _printed, said) = start_against_with_args(&client, &args).await;
assert_eq!(code, ExitCode::Success, "{said}");
let mut order = Vec::new();
while let Ok(envelope) = envelopes.try_recv() {
match envelope.body {
Request::SetSheepField { name, key, value } => {
assert_eq!(name, "rotating", "the token named this sheep");
assert_eq!(key, "log_timestamps");
assert_eq!(value, serde_json::json!(false));
order.push("field".to_string());
}
Request::Restart { .. } => order.push("restart".to_string()),
_ => {}
}
}
assert_eq!(
order,
["field", "restart"],
"a named sheep is resumed without a merge, so the write is the only \
route the flag has, and it goes first: {said}"
);
assert!(
said.contains(
"notice[start]: rotating: log_timestamps waiting on the next spawn \
(`shep reload rotating` promotes them)"
),
"the write parked, and the verb says so: {said}"
);
}
#[tokio::test]
async fn a_sheep_named_by_the_token_without_the_flag_gets_no_field_write() {
use shep_client::testing::fake_client_answering;
use shep_core::status::ProcStatus;
let dir = tempfile::tempdir().unwrap();
let sock = shep_client::testing::control_address(dir.path());
let flock = vec![ProcessInfo::builder(0, "rotating", ProcStatus::Stopped).build()];
let (client, mut envelopes) =
fake_client_answering(&sock, move |request: &Request| match request {
Request::ListFlock => Response::Flock(flock.clone()),
Request::Restart { .. } => Response::Restarted {
accepted: vec![ProcessInfo::builder(0, "rotating", ProcStatus::Online).build()],
refused: Vec::new(),
},
_ => Response::Pong,
})
.await;
let (code, _printed, said) = start_against(&client, "rotating").await;
assert_eq!(code, ExitCode::Success, "{said}");
assert!(
!respawns(&mut envelopes).is_empty(),
"the resume is what this verb was asked for: {said}"
);
}
#[tokio::test]
async fn a_refused_field_write_on_a_named_sheep_stops_before_the_resume() {
use shep_client::testing::fake_client_answering_refusals;
use shep_core::protocol::RpcError;
use shep_core::status::ProcStatus;
let dir = tempfile::tempdir().unwrap();
let sock = shep_client::testing::control_address(dir.path());
let flock = vec![ProcessInfo::builder(0, "rotating", ProcStatus::Stopped).build()];
let (client, mut envelopes) =
fake_client_answering_refusals(&sock, move |request: &Request| match request {
Request::ListFlock => Ok(Response::Flock(flock.clone())),
Request::SetSheepField { .. } => Err(RpcError {
code: RpcErrorCode::InvalidConfig,
message: "no config field named log_timestamps".to_string(),
daemon_version: None,
}),
_ => Ok(Response::Pong),
})
.await;
let mut args = start_args("rotating");
args.no_log_timestamps = true;
let (code, printed, said) = start_against_with_args(&client, &args).await;
assert_eq!(code, ExitCode::InvalidConfig, "{said}");
assert!(printed.is_empty(), "a failed verb leaves stdout empty");
assert!(
said.contains("rotating: log_timestamps"),
"the failure names the sheep and the value: {said}"
);
assert!(
respawns(&mut envelopes).is_empty(),
"and the sheep is not brought back up stamped"
);
}