From ef9428ba4828eb02bc496028bb4dabc4dcdf701a Mon Sep 17 00:00:00 2001 From: andrussal Date: Sun, 8 Mar 2026 15:25:01 +0100 Subject: [PATCH] Let builders derive existing clusters from metadata --- .../tests/compose_attach_node_control.rs | 6 ++--- .../examples/tests/k8s_attach_node_control.rs | 6 ++--- .../core/src/scenario/definition.rs | 24 +++++++++++++++++-- testing-framework/core/src/scenario/mod.rs | 4 +++- .../core/src/scenario/sources/mod.rs | 4 +++- .../core/src/scenario/sources/model.rs | 19 +++++++++++++++ .../deployers/compose/src/deployer/mod.rs | 16 +++++++++++-- .../deployers/k8s/src/deployer/mod.rs | 14 ++++++++++- 8 files changed, 78 insertions(+), 15 deletions(-) diff --git a/logos/examples/tests/compose_attach_node_control.rs b/logos/examples/tests/compose_attach_node_control.rs index 4f909a6..5c36326 100644 --- a/logos/examples/tests/compose_attach_node_control.rs +++ b/logos/examples/tests/compose_attach_node_control.rs @@ -20,12 +20,10 @@ async fn compose_attach_mode_queries_node_api_opt_in() -> Result<()> { Err(error) => return Err(Error::new(error)), }; - let attach_source = metadata - .existing_cluster() - .map_err(|err| anyhow!("{err}"))?; let attached = ScenarioBuilder::deployment_with(|d| d.with_node_count(1)) .with_run_duration(Duration::from_secs(5)) - .with_existing_cluster(attach_source) + .with_existing_cluster_from(&metadata) + .map_err(|err| anyhow!("{err}"))? .build()?; let attached_deployer = LbcComposeDeployer::default(); diff --git a/logos/examples/tests/k8s_attach_node_control.rs b/logos/examples/tests/k8s_attach_node_control.rs index 47bbe35..66785f8 100644 --- a/logos/examples/tests/k8s_attach_node_control.rs +++ b/logos/examples/tests/k8s_attach_node_control.rs @@ -20,12 +20,10 @@ async fn k8s_attach_mode_queries_node_api_opt_in() -> Result<()> { Err(error) => return Err(Error::new(error)), }; - let attach_source = metadata - .existing_cluster() - .map_err(|err| anyhow!("{err}"))?; let attached = ScenarioBuilder::deployment_with(|d| d.with_node_count(1)) .with_run_duration(Duration::from_secs(5)) - .with_existing_cluster(attach_source) + .with_existing_cluster_from(&metadata) + .map_err(|err| anyhow!("{err}"))? .build()?; let attached_deployer = LbcK8sDeployer::default(); diff --git a/testing-framework/core/src/scenario/definition.rs b/testing-framework/core/src/scenario/definition.rs index 19fb3c7..4f4d4ac 100644 --- a/testing-framework/core/src/scenario/definition.rs +++ b/testing-framework/core/src/scenario/definition.rs @@ -5,8 +5,8 @@ use tracing::{debug, info}; use super::{ Application, ClusterControlProfile, ClusterMode, DeploymentPolicy, DynError, ExistingCluster, - ExternalNodeSource, HttpReadinessRequirement, NodeControlCapability, ObservabilityCapability, - RequiresNodeControl, + ExternalNodeSource, HttpReadinessRequirement, IntoExistingCluster, NodeControlCapability, + ObservabilityCapability, RequiresNodeControl, builder_ops::CoreBuilderAccess, expectation::Expectation, runtime::{ @@ -265,6 +265,16 @@ macro_rules! impl_common_builder_methods { self.map_core_builder(|builder| builder.with_existing_cluster(cluster)) } + #[must_use] + pub fn with_existing_cluster_from( + self, + cluster: impl IntoExistingCluster, + ) -> Result { + let cluster = cluster.into_existing_cluster()?; + + Ok(self.with_existing_cluster(cluster)) + } + #[must_use] #[doc(hidden)] pub fn with_attach_source(self, attach: ExistingCluster) -> Self { @@ -601,6 +611,16 @@ impl Builder { self } + #[must_use] + pub fn with_existing_cluster_from( + self, + cluster: impl IntoExistingCluster, + ) -> Result { + let cluster = cluster.into_existing_cluster()?; + + Ok(self.with_existing_cluster(cluster)) + } + #[must_use] #[doc(hidden)] pub fn with_attach_source(self, attach: ExistingCluster) -> Self { diff --git a/testing-framework/core/src/scenario/mod.rs b/testing-framework/core/src/scenario/mod.rs index dc464dc..4089111 100644 --- a/testing-framework/core/src/scenario/mod.rs +++ b/testing-framework/core/src/scenario/mod.rs @@ -54,7 +54,9 @@ 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::{ClusterControlProfile, ClusterMode, ExistingCluster, ExternalNodeSource}; +pub use sources::{ + ClusterControlProfile, ClusterMode, ExistingCluster, ExternalNodeSource, IntoExistingCluster, +}; pub use workload::Workload; pub use crate::env::Application; diff --git a/testing-framework/core/src/scenario/sources/mod.rs b/testing-framework/core/src/scenario/sources/mod.rs index 01e8807..68a9fa4 100644 --- a/testing-framework/core/src/scenario/sources/mod.rs +++ b/testing-framework/core/src/scenario/sources/mod.rs @@ -2,4 +2,6 @@ mod model; pub(crate) use model::ScenarioSources; #[doc(hidden)] -pub use model::{ClusterControlProfile, ClusterMode, ExistingCluster, ExternalNodeSource}; +pub use model::{ + ClusterControlProfile, ClusterMode, ExistingCluster, ExternalNodeSource, IntoExistingCluster, +}; diff --git a/testing-framework/core/src/scenario/sources/model.rs b/testing-framework/core/src/scenario/sources/model.rs index e720524..ea48b1d 100644 --- a/testing-framework/core/src/scenario/sources/model.rs +++ b/testing-framework/core/src/scenario/sources/model.rs @@ -1,3 +1,5 @@ +use crate::scenario::DynError; + /// Typed descriptor for an existing cluster. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ExistingCluster { @@ -94,6 +96,23 @@ impl ExistingCluster { } } +/// Converts a value into an existing-cluster descriptor. +pub trait IntoExistingCluster { + fn into_existing_cluster(self) -> Result; +} + +impl IntoExistingCluster for ExistingCluster { + fn into_existing_cluster(self) -> Result { + Ok(self) + } +} + +impl IntoExistingCluster for &ExistingCluster { + fn into_existing_cluster(self) -> Result { + Ok(self.clone()) + } +} + /// Static external node endpoint that should be included in the runtime /// inventory. #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/testing-framework/deployers/compose/src/deployer/mod.rs b/testing-framework/deployers/compose/src/deployer/mod.rs index a0c35d5..9771a9a 100644 --- a/testing-framework/deployers/compose/src/deployer/mod.rs +++ b/testing-framework/deployers/compose/src/deployer/mod.rs @@ -9,8 +9,8 @@ use std::marker::PhantomData; use async_trait::async_trait; use testing_framework_core::scenario::{ - CleanupGuard, Deployer, DynError, ExistingCluster, FeedHandle, ObservabilityCapabilityProvider, - RequiresNodeControl, Runner, Scenario, + CleanupGuard, Deployer, DynError, ExistingCluster, FeedHandle, IntoExistingCluster, + ObservabilityCapabilityProvider, RequiresNodeControl, Runner, Scenario, }; use crate::{env::ComposeDeployEnv, errors::ComposeRunnerError, lifecycle::cleanup::RunnerCleanup}; @@ -100,6 +100,18 @@ impl ComposeDeploymentMetadata { } } +impl IntoExistingCluster for ComposeDeploymentMetadata { + fn into_existing_cluster(self) -> Result { + self.existing_cluster() + } +} + +impl IntoExistingCluster for &ComposeDeploymentMetadata { + fn into_existing_cluster(self) -> Result { + self.existing_cluster() + } +} + impl Default for ComposeDeployer { fn default() -> Self { Self::new() diff --git a/testing-framework/deployers/k8s/src/deployer/mod.rs b/testing-framework/deployers/k8s/src/deployer/mod.rs index d97615b..33d74dd 100644 --- a/testing-framework/deployers/k8s/src/deployer/mod.rs +++ b/testing-framework/deployers/k8s/src/deployer/mod.rs @@ -2,7 +2,7 @@ mod attach_provider; mod orchestrator; pub use orchestrator::{K8sDeployer, K8sRunnerError}; -use testing_framework_core::scenario::{DynError, ExistingCluster}; +use testing_framework_core::scenario::{DynError, ExistingCluster, IntoExistingCluster}; /// Kubernetes deployment metadata returned by k8s-specific deployment APIs. #[derive(Clone, Debug, Eq, PartialEq)] @@ -64,3 +64,15 @@ impl K8sDeploymentMetadata { self.existing_cluster() } } + +impl IntoExistingCluster for K8sDeploymentMetadata { + fn into_existing_cluster(self) -> Result { + self.existing_cluster() + } +} + +impl IntoExistingCluster for &K8sDeploymentMetadata { + fn into_existing_cluster(self) -> Result { + self.existing_cluster() + } +}