Project

General

Profile

Feature #42 » qa_42_soups_proof.txt

Redmine Admin, 06/11/2026 08:19 PM

 
================================================================================
PREUVE QA — Ticket #42 « Endpoint Aggregator /api/projects/{key}/soups »
Epic parent #28 | Repo: omdev/aggregator | Branche: feat/42-soups-endpoint
PR aggregator#4 -> dev | Date: 2026-06-11
Agent: QA manuel (#25). Aucun secret n'est inclus dans cette preuve.
================================================================================

PERIMETRE
- Smoke test du read-plane aggregator : adaptateur Dependency-Track (DTrack)
+ endpoint GET /api/projects/{key}/soups + flag healthz `dtrack`.
- Gate aggregator (CLAUDE.md) : `python -m pytest -q` et `ruff check .` verts
(mypy NON inclus dans le gate aggregator).

--------------------------------------------------------------------------------
1) SUITE COMPLETE PYTEST
--------------------------------------------------------------------------------
$ .venv/bin/python -m pytest -q
........................................................................ [ 90%]
........ [100%]
80 passed in 0.39s
=> 80 passed (conforme au run dev "80 passed x2").

--------------------------------------------------------------------------------
2) RUFF
--------------------------------------------------------------------------------
$ .venv/bin/python -m ruff check .
All checks passed! (exit 0)
=> ruff clean.

--------------------------------------------------------------------------------
3) TESTS SOUPs / DTRACK (ciblés)
--------------------------------------------------------------------------------
$ .venv/bin/python -m pytest -v -k "soup or dtrack"
tests/test_api.py::test_dtrack_enabled_default_off PASSED
tests/test_api.py::test_dtrack_poll_dormant_without_config PASSED
tests/test_api.py::test_dtrack_risk_level_worst_first PASSED
tests/test_api.py::test_dtrack_shape_masks_suppressions_and_builds_envelope PASSED
tests/test_api.py::test_dtrack_shape_top10_cap PASSED
tests/test_api.py::test_soups_endpoint_unknown_key_is_empty_200 PASSED
tests/test_api.py::test_soups_endpoint_dormant_dtrack_empty_200 PASSED
tests/test_api.py::test_soups_endpoint_returns_populated_slice PASSED
tests/test_api.py::test_soups_poll_shapes_and_stores PASSED
=> 9 passed, 71 deselected.

--------------------------------------------------------------------------------
4) SMOKE RUNTIME (TestClient FastAPI, env sans creds DTrack)
--------------------------------------------------------------------------------
- Import adaptateur app.adapters.dtrack : OK
- Cache TTL : 21600 s == 6 h : True
- settings.dtrack_enabled (defaut, sans creds) : False (client DTrack dormant)
- GET /healthz -> 200 ; upstreams.dtrack : False (flag dormant cable)
- GET /api/projects/__no_such_key__/soups -> 200
* tous les champs requis presents : True
{key, risk_level, total_vulnerabilities, by_severity, components,
top_3_critical, suppressions, generated_at}
* key estampillee : True ("__no_such_key__")
* enveloppe vide : risk_level="clean", total_vulnerabilities=0,
by_severity all-zero, components=[], top_3_critical=[], suppressions=0
=> Degradation en 200 enveloppe vide schema-valide (jamais 404/500). OK

--------------------------------------------------------------------------------
5) MASQUAGE DES SUPPRESSIONS (_shape direct)
--------------------------------------------------------------------------------
Entree: metrics suppressed=5 ; finding critique SUPPRIME (CVE-SUPP) sur libbar.
Resultat:
- suppressions : 5 (compte seul expose)
- top_3_critical ids : ['CVE-A'] -> CVE-SUPP ABSENT : True
- composant libbar : vulnerabilities=1, critical=0 -> finding supprime exclu : True
=> Faux positifs / relances jamais comptes dans totals/by_severity/components/top_3.
Seul un compteur opaque `suppressions` est expose. OK

--------------------------------------------------------------------------------
6) GATING DES CREDENTIALS (app/config.py)
--------------------------------------------------------------------------------
dtrack_enabled := bool(dtrack_url AND dtrack_api_key)
=> Le client DTrack reste dormant tant que DTRACK_URL + DTRACK_API_KEY non definis.
(Valeurs de secrets NON imprimees.)

--------------------------------------------------------------------------------
7) DOCUMENTATION DU SCHEMA (docs/SBOM.md)
--------------------------------------------------------------------------------
- Endpoint, schema de reponse complet, contrat d'enveloppe vide documentes.
- Cache 6h documente (section "6h cache").
- Masquage des suppressions documente (section "Suppressions are MASKED").
- Note : la tendance 30 jours provient de l'export Prometheus (comme Security Ops),
PAS de cet endpoint -> conforme a la spec, ce n'est pas une lacune.

================================================================================
MATRICE DES CRITERES D'ACCEPTATION
================================================================================
AC1 GET /soups renvoie {key, risk_level, total_vulnerabilities, by_severity,
components(top-10), top_3_critical, suppressions, generated_at} ........ OK
AC2 Donnees mises en cache, rafraichissement 6h (TTL=21600s) ............... OK
AC3 Faux positifs/relances (suppressions) jamais dans la reponse
(masquage totals/by_severity/components/top_3 ; compte seul expose) .... OK
AC4 Aggregator seule source ; client DTrack dormant sans creds ;
degradation 200 enveloppe vide (jamais 404/500) ...................... OK
AC5 Schema de reponse documente (aggregator/docs/SBOM.md) ................. OK
NOTE Tendance 30j via export Prometheus (docs/SBOM.md) — per-spec, pas une lacune.

VERDICT : PASS — tous les criteres OK. Le ticket reste en QA.
================================================================================
    (1-1/1)