mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 15:26:51 +08:00
Reorganize project structure to improve maintainability and add comprehensive testing documentation and tooling support.
301 lines
7.1 KiB
Markdown
301 lines
7.1 KiB
Markdown
# MinIO Rust SDK Testing Strategy
|
|
|
|
## Overview
|
|
|
|
The MinIO Rust SDK uses a comprehensive testing approach combining unit tests, property-based tests, and integration tests to ensure reliability and correctness.
|
|
|
|
## Test Categories
|
|
|
|
### 1. Unit Tests (Primary Focus)
|
|
|
|
**Location:** `src/madmin/types/*.rs`, inline `#[cfg(test)]` modules
|
|
|
|
**Purpose:** Test individual components in isolation
|
|
- Type serialization/deserialization
|
|
- Builder pattern correctness
|
|
- Response parsing
|
|
- Validation logic
|
|
|
|
**Coverage Goal:** >90% for library code
|
|
|
|
**Example:**
|
|
```rust
|
|
#[test]
|
|
fn test_batch_job_type_serialization() {
|
|
let job_type = BatchJobType::Replicate;
|
|
let json = serde_json::to_string(&job_type).unwrap();
|
|
assert_eq!(json, "\"replicate\"");
|
|
}
|
|
```
|
|
|
|
### 2. Error Path Tests
|
|
|
|
**Location:** `src/madmin/types/error_tests.rs`
|
|
|
|
**Purpose:** Verify error handling and edge cases
|
|
- Invalid JSON deserialization
|
|
- Missing required fields
|
|
- Type mismatches
|
|
- Boundary conditions
|
|
- Unicode and special characters
|
|
- Malformed data
|
|
|
|
**Coverage Goal:** All error paths in critical code
|
|
|
|
**Example:**
|
|
```rust
|
|
#[test]
|
|
fn test_invalid_json_batch_job_type() {
|
|
let invalid_json = "\"invalid_type\"";
|
|
let result: Result<BatchJobType, _> = serde_json::from_str(invalid_json);
|
|
assert!(result.is_err(), "Should fail on invalid batch job type");
|
|
}
|
|
```
|
|
|
|
### 3. Property-Based Tests
|
|
|
|
**Location:** `src/madmin/builders/property_tests.rs`
|
|
|
|
**Tool:** `quickcheck` crate
|
|
|
|
**Purpose:** Test properties that should hold for arbitrary inputs
|
|
- Builder idempotence
|
|
- Validation consistency
|
|
- No panics on valid inputs
|
|
- Encoding/decoding round-trips
|
|
|
|
**Coverage Goal:** Key invariants and properties
|
|
|
|
**Example:**
|
|
```rust
|
|
quickcheck! {
|
|
fn prop_bucket_name_no_panic(name: String) -> TestResult {
|
|
if name.is_empty() {
|
|
return TestResult::discard();
|
|
}
|
|
let _result = validate_bucket_name(&name);
|
|
TestResult::passed()
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4. Integration Tests
|
|
|
|
**Location:** `tests/` directory
|
|
|
|
**Purpose:** Test end-to-end workflows with live MinIO server
|
|
- Client initialization
|
|
- Request execution
|
|
- Response handling
|
|
- Multi-step operations
|
|
|
|
**Coverage Goal:** Critical user workflows
|
|
|
|
**Note:** Integration tests are **NOT** counted in unit test coverage metrics as they require external infrastructure.
|
|
|
|
**Example:**
|
|
```rust
|
|
#[tokio::test]
|
|
#[ignore] // Run only when MinIO server is available
|
|
async fn test_list_buckets() {
|
|
let client = create_test_client();
|
|
let buckets = client.list_buckets().send().await.unwrap();
|
|
assert!(buckets.buckets.len() >= 0);
|
|
}
|
|
```
|
|
|
|
## What NOT to Test
|
|
|
|
### 1. Client Execution Methods
|
|
- Methods in `src/madmin/client/` that call `.send()`
|
|
- These require live server and belong in integration tests
|
|
- Focus unit tests on request building, not execution
|
|
|
|
### 2. Trivial Code
|
|
- Simple getter/setter methods
|
|
- Derived trait implementations (Debug, Clone, etc.)
|
|
- Pass-through wrapper functions
|
|
|
|
### 3. External Dependencies
|
|
- `reqwest` HTTP client behavior
|
|
- `serde_json` serialization correctness
|
|
- `tokio` runtime functionality
|
|
|
|
## Test Organization
|
|
|
|
### File Structure
|
|
```
|
|
src/
|
|
├── madmin/
|
|
│ ├── types/
|
|
│ │ ├── user.rs # Type definitions + inline tests
|
|
│ │ ├── batch.rs # Type definitions + inline tests
|
|
│ │ └── error_tests.rs # Centralized error path tests
|
|
│ ├── builders/
|
|
│ │ ├── user_management/ # Builder implementations
|
|
│ │ └── property_tests.rs # Property-based tests
|
|
│ └── client/ # NO unit tests (integration only)
|
|
tests/
|
|
└── integration_tests.rs # End-to-end tests (ignored by default)
|
|
```
|
|
|
|
### Test Naming Conventions
|
|
|
|
**Unit Tests:**
|
|
- `test_<functionality>_<scenario>`
|
|
- Example: `test_user_serialization_with_utf8`
|
|
|
|
**Error Tests:**
|
|
- `test_<error_condition>`
|
|
- Example: `test_invalid_json_batch_job_type`
|
|
|
|
**Property Tests:**
|
|
- `prop_<property_being_tested>`
|
|
- Example: `prop_builder_idempotent`
|
|
|
|
## Running Tests
|
|
|
|
### All Tests
|
|
```bash
|
|
cargo test
|
|
```
|
|
|
|
### Unit Tests Only (Fast)
|
|
```bash
|
|
cargo test --lib
|
|
```
|
|
|
|
### Specific Test Module
|
|
```bash
|
|
cargo test --lib types::error_tests
|
|
```
|
|
|
|
### Property-Based Tests
|
|
```bash
|
|
cargo test --lib property_tests
|
|
```
|
|
|
|
### Integration Tests (Requires MinIO Server)
|
|
```bash
|
|
cargo test --test integration_tests -- --ignored
|
|
```
|
|
|
|
### Coverage Report
|
|
```bash
|
|
cargo llvm-cov --lib --tests --html --output-dir target/coverage
|
|
```
|
|
|
|
## Coverage Goals
|
|
|
|
### Overall Target: 85%+
|
|
|
|
**By Module:**
|
|
- `src/madmin/types/`: 95%+ (high value, easy to test)
|
|
- `src/madmin/builders/`: 90%+ (core functionality)
|
|
- `src/madmin/response/`: 90%+ (parsing critical)
|
|
- `src/madmin/client/`: 20%+ (mostly integration tests)
|
|
- `src/s3/`: 85%+ (established S3 client)
|
|
|
|
### Acceptable Gaps
|
|
- Client method bodies (integration test coverage)
|
|
- Error display formatting
|
|
- Debug implementations
|
|
- Example code in doc comments
|
|
|
|
## Adding New Tests
|
|
|
|
### For New Type Definitions
|
|
|
|
1. Add inline serialization test
|
|
2. Add to error_tests.rs for edge cases
|
|
3. Consider property test if validation exists
|
|
|
|
### For New Builders
|
|
|
|
1. Test required parameter validation
|
|
2. Test optional parameter combinations
|
|
3. Add property test for invariants
|
|
4. Verify request URL/headers/body
|
|
|
|
### For New Response Types
|
|
|
|
1. Test successful parsing with sample JSON
|
|
2. Test error cases (missing fields, wrong types)
|
|
3. Test optional field handling
|
|
|
|
## Continuous Integration
|
|
|
|
### Pre-Commit Checklist
|
|
```bash
|
|
cargo fmt --all --check
|
|
cargo clippy -- -D warnings
|
|
cargo test --lib
|
|
```
|
|
|
|
### CI Pipeline
|
|
```yaml
|
|
- Run: cargo test --lib --all-features
|
|
- Coverage: cargo llvm-cov --lib --tests
|
|
- Minimum: 85% coverage required
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### DO:
|
|
- ✅ Test error paths explicitly
|
|
- ✅ Use property tests for validation logic
|
|
- ✅ Test edge cases (empty, null, oversized)
|
|
- ✅ Keep tests focused and independent
|
|
- ✅ Use descriptive test names
|
|
|
|
### DON'T:
|
|
- ❌ Test external library behavior
|
|
- ❌ Require live server for unit tests
|
|
- ❌ Test implementation details
|
|
- ❌ Write flaky tests with timeouts
|
|
- ❌ Duplicate coverage across test types
|
|
|
|
## Debugging Test Failures
|
|
|
|
### View Detailed Output
|
|
```bash
|
|
cargo test --lib -- --nocapture test_name
|
|
```
|
|
|
|
### Run Single Test
|
|
```bash
|
|
cargo test --lib test_name -- --exact
|
|
```
|
|
|
|
### Debug Coverage Gaps
|
|
```bash
|
|
cargo llvm-cov --lib --tests --html
|
|
# Open target/coverage/index.html
|
|
```
|
|
|
|
## Maintenance
|
|
|
|
### Regular Tasks
|
|
- Review coverage reports monthly
|
|
- Update tests when APIs change
|
|
- Remove obsolete tests
|
|
- Refactor duplicated test code
|
|
|
|
### When Coverage Drops
|
|
1. Identify uncovered code with llvm-cov HTML report
|
|
2. Assess if coverage gap is acceptable (client methods, trivial code)
|
|
3. Add targeted tests for critical uncovered paths
|
|
4. Document intentional coverage exclusions
|
|
|
|
## Resources
|
|
|
|
- [Rust Book - Testing](https://doc.rust-lang.org/book/ch11-00-testing.html)
|
|
- [quickcheck Documentation](https://docs.rs/quickcheck/)
|
|
- [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov)
|
|
|
|
## Questions?
|
|
|
|
For testing strategy questions, see:
|
|
- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines
|
|
- [CLAUDE.md](CLAUDE.md) - Code quality standards
|