Watch
0
0
Fork
You've already forked hyperhive
0

swarm-builder: an agent option whose eval failed is left out of the reply, not read as its default

This commit is contained in:
atlas 2026-11-06 10:03:18 +01:00 • committed by mara
commit 5d2b0c9a54

View file

@ -40,15 +40,15 @@ pub struct AgentClosure {
pub cached: bool,
/// Whether the agent's evaluated config sets
/// `services.hyperhive.agent.user.privateUsers`: the agent runs in its own
/// user namespace. A record written before the field existed reads as
/// false, which keeps the agent out of one.
#[serde(default)]
pub private_users: bool,
/// user namespace. `None` when the builder could not read it, and for a
/// record written before the field existed: the record says nothing, and
/// the reader leaves the agent as its last start set it.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub private_users: Option<bool>,
/// The agent's `services.hyperhive.agent.nixBuilds`: where its nix builds
/// run. A record written before the field existed reads as
/// [`NixBuilds::Host`], which is what every agent did before it.
#[serde(default)]
pub nix_builds: NixBuilds,
/// run. `None` as for `private_users`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub nix_builds: Option<NixBuilds>,
}
#[cfg(test)]
@ -69,8 +69,8 @@ mod tests {
system: "x86_64-linux".to_owned(),
built_unix: 7,
cached: true,
private_users: true,
nix_builds: NixBuilds::Disabled,
private_users: Some(true),
nix_builds: Some(NixBuilds::Disabled),
};
let wire = serde_json::json!({
"meta_rev": "abc",
@ -89,7 +89,7 @@ mod tests {
}
#[test]
fn a_record_without_the_fields_reads_as_not_cached_not_namespaced_and_host_builds() {
fn a_record_without_the_fields_reads_as_not_cached_and_says_nothing_of_the_options() {
let old = serde_json::json!({
"meta_rev": "abc",
"store_path": "/nix/store/x",
@ -98,7 +98,41 @@ mod tests {
});
let record = serde_json::from_value::<AgentClosure>(old).expect("decodes");
assert!(!record.cached);
assert!(!record.private_users);
assert_eq!(record.nix_builds, NixBuilds::Host);
assert_eq!(record.private_users, None);
assert_eq!(record.nix_builds, None);
}
/// An option the builder could not read is left out of the record, not
/// written as `null`: a reader that predates the option still decodes it.
#[test]
fn an_unread_option_is_left_out_of_the_record() {
// The shape a reader before the option had: a bool that defaults to false.
#[derive(serde::Deserialize)]
struct Before {
#[serde(default)]
private_users: bool,
}
let record = AgentClosure {
meta_rev: "abc".to_owned(),
store_path: "/nix/store/x".to_owned(),
system: "x86_64-linux".to_owned(),
built_unix: 7,
cached: true,
private_users: None,
nix_builds: Some(NixBuilds::Host),
};
let wire = serde_json::to_value(&record).expect("encodes");
let fields = wire.as_object().expect("an object");
assert!(!fields.contains_key("private_users"), "{wire}");
assert_eq!(fields["nix_builds"], "host");
assert!(
!serde_json::from_value::<Before>(wire.clone())
.expect("decodes")
.private_users
);
assert_eq!(
serde_json::from_value::<AgentClosure>(wire).expect("decodes"),
record
);
}
}