v0.3.2-pre.004-fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-lib/src/settings.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
const DEFAULT_CONNECT_TIMEOUT_MS: u64 = 10_000;
|
||||
const DEFAULT_MAX_CONNECTIONS: u32 = 8;
|
||||
@@ -117,7 +117,12 @@ impl PostgresPoolSettings {
|
||||
.with_context("maximum", MAX_CONNECTIONS.to_string()),
|
||||
);
|
||||
}
|
||||
let connect_validation = validate_duration("postgres.pool.connect_timeout", self.connect_timeout, MIN_CONNECT_TIMEOUT_MS, MAX_CONNECT_TIMEOUT_MS);
|
||||
let connect_validation = validate_duration(
|
||||
"postgres.pool.connect_timeout",
|
||||
self.connect_timeout,
|
||||
MIN_CONNECT_TIMEOUT_MS,
|
||||
MAX_CONNECT_TIMEOUT_MS,
|
||||
);
|
||||
if let std::result::Result::Err(error) = connect_validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
@@ -125,12 +130,21 @@ impl PostgresPoolSettings {
|
||||
if let std::result::Result::Err(error) = wait_validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let create_validation = validate_duration("postgres.pool.create_timeout", self.create_timeout, MIN_POOL_CREATE_TIMEOUT_MS, MAX_POOL_CREATE_TIMEOUT_MS);
|
||||
let create_validation = validate_duration(
|
||||
"postgres.pool.create_timeout",
|
||||
self.create_timeout,
|
||||
MIN_POOL_CREATE_TIMEOUT_MS,
|
||||
MAX_POOL_CREATE_TIMEOUT_MS,
|
||||
);
|
||||
if let std::result::Result::Err(error) = create_validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let recycle_validation =
|
||||
validate_duration("postgres.pool.recycle_timeout", self.recycle_timeout, MIN_POOL_RECYCLE_TIMEOUT_MS, MAX_POOL_RECYCLE_TIMEOUT_MS);
|
||||
let recycle_validation = validate_duration(
|
||||
"postgres.pool.recycle_timeout",
|
||||
self.recycle_timeout,
|
||||
MIN_POOL_RECYCLE_TIMEOUT_MS,
|
||||
MAX_POOL_RECYCLE_TIMEOUT_MS,
|
||||
);
|
||||
if let std::result::Result::Err(error) = recycle_validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
@@ -185,8 +199,12 @@ impl PostgresBootstrapSettings {
|
||||
|
||||
/// Validates bootstrap and migration deadlines without contacting PostgreSQL.
|
||||
pub fn validate(&self) -> ksp_store_api::Result<()> {
|
||||
let migration_validation =
|
||||
validate_duration("postgres.bootstrap.migration_timeout", self.migration_timeout, MIN_MIGRATION_TIMEOUT_MS, MAX_MIGRATION_TIMEOUT_MS);
|
||||
let migration_validation = validate_duration(
|
||||
"postgres.bootstrap.migration_timeout",
|
||||
self.migration_timeout,
|
||||
MIN_MIGRATION_TIMEOUT_MS,
|
||||
MAX_MIGRATION_TIMEOUT_MS,
|
||||
);
|
||||
if let std::result::Result::Err(error) = migration_validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
@@ -312,14 +330,15 @@ impl StoreBackendSettings {
|
||||
#[derive(Debug)]
|
||||
pub struct StoreSettings {
|
||||
backend: StoreBackendSettings,
|
||||
network: ksp_store_api::RawNetworkId,
|
||||
shutdown_timeout: std::time::Duration,
|
||||
}
|
||||
|
||||
impl StoreSettings {
|
||||
/// Creates complete Store runtime settings from one explicit backend and shutdown bound.
|
||||
/// Creates complete Store runtime settings for one explicit logical network, backend and shutdown bound.
|
||||
#[must_use]
|
||||
pub const fn new(backend: StoreBackendSettings, shutdown_timeout: std::time::Duration) -> Self {
|
||||
return Self { backend, shutdown_timeout };
|
||||
pub fn new(network: ksp_store_api::RawNetworkId, backend: StoreBackendSettings, shutdown_timeout: std::time::Duration) -> Self {
|
||||
return Self { backend, network, shutdown_timeout };
|
||||
}
|
||||
|
||||
/// Returns the selected backend settings.
|
||||
@@ -334,6 +353,12 @@ impl StoreSettings {
|
||||
return self.backend.kind();
|
||||
}
|
||||
|
||||
/// Returns the single logical network bound to this Store instance.
|
||||
#[must_use]
|
||||
pub const fn network(&self) -> &ksp_store_api::RawNetworkId {
|
||||
return &self.network;
|
||||
}
|
||||
|
||||
/// Returns the maximum duration allowed for explicit Store shutdown.
|
||||
#[must_use]
|
||||
pub const fn shutdown_timeout(&self) -> std::time::Duration {
|
||||
@@ -355,10 +380,10 @@ impl StoreSettings {
|
||||
}
|
||||
|
||||
impl StoreSettings {
|
||||
/// Creates settings using the common default shutdown bound while keeping backend construction explicit.
|
||||
/// Creates settings using the common default shutdown bound while keeping network and backend construction explicit.
|
||||
#[must_use]
|
||||
pub fn with_default_shutdown(backend: StoreBackendSettings) -> Self {
|
||||
return Self::new(backend, std::time::Duration::from_millis(DEFAULT_SHUTDOWN_TIMEOUT_MS));
|
||||
pub fn with_default_shutdown(network: ksp_store_api::RawNetworkId, backend: StoreBackendSettings) -> Self {
|
||||
return Self::new(network, backend, std::time::Duration::from_millis(DEFAULT_SHUTDOWN_TIMEOUT_MS));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-lib/tests/feature_mismatch.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -17,6 +17,13 @@ fn poll_ready<T>(future: impl std::future::Future<Output = T>) -> T {
|
||||
};
|
||||
}
|
||||
|
||||
fn valid_network() -> ksp_store_lib::RawNetworkId {
|
||||
return match ksp_store_lib::RawNetworkId::new("devnet") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("valid test network rejected: {error:?}"),
|
||||
};
|
||||
}
|
||||
|
||||
fn settings() -> ksp_store_lib::StoreSettings {
|
||||
let postgres = ksp_store_lib::PostgresStoreSettings::new(
|
||||
"postgresql://operator-supplied-sensitive-value",
|
||||
@@ -24,7 +31,7 @@ fn settings() -> ksp_store_lib::StoreSettings {
|
||||
ksp_store_lib::PostgresTlsMode::Disabled,
|
||||
ksp_store_lib::PostgresBootstrapSettings::default(),
|
||||
);
|
||||
return ksp_store_lib::StoreSettings::with_default_shutdown(ksp_store_lib::StoreBackendSettings::Postgres(postgres));
|
||||
return ksp_store_lib::StoreSettings::with_default_shutdown(valid_network(), ksp_store_lib::StoreBackendSettings::Postgres(postgres));
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "postgres"))]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-lib/tests/public_api.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -15,8 +15,13 @@ fn pre_003_settings_and_lifecycle_contract_are_available_from_crate_root() {
|
||||
ksp_store_lib::PostgresTlsMode::VerifyFull,
|
||||
ksp_store_lib::PostgresBootstrapSettings::default(),
|
||||
);
|
||||
let settings = ksp_store_lib::StoreSettings::with_default_shutdown(ksp_store_lib::StoreBackendSettings::Postgres(postgres));
|
||||
let network = match ksp_store_lib::RawNetworkId::new("devnet") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("valid public API network rejected: {error:?}"),
|
||||
};
|
||||
let settings = ksp_store_lib::StoreSettings::with_default_shutdown(network, ksp_store_lib::StoreBackendSettings::Postgres(postgres));
|
||||
assert_eq!(settings.backend_kind(), ksp_store_lib::StoreBackendKind::Postgres);
|
||||
assert_eq!(settings.network().as_str(), "devnet");
|
||||
assert!(settings.validate().is_ok());
|
||||
let _open = ksp_store_lib::Store::open;
|
||||
let _close = ksp_store_lib::Store::close;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
// file: crates/ksp-store-lib/unit_tests/settings.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
fn valid_network() -> crate::RawNetworkId {
|
||||
return match crate::RawNetworkId::new("devnet") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("valid test network rejected: {error:?}"),
|
||||
};
|
||||
}
|
||||
|
||||
fn valid_postgres_settings() -> crate::PostgresStoreSettings {
|
||||
return crate::PostgresStoreSettings::new(
|
||||
@@ -22,9 +29,10 @@ fn defaults_match_the_pre_001_runtime_bounds() {
|
||||
assert!(bootstrap.auto_migrate());
|
||||
assert_eq!(bootstrap.migration_timeout(), std::time::Duration::from_millis(30_000));
|
||||
assert_eq!(bootstrap.migration_lock_timeout(), std::time::Duration::from_millis(10_000));
|
||||
let store = crate::StoreSettings::with_default_shutdown(crate::StoreBackendSettings::Postgres(valid_postgres_settings()));
|
||||
let store = crate::StoreSettings::with_default_shutdown(valid_network(), crate::StoreBackendSettings::Postgres(valid_postgres_settings()));
|
||||
assert_eq!(store.shutdown_timeout(), std::time::Duration::from_millis(5_000));
|
||||
assert_eq!(store.backend_kind(), crate::StoreBackendKind::Postgres);
|
||||
assert_eq!(store.network().as_str(), "devnet");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,9 +117,11 @@ fn exact_runtime_boundaries_validate_and_adjacent_values_are_rejected() {
|
||||
|
||||
#[test]
|
||||
fn store_shutdown_bound_is_independent_from_backend_and_rejects_outside_values() {
|
||||
let valid = crate::StoreSettings::new(crate::StoreBackendSettings::Postgres(valid_postgres_settings()), std::time::Duration::from_millis(100));
|
||||
let valid =
|
||||
crate::StoreSettings::new(valid_network(), crate::StoreBackendSettings::Postgres(valid_postgres_settings()), std::time::Duration::from_millis(100));
|
||||
assert!(valid.validate().is_ok());
|
||||
let invalid = crate::StoreSettings::new(crate::StoreBackendSettings::Postgres(valid_postgres_settings()), std::time::Duration::from_millis(30_001));
|
||||
let invalid =
|
||||
crate::StoreSettings::new(valid_network(), crate::StoreBackendSettings::Postgres(valid_postgres_settings()), std::time::Duration::from_millis(30_001));
|
||||
let error = invalid.validate().err();
|
||||
assert_eq!(error.map(|value| return value.code()), std::option::Option::Some(crate::ERROR_CODE_SETTINGS_INVALID));
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-lib/unit_tests/store.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
fn poll_ready<T>(future: impl std::future::Future<Output = T>) -> T {
|
||||
let mut future = std::boxed::Box::pin(future);
|
||||
@@ -11,6 +11,13 @@ fn poll_ready<T>(future: impl std::future::Future<Output = T>) -> T {
|
||||
};
|
||||
}
|
||||
|
||||
fn valid_network() -> crate::RawNetworkId {
|
||||
return match crate::RawNetworkId::new("devnet") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("valid test network rejected: {error:?}"),
|
||||
};
|
||||
}
|
||||
|
||||
fn valid_store_settings() -> crate::StoreSettings {
|
||||
let postgres = crate::PostgresStoreSettings::new(
|
||||
"postgresql://secret-user:secret-password@db.internal/ksp",
|
||||
@@ -18,7 +25,7 @@ fn valid_store_settings() -> crate::StoreSettings {
|
||||
crate::PostgresTlsMode::VerifyFull,
|
||||
crate::PostgresBootstrapSettings::default(),
|
||||
);
|
||||
return crate::StoreSettings::with_default_shutdown(crate::StoreBackendSettings::Postgres(postgres));
|
||||
return crate::StoreSettings::with_default_shutdown(valid_network(), crate::StoreBackendSettings::Postgres(postgres));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -29,7 +36,7 @@ fn invalid_settings_are_rejected_before_backend_dispatch() {
|
||||
crate::PostgresTlsMode::Disabled,
|
||||
crate::PostgresBootstrapSettings::default(),
|
||||
);
|
||||
let settings = crate::StoreSettings::with_default_shutdown(crate::StoreBackendSettings::Postgres(postgres));
|
||||
let settings = crate::StoreSettings::with_default_shutdown(valid_network(), crate::StoreBackendSettings::Postgres(postgres));
|
||||
let result = poll_ready(crate::Store::open(settings));
|
||||
let error = result.err();
|
||||
assert_eq!(error.map(|value| return value.code()), std::option::Option::Some(crate::ERROR_CODE_SETTINGS_INVALID));
|
||||
|
||||
Reference in New Issue
Block a user