Separate attached semantics from node control capability

This commit is contained in:
andrussal 2026-03-08 15:03:03 +01:00
parent 898eadf976
commit aa838ecca9
3 changed files with 9 additions and 14 deletions

View File

@ -765,10 +765,10 @@ where
{
let profile = sources.control_profile();
if Caps::REQUIRED && !profile.supports_node_control() {
if Caps::REQUIRED && matches!(profile, ClusterControlProfile::ExternalUncontrolled) {
return Err(ScenarioBuildError::SourceConfiguration {
message: format!(
"node control requires a controllable cluster surface, but cluster mode '{}' uses control profile '{}'",
"node control is not available for cluster mode '{}' with control profile '{}'",
sources.cluster_mode().as_str(),
profile.as_str(),
),
@ -905,7 +905,7 @@ mod tests {
));
assert_eq!(
error.to_string(),
"invalid scenario source configuration: node control requires a controllable cluster surface, but cluster mode 'external-only' uses control profile 'external-uncontrolled'"
"invalid scenario source configuration: node control is not available for cluster mode 'external-only' with control profile 'external-uncontrolled'"
);
}

View File

@ -192,10 +192,10 @@ impl<E: Application> Runner<E> {
}
fn settle_wait_duration(context: &RunContext<E>) -> Option<Duration> {
let control_profile = context.cluster_control_profile();
let has_node_control = context.node_control().is_some();
let configured_wait = context.expectation_cooldown();
if configured_wait.is_zero() && !control_profile.supports_node_control() {
if configured_wait.is_zero() && !has_node_control {
return None;
}

View File

@ -142,7 +142,7 @@ impl ClusterMode {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ClusterControlProfile {
FrameworkManaged,
ExistingClusterControlled,
ExistingClusterAttached,
ExternalUncontrolled,
ManualControlled,
}
@ -152,7 +152,7 @@ impl ClusterControlProfile {
pub const fn as_str(self) -> &'static str {
match self {
Self::FrameworkManaged => "framework-managed",
Self::ExistingClusterControlled => "existing-cluster-controlled",
Self::ExistingClusterAttached => "existing-cluster-attached",
Self::ExternalUncontrolled => "external-uncontrolled",
Self::ManualControlled => "manual-controlled",
}
@ -162,11 +162,6 @@ impl ClusterControlProfile {
pub const fn framework_owns_lifecycle(self) -> bool {
matches!(self, Self::FrameworkManaged)
}
#[must_use]
pub const fn supports_node_control(self) -> bool {
!matches!(self, Self::ExternalUncontrolled)
}
}
/// Source model that makes invalid managed+attached combinations
@ -249,7 +244,7 @@ impl ScenarioSources {
pub(crate) const fn control_profile(&self) -> ClusterControlProfile {
match self.cluster_mode() {
ClusterMode::Managed => ClusterControlProfile::FrameworkManaged,
ClusterMode::ExistingCluster => ClusterControlProfile::ExistingClusterControlled,
ClusterMode::ExistingCluster => ClusterControlProfile::ExistingClusterAttached,
ClusterMode::ExternalOnly => ClusterControlProfile::ExternalUncontrolled,
}
}
@ -274,7 +269,7 @@ mod tests {
assert_eq!(
sources.control_profile(),
ClusterControlProfile::ExistingClusterControlled,
ClusterControlProfile::ExistingClusterAttached,
);
}