openstack-qe provides Kubernetes-hosted smoke and regression validation for an OpenStack cloud.
Current test lanes cover:
- minimal instance boot validation for the fastest first proof
- API checks for auth, endpoint discovery, image lookup, and network prerequisites
- instance lifecycle checks for boot, addressing, and console output access
- Tobiko-backed SSH checks for guest reachability and command execution
- Barbican, Glance, Neutron, Octavia, and Magnum basics aligned with existing QE scenarios
The project runs through Argo Workflows and uses mounted OpenStack credentials.
This project uses pytest as the primary framework for OpenStack end-to-end workflows that need:
- Nova boot-from-disk and boot-from-volume coverage across the available images
- Nova lifecycle checks such as live migration, cold migration, resize, snapshot, and rebuild
- connectivity checks that prove ping fails before a security-group rule and succeeds after it
- FLEX-specific validation for static vendor data and cloud-init behavior, plus heavier Magnum, Octavia, and Blazar scenarios outside the smallest daily lane
Detailed rationale and trade-offs: docs/WHY_APPROACH.md
Representative examples from the requirement set:
- Nova boot coverage across both boot-from-disk and boot-from-volume paths for every available image.
- Nova lifecycle validation such as live migration, cold migration, resize, snapshot, and rebuild flows.
- Connectivity behavior checks that prove ping fails before the right security-group rule and succeeds after it.
- FLEX-specific validation for static vendor data and cloud-init interaction.
- Service basics for Neutron, Glance, Cinder, Swift, Octavia, Barbican, Magnum, Heat, Blazar, and Zaqar.
For the explained summary and the full requirement list, see docs/REQUIREMENT_LIST.md.
runner/: CLI entrypoint, config loading, result publishing, and shared OpenStack helperstests/api/: minimal OpenStack API smoke checkstests/instance/: boot-and-cleanup validationtests/tobiko/: SSH-only Tobiko validationdeploy/: namespace, RBAC, PVC, config, and secret contractsworkflows/: Argo workflow templates and schedulesgitops/: Argo CD app-of-apps manifests and the tracked runner image referencebootstrap/: bastion-host bootstrap scripts for seeding Argo CD and repo credentialsdocs/: operator notes, suite definitions, and behavior coverage design
The deployment path is pull-based:
- GitHub Actions runs lightweight checks.
- On
main, GitHub Actions builds and pushes an immutable GHCR image. - GitHub Actions updates the tracked runner image in Git.
- Argo CD, running in the cluster, pulls the changed Git state and syncs it.
- Argo Workflows runs the QE suites using the synced runner image.
Argo CD pulls manifest changes from Git and syncs them in the cluster. Bootstrap steps are documented in bootstrap/README.md.
- Create a Python 3.10+ virtual environment (required).
python3.10 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip- Install dependencies:
pip install -e '.[dev,tobiko]'Note for zsh: the quotes are required so the shell does not treat [] as a glob pattern.
If python --version is below 3.10, installation will fail because the project declares requires-python = ">=3.10" in pyproject.toml.
- Export the required runtime variables:
export OS_CLIENT_CONFIG_FILE=/path/to/clouds.yaml
export OS_CLOUD=mycloud
export QE_IMAGE=ubuntu-22.04
export QE_FLAVOR=m1.small
export QE_FIXED_NETWORK=private
export QE_BOOT_MODE=auto
export QE_FLOATING_NETWORK=public
export QE_SSH_USERNAME=ubuntu
export QE_SSH_KEY_PATH=/path/to/private-key
export QE_PARALLEL_WORKERS=1QE_BOOT_MODE supports auto, disk, and volume. auto uses volume-backed boot automatically when the selected flavor has zero disk.
- Run the smallest possible instance test:
python -m runner.cli --suite minimalThis suite only checks that one instance can be created and reaches ACTIVE.
- Run the smoke suite:
python -m runner.cli --suite smoke- Run the smoke suite with 5 tests in parallel:
python -m runner.cli --suite smoke --parallel 5You can also set QE_PARALLEL_WORKERS=5 to make parallel execution the default.
To run one specific test instead of the whole suite, pass the pytest nodeid after the suite selection. Example:
python -m runner.cli --suite minimal tests/minimal/test_boot_minimal.py::test_instance_boots_successfullyArtifacts are written under artifacts/ by default:
junit-<suite>.xmlpytest-<suite>.logsummary-<suite>.jsonsummary-<suite>.txtstatus-<suite>.txtdiagnostics/<suite>/: failure-focused artifacts such as server fault details and console logs
During a run, the console prints each test as it starts so it is clearer what is being validated. The final summary includes:
- total, passed, failed, error, and skipped counts
- one line per test with its result
- all artifact and log file paths saved for the run
If you want the complete unfiltered pytest and runner output, open artifacts/console-<suite>.log.
The service expects:
clouds.yamlmounted into the container- a private SSH key secret mounted for guest reachability checks
- a PVC or object storage-compatible mount for workflow artifacts
- Argo parameters for suite selection and runner image selection
- optional service-specific QE flags and inputs for Barbican, Octavia, and Magnum checks
- The repo owns its own build, test, and deployment pipeline.
- Argo CD syncs manifests in the cluster; Argo Workflows executes the in-cluster test runs.
- Test selection is organized by suites such as
smoke,nightly, andmanual. - Artifacts are designed for CI, Argo, and operator troubleshooting workflows.