mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-29 08:27:06 +00:00
test: deflake config snapshot, presigned tamper, and pool resume tests (#6721)
* test(ecstore): decouple server config snapshot test from global defaults The final assertion of server_config_snapshot_serializes_read_modify_write_transactions compared the second snapshot against a fresh Config::new(). Config::new() reads the process-global DEFAULT_KVS OnceLock, which a sibling test in the same process can register mid-run (crate::config::init()), so the in-process run 'cargo test -p rustfs-ecstore --lib config::' failed while nextest's process-per-test isolation hid the coupling. Assert on the snapshot's raw bytes against the baseline blob instead, which is deterministic and matches the invariant under test: the second transaction observes the store unchanged by the first. * test: deflake presigned tamper helper and relocated-pool resume staging tamper_signature only remapped '0' and 'a', so a signature containing neither (about 1 in 5000) left the URI unchanged and tripped the helper's own guard assert in CI. Complement every hex digit (15 - v) instead: the map has no fixed point, so the tamper always changes the value while keeping length and hex shape. execute_get_object_resumes_from_relocated_pool_without_splicing_body staged the relocation by reading xl.meta from every source-pool disk, but a write-quorum commit legitimately leaves a lagging minority disk without the object directory (#6701) — the test already tolerates that gap when normalizing the upload pool, and CI suite IO load hit the same gap in the staging loop. Skip sourceless disks, carry the staged metadata path explicitly, and assert a write-quorum majority was staged.
This commit is contained in:
@@ -87,7 +87,9 @@ fn valid_config() -> PresigningConfig {
|
||||
}
|
||||
|
||||
/// Flip bytes inside the `X-Amz-Signature=` query value without changing its
|
||||
/// length, producing a structurally valid but incorrect signature.
|
||||
/// length, producing a structurally valid but incorrect signature. Every hex
|
||||
/// digit is replaced by its complement (15 - v), which has no fixed point, so
|
||||
/// the tamper changes the value no matter which digits the signature contains.
|
||||
fn tamper_signature(uri: &str) -> String {
|
||||
let marker = "X-Amz-Signature=";
|
||||
let idx = uri.find(marker).expect("presigned uri must carry X-Amz-Signature") + marker.len();
|
||||
@@ -96,10 +98,9 @@ fn tamper_signature(uri: &str) -> String {
|
||||
let (sig, tail) = rest.split_at(end);
|
||||
let tampered: String = sig
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'0' => 'f',
|
||||
'a' => '0',
|
||||
other => other,
|
||||
.map(|c| {
|
||||
let v = c.to_digit(16).expect("X-Amz-Signature value must be hex");
|
||||
char::from_digit(15 - v, 16).expect("complement of a hex digit is a hex digit")
|
||||
})
|
||||
.collect();
|
||||
assert_ne!(sig, tampered, "tamper must actually change the signature hex");
|
||||
|
||||
@@ -5220,7 +5220,7 @@ mod tests {
|
||||
#[tokio::test]
|
||||
async fn server_config_snapshot_serializes_read_modify_write_transactions() {
|
||||
let baseline = encode_server_config_blob(&Config::new(), None).expect("baseline config should encode");
|
||||
let store = Arc::new(RecoveryMockStore::new(RecoveryReadState::Blob(baseline), None));
|
||||
let store = Arc::new(RecoveryMockStore::new(RecoveryReadState::Blob(baseline.clone()), None));
|
||||
let first = read_server_config_snapshot(store.clone())
|
||||
.await
|
||||
.expect("first config snapshot");
|
||||
@@ -5234,7 +5234,11 @@ mod tests {
|
||||
.await
|
||||
.expect("second transaction should acquire after the first snapshot is dropped")
|
||||
.expect("second config snapshot");
|
||||
assert!(configs_semantically_equal(&second.config, &Config::new()));
|
||||
// Compare raw bytes against the baseline blob rather than a fresh
|
||||
// Config::new(): the process-global DEFAULT_KVS can be registered by a
|
||||
// sibling test mid-run, which would make a Config::new() evaluated here
|
||||
// diverge from the baseline encoded above.
|
||||
assert_eq!(second.raw.as_deref(), Some(baseline.as_slice()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user