Skip to content

Testing

虚拟世界的懒猫 edited this page Feb 26, 2026 · 2 revisions

English | 中文

Testing

FileHunter ships with 106 tests covering configuration parsing, path security, HTTP behavior, search logic, routing, and authentication. The test suite uses Rust's built-in #[test] / #[tokio::test] framework with zero external test runners.

Running Tests

cargo test                    # all 106 tests
cargo test --lib              # unit tests only (73)
cargo test --test integration # integration tests only (33)
cargo test -- <name>          # filter by test name substring

Test Architecture

┌───────────────────────────────────────────────┐
│              Unit Tests (73)                   │
│         inline #[cfg(test)] modules           │
├───────────────────┬───────────────────────────┤
│  config::tests    │     server::tests         │
│  27 tests         │     46 tests              │
├───────────────────┴───────────────────────────┤
│           Integration Tests (33)              │
│         tests/integration.rs                  │
│    tempdir + Request<Empty<Bytes>>            │
└───────────────────────────────────────────────┘

The project uses a lib+bin crate pattern (src/lib.rs re-exports modules) so that integration tests in tests/ can import internal types via use filehunter::config::*.

Unit Tests — config::tests (27)

Embedded in src/config.rs inside a #[cfg(test)] module. These test private parsing and validation logic:

Category Tests What's covered
ByteSize parsing 6 KB/MB/GB strings, integer passthrough, case insensitivity, error on negative/unknown unit
ByteSize display 4 Human-readable formatting (KB, MB, zero, non-aligned)
Extension filtering 3 Deduplication, dot-stripping + lowercasing, empty → None
Prefix normalization 4 Leading slash insertion, trailing slash removal, root /, multi-segment
Config validation 10 Rejects: no locations, duplicate prefix, CORS credential+wildcard, zero RPS rate limit, small header size, zero stream buffer, basic auth empty username/password; allows disabled auth with empty credentials

Unit Tests — server::tests (46)

Embedded in src/server.rs inside a #[cfg(test)] module. These test private routing, security, and authentication functions:

Category Tests What's covered
Path sanitization 10 Normal paths, nested directories, single file, .. traversal rejection, dotfile blocking, hidden directories, null bytes, URL-encoded %2e%2e, URL-encoded spaces
Extension matching 3 None accepts all, case-insensitive match, reject non-matching
Prefix matching 6 Exact match, prefix with remainder, root catch-all, longest prefix wins, no false partial match, no match returns None
ETag / conditional 5 ETag format, deterministic generation, If-None-Match, If-Modified-Since, priority rules
Range requests 12 From-To, open range, suffix, multi-range unsupported, no prefix, garbage, empty suffix; resolve normal, clamped, beyond EOF, suffix zero, empty file
If-Range 3 No If-Range, ETag match, ETag mismatch
Basic Auth 7 Missing header, valid credentials, wrong password, non-Basic scheme, malformed base64, no colon separator, password with colon (RFC 7617)

Integration Tests (33)

Located in tests/integration.rs. Each test creates a temporary directory with real files and invokes handle_request() directly — no TCP socket needed.

Category Tests What's covered
HTTP methods & status 5 GET 200 with body, GET 404, HEAD 200 with empty body, POST 405, oversized Content-Length 413
MIME types 2 .jpgimage/jpeg, .htmltext/html
Extension filtering 2 Disallowed extension → 404, allowed extension → 200
Search modes 2 sequential returns first root's file, latest_modified returns newer file
Routing 1 Longest-prefix routing picks /img over /
Rate limiting 1 Second request to burst=1 limiter returns 429 with Retry-After header
Health checks 4 GET /health 200, HEAD /health 200, GET /ready 200, POST /health 405
ETag / 304 4 Response includes ETag + Last-Modified, If-None-Match 304, wrong ETag 200, If-Modified-Since 304
Range requests 5 From-To 206, open range 206, suffix 206, beyond EOF 416, HEAD with range 206
Basic Auth 7 Missing credentials 401, valid credentials 200, wrong password 401, wrong username 401, disabled allows unauthenticated, /health exempt, /ready exempt

Test Helper Pattern

Integration tests share a setup_single_root() helper:

fn setup_single_root(
    files: &[(&str, &[u8])],
    extensions: Vec<String>,
) -> (TempDir, Arc<FileSearcher>)

This creates a temporary directory, writes files into it, constructs a Config + FileSearcher, and returns both (the TempDir must be kept alive to prevent cleanup).

Dev Dependencies

Crate Purpose
tempfile Creates OS-managed temporary directories that auto-delete on drop

Clone this wiki locally