diff --git a/testing-framework/core/src/scenario/definition.rs b/testing-framework/core/src/scenario/definition.rs index 0eea6f2..c423fb5 100644 --- a/testing-framework/core/src/scenario/definition.rs +++ b/testing-framework/core/src/scenario/definition.rs @@ -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 Scenario { } #[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 Scenario { 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] diff --git a/testing-framework/core/src/scenario/mod.rs b/testing-framework/core/src/scenario/mod.rs index 9f927da..431ee7c 100644 --- a/testing-framework/core/src/scenario/mod.rs +++ b/testing-framework/core/src/scenario/mod.rs @@ -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; diff --git a/testing-framework/core/src/scenario/runtime/orchestration/source_orchestration_plan.rs b/testing-framework/core/src/scenario/runtime/orchestration/source_orchestration_plan.rs index 2c3cb4e..35bb510 100644 --- a/testing-framework/core/src/scenario/runtime/orchestration/source_orchestration_plan.rs +++ b/testing-framework/core/src/scenario/runtime/orchestration/source_orchestration_plan.rs @@ -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") + } }, } } diff --git a/testing-framework/core/src/scenario/sources/mod.rs b/testing-framework/core/src/scenario/sources/mod.rs index 506a8aa..7f63800 100644 --- a/testing-framework/core/src/scenario/sources/mod.rs +++ b/testing-framework/core/src/scenario/sources/mod.rs @@ -2,4 +2,4 @@ mod model; pub(crate) use model::ScenarioSources; #[doc(hidden)] -pub use model::{ExistingCluster, ExternalNodeSource}; +pub use model::{ClusterMode, ExistingCluster, ExternalNodeSource}; diff --git a/testing-framework/core/src/scenario/sources/model.rs b/testing-framework/core/src/scenario/sources/model.rs index a64b010..63c6c1b 100644 --- a/testing-framework/core/src/scenario/sources/model.rs +++ b/testing-framework/core/src/scenario/sources/model.rs @@ -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, + } } } diff --git a/testing-framework/deployers/compose/src/deployer/orchestrator.rs b/testing-framework/deployers/compose/src/deployer/orchestrator.rs index 3025eaf..293dd55 100644 --- a/testing-framework/deployers/compose/src/deployer/orchestrator.rs +++ b/testing-framework/deployers/compose/src/deployer/orchestrator.rs @@ -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 DeploymentOrchestrator { } })?; - if scenario.uses_existing_cluster() { + if matches!(scenario.cluster_mode(), ClusterMode::ExistingCluster) { return self .deploy_attached_only::(scenario, source_plan) .await diff --git a/testing-framework/deployers/k8s/src/deployer/orchestrator.rs b/testing-framework/deployers/k8s/src/deployer/orchestrator.rs index f685a7d..2b177fe 100644 --- a/testing-framework/deployers/k8s/src/deployer/orchestrator.rs +++ b/testing-framework/deployers/k8s/src/deployer/orchestrator.rs @@ -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::(scenario, source_plan, observability).await?; return Ok((runner, attached_metadata(scenario))); }