mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 03:46:37 +00:00
test(e2e): gate protocol runner by requested features (#2912)
This commit is contained in:
@@ -16,9 +16,9 @@ RUSTFS_BUILD_FEATURES=ftps,webdav,sftp cargo test --package e2e_test test_protoc
|
||||
```
|
||||
|
||||
`RUSTFS_BUILD_FEATURES` controls which features the test rustfs binary is
|
||||
built with. The protocol test runner schedules every entry (FTPS, WebDAV,
|
||||
SFTP) regardless of the feature set, so the binary must include every
|
||||
protocol the runner spawns or the corresponding entries will fail.
|
||||
built with. When this variable is set, the protocol test runner schedules
|
||||
only entries whose protocol is present in the requested feature list. Leave
|
||||
it unset to run every protocol entry.
|
||||
`--test-threads=1` is required because every entry spawns a rustfs server
|
||||
on fixed bind ports.
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
//! Protocol test runner
|
||||
|
||||
use crate::common::init_logging;
|
||||
use crate::common::{requested_rustfs_build_features, rustfs_build_feature_enabled};
|
||||
use crate::protocols::ftps_core::test_ftps_core_operations;
|
||||
use crate::protocols::sftp_compliance::{
|
||||
test_sftp_compliance_readonly, test_sftp_compliance_standalone, test_sftp_compliance_suite,
|
||||
@@ -59,36 +60,22 @@ pub struct ProtocolTestSuite {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct TestDefinition {
|
||||
name: String,
|
||||
name: &'static str,
|
||||
required_feature: &'static str,
|
||||
}
|
||||
|
||||
impl ProtocolTestSuite {
|
||||
/// Create default test suite
|
||||
pub fn new() -> Self {
|
||||
let tests = vec![
|
||||
TestDefinition {
|
||||
name: "test_ftps_core_operations".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_webdav_core_operations".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_core_operations".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_suite".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_readonly".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_idle_timeout_disconnects".to_string(),
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_standalone".to_string(),
|
||||
},
|
||||
];
|
||||
let requested_features = requested_rustfs_build_features();
|
||||
Self::with_requested_features(requested_features.as_deref())
|
||||
}
|
||||
|
||||
fn with_requested_features(requested_features: Option<&str>) -> Self {
|
||||
let tests = all_protocol_tests()
|
||||
.into_iter()
|
||||
.filter(|test| rustfs_build_feature_enabled(requested_features, test.required_feature))
|
||||
.collect();
|
||||
Self { tests }
|
||||
}
|
||||
|
||||
@@ -104,7 +91,7 @@ impl ProtocolTestSuite {
|
||||
|
||||
// Run tests
|
||||
for (i, test_def) in self.tests.iter().enumerate() {
|
||||
let test_description = match test_def.name.as_str() {
|
||||
let test_description = match test_def.name {
|
||||
"test_ftps_core_operations" => {
|
||||
info!("=== Starting FTPS Module Test ===");
|
||||
"FTPS core operations (put, ls, mkdir, rmdir, delete)"
|
||||
@@ -147,11 +134,11 @@ impl ProtocolTestSuite {
|
||||
match result {
|
||||
Ok(_) => {
|
||||
info!("Test passed: {} ({:.2}s)", test_def.name, test_duration.as_secs_f64());
|
||||
results.push(TestResult::success(test_def.name.clone()));
|
||||
results.push(TestResult::success(test_def.name.to_string()));
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Test failed: {} ({:.2}s): {}", test_def.name, test_duration.as_secs_f64(), e);
|
||||
results.push(TestResult::failure(test_def.name.clone(), e.to_string()));
|
||||
results.push(TestResult::failure(test_def.name.to_string(), e.to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +156,7 @@ impl ProtocolTestSuite {
|
||||
|
||||
/// Run a single test
|
||||
async fn run_single_test(&self, test_def: &TestDefinition) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
match test_def.name.as_str() {
|
||||
match test_def.name {
|
||||
"test_ftps_core_operations" => test_ftps_core_operations().await.map_err(|e| e.into()),
|
||||
"test_webdav_core_operations" => test_webdav_core_operations().await.map_err(|e| e.into()),
|
||||
"test_sftp_core_operations" => test_sftp_core_operations().await.map_err(|e| e.into()),
|
||||
@@ -186,6 +173,10 @@ impl ProtocolTestSuite {
|
||||
info!("=== Test Suite Summary ===");
|
||||
info!("Total duration: {:.2}s", total_duration.as_secs_f64());
|
||||
info!("Total tests: {}", results.len());
|
||||
if results.is_empty() {
|
||||
info!("No protocol tests scheduled for the requested feature set");
|
||||
return;
|
||||
}
|
||||
|
||||
let passed = results.iter().filter(|r| r.success).count();
|
||||
let failed = results.len() - passed;
|
||||
@@ -203,6 +194,39 @@ impl ProtocolTestSuite {
|
||||
}
|
||||
}
|
||||
|
||||
fn all_protocol_tests() -> Vec<TestDefinition> {
|
||||
vec![
|
||||
TestDefinition {
|
||||
name: "test_ftps_core_operations",
|
||||
required_feature: "ftps",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_webdav_core_operations",
|
||||
required_feature: "webdav",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_core_operations",
|
||||
required_feature: "sftp",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_suite",
|
||||
required_feature: "sftp",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_readonly",
|
||||
required_feature: "sftp",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_idle_timeout_disconnects",
|
||||
required_feature: "sftp",
|
||||
},
|
||||
TestDefinition {
|
||||
name: "test_sftp_compliance_standalone",
|
||||
required_feature: "sftp",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/// Test suite
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
@@ -218,3 +242,72 @@ async fn test_protocol_core_suite() -> Result<(), Box<dyn std::error::Error + Se
|
||||
info!("All protocol tests passed");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn scheduled_names(suite: ProtocolTestSuite) -> Vec<&'static str> {
|
||||
suite.tests.into_iter().map(|test| test.name).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schedules_all_protocol_tests_without_feature_filter() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(None));
|
||||
|
||||
assert_eq!(names.len(), 7);
|
||||
assert!(names.contains(&"test_ftps_core_operations"));
|
||||
assert!(names.contains(&"test_webdav_core_operations"));
|
||||
assert!(names.contains(&"test_sftp_core_operations"));
|
||||
assert!(names.contains(&"test_sftp_compliance_standalone"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schedules_only_requested_non_sftp_protocols() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(Some("ftps, webdav")));
|
||||
|
||||
assert_eq!(names, vec!["test_ftps_core_operations", "test_webdav_core_operations"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schedules_all_sftp_entries_for_sftp_feature() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(Some("sftp")));
|
||||
|
||||
assert_eq!(
|
||||
names,
|
||||
vec![
|
||||
"test_sftp_core_operations",
|
||||
"test_sftp_compliance_suite",
|
||||
"test_sftp_compliance_readonly",
|
||||
"test_sftp_idle_timeout_disconnects",
|
||||
"test_sftp_compliance_standalone",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn feature_filter_is_case_insensitive() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(Some("SFTP")));
|
||||
|
||||
assert_eq!(names.len(), 5);
|
||||
assert!(names.iter().all(|name| name.contains("sftp")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn full_feature_schedules_all_protocol_tests() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(Some("full")));
|
||||
|
||||
assert_eq!(names.len(), 7);
|
||||
assert!(names.contains(&"test_ftps_core_operations"));
|
||||
assert!(names.contains(&"test_webdav_core_operations"));
|
||||
assert!(names.contains(&"test_sftp_core_operations"));
|
||||
assert!(names.contains(&"test_sftp_compliance_standalone"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schedules_no_tests_when_requested_features_have_no_protocols() {
|
||||
let names = scheduled_names(ProtocolTestSuite::with_requested_features(Some("diagnostics")));
|
||||
|
||||
assert!(names.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user