mirror of
https://github.com/logos-blockchain/logos-blockchain-testing.git
synced 2026-07-30 19:33:16 +00:00
workflows: add try_* builder APIs for URLs and rates
This commit is contained in:
parent
f0e9d2807b
commit
8a6d7236ef
@ -13,6 +13,18 @@ use crate::{
|
|||||||
workloads::{chaos::RandomRestartWorkload, da, transaction},
|
workloads::{chaos::RandomRestartWorkload, da, transaction},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum BuilderInputError {
|
||||||
|
#[error("{field} must be non-zero")]
|
||||||
|
ZeroValue { field: &'static str },
|
||||||
|
#[error("invalid url for {field}: '{value}': {message}")]
|
||||||
|
InvalidUrl {
|
||||||
|
field: &'static str,
|
||||||
|
value: String,
|
||||||
|
message: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! non_zero_rate_fn {
|
macro_rules! non_zero_rate_fn {
|
||||||
($name:ident, $message:literal) => {
|
($name:ident, $message:literal) => {
|
||||||
const fn $name(rate: u64) -> NonZeroU64 {
|
const fn $name(rate: u64) -> NonZeroU64 {
|
||||||
@ -106,6 +118,13 @@ pub trait ObservabilityBuilderExt: Sized {
|
|||||||
/// Convenience wrapper that parses a URL string (panics if invalid).
|
/// Convenience wrapper that parses a URL string (panics if invalid).
|
||||||
fn with_metrics_query_url_str(self, url: &str) -> CoreScenarioBuilder<ObservabilityCapability>;
|
fn with_metrics_query_url_str(self, url: &str) -> CoreScenarioBuilder<ObservabilityCapability>;
|
||||||
|
|
||||||
|
/// Like `with_metrics_query_url_str`, but returns an error instead of
|
||||||
|
/// panicking.
|
||||||
|
fn try_with_metrics_query_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError>;
|
||||||
|
|
||||||
/// Configure the OTLP HTTP metrics ingest endpoint to which nodes should
|
/// Configure the OTLP HTTP metrics ingest endpoint to which nodes should
|
||||||
/// export metrics (must be a full URL, including any required path).
|
/// export metrics (must be a full URL, including any required path).
|
||||||
fn with_metrics_otlp_ingest_url(
|
fn with_metrics_otlp_ingest_url(
|
||||||
@ -119,12 +138,25 @@ pub trait ObservabilityBuilderExt: Sized {
|
|||||||
url: &str,
|
url: &str,
|
||||||
) -> CoreScenarioBuilder<ObservabilityCapability>;
|
) -> CoreScenarioBuilder<ObservabilityCapability>;
|
||||||
|
|
||||||
|
/// Like `with_metrics_otlp_ingest_url_str`, but returns an error instead of
|
||||||
|
/// panicking.
|
||||||
|
fn try_with_metrics_otlp_ingest_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError>;
|
||||||
|
|
||||||
/// Optional Grafana base URL for printing/logging (human access).
|
/// Optional Grafana base URL for printing/logging (human access).
|
||||||
fn with_grafana_url(self, url: reqwest::Url) -> CoreScenarioBuilder<ObservabilityCapability>;
|
fn with_grafana_url(self, url: reqwest::Url) -> CoreScenarioBuilder<ObservabilityCapability>;
|
||||||
|
|
||||||
/// Convenience wrapper that parses a URL string (panics if invalid).
|
/// Convenience wrapper that parses a URL string (panics if invalid).
|
||||||
fn with_grafana_url_str(self, url: &str) -> CoreScenarioBuilder<ObservabilityCapability>;
|
fn with_grafana_url_str(self, url: &str) -> CoreScenarioBuilder<ObservabilityCapability>;
|
||||||
|
|
||||||
|
/// Like `with_grafana_url_str`, but returns an error instead of panicking.
|
||||||
|
fn try_with_grafana_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError>;
|
||||||
|
|
||||||
#[deprecated(note = "use with_metrics_query_url")]
|
#[deprecated(note = "use with_metrics_query_url")]
|
||||||
fn with_external_prometheus(
|
fn with_external_prometheus(
|
||||||
self,
|
self,
|
||||||
@ -175,6 +207,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<()> {
|
|||||||
self.with_metrics_query_url(parsed)
|
self.with_metrics_query_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_metrics_query_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "metrics_query_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_metrics_query_url(parsed))
|
||||||
|
}
|
||||||
|
|
||||||
fn with_metrics_otlp_ingest_url(
|
fn with_metrics_otlp_ingest_url(
|
||||||
self,
|
self,
|
||||||
url: reqwest::Url,
|
url: reqwest::Url,
|
||||||
@ -194,6 +238,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<()> {
|
|||||||
self.with_metrics_otlp_ingest_url(parsed)
|
self.with_metrics_otlp_ingest_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_metrics_otlp_ingest_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "metrics_otlp_ingest_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_metrics_otlp_ingest_url(parsed))
|
||||||
|
}
|
||||||
|
|
||||||
fn with_grafana_url(self, url: reqwest::Url) -> CoreScenarioBuilder<ObservabilityCapability> {
|
fn with_grafana_url(self, url: reqwest::Url) -> CoreScenarioBuilder<ObservabilityCapability> {
|
||||||
self.with_capabilities(ObservabilityCapability {
|
self.with_capabilities(ObservabilityCapability {
|
||||||
metrics_query_url: None,
|
metrics_query_url: None,
|
||||||
@ -206,6 +262,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<()> {
|
|||||||
let parsed = reqwest::Url::parse(url).expect("grafana url must be valid");
|
let parsed = reqwest::Url::parse(url).expect("grafana url must be valid");
|
||||||
self.with_grafana_url(parsed)
|
self.with_grafana_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_grafana_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "grafana_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_grafana_url(parsed))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObservabilityBuilderExt for CoreScenarioBuilder<ObservabilityCapability> {
|
impl ObservabilityBuilderExt for CoreScenarioBuilder<ObservabilityCapability> {
|
||||||
@ -222,6 +290,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<ObservabilityCapability> {
|
|||||||
self.with_metrics_query_url(parsed)
|
self.with_metrics_query_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_metrics_query_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "metrics_query_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_metrics_query_url(parsed))
|
||||||
|
}
|
||||||
|
|
||||||
fn with_metrics_otlp_ingest_url(
|
fn with_metrics_otlp_ingest_url(
|
||||||
mut self,
|
mut self,
|
||||||
url: reqwest::Url,
|
url: reqwest::Url,
|
||||||
@ -238,6 +318,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<ObservabilityCapability> {
|
|||||||
self.with_metrics_otlp_ingest_url(parsed)
|
self.with_metrics_otlp_ingest_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_metrics_otlp_ingest_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "metrics_otlp_ingest_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_metrics_otlp_ingest_url(parsed))
|
||||||
|
}
|
||||||
|
|
||||||
fn with_grafana_url(
|
fn with_grafana_url(
|
||||||
mut self,
|
mut self,
|
||||||
url: reqwest::Url,
|
url: reqwest::Url,
|
||||||
@ -250,6 +342,18 @@ impl ObservabilityBuilderExt for CoreScenarioBuilder<ObservabilityCapability> {
|
|||||||
let parsed = reqwest::Url::parse(url).expect("grafana url must be valid");
|
let parsed = reqwest::Url::parse(url).expect("grafana url must be valid");
|
||||||
self.with_grafana_url(parsed)
|
self.with_grafana_url(parsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_with_grafana_url_str(
|
||||||
|
self,
|
||||||
|
url: &str,
|
||||||
|
) -> Result<CoreScenarioBuilder<ObservabilityCapability>, BuilderInputError> {
|
||||||
|
let parsed = reqwest::Url::parse(url).map_err(|err| BuilderInputError::InvalidUrl {
|
||||||
|
field: "grafana_url",
|
||||||
|
value: url.to_string(),
|
||||||
|
message: err.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(self.with_grafana_url(parsed))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builder for transaction workloads.
|
/// Builder for transaction workloads.
|
||||||
@ -279,6 +383,16 @@ impl<Caps> TransactionFlowBuilder<Caps> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `rate`, but returns an error instead of panicking.
|
||||||
|
pub fn try_rate(self, rate: u64) -> Result<Self, BuilderInputError> {
|
||||||
|
let Some(rate) = NonZeroU64::new(rate) else {
|
||||||
|
return Err(BuilderInputError::ZeroValue {
|
||||||
|
field: "transaction_rate",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Ok(self.rate_per_block(rate))
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// Set transaction submission rate per block.
|
/// Set transaction submission rate per block.
|
||||||
pub const fn rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
pub const fn rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
||||||
@ -296,6 +410,17 @@ impl<Caps> TransactionFlowBuilder<Caps> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `users`, but returns an error instead of panicking.
|
||||||
|
pub fn try_users(mut self, users: usize) -> Result<Self, BuilderInputError> {
|
||||||
|
let Some(value) = NonZeroUsize::new(users) else {
|
||||||
|
return Err(BuilderInputError::ZeroValue {
|
||||||
|
field: "transaction_users",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
self.users = Some(value);
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// Attach the transaction workload to the scenario.
|
/// Attach the transaction workload to the scenario.
|
||||||
pub fn apply(mut self) -> CoreScenarioBuilder<Caps> {
|
pub fn apply(mut self) -> CoreScenarioBuilder<Caps> {
|
||||||
@ -347,6 +472,16 @@ impl<Caps> DataAvailabilityFlowBuilder<Caps> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `channel_rate`, but returns an error instead of panicking.
|
||||||
|
pub fn try_channel_rate(self, rate: u64) -> Result<Self, BuilderInputError> {
|
||||||
|
let Some(rate) = NonZeroU64::new(rate) else {
|
||||||
|
return Err(BuilderInputError::ZeroValue {
|
||||||
|
field: "da_channel_rate",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Ok(self.channel_rate_per_block(rate))
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// Set the number of DA channels to run.
|
/// Set the number of DA channels to run.
|
||||||
pub const fn channel_rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
pub const fn channel_rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
||||||
@ -361,6 +496,16 @@ impl<Caps> DataAvailabilityFlowBuilder<Caps> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `blob_rate`, but returns an error instead of panicking.
|
||||||
|
pub fn try_blob_rate(self, rate: u64) -> Result<Self, BuilderInputError> {
|
||||||
|
let Some(rate) = NonZeroU64::new(rate) else {
|
||||||
|
return Err(BuilderInputError::ZeroValue {
|
||||||
|
field: "da_blob_rate",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Ok(self.blob_rate_per_block(rate))
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
/// Set blob publish rate per block.
|
/// Set blob publish rate per block.
|
||||||
pub const fn blob_rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
pub const fn blob_rate_per_block(mut self, rate: NonZeroU64) -> Self {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user