Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/pr-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,11 @@ jobs:
cat .containerignore
fi

- name: Run container tests
run: uv run pytest tests/e2e/test_podman.py -v

- name: Run container build test
run: uv run pytest tests/e2e/test_container.py::test_containerfile_exists tests/e2e/test_container.py::test_container_build -v
- name: Run Podman container tests
run: uv run pytest tests/e2e/test_podman_container.py -v

e2e:
name: Other E2E Tests
name: E2E Tests
runs-on: ubuntu-latest
needs: test # Only run E2E tests if unit and integration tests pass

Expand Down Expand Up @@ -175,4 +172,4 @@ jobs:
sbctl --help

- name: Run E2E tests (excluding container tests)
run: uv run pytest -m "e2e and not container" -v
run: uv run pytest tests/e2e/test_non_container.py -v
62 changes: 59 additions & 3 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,26 @@ The integration tests test multiple components working together:

The e2e tests test the full system:

- `test_container.py`: Tests the container functionality
- `test_docker.py`: Tests Docker-specific functionality
- `quick_check.py`: Fast tests for basic functionality checks
#### Test Files

- `test_non_container.py`: Tests that verify basic e2e functionality without needing containers
- Tests package imports and API functionality
- Verifies CLI commands work correctly
- Tests actual API components initialization and interaction

- `test_podman_container.py`: Podman container tests with efficient fixtures
- Uses module-scoped fixtures to build container image only once
- Provides isolated container instances for each test
- Tests multiple container aspects (startup, tools, volume mounting)
- Verifies required files exist (Containerfile, scripts)
- Checks that tools are properly installed (sbctl, kubectl)

- `test_podman.py`: Additional Podman tests focused on container build and run processes
- Tests file existence (Containerfile, .containerignore)
- Tests script executability (build.sh, run.sh)
- Tests container building, running, and tool installation

- `quick_check.py`: Basic checks for development and testing environment

## Test Implementation Patterns

Expand Down Expand Up @@ -137,6 +154,45 @@ Several fixtures provide standardized test environments:
- `mock_command_environment`: Sets up isolated command testing environment
- `error_setup`: Provides standard error scenarios for testing

## Test Suite Improvements

The test suite has been optimized with a focus on Podman for container testing:

### 1. Podman-Focused Container Testing

- **Podman-Only**: Tests now use Podman exclusively for container operations
- **Module-Scoped Fixtures**: Container images are built only once per test module
- **Concurrent Test Execution**: Tests are designed to run in parallel where possible
- **Reduced Redundancy**: Eliminated duplicate code across container test files

### 2. Maintainability Improvements

- **Focused Test Files**: Each test file has a clear, specific purpose
- **Better Documentation**: Improved docstrings and README documentation
- **Consistent Patterns**: Used consistent fixture and test patterns throughout
- **Simplified Structure**: Clear separation between container and non-container tests

### 3. Functionality Focus

- **Value-Based Testing**: Tests focus on actual behavior rather than implementation details
- **Better Test Coverage**: Tests cover real functionality and edge cases
- **API-Driven Tests**: Tests verify API contracts and component interactions
- **Real-World Scenarios**: Tests simulate actual usage patterns

### 4. Container Testing Optimization

- **Single Build Process**: Podman container is built only once during test suite execution
- **Isolated Test Instances**: Each test gets a fresh container instance without rebuilding
- **Proper Resource Cleanup**: All containers and images are properly cleaned up
- **Clear Container Lifecycle**: Tests clearly separate build, run, and cleanup phases

### 5. CI Workflow Improvements

- **Targeted Test Selection**: CI workflow runs tests based on their category
- **Better Failure Reporting**: Test failures are more clearly reported
- **Faster Feedback Loop**: Developers get faster feedback on their changes
- **Simplified CI Configuration**: Workflow steps clearly match test categories

## Best Practices

Follow these guidelines when writing tests:
Expand Down
37 changes: 37 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,40 @@ def ensure_bundles_directory():
fixtures_dir = Path(__file__).parent / "fixtures"
assert fixtures_dir.exists(), f"Fixtures directory not found at {fixtures_dir}"
return fixtures_dir


