Name scenario cluster modes explicitly

This commit is contained in:
andrussal 2026-03-08 14:41:28 +01:00
parent 19a0c904c1
commit 0911818626
7 changed files with 65 additions and 41 deletions

View File

@ -4,7 +4,7 @@ use thiserror::Error;
use tracing::{debug, info};
use super::{
Application, DeploymentPolicy, DynError, ExistingCluster, ExternalNodeSource,
Application, ClusterMode, DeploymentPolicy, DynError, ExistingCluster, ExternalNodeSource,
HttpReadinessRequirement, NodeControlCapability, ObservabilityCapability,
builder_ops::CoreBuilderAccess,
expectation::Expectation,
@ -119,8 +119,8 @@ impl<E: Application, Caps> Scenario<E, Caps> {
}
#[must_use]
pub const fn uses_existing_cluster(&self) -> bool {
self.sources.uses_existing_cluster()
pub const fn cluster_mode(&self) -> ClusterMode {
self.sources.cluster_mode()
}
#[must_use]
@ -134,14 +134,19 @@ impl<E: Application, Caps> Scenario<E, Caps> {
self.sources.external_nodes()
}
#[must_use]
pub const fn uses_existing_cluster(&self) -> bool {
matches!(self.cluster_mode(), ClusterMode::ExistingCluster)
}
#[must_use]
pub const fn is_managed(&self) -> bool {
self.sources.is_managed()
matches!(self.cluster_mode(), ClusterMode::Managed)
}
#[must_use]
pub const fn is_external_only(&self) -> bool {
self.sources.is_external_only()
matches!(self.cluster_mode(), ClusterMode::ExternalOnly)
}
#[must_use]

View File

@ -54,7 +54,7 @@ pub use runtime::{
wait_for_http_ports_with_host_and_requirement, wait_for_http_ports_with_requirement,
wait_http_readiness, wait_until_stable,
};
pub use sources::{ExistingCluster, ExternalNodeSource};
pub use sources::{ClusterMode, ExistingCluster, ExternalNodeSource};
pub use workload::Workload;
pub use crate::env::Application;

View File

@ -1,4 +1,4 @@
use crate::scenario::{ExistingCluster, ExternalNodeSource, sources::ScenarioSources};
use crate::scenario::{ClusterMode, ExistingCluster, ExternalNodeSource, sources::ScenarioSources};
/// Explicit descriptor for managed node sourcing.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@ -89,17 +89,32 @@ mod tests {
}
fn mode_from_sources(sources: &ScenarioSources) -> SourceOrchestrationMode {
match sources {
ScenarioSources::Managed { external } => SourceOrchestrationMode::Managed {
managed: ManagedSource::DeployerManaged,
external: external.clone(),
match sources.cluster_mode() {
ClusterMode::Managed => match sources {
ScenarioSources::Managed { external } => SourceOrchestrationMode::Managed {
managed: ManagedSource::DeployerManaged,
external: external.clone(),
},
ScenarioSources::Attached { .. } | ScenarioSources::ExternalOnly { .. } => {
unreachable!("cluster mode and source storage must stay aligned")
}
},
ScenarioSources::Attached { attach, external } => SourceOrchestrationMode::Attached {
attach: attach.clone(),
external: external.clone(),
ClusterMode::ExistingCluster => match sources {
ScenarioSources::Attached { attach, external } => SourceOrchestrationMode::Attached {
attach: attach.clone(),
external: external.clone(),
},
ScenarioSources::Managed { .. } | ScenarioSources::ExternalOnly { .. } => {
unreachable!("cluster mode and source storage must stay aligned")
}
},
ScenarioSources::ExternalOnly { external } => SourceOrchestrationMode::ExternalOnly {
external: external.clone(),
ClusterMode::ExternalOnly => match sources {
ScenarioSources::ExternalOnly { external } => SourceOrchestrationMode::ExternalOnly {
external: external.clone(),
},
ScenarioSources::Managed { .. } | ScenarioSources::Attached { .. } => {
unreachable!("cluster mode and source storage must stay aligned")
}
},
}
}

View File

@ -2,4 +2,4 @@ mod model;
pub(crate) use model::ScenarioSources;
#[doc(hidden)]
pub use model::{ExistingCluster, ExternalNodeSource};
pub use model::{ClusterMode, ExistingCluster, ExternalNodeSource};

View File

@ -119,6 +119,14 @@ impl ExternalNodeSource {
}
}
/// High-level source mode of a scenario cluster.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ClusterMode {
Managed,
ExistingCluster,
ExternalOnly,
}
/// Source model that makes invalid managed+attached combinations
/// unrepresentable by type.
#[derive(Clone, Debug, Eq, PartialEq)]
@ -187,17 +195,11 @@ impl ScenarioSources {
}
#[must_use]
pub(crate) const fn is_managed(&self) -> bool {
matches!(self, Self::Managed { .. })
}
#[must_use]
pub(crate) const fn uses_existing_cluster(&self) -> bool {
matches!(self, Self::Attached { .. })
}
#[must_use]
pub(crate) const fn is_external_only(&self) -> bool {
matches!(self, Self::ExternalOnly { .. })
pub(crate) const fn cluster_mode(&self) -> ClusterMode {
match self {
Self::Managed { .. } => ClusterMode::Managed,
Self::Attached { .. } => ClusterMode::ExistingCluster,
Self::ExternalOnly { .. } => ClusterMode::ExternalOnly,
}
}
}

View File

@ -3,11 +3,12 @@ use std::{env, sync::Arc, time::Duration};
use reqwest::Url;
use testing_framework_core::{
scenario::{
ApplicationExternalProvider, CleanupGuard, ClusterWaitHandle, DeploymentPolicy, FeedHandle,
FeedRuntime, HttpReadinessRequirement, Metrics, NodeClients, NodeControlHandle,
ObservabilityCapabilityProvider, ObservabilityInputs, RequiresNodeControl, Runner,
RuntimeAssembly, Scenario, SourceOrchestrationPlan, SourceProviders, StaticManagedProvider,
build_source_orchestration_plan, orchestrate_sources_with_providers,
ApplicationExternalProvider, CleanupGuard, ClusterMode, ClusterWaitHandle,
DeploymentPolicy, FeedHandle, FeedRuntime, HttpReadinessRequirement, Metrics, NodeClients,
NodeControlHandle, ObservabilityCapabilityProvider, ObservabilityInputs,
RequiresNodeControl, Runner, RuntimeAssembly, Scenario, SourceOrchestrationPlan,
SourceProviders, StaticManagedProvider, build_source_orchestration_plan,
orchestrate_sources_with_providers,
},
topology::DeploymentDescriptor,
};
@ -70,7 +71,7 @@ impl<E: ComposeDeployEnv> DeploymentOrchestrator<E> {
}
})?;
if scenario.uses_existing_cluster() {
if matches!(scenario.cluster_mode(), ClusterMode::ExistingCluster) {
return self
.deploy_attached_only::<Caps>(scenario, source_plan)
.await

View File

@ -5,11 +5,12 @@ use kube::Client;
use reqwest::Url;
use testing_framework_core::{
scenario::{
Application, ApplicationExternalProvider, CleanupGuard, ClusterWaitHandle, Deployer,
DynError, FeedHandle, FeedRuntime, HttpReadinessRequirement, Metrics, MetricsError,
NodeClients, ObservabilityCapabilityProvider, ObservabilityInputs, RequiresNodeControl,
Runner, RuntimeAssembly, Scenario, SourceOrchestrationPlan, SourceProviders,
StaticManagedProvider, build_source_orchestration_plan, orchestrate_sources_with_providers,
Application, ApplicationExternalProvider, CleanupGuard, ClusterMode, ClusterWaitHandle,
Deployer, DynError, FeedHandle, FeedRuntime, HttpReadinessRequirement, Metrics,
MetricsError, NodeClients, ObservabilityCapabilityProvider, ObservabilityInputs,
RequiresNodeControl, Runner, RuntimeAssembly, Scenario, SourceOrchestrationPlan,
SourceProviders, StaticManagedProvider, build_source_orchestration_plan,
orchestrate_sources_with_providers,
},
topology::DeploymentDescriptor,
};
@ -179,7 +180,7 @@ where
let observability = resolve_observability_inputs(scenario.capabilities())?;
if scenario.uses_existing_cluster() {
if matches!(scenario.cluster_mode(), ClusterMode::ExistingCluster) {
let runner = deploy_attached_only::<E, Caps>(scenario, source_plan, observability).await?;
return Ok((runner, attached_metadata(scenario)));
}