Skip to content

test(ci): re-integrate coverage lost with dead FullGas relics (REINTEGRATE-ORPHAN-TESTS)#20

Merged
davidp57 merged 12 commits into
developfrom
feature/reintegrate-orphan-tests
Jul 12, 2026
Merged

test(ci): re-integrate coverage lost with dead FullGas relics (REINTEGRATE-ORPHAN-TESTS)#20
davidp57 merged 12 commits into
developfrom
feature/reintegrate-orphan-tests

Conversation

@davidp57

@davidp57 davidp57 commented Jul 11, 2026

Copy link
Copy Markdown
Member

Context

A coverage audit found 62 features tested only by the ~194 dead FullGas relics under
tests/dcs/noPlayer/ (no @tier header, dofile of an absent DCS-CTLD_FG/recette/setup.lua,
missing ctld_test framework — they execute nothing). Breakdown:

  • 46 GAP — behaviour alive in src/, tested nowhere active → re-integrated by this lot.
  • 10 COVERED — false orphans, already covered elsewhere → relic safe to purge, no action.
  • 6 FULLGAS — deep refactors / visual check, deferred to FullGas (dev/fullgas-report.md).

This lot rebuilds the 46, busted-first (mockable → tests/ci/ in CI; only real-engine
behaviour stays as live-DCS tagged scenarios). It precedes and unblocks the planned
CLEANUP-LEGACY-DCS-TESTS purge.

See .backlog/REINTEGRATE-ORPHAN-TESTS/PRD.md for the full audit + the 7-ticket plan.

This PR so far (draft)

  • Lot backlog: PRD + 7 tickets.
  • Ticket 01 pilotcrate_lifecycle_spec.lua: CTLDCrateManager loadCrate/unpackCrate/
    registerMMCrate + events/guards (F-027/028/030/041). Pilot subset (no static respawn) to
    validate the busted pattern in CI; F-029/031/032 + tickets 02–06 follow once green.

Draft until the busted lots (01–06) are complete; ticket 07 (live-DCS) is validated separately
against a running mission.

🤖 Generated with Claude Code

Summary by Sourcery

Reintegrate test coverage for previously untested CTLD features and DCS behaviours, and wire them into CI and integration tooling.

New Features:

  • Add busted unit test suites covering crate lifecycle, deployment managers, menu gating and player wiring, legacy API wrappers, scene structures, minefield logic, JTAC configuration, and recon auto-refresh.
  • Introduce live-DCS scenarios for beacon lifecycle, recon scan payloads, and native vehicle loading/unloading, tagged for automated scenario running.

Enhancements:

  • Update the integration runner to authenticate against dcs-bridge using a Bearer token instead of the legacy X-API-Key header.
  • Ensure CI Lua test loading includes the legacy v1→v2 API wrappers to keep compatibility functions under test.
  • Extend the internal backlog with a PRD and ticket breakdown for the REINTEGRATE-ORPHAN-TESTS lot, including status and branch metadata.

Documentation:

  • Document the REINTEGRATE-ORPHAN-TESTS lot, its audit of orphaned features, and the seven-ticket plan to restore coverage.
  • Add ticket-specific backlog documents describing scope and acceptance criteria for crate lifecycle, legacy API wrappers, scenes/minefields, deploy managers, menu gating and player wiring, JTAC/recon, and live-DCS coverage.

Tests:

  • Add comprehensive busted unit specs for CTLDCrateManager lifecycle and events, deployment managers for AA systems, FOBs, and vehicle packing, F10 menu gating, legacy API wrappers, scene/minefield models, and JTAC/recon behaviour.
  • Add DCS no-player scenarios to validate beacon lifecycle, recon scan payloads, and native vehicle cargo handling against the real engine.

davidp57 and others added 2 commits July 11, 2026 16:30
Coverage audit found 62 features tested ONLY by the dead FullGas relics under
tests/dcs/noPlayer/. 46 are genuine gaps (behaviour alive in src/, tested
nowhere active), 10 are false orphans already covered elsewhere, 6 need
FullGas (deep refactors / visual check — logged in dev/fullgas-report.md).

This lot re-integrates the 46 gaps, busted-first (mockable -> tests/ci/ in CI;
only real-engine behaviour stays as live-DCS tagged scenarios). It precedes and
unblocks the planned CLEANUP-LEGACY-DCS-TESTS purge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lot)

CTLDCrateManager loadCrate/unpackCrate/registerMMCrate + their OnCrate*/
OnMMCrateDetected events and guards — previously covered only by dead relics
F-027/F-028/F-030/F-041. Complements crate_manager_spec.lua (entity level only).

