mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-11 07:36:53 +00:00
test(ecstore): add TierConfigMgr state-machine unit coverage (#4713)
* test(ecstore): unit-test TierConfigMgr add/edit/remove/verify state machine (backlog#1148 ilm-4) Covers the tier config state machine and persistence paths that previously had only 4 codec tests and none for tier_config.rs: - add: non-uppercase name, duplicate name, unsupported type, missing backend payload, and a regression anchor documenting that AWS-reserved names (STANDARD) are not currently rejected. - edit: unknown tier, missing-credentials rejection for RustFS and MinIO. - remove: idempotent unknown-tier no-op, in-use rejection, empty-backend success, force skips the in_use probe, and probe-error surfacing. - verify: unknown tier, healthy backend, unhealthy backend. - pure query helpers (empty/is_tier_valid/tier_type/get/list_tiers). - persistence: JSON marshal/unmarshal roundtrip, external tier-config.bin roundtrip for Azure and GCS payload mapping, truncated/unknown-format/ unknown-version rejection, legacy v1 version-word acceptance, and encode failure on missing payload. Tests are hermetic: error paths return before backend construction, and a MockWarmBackend injected into driver_cache exercises remove/verify without any real remote. Refs backlog#1155. Co-authored-by: overtrue <anzhengchao@gmail.com> * fix(tier): reject reserved names STANDARD/RRS in TierConfigMgr::add (backlog#1148 ilm-4) (#4721)
This commit is contained in:
@@ -17,7 +17,7 @@ use crate::admin::runtime_sources::object_store_from_extensions;
|
||||
use crate::admin::storage_api::tier::{
|
||||
AdminError, DailyAllTierStats, ERR_TIER_ALREADY_EXISTS, ERR_TIER_BACKEND_IN_USE, ERR_TIER_BACKEND_NOT_EMPTY,
|
||||
ERR_TIER_CONNECT_ERR, ERR_TIER_INVALID_CREDENTIALS, ERR_TIER_MISSING_CREDENTIALS, ERR_TIER_NAME_NOT_UPPERCASE,
|
||||
ERR_TIER_NOT_FOUND, TierConfig, TierCreds, TierType, storageclass,
|
||||
ERR_TIER_NOT_FOUND, ERR_TIER_RESERVED_NAME, TierConfig, TierCreds, TierType,
|
||||
};
|
||||
use crate::{
|
||||
admin::runtime_sources::{current_daily_tier_stats, current_notification_system, current_tier_config_handle},
|
||||
@@ -311,22 +311,6 @@ impl Operation for AddTier {
|
||||
s3_error!(InvalidRequest, "invalid force flag")
|
||||
})?;
|
||||
}
|
||||
match args.name.as_str() {
|
||||
storageclass::STANDARD | storageclass::RRS => {
|
||||
warn!(
|
||||
event = EVENT_ADMIN_TIER_STATE,
|
||||
component = LOG_COMPONENT_ADMIN,
|
||||
subsystem = LOG_SUBSYSTEM_TIER,
|
||||
action = "add_tier",
|
||||
tier_name = %args.name,
|
||||
result = "reserved_name_rejected",
|
||||
"admin tier state"
|
||||
);
|
||||
return Err(s3_error!(InvalidRequest, "Cannot use reserved tier name"));
|
||||
}
|
||||
&_ => (),
|
||||
}
|
||||
|
||||
let Some(store) = object_store_from_extensions(&req.extensions) else {
|
||||
return Err(s3_error!(InternalError, "object store is not initialized"));
|
||||
};
|
||||
@@ -350,7 +334,18 @@ impl Operation for AddTier {
|
||||
));
|
||||
}
|
||||
if let Err(err) = tier_config_mgr.add(args, force).await {
|
||||
return if err.code == ERR_TIER_ALREADY_EXISTS.code {
|
||||
return if err.code == ERR_TIER_RESERVED_NAME.code {
|
||||
warn!(
|
||||
event = EVENT_ADMIN_TIER_STATE,
|
||||
component = LOG_COMPONENT_ADMIN,
|
||||
subsystem = LOG_SUBSYSTEM_TIER,
|
||||
action = "add_tier",
|
||||
tier_name = %tier_name_for_log,
|
||||
result = "reserved_name_rejected",
|
||||
"admin tier state"
|
||||
);
|
||||
Err(s3_error!(InvalidRequest, "Cannot use reserved tier name"))
|
||||
} else if err.code == ERR_TIER_ALREADY_EXISTS.code {
|
||||
Err(S3Error::with_message(
|
||||
S3ErrorCode::Custom("TierNameAlreadyExist".into()),
|
||||
"tier name already exists",
|
||||
|
||||
@@ -378,9 +378,7 @@ pub(crate) mod versioning_sys {
|
||||
pub(crate) mod storageclass {
|
||||
pub(crate) const INLINE_BLOCK_ENV: &str = super::ecstore_config::storageclass::INLINE_BLOCK_ENV;
|
||||
pub(crate) const OPTIMIZE_ENV: &str = super::ecstore_config::storageclass::OPTIMIZE_ENV;
|
||||
pub(crate) const RRS: &str = super::ecstore_config::storageclass::RRS;
|
||||
pub(crate) const RRS_ENV: &str = super::ecstore_config::storageclass::RRS_ENV;
|
||||
pub(crate) const STANDARD: &str = super::ecstore_config::storageclass::STANDARD;
|
||||
pub(crate) const STANDARD_ENV: &str = super::ecstore_config::storageclass::STANDARD_ENV;
|
||||
|
||||
pub(crate) type Config = super::ecstore_config::storageclass::Config;
|
||||
@@ -449,6 +447,7 @@ pub(crate) static ERR_TIER_INVALID_CREDENTIALS: AdminErrorRef =
|
||||
pub(crate) static ERR_TIER_NAME_NOT_UPPERCASE: AdminErrorRef =
|
||||
AdminErrorRef(|| &ecstore_tier::tier_handlers::ERR_TIER_NAME_NOT_UPPERCASE);
|
||||
pub(crate) static ERR_TIER_NOT_FOUND: AdminErrorRef = AdminErrorRef(|| &ecstore_tier::tier_handlers::ERR_TIER_NOT_FOUND);
|
||||
pub(crate) static ERR_TIER_RESERVED_NAME: AdminErrorRef = AdminErrorRef(|| &ecstore_tier::tier_handlers::ERR_TIER_RESERVED_NAME);
|
||||
|
||||
pub(crate) mod data_usage {
|
||||
use std::sync::Arc;
|
||||
@@ -584,10 +583,9 @@ pub(crate) mod runtime {
|
||||
}
|
||||
|
||||
pub(crate) mod tier {
|
||||
pub(crate) use super::storageclass;
|
||||
pub(crate) use super::{
|
||||
AdminError, DailyAllTierStats, ERR_TIER_ALREADY_EXISTS, ERR_TIER_BACKEND_IN_USE, ERR_TIER_BACKEND_NOT_EMPTY,
|
||||
ERR_TIER_CONNECT_ERR, ERR_TIER_INVALID_CREDENTIALS, ERR_TIER_MISSING_CREDENTIALS, ERR_TIER_NAME_NOT_UPPERCASE,
|
||||
ERR_TIER_NOT_FOUND, TierConfig, TierCreds, TierType,
|
||||
ERR_TIER_NOT_FOUND, ERR_TIER_RESERVED_NAME, TierConfig, TierCreds, TierType,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user