Public Access
77 lines
3.6 KiB
Markdown
77 lines
3.6 KiB
Markdown
# DEVX-177: Honest molecule selection — fail-open coverage and real command contract
|
|
|
|
## Problem
|
|
|
|
`devx.molecule.molecule_changed` and `devx.ci.fast_molecule` violate the
|
|
S09/REQ-9 honesty contract in three ways:
|
|
|
|
1. **Silent skips.** `detect_changed_roles` only knows four playbooks and
|
|
`ansible/roles/`. Changes to `restore.yml`, `deploy-sso-bridge.yml`,
|
|
`upgrade-postgres.yml`, `rolling-update-gitea.yml`,
|
|
`update-alertmanager.yml`, `build-image.yml`, `playbooks/_tasks/`,
|
|
`playbooks/tasks/`, or `ansible/group_vars/` trigger zero molecule
|
|
coverage — the fast path passes by skipping work.
|
|
2. **Phantom targets.** `ROLE_TARGET_MAP` includes `sso_config` (role
|
|
moved to the sso-bridge repo) and emits `molecule-crowdsec` /
|
|
`molecule-disk-cleanup` targets that do not exist in infra's Makefile.
|
|
Playbook mappings also inject absent roles, so `make molecule-changed`
|
|
can select nonexistent targets.
|
|
3. **Dishonest contract.** `fast_molecule` documents "converge + verify
|
|
only, no idempotence" and builds `molecule test -s X --destroy=never
|
|
--platform-name=...` commands that nothing executes — CI actually runs
|
|
full `molecule test -s X` via `run_molecule_scenario.py` (which does
|
|
include idempotence where the scenario defines it).
|
|
|
|
## Approach
|
|
|
|
REQ-1: Fail-open coverage in `detect_changed_roles` — add the missing
|
|
playbook→role mappings; `ansible/group_vars/**` and any other
|
|
`ansible/playbooks/**` file (including `_tasks/`/`tasks/`) not explicitly
|
|
mapped select all molecule-covered roles. `ansible/environments/` stays
|
|
unmapped (env data is covered by unit/deploy tests, not molecule) and is
|
|
documented as such.
|
|
|
|
REQ-2: Selection only emits roles that exist — `detect_changed_roles`
|
|
gains a `roles_dir` parameter; role names from file paths and playbook
|
|
maps are kept only when `<roles_dir>/<role>` exists. Shared-path and
|
|
fail-open "all roles" resolution returns only directories under
|
|
`roles_dir` containing a `molecule/` dir (untestable roles select
|
|
nothing rather than phantom targets).
|
|
|
|
REQ-3: Honest fast-molecule contract — `build_molecule_commands` emits
|
|
exactly what the CI runner executes (`molecule test -s <scenario>`);
|
|
docstrings state the real sequence (full `molecule test` per scenario on
|
|
changed roles, single platform as configured by the scenario) instead of
|
|
the old "converge + verify only" claim.
|
|
|
|
## Test Plan
|
|
|
|
- Update `test_molecule_changed.py`: unmapped playbook → all present
|
|
roles; `group_vars` change → all; mapped playbook → mapped roles only;
|
|
role absent from `roles_dir` → filtered out; shared path → only roles
|
|
with `molecule/` dirs.
|
|
- Update `test_fast_molecule.py`: emitted commands are `molecule test -s
|
|
<scenario>` with no `--destroy`/`--platform-name` flags.
|
|
- `make pytest-cov` (100% gate), `make lint-all`.
|
|
|
|
## Deploy Plan
|
|
|
|
Merge → devx release publishes automatically → infra dep-PR bumps the
|
|
pin; the honest selection takes effect on the next infra CI run.
|
|
|
|
## Rollback Plan
|
|
|
|
Revert the squash commit; previous (under-covering) selection returns —
|
|
acceptable short-term because coverage only widens with this change.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [x] REQ-1: All `ansible/playbooks/**` and `ansible/group_vars/**`
|
|
changes select molecule coverage; unmapped files fail open to all
|
|
testable roles.
|
|
- [x] REQ-2: No nonexistent roles or make targets are emitted; `sso_config`
|
|
no longer appears when absent from `roles_dir`.
|
|
- [x] REQ-3: `build_molecule_commands` output matches the executed CI
|
|
command shape; module docstrings describe the real sequence.
|
|
- [x] Unit tests cover every new behavior; 100% coverage maintained.
|