Pilot subset (no static respawn): validates the busted pattern in CI before the
rest of the lot. F-029/031/032 (with addStaticObject mock) follow once green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Reviewer's Guide

Reintegrates previously orphaned CTLD coverage by adding busted unit tests for crate lifecycle, deploy managers, menu gating, legacy wrappers, JTAC/recon behaviour plus a few live-DCS scenarios, and wires CI/DCS helpers and backlog docs to track the REINTEGRATE-ORPHAN-TESTS lot.

Sequence diagram for updated dcs-bridge auth in integration runner

sequenceDiagram
    participant IntegrationRunner
    participant DCSBridge

    IntegrationRunner->>IntegrationRunner: http_post
    IntegrationRunner->>DCSBridge: POST /api/exec Authorization Bearer api_key
    DCSBridge-->>IntegrationRunner: response
Loading

File-Level Changes

Change Details Files
Switch integration runner HTTP auth from X-API-Key header to Bearer token to match updated dcs-bridge authentication.
  • Update exec API requests to send Authorization: Bearer <api_key> instead of X-API-Key
  • Keep content type and request body structure unchanged
tools/integration-runner/run_scenarios.py
Load legacy v1→v2 CTLD API wrapper module in the CI test harness so new busted specs can exercise legacy entry points.
  • Extend CI Lua loader to dofile the legacy API module after core CTLD scripts
  • Document load order comment for legacy API wrappers
tests/ci/helpers/loader.lua
Document the REINTEGRATE-ORPHAN-TESTS lot and mark it as pending merge with details on gap analysis, tickets, and coverage stats.
  • Update backlog overview to add REINTEGRATE-ORPHAN-TESTS row with status, description, counts, and linkage to cleanup lot
  • Add product requirements doc describing problem, audit, solution and ticket breakdown
  • Add per-ticket specs for crate lifecycle, legacy API, scenes/minefields, deploy managers, menu gating, JTAC/recon, and live-DCS scenarios
.backlog/README.md
.backlog/REINTEGRATE-ORPHAN-TESTS/PRD.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/01-crate-lifecycle.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/02-legacy-api-wrappers.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/03-scenes-minefields.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/04-deploy-managers.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/05-menu-gating-player-wiring.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/06-jtac-recon.md
.backlog/REINTEGRATE-ORPHAN-TESTS/tickets/07-live-dcs-coverage.md
Add busted unit specs for deploy managers covering AA system assembly/repair, FOB lifecycle events, and vehicle packing behaviour.
  • Mock DCS group/static spawning and event dispatcher to test CTLDCrateAssemblyManager deployment and repair paths
  • Verify FOB deployment registration, reverse object lookup, integrity-based destruction and corresponding events
  • Test CTLDVehicleSpawner findPackableVehicles and packVehicle including crate spawning, events, and deferred menu refresh
tests/ci/unit/deploy_managers_spec.lua
Add busted unit specs for F10 menu gating by config/capability and CTLDPlayerManager cargo-event wiring.
  • Build full CTLD menus under different config flags and unit capabilities, asserting presence/absence of sections
  • Exercise menu clearBranch/refreshMenuForGroup behaviour and troop embark filtering by side/capacity/disabled templates
  • Test CTLDPlayerManager updates to loadedVehicles on OnVehicleLoaded/Unloaded events
tests/ci/unit/menu_gating_spec.lua
Add busted unit specs for scene models and minefield spawning logic, asserting structure and mine counts.
  • Load FARP and minefield scene modules and inspect registered models for expected step structure and crate descriptors
  • Stub CTLDObjectRegistry.spawnObject to count mines spawned for various grid configurations
  • Verify setLandMineAuto parameterised layout, single-mine path, and input validation guards
tests/ci/unit/scenes_minefields_spec.lua
Add busted unit specs for CTLDCrateManager lifecycle methods and their event contracts, including mission-maker crates and drop/unload paths.
  • Test loadCrate, unloadCrate, unpackCrate and dropCrate state transitions and event publication with guards for invalid states
  • Mock coalition.addStaticObject/StaticObject.getByName/timer to exercise crate respawn-on-unload and drop impact destruction
  • Validate registerMMCrate registration, duplicate/unknown-type guards, and OnMMCrateDetected publishing
tests/ci/unit/crate_lifecycle_spec.lua
Introduce live-DCS scenarios for beacon lifecycle, vehicle dcs_native load/unload, and recon scan payloads that require the real engine.
  • Implement auto-tier beacon scenario validating dropBeacon, removeClosestBeacon and FOB beacon behaviour via real group spawns
  • Implement auto-tier vehicle scenario validating dcs_native loadVehicle/unloadVehicle state and events using real ground units
  • Implement auto-tier recon scenario spawning a real observer unit and asserting OnReconScan payload/marks against real enemy units
