CRITICAL Security Fixes: - Add command injection protection with whitelist validation - Implement robust SSL/TLS certificate handling and validation - Add backup verification with SHA256 checksums and content validation - Implement atomic backup operations with proper cleanup - Create comprehensive security documentation Security Improvements: - Enhanced backup_command.rb with command sanitization and whitelisting - Added SSL certificate expiration checks and key matching validation - Implemented atomic file operations to prevent backup corruption - Added backup metadata storage for integrity tracking - Created SECURITY.md with Docker socket security guidance Testing Updates: - Added comprehensive security tests for command injection prevention - Updated SSL tests with proper certificate validation - Enhanced PostgreSQL alias method test coverage (100% coverage achieved) - Maintained 94.94% overall line coverage Documentation Updates: - Updated README.md with security warnings and test coverage information - Updated TODO.md marking all critical security items as completed - Enhanced TESTING.md and CLAUDE.md with current coverage metrics - Added comprehensive SECURITY.md with deployment best practices 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
---|---|---|
.. | ||
fixtures | ||
integration | ||
support | ||
unit | ||
examples.txt | ||
README.md | ||
spec_helper.rb |
Baktainer Testing Guide
This directory contains the complete test suite for Baktainer, including unit tests, integration tests, and testing infrastructure.
Test Structure
spec/
├── unit/ # Unit tests for individual components
│ ├── backup_command_spec.rb # Tests for backup command generation
│ ├── container_spec.rb # Tests for container management
│ └── baktainer_spec.rb # Tests for main runner class
├── integration/ # Integration tests with real containers
│ └── backup_workflow_spec.rb # End-to-end backup workflow tests
├── fixtures/ # Test data and configuration
│ ├── docker-compose.test.yml # Test database containers
│ └── factories.rb # Test data factories
├── support/ # Test support files
│ └── coverage.rb # Coverage configuration
├── spec_helper.rb # Main test configuration
└── README.md # This file
Running Tests
Quick Start
# Run unit tests only (fast)
cd app && bundle exec rspec spec/unit/
# Run all tests with coverage
cd app && COVERAGE=true bundle exec rspec
# Use the test runner script
cd app && bin/test --all --coverage
Test Runner Script
The bin/test
script provides a convenient way to run tests with various options:
# Run unit tests (default)
bin/test
# Run integration tests with container setup
bin/test --integration --setup --cleanup
# Run all tests with coverage
bin/test --all --coverage
# Show help
bin/test --help
Using Rake Tasks
# Install dependencies
rake install
# Run unit tests
rake spec
# Run integration tests
rake integration
# Run all tests
rake spec_all
# Run tests with coverage
rake coverage
# Full test suite with setup/cleanup
rake test_full
# Open coverage report
rake coverage_report
Test Categories
Unit Tests
Unit tests focus on individual components in isolation:
- Backup Command Tests (
backup_command_spec.rb
): Test command generation for different database engines - Container Tests (
container_spec.rb
): Test container discovery, validation, and backup orchestration - Runner Tests (
baktainer_spec.rb
): Test the main application runner, thread pool, and scheduling
Unit tests use mocks and stubs to isolate functionality and run quickly without external dependencies.
Integration Tests
Integration tests validate the complete backup workflow with real Docker containers:
- Container Discovery: Test finding containers with backup labels
- Database Backups: Test actual backup creation for PostgreSQL, MySQL, and SQLite
- Error Handling: Test graceful handling of failures and edge cases
- Concurrent Execution: Test thread pool and concurrent backup execution
Integration tests require Docker and may take longer to run.
Test Environment Setup
Dependencies
Install test dependencies:
cd app
bundle install
Required gems for testing:
rspec
- Testing frameworksimplecov
- Code coverage reportingfactory_bot
- Test data factorieswebmock
- HTTP request stubbing
Test Database Containers
Integration tests use Docker containers defined in spec/fixtures/docker-compose.test.yml
:
- PostgreSQL container with test database
- MySQL container with test database
- SQLite container with test database file
- Control container without backup labels
Start test containers:
cd app
docker-compose -f spec/fixtures/docker-compose.test.yml up -d
Stop test containers:
cd app
docker-compose -f spec/fixtures/docker-compose.test.yml down -v
Test Configuration
RSpec Configuration (.rspec
)
--require spec_helper
--format documentation
--color
--profile 10
--order random
Coverage Configuration
Test coverage is configured in spec/support/coverage.rb
:
- Minimum coverage: 80%
- Minimum per-file coverage: 70%
- HTML and console output formats
- Branch coverage tracking (Ruby 2.5+)
- Coverage tracking over time
Enable coverage:
COVERAGE=true bundle exec rspec
Environment Variables
Tests clean up environment variables between runs and use temporary directories for backup files.
Writing Tests
Unit Test Example
RSpec.describe Baktainer::BackupCommand do
describe '.postgres' do
it 'generates correct pg_dump command' do
result = described_class.postgres(login: 'user', password: 'pass', database: 'testdb')
expect(result).to be_a(Hash)
expect(result[:env]).to eq(['PGPASSWORD=pass'])
expect(result[:cmd]).to eq(['pg_dump', '-U', 'user', '-d', 'testdb'])
end
end
end
Integration Test Example
RSpec.describe 'PostgreSQL Backup', :integration do
let(:postgres_container) do
containers = Baktainer::Containers.find_all
containers.find { |c| c.engine == 'postgres' }
end
it 'creates a valid PostgreSQL backup' do
postgres_container.backup
backup_files = Dir.glob(File.join(test_backup_dir, '**', '*.sql'))
expect(backup_files).not_to be_empty
backup_content = File.read(backup_files.first)
expect(backup_content).to include('PostgreSQL database dump')
end
end
Test Helpers
Use test helpers defined in spec_helper.rb
:
# Create mock Docker container
container = mock_docker_container(labels)
# Create temporary backup directory
test_dir = create_test_backup_dir
# Set environment variables for test
with_env('BT_BACKUP_DIR' => test_dir) do
# test code
end
Continuous Integration
GitHub Actions
Add to .github/workflows/test.yml
:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- name: Run tests
run: |
cd app
COVERAGE=true bundle exec rspec
- name: Upload coverage
uses: codecov/codecov-action@v3
Coverage Reporting
Coverage reports are generated in coverage/
directory:
coverage/index.html
- HTML reportcoverage/coverage.json
- JSON data- Console summary during test runs
Troubleshooting
Common Issues
- Docker containers not starting: Check Docker daemon is running and ports are available
- Permission errors: Ensure test script is executable (
chmod +x bin/test
) - Bundle errors: Run
bundle install
in theapp
directory - Coverage not working: Set
COVERAGE=true
environment variable
Debugging Tests
# Run specific test file
bundle exec rspec spec/unit/container_spec.rb
# Run specific test
bundle exec rspec spec/unit/container_spec.rb:45
# Run with debug output
bundle exec rspec --format documentation --backtrace
# Run integration tests with container logs
docker-compose -f spec/fixtures/docker-compose.test.yml logs
Performance
- Unit tests should complete in under 10 seconds
- Integration tests may take 30-60 seconds including container startup
- Use
bin/test --unit
for quick feedback during development - Run full test suite before committing changes
Best Practices
- Isolation: Each test should be independent and clean up after itself
- Descriptive Names: Use clear, descriptive test names and descriptions
- Mock External Dependencies: Use mocks for Docker API calls in unit tests
- Test Error Conditions: Include tests for error handling and edge cases
- Coverage: Aim for high test coverage, especially for critical backup logic
- Fast Feedback: Keep unit tests fast for quick development feedback