@pytest.fixture
def temp_bundles_directory():
"""
Create a temporary directory for bundles during tests.

This isolates each test to use a separate bundles directory, preventing
cross-test contamination.
"""
import tempfile

with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
yield temp_path


@pytest.fixture
def container_test_env():
"""
Create a test environment for container tests.

This sets up common environment variables and resources for container testing.
"""
# Store original environment
original_env = os.environ.copy()

# Set up test environment
os.environ["SBCTL_TOKEN"] = "test-token"
os.environ["MCP_BUNDLE_STORAGE"] = "/data/bundles"

# Yield to run the test
yield os.environ

# Restore original environment
os.environ.clear()
os.environ.update(original_env)
61 changes: 40 additions & 21 deletions tests/e2e/README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,72 @@
# End-to-End Tests

This directory contains end-to-end tests that verify the full functionality of the MCP server, including the Docker container build and execution.
This directory contains end-to-end tests that verify the full functionality of the MCP server, including the Podman container build and execution.

## Test Types

1. **Docker Build Tests** (`test_docker.py`): Test that the Docker image builds correctly and contains all required components.
2. **Container Basic Tests** (`test_container.py`): Test basic functionality of the container like running commands and verifying Python is installed.
3. **MCP Protocol Tests** (`test_mcp_protocol.py`): Test the MCP protocol communication directly with the Python module.
4. **Container MCP Tests** (`test_container_mcp.py`): Test MCP protocol communication with the containerized server.
1. **Container Infrastructure Tests** (`test_podman.py`): Tests basic Podman functionality, container building, and verifies the container has all required components and tools.
2. **Container Application Tests** (`test_podman_container.py`): Tests the MCP server application running inside the container with features like bundle processing.
3. **Quick Checks** (`quick_check.py`): Fast tests with strict timeouts to verify basic functionality without running the full test suite.

## Setup

Before running the e2e tests, you need to prepare the environment:

```bash
# Run the preparation script
./scripts/prepare_tests.sh
# Install dependencies
uv pip install -e ".[dev]"

# Make sure Podman is installed
podman --version
```

This script will:
1. Build the test Docker image with a mock version of sbctl
2. Prepare test fixtures and support bundles
3. Create environment variables for testing
The test suite supports both Docker and Podman, with Podman being the preferred container runtime.

## Running Tests

After preparation, you can run the tests:
You can run the tests using the following commands:

```bash
# Source the environment variables
source tests/fixtures/env.sh

# Run all e2e tests
python -m pytest tests/e2e/
uv run pytest -m e2e

# Run container-specific tests
uv run pytest -m container

# Run a specific test file
python -m pytest tests/e2e/test_docker.py
uv run pytest tests/e2e/test_podman_container.py

# Run a specific test function
python -m pytest tests/e2e/test_container.py::test_basic_container_functionality -v
uv run pytest tests/e2e/test_podman_container.py::test_bundle_processing -v
```

## Container Image Reuse

The test suite uses a session-scoped fixture that builds the container image once and reuses it across all tests. This significantly improves test performance by avoiding rebuilding the image for each test.

```python
@pytest.fixture(scope="session")
def docker_image():
# This fixture builds the image once for all tests
# ...
```

## Environment-Aware Testing

The tests are designed to work in different environments:

1. **Local Development**: Full tests with all features
2. **CI Environment**: Some tests may be skipped or modified depending on the CI capabilities

The tests automatically detect when they are running in CI environments like GitHub Actions and adjust accordingly.

## Troubleshooting

If tests are hanging or failing, check the following:

1. **Docker availability**: Make sure Docker is running
2. **Mock sbctl**: Ensure `mock_sbctl.py` is executable and working correctly
3. **Test image**: Verify the test image was built with `docker images`
1. **Podman availability**: Make sure Podman is running
2. **Mock sbctl**: Ensure `mock_sbctl.py` is executable when needed
3. **Test image**: Verify the test image was built with `podman images`
4. **Debug mode**: Set `MCP_CLIENT_DEBUG=true` to see detailed logs

## Test Timeouts
Expand Down
Loading