tests/dcs/noPlayer/scenario_beacon_lifecycle.lua
tests/dcs/noPlayer/scenario_vehicle_dcs_native.lua
tests/dcs/noPlayer/scenario_recon_scan_payload.lua
Add busted unit specs for JTAC config defaults, JTAC deregistration behaviour, recon auto-refresh events, and CTLD legacy API wrappers.
  • Assert JTAC drone radius/altitude/config and per-coalition JTAC drone descriptors against current config model
  • Test deregisterJTAC removes registry entries, returns laser codes to pool, stays silent on OnJTACDead, and is idempotent
  • Exercise recon enable/disable auto-refresh toggles and their event payloads
  • Stub manager methods and ctld.logWarning to verify each legacy API wrapper routes to the correct v2 method with preserved args and emits a deprecation warning
tests/ci/unit/jtac_recon_reintegration_spec.lua
tests/ci/unit/legacy_api_spec.lua

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

davidp57 and others added 10 commits July 11, 2026 16:33
…9/031/032)

Adds the static-respawn cases to crate_lifecycle_spec: unloadCrate (LANDED +
OnCrateUnloaded + re-register), dropCrate safe (method=drop) / destroy
(drop_impact + unregister), and the not-loaded guard. Mocks coalition.
addStaticObject + StaticObject.getByName as in crate_manager_spec's spawnCrate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
legacy_api_spec covers all 21 v1→v2 wrappers (Troops/Zones/Crates/Beacon/JTAC):
each routes to the correct v2 manager method with args preserved and logs a
DEPRECATED warning. An is_function guard asserts the routing target actually
exists on the manager. Re-integrates dead relics F-094..F-098.

Also loads src/legacy/legacy_api.lua in the busted helper (loader.lua) — it was
missing from the module list, so the wrappers were unreachable from any spec.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…icket 06)

- F-110: JTAC drone config defaults (droneRadius/droneAltitude/lock) + per-
  coalition JTAC drone descriptors. NB: the relic's JTAC_unitTypeNames key is
  gone — the JTAC role is now declared via isJTAC=true in spawnableCrates;
  re-integrated against the current model, not the dead key.
- F-112: deregisterJTAC is silent (no OnJTACDead), returns the laser code to the
  pool, idempotent, unknown group is a no-op.
- F-011: recon enable/disableAutoRefresh toggle scan.autoRefresh and publish
  OnReconAutoRefresh{Enabled,Disabled} with previous/new state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- F-043/F-091: FARP Alpha (14 steps) and farpScene (6 steps) model structure
  via getModel(), asserting steps/registry keys/polar params against current src.
- F-083/084/085: setLandMine mine counts — staggered formula T(N,R)=R*N-floor(R/2)
  gives 1 / 68 / 11 (verified by running the real src).
- F-087: setLandMineAuto parametric count (39), single-mine branch, and guards.

