mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-19 11:06:17 +00:00
f12f3c47e1
Removes the remaining 230 no-op `#[serial]` markers across 77 files, plus the 77 imports that went with them. Stacked on the six-suite batch; together they take `crates/e2e_test` from 345 markers to 36. The reasoning is unchanged from #6209: `#[serial]` is an in-process mutex and cargo-nextest gives every test its own process, so only a `[test-groups]` binding with `max-threads = 1` serializes anything. Everything still carrying a marker now has a reason to: inline_fast_path_cluster_test 14 test-group e2e-inline-boundaries policy/policy_variables_test 6 binds a fixed port kms/kms_vault_test 5 test-group e2e-vault reliability_disk_fault_test 4 test-group e2e-reliability degraded_read_eof_regression_test 3 test-group e2e-reliability replacement_privileged_e2e_test 2 test-group e2e-reliability protocols/webdav_core 1 binds fixed ports policy/test_runner 1 binds a fixed port The three fixed-port files are held back rather than swept, because their markers are not merely useless: `PolicyTestEnvironment::with_address("127.0.0.1:9000")` and webdav_core's `127.0.0.1:9080`/`:9010` bind fixed ports, which an in-process mutex cannot protect against a second test process. They need a test-group, which is a config change rather than a deletion, so it is filed on the issue instead. `security_boundary_test` was checked and swept: its `127.0.0.1:8080` strings are SSRF targets fed to AddTier in a negative test, not ports it binds. Refs backlog#1846 (T1)
111 lines
3.3 KiB
Rust
111 lines
3.3 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use aws_sdk_s3::primitives::ByteStream;
|
|
use std::path::{Path, PathBuf};
|
|
use uuid::Uuid;
|
|
|
|
use crate::common::{RustFSTestEnvironment, init_logging};
|
|
|
|
const TEST_BUCKET: &str = "overwrite-cleanup-regression";
|
|
const TEST_OBJECT: &str = "large-object.bin";
|
|
const PAYLOAD_SIZE: usize = 512 * 1024;
|
|
|
|
#[tokio::test(flavor = "multi_thread")]
|
|
async fn unversioned_overwrite_removes_previous_physical_data_dir() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
init_logging();
|
|
|
|
let mut env = RustFSTestEnvironment::new().await?;
|
|
env.start_rustfs_server(vec![]).await?;
|
|
|
|
let client = env.create_s3_client();
|
|
client.create_bucket().bucket(TEST_BUCKET).send().await?;
|
|
|
|
let first_payload = vec![b'a'; PAYLOAD_SIZE];
|
|
client
|
|
.put_object()
|
|
.bucket(TEST_BUCKET)
|
|
.key(TEST_OBJECT)
|
|
.body(ByteStream::from(first_payload))
|
|
.send()
|
|
.await?;
|
|
|
|
let object_dir = Path::new(&env.temp_dir).join(TEST_BUCKET).join(TEST_OBJECT);
|
|
let first_data_dirs = physical_data_dirs(&object_dir)?;
|
|
assert_eq!(
|
|
first_data_dirs.len(),
|
|
1,
|
|
"first non-inline put should create exactly one physical data directory: {first_data_dirs:?}"
|
|
);
|
|
|
|
let second_payload = vec![b'z'; PAYLOAD_SIZE];
|
|
client
|
|
.put_object()
|
|
.bucket(TEST_BUCKET)
|
|
.key(TEST_OBJECT)
|
|
.body(ByteStream::from(second_payload.clone()))
|
|
.send()
|
|
.await?;
|
|
|
|
let second_data_dirs = physical_data_dirs(&object_dir)?;
|
|
assert_eq!(
|
|
second_data_dirs.len(),
|
|
1,
|
|
"unversioned overwrite should clean the previous physical data directory: {second_data_dirs:?}"
|
|
);
|
|
assert_ne!(
|
|
first_data_dirs[0], second_data_dirs[0],
|
|
"overwrite should replace the old physical data directory with the new one"
|
|
);
|
|
|
|
let current = client
|
|
.get_object()
|
|
.bucket(TEST_BUCKET)
|
|
.key(TEST_OBJECT)
|
|
.send()
|
|
.await?
|
|
.body
|
|
.collect()
|
|
.await?
|
|
.into_bytes();
|
|
assert_eq!(
|
|
current.as_ref(),
|
|
second_payload.as_slice(),
|
|
"object data should remain readable after old data directory cleanup"
|
|
);
|
|
|
|
env.stop_server();
|
|
Ok(())
|
|
}
|
|
|
|
fn physical_data_dirs(object_dir: &Path) -> Result<Vec<Uuid>, Box<dyn std::error::Error + Send + Sync>> {
|
|
let mut data_dirs = Vec::new();
|
|
for entry in std::fs::read_dir(object_dir)? {
|
|
let entry = entry?;
|
|
if !entry.file_type()?.is_dir() {
|
|
continue;
|
|
}
|
|
|
|
let path: PathBuf = entry.path();
|
|
let Some(name) = path.file_name().and_then(|name| name.to_str()) else {
|
|
continue;
|
|
};
|
|
if let Ok(uuid) = Uuid::parse_str(name) {
|
|
data_dirs.push(uuid);
|
|
}
|
|
}
|
|
data_dirs.sort_unstable();
|
|
Ok(data_dirs)
|
|
}
|