Let builders derive existing clusters from metadata

This commit is contained in:
andrussal 2026-03-08 15:25:01 +01:00
parent 6ad6ff33c4
commit ef9428ba48
8 changed files with 78 additions and 15 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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<Self, DynError> {
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<E: Application, Caps> Builder<E, Caps> {
self
}
#[must_use]
pub fn with_existing_cluster_from(
self,
cluster: impl IntoExistingCluster,
) -> Result<Self, DynError> {
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 {

View File

@ -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;

View File

@ -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,
};

View File

@ -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<ExistingCluster, DynError>;
}
impl IntoExistingCluster for ExistingCluster {
fn into_existing_cluster(self) -> Result<ExistingCluster, DynError> {
Ok(self)
}
}
impl IntoExistingCluster for &ExistingCluster {
fn into_existing_cluster(self) -> Result<ExistingCluster, DynError> {
Ok(self.clone())
}
}
/// Static external node endpoint that should be included in the runtime
/// inventory.
#[derive(Clone, Debug, Eq, PartialEq)]

View File

@ -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<ExistingCluster, DynError> {
self.existing_cluster()
}
}
impl IntoExistingCluster for &ComposeDeploymentMetadata {
fn into_existing_cluster(self) -> Result<ExistingCluster, DynError> {
self.existing_cluster()
}
}
impl<E: ComposeDeployEnv> Default for ComposeDeployer<E> {
fn default() -> Self {
Self::new()

View File

@ -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<ExistingCluster, DynError> {
self.existing_cluster()
}
}
impl IntoExistingCluster for &K8sDeploymentMetadata {
fn into_existing_cluster(self) -> Result<ExistingCluster, DynError> {
self.existing_cluster()
}
}