Loads src/scenes/* and i18n fr/es/ko in setup (same as minefield_spec/i18n_spec),
since loader.lua does not pull those in. Complements minefield_spec (which covers
structure + guards) with the actual counts and the FARP scenes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- F-021/022/023: CTLDCrateAssemblyManager tryUnpackOrRepair — complete assembly
  (OnAASystemDeployed + crates consumed), incomplete (no deploy), repair
  (OnAASystemRepaired). Template pulled from TEMPLATES, no hardcoded types.
- F-012/013: CTLDFOBManager _registerDeployedFOB (OnFOBDeployed + _objectToFOB
  reverse lookup) and onDead/_destroyFOB (integrity threshold + OnFOBDestroyed
  + cleanup).
- F-099: findPackableVehicles + packVehicle (OnVehiclePacked, cratesSpawned
  derived from descriptor.cratesRequired, deferred refresh via scheduleFunction).

Assertions recomputed against current src (M1043 cratesRequired=3, deferred
refresh, _repairFor contract), not the stale relic assumptions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
buildMenu F10 section gating by config flag / transport capability (F-048/049/
050/052/053/054/055/056), clearBranch+repopulate (F-075), refreshMenuForGroup
unknown-group failure shape (F-077), _loadUserConfig ingestion (F-088), troop
Embark filter disabled/side/capacity (F-089), and player OnVehicleLoaded/
Unloaded -> loadedVehicles wiring (F-025).

Deviations recomputed against current src (not the relic intent): FOBs is now a
top-level "FOBs List" section, "Pack Vehicle" -> "Pack Equipt" with a combined
enableFARPRepack/enablePackingVehicles gate, CTLDTroopManager:buildMenu gone ->
buildMenuSection/refreshMenuSection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mock

Two CI-only failures the local harness could not surface:

- F-088 (_loadUserConfig): busted insulates each describe's environment, so a
  bare `ctld_config_user = {...}` landed in the sandbox while _loadUserConfig
  reads the real _G global — it saw nil and created no custom groups (3 templates
  instead of 6). Write/read/restore via _G.ctld_config_user explicitly.
- F-056 (canCarryVehicles): buildFullMenu now stubs Unit.getByName for the build,
  so the vehicle section's findLoadableVehicles gets a real unit object
  (getTypeName/getCoalition/getPoint) instead of crashing on nil. Restored
  immediately after the build to avoid polluting other specs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ket 07)

Three tagged live-DCS scenarios for the relics that need the real engine (spawn,
world events) and can't be busted-mocked:
- scenario_beacon_lifecycle (F-006/007/092): dropBeacon spawn + OnBeaconDropped,
  removeClosestBeacon + OnBeaconRemoved, FOB beacon infinite battery.
- scenario_recon_scan_payload (F-009): scan() OnReconScan payload + marks.
- scenario_vehicle_dcs_native (F-018/019): loadVehicle/unloadVehicle dcs_native.

Parity fixes vs the stale relics: in dcs_native the unit stays alive (relic
expected unit==nil), unload -> WAITING, recon payload exposes totalTargetsDetected.

Validated live against Test_CTLDNEXT_01: BCN 30/30, RCN 10/10, VEH 22/22.

Also migrates the runner auth to Authorization: Bearer <token> (dcs-bridge
LOT-018; /api/exec now requires the SUPERUSER role). Older X-API-Key is rejected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@davidp57 davidp57 marked this pull request as ready for review July 12, 2026 17:44
@davidp57 davidp57 merged commit 5ab9a62 into develop Jul 12, 2026
4 checks passed
@davidp57 davidp57 deleted the feature/reintegrate-orphan-tests branch July 12, 2026 17:44

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Several of the new DCS scenarios (e.g. beacon/vehicle/recon) duplicate common patterns for CTLD-ready guards, double-injection guards, anchor position resolution, and event-capture/cleanup; consider extracting these into a shared helper or template to reduce drift and keep the scenarios focused on scenario-specific assertions.
  • Many of the new busted specs reach into manager internals (e.g. _completeSystems, _fobs, _activeScans, _laserPool, _spawnedStatics); where feasible, prefer asserting through public methods or small helper accessors so that refactors of internal representations don’t require broad test rewrites.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several of the new DCS scenarios (e.g. beacon/vehicle/recon) duplicate common patterns for CTLD-ready guards, double-injection guards, anchor position resolution, and event-capture/cleanup; consider extracting these into a shared helper or template to reduce drift and keep the scenarios focused on scenario-specific assertions.
- Many of the new busted specs reach into manager internals (e.g. `_completeSystems`, `_fobs`, `_activeScans`, `_laserPool`, `_spawnedStatics`); where feasible, prefer asserting through public methods or small helper accessors so that refactors of internal representations don’t require broad test rewrites.

## Individual Comments

### Comment 1
<location path="tools/integration-runner/run_scenarios.py" line_range="263-264" />
<code_context>
+            # endpoint (/api/exec requires the SUPERUSER role). The api_key from the config
+            # is used as that token. (Older builds used an X-API-Key header.)
+            headers={"Content-Type": "application/json",
+                     "Authorization": "Bearer " + api_key},
             method="POST",
         )
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider more robust construction of the Authorization header.

String-concatenating the scheme assumes `api_key` has no extra whitespace or existing scheme. Prefer constructing the header as `f"Bearer {api_key.strip()}"` (or validating/normalizing `api_key` at load time) to avoid subtle auth failures from non-normalized config values.

```suggestion
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {api_key.strip()}",
            },
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +263 to +264
headers={"Content-Type": "application/json",
"Authorization": "Bearer " + api_key},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Consider more robust construction of the Authorization header.

String-concatenating the scheme assumes api_key has no extra whitespace or existing scheme. Prefer constructing the header as f"Bearer {api_key.strip()}" (or validating/normalizing api_key at load time) to avoid subtle auth failures from non-normalized config values.

Suggested change
headers={"Content-Type": "application/json",
"Authorization": "Bearer " + api_key},
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key.strip()}",
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant