177 lines
5.9 KiB
Markdown
177 lines
5.9 KiB
Markdown
|
|
# WebTerm Test Suite
|
||
|
|
|
||
|
|
This directory contains the unit and integration tests for the socktop webterm project.
|
||
|
|
|
||
|
|
## Test Structure
|
||
|
|
|
||
|
|
Tests are organized into separate files by module:
|
||
|
|
|
||
|
|
### `event_tests.rs`
|
||
|
|
Tests for the `event` module, covering:
|
||
|
|
- **IO message creation**: Testing conversion from Bytes, String, and &str
|
||
|
|
- **IO equality and cloning**: Verifying proper equality checks and clone behavior
|
||
|
|
- **Binary and Unicode data**: Testing handling of binary data and Unicode strings
|
||
|
|
- **ChildDied events**: Testing the ChildDied event structure
|
||
|
|
|
||
|
|
**Total tests**: 11
|
||
|
|
|
||
|
|
### `terminado_tests.rs`
|
||
|
|
Comprehensive tests for the Terminado protocol implementation:
|
||
|
|
- **Serialization**: Converting TerminadoMessage to JSON format
|
||
|
|
- `stdin`, `stdout`, and `set_size` (resize) messages
|
||
|
|
- Special characters, Unicode, and empty strings
|
||
|
|
- **Deserialization**: Parsing JSON into TerminadoMessage
|
||
|
|
- Valid message formats
|
||
|
|
- Error handling for invalid JSON, wrong types, wrong lengths
|
||
|
|
- **Round-trip testing**: Serialize → Deserialize → Compare
|
||
|
|
- **Error cases**: Testing all failure modes
|
||
|
|
- Invalid JSON
|
||
|
|
- Wrong array lengths
|
||
|
|
- Non-string types where strings expected
|
||
|
|
- Unknown message types
|
||
|
|
|
||
|
|
**Total tests**: 38
|
||
|
|
|
||
|
|
### `config_tests.rs`
|
||
|
|
Integration tests verifying configuration constants and relationships:
|
||
|
|
- **Timeout values**: Heartbeat, client timeout, idle timeout
|
||
|
|
- **Timeout relationships**: Ensuring timeouts have logical relationships
|
||
|
|
- **PTY configuration**: Initial size, buffer sizes
|
||
|
|
- **Path validation**: Template paths, static paths, endpoints
|
||
|
|
- **Network configuration**: Default ports, hosts
|
||
|
|
- **Size boundaries**: Terminal size limits and validation
|
||
|
|
|
||
|
|
**Total tests**: 17
|
||
|
|
|
||
|
|
### `security_tests.rs`
|
||
|
|
Comprehensive security tests for command sanitization and validation:
|
||
|
|
- **Command path validation**: Absolute paths, no path traversal, no shell metacharacters
|
||
|
|
- **Shell injection prevention**: Detecting and rejecting injection attempts
|
||
|
|
- **Environment variable security**: Sanitizing TERM and other env vars
|
||
|
|
- **Whitelist enforcement**: Only allowing approved shell commands
|
||
|
|
- **Path traversal prevention**: Blocking `..`, `./`, `~` patterns
|
||
|
|
- **Input validation**: Length limits, null byte detection, control characters
|
||
|
|
- **File descriptor security**: No redirection operators in commands
|
||
|
|
- **Unicode and special characters**: ASCII-only enforcement
|
||
|
|
- **Dangerous directory prevention**: Blocking execution from `/tmp`, `/var/tmp`, etc.
|
||
|
|
- **Command execution logging**: Ensuring commands are safely loggable
|
||
|
|
- **Integration with Command::new()**: Verifying safe process spawning
|
||
|
|
- **Complete security checklist**: Comprehensive validation of all security requirements
|
||
|
|
|
||
|
|
**Total tests**: 28 (plus 11 in `src/security.rs`)
|
||
|
|
|
||
|
|
## Running Tests
|
||
|
|
|
||
|
|
### Run all tests
|
||
|
|
```bash
|
||
|
|
cargo test --all-targets --all-features
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run specific test file
|
||
|
|
```bash
|
||
|
|
cargo test --test event_tests
|
||
|
|
cargo test --test terminado_tests
|
||
|
|
cargo test --test config_tests
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run with output
|
||
|
|
```bash
|
||
|
|
cargo test -- --nocapture
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run specific test
|
||
|
|
```bash
|
||
|
|
cargo test test_serialize_resize
|
||
|
|
```
|
||
|
|
|
||
|
|
## Test Coverage
|
||
|
|
|
||
|
|
Current test coverage includes:
|
||
|
|
|
||
|
|
- ✅ **Event handling**: IO messages and ChildDied events
|
||
|
|
- ✅ **Protocol parsing**: Terminado message serialization/deserialization
|
||
|
|
- ✅ **Configuration validation**: Timeout relationships and constants
|
||
|
|
- ✅ **Error handling**: Invalid input parsing and edge cases
|
||
|
|
- ✅ **Data types**: Binary data, Unicode, special characters
|
||
|
|
- ✅ **Security validation**: Command sanitization, injection prevention, whitelist enforcement
|
||
|
|
|
||
|
|
## CI/CD Integration
|
||
|
|
|
||
|
|
Tests run automatically in the Gitea Actions workflow:
|
||
|
|
|
||
|
|
1. **Test Job**: Runs `cargo test --all-targets --all-features`
|
||
|
|
2. **Lint Job**: Runs after tests pass
|
||
|
|
3. **Build Job**: Runs after linting passes
|
||
|
|
4. **Deploy Job**: Runs after build passes
|
||
|
|
|
||
|
|
## Adding New Tests
|
||
|
|
|
||
|
|
When adding new tests:
|
||
|
|
|
||
|
|
1. Choose the appropriate test file based on the module being tested
|
||
|
|
2. Follow the existing test naming convention: `test_<feature>_<scenario>`
|
||
|
|
3. Group related tests together with comments
|
||
|
|
4. Include both success and failure cases
|
||
|
|
5. Test edge cases (empty strings, zero values, max values, etc.)
|
||
|
|
6. Add documentation comments for complex test scenarios
|
||
|
|
|
||
|
|
### Example Test Structure
|
||
|
|
```rust
|
||
|
|
#[test]
|
||
|
|
fn test_feature_success_case() {
|
||
|
|
// Arrange
|
||
|
|
let input = setup_test_data();
|
||
|
|
|
||
|
|
// Act
|
||
|
|
let result = function_under_test(input);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
assert_eq!(result, expected_value);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_feature_error_case() {
|
||
|
|
let invalid_input = "invalid";
|
||
|
|
let result = function_under_test(invalid_input);
|
||
|
|
assert!(result.is_err());
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Test Guidelines
|
||
|
|
|
||
|
|
- **Fast**: Unit tests should run in milliseconds
|
||
|
|
- **Isolated**: Each test should be independent
|
||
|
|
- **Deterministic**: Tests should always produce the same result
|
||
|
|
- **Clear**: Test names should clearly describe what is being tested
|
||
|
|
- **Comprehensive**: Test happy paths, error paths, and edge cases
|
||
|
|
|
||
|
|
## Clippy Allowances
|
||
|
|
|
||
|
|
Some tests use `#![allow(clippy::assertions_on_constants)]` because they document expected constant values for configuration. This is intentional and helps verify that constants maintain reasonable values.
|
||
|
|
|
||
|
|
## Security Features
|
||
|
|
|
||
|
|
The test suite includes comprehensive security validation to prevent:
|
||
|
|
- Shell injection attacks
|
||
|
|
- Path traversal attempts
|
||
|
|
- Command injection via metacharacters
|
||
|
|
- Null byte injection
|
||
|
|
- Execution from untrusted directories
|
||
|
|
- Unicode/encoding tricks
|
||
|
|
- Environment variable injection
|
||
|
|
|
||
|
|
The `security` module provides `validate_command()` and `validate_env_value()` functions that are used by the server to validate all commands before execution.
|
||
|
|
|
||
|
|
## Total Test Count
|
||
|
|
|
||
|
|
- **Unit tests** (in src/):
|
||
|
|
- terminado.rs: 6 tests
|
||
|
|
- security.rs: 11 tests
|
||
|
|
- **Integration tests** (in tests/):
|
||
|
|
- event_tests.rs: 11 tests
|
||
|
|
- terminado_tests.rs: 38 tests
|
||
|
|
- config_tests.rs: 17 tests
|
||
|
|
- security_tests.rs: 28 tests
|
||
|
|
- **Total**: 111 tests
|
||
|
|
|
||
|
|
All tests must pass before code can be merged.
|