From ee82d6c026011cb4c368c9e72c629bbe5241b53d Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Sun, 28 Jun 2026 16:10:07 +0800 Subject: [PATCH] test: add insta snapshot test for storage error display format (#740) (#4001) test: add insta snapshot test for storage error display format Add snapshot test to detect unexpected changes in StorageError display format. This catches output format regressions that traditional assert tests might miss. Refs #740 --- Cargo.lock | 37 +++++++++++++++++++ Cargo.toml | 2 + crates/ecstore/Cargo.toml | 1 + crates/ecstore/src/error/mod.rs | 30 +++++++++++++++ ...__error__tests__storage_error_display.snap | 18 +++++++++ 5 files changed, 88 insertions(+) create mode 100644 crates/ecstore/src/error/snapshots/rustfs_ecstore__error__tests__storage_error_display.snap diff --git a/Cargo.lock b/Cargo.lock index cc185ac41..cdbac3713 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2031,6 +2031,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -3835,6 +3846,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -5288,6 +5305,19 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "insta" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" +dependencies = [ + "console", + "once_cell", + "serde", + "similar", + "tempfile", +] + [[package]] name = "internal-russh-num-bigint" version = "0.5.0" @@ -9282,6 +9312,7 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", + "insta", "lazy_static", "libc", "md-5 0.11.0", @@ -10910,6 +10941,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "simple_asn1" version = "0.6.4" diff --git a/Cargo.toml b/Cargo.toml index 0b66e0235..a12feb58e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -333,6 +333,8 @@ mimalloc = "0.1" tikv-jemallocator = { version = "0.6", features = ["profiling", "stats", "unprefixed_malloc_on_supported_platforms", "background_threads"] } # Used to control and obtain statistics for jemalloc at runtime tikv-jemalloc-ctl = { version = "0.6", features = ["use_std", "stats", "profiling"] } +# Snapshot testing for output format regression detection +insta = { version = "1.41", features = ["yaml", "json"] } # Used to generate pprof-compatible memory profiling data and support symbolization and flame graphs jemalloc_pprof = { version = "0.8.2", features = ["symbolize", "flamegraph"] } # Used to generate CPU performance analysis data and flame diagrams diff --git a/crates/ecstore/Cargo.toml b/crates/ecstore/Cargo.toml index a7e418542..926d18946 100644 --- a/crates/ecstore/Cargo.toml +++ b/crates/ecstore/Cargo.toml @@ -145,6 +145,7 @@ serial_test = { workspace = true } opentelemetry_sdk = { workspace = true } proptest = "1" rcgen.workspace = true +insta = { workspace = true } [build-dependencies] shadow-rs = { workspace = true, features = ["build", "metadata"] } diff --git a/crates/ecstore/src/error/mod.rs b/crates/ecstore/src/error/mod.rs index 0b1e2c1d9..ade95c1fd 100644 --- a/crates/ecstore/src/error/mod.rs +++ b/crates/ecstore/src/error/mod.rs @@ -1448,4 +1448,34 @@ mod tests { assert_eq!(original_error, recovered_error); } } + + #[test] + fn test_storage_error_display_snapshot() { + // Snapshot test to detect unexpected changes in error display format + let errors = vec![ + StorageError::BucketNotFound("test-bucket".to_string()), + StorageError::ObjectNotFound("bucket".to_string(), "object".to_string()), + StorageError::VersionNotFound("bucket".to_string(), "object".to_string(), "v1".to_string()), + StorageError::InvalidUploadID("bucket".to_string(), "object".to_string(), "upload123".to_string()), + StorageError::DiskFull, + StorageError::FaultyDisk, + StorageError::FileNotFound, + StorageError::VolumeNotFound, + StorageError::ErasureReadQuorum, + StorageError::ErasureWriteQuorum, + StorageError::DecommissionAlreadyRunning, + StorageError::RebalanceAlreadyRunning, + StorageError::OperationCanceled, + StorageError::NamespaceLockQuorumUnavailable { + mode: "write", + bucket: "bucket".into(), + object: "object".into(), + required: 3, + achieved: 2, + }, + ]; + + let error_messages: Vec = errors.iter().map(|e| e.to_string()).collect(); + insta::assert_yaml_snapshot!("storage_error_display", error_messages); + } } diff --git a/crates/ecstore/src/error/snapshots/rustfs_ecstore__error__tests__storage_error_display.snap b/crates/ecstore/src/error/snapshots/rustfs_ecstore__error__tests__storage_error_display.snap new file mode 100644 index 000000000..08ece6610 --- /dev/null +++ b/crates/ecstore/src/error/snapshots/rustfs_ecstore__error__tests__storage_error_display.snap @@ -0,0 +1,18 @@ +--- +source: crates/ecstore/src/error/mod.rs +expression: error_messages +--- +- "Bucket not found: test-bucket" +- "Object not found: bucket/object" +- "Version not found: bucket/object-v1" +- "Invalid upload id: bucket/object-upload123" +- Disk full +- Faulty disk +- File not found +- Volume not found +- erasure read quorum +- erasure write quorum +- Decommission already running +- Rebalance already running +- Operation canceled +- "Namespace lock quorum unavailable for write lock on bucket/object: required 3, achieved 2"