RFC: Testing foremanctl in a Multi-Flavor Environment
TL;DR — foremanctl is adding multiple deployment flavors (katello, foreman, foreman-proxy-content). Each deploys different features and services. This RFC proposes approches/solutions
for multi-flavor foremanctl.
Context and Problem Statement
foremanctl will support multiple deployment flavors (katello, foreman, foreman-proxy-content, etc.). Each flavor deploys a different set of features and services. We need a test selection strategy that answers one question: given a flavor deployment, which tests should run?
Current state
Today, foremanctl supports a single flavor (katello). Tests live under tests/ and use pytest with testinfra to SSH into deployed VMs and assert against real services.
We have feature-gated tests which use @pytest.mark.feature("name") markers. At collection time, conftest.py calls foremanctl features to discover which features are enabled and skips tests whose required features are not enabled.
What changes with multiple flavors
New flavors are coming — at minimum foreman (standalone, no content management) and foreman-proxy-content (standalone content proxy). Each flavor deploys a different combination of features and services:
Proposal
Here are the list of proposed solutions/approches:
Approach 1: Feature Markers (Extend Current System)
Keep @pytest.mark.feature() as the sole selection mechanism. Make foremanctl features and features.yaml flavor-aware.
What changes:
foremanctl featuresmust only list features valid for the deployed flavorfeatures.yamlneeds internal features likepulpandcandlepinso tests can gateforemanctl deploy --add-featuremust reject features invalid for the current flavor
Strengths:
- One marker type for everything — simple and consistent
foremanctl featuresalready exists; extending it keeps test infra minimal
Limitations:
-
Flavor blind * Currently
foremanctl featureslist features without considering flavor(flavor blind), so all features are listed for every flavor. -
Features != services making
pulpan internal feature is a workaround that blurs the line between user capabilities and deployment topology -
No negative testing skipping != asserting absence
-
Same thing with httpd tests, in case of standalone proxy, we need to test pulp routes but for plain foreman those does not exist
-
While our test works on enabled features we need to make sure we must enable relevant features for a flavor. As enabling non relevant features would invoke tests marked with that feature as well.
Ex: we should not be able to add
—add-feature katelloto standalone proxy flavor.
Approach 2: Runtime Service Discovery
SSH into the deployment before test collection, probe running containers/systemd units and select tests(probably via markers but not restricted to it) from that map to run.
Strengths:
- Uses actual deployed state. Flavor-independent — if Pulp is up, Pulp tests run.
- Solves the feature-vs-service mismatch directly.
Limitations:
- SSH overhead
- flaky probe logic that itself needs testing, could run into false positive scenarios
- Doesn’t prevent deploying invalid features, similar to first approach
Approach 3: Flavor-Specific Directories + Feature Markers (Recommended)
Per-flavor test directories. conftest.py reads the deployed flavor and deselects non-matching directories. Feature markers continue to gate optional capabilities.
Proposed test structure
tests/
common/ # runs on EVERY flavor
foreman_target_test.py
playbooks_test.py
flavors/
katello/
postgresql_test.py # asserts pulp + candlepin DBs exist
httpd_test.py
foreman/
postgresql_test.py # asserts pulp/candlepin DBs do NOT exist
httpd_test.py
foreman-proxy-content/
pulp_test.py # mirror-mode specific assertions
httpd_test.py
feature/ # independent features
hammer/
foreman-proxy/
bmc/
iop/
remote-execution/
Strengths:
- Directory path IS the selection for flavor specific tests
- Negative testing is natural for flavor specfic tests — each flavor asserts what must be absent
- Solves the Pulp problem — pulp tests exist in both katello/ and foreman-proxy-content/ flavor directories, each tailored to how that flavor uses Pulp
- CI is straightforward — one workflow per flavor**
Limitations:
- Some test duplication across flavors
foremanctl deploymust still enforce flavor constraints- No negative testing for features, only for flavor specific tests
Decision Outcome
Decide one of suggested solutions or suggest a better one that could be used and implmented in foremanctl
Impacts
This decision will have significant impact on how we will introduce new flavors and tests those in foremanctl