Skip to content

[Epic] Diff-driven & scenario-based E2E testing for Cozystack #2847

Description

@myasnikovdaniil

Goal

Make Cozystack's E2E testing fast, scenario-driven, and trustworthy enough that we can cut releases faster and with more confidence. Two complementary tracks: (1) diff-driven install so a PR's CI installs only what the changed app actually needs, and (2) scenario coverage (install, upgrade, per-app workloads) so the major usage paths are continuously exercised.

Status as of 2026-10-01

Checked against main at bc400dff1.

Three tasks are done, the .deps pivot, the install selector (select-install.sh, #3279) and the install smoke scenario (Track C). Two are obsolete as written, the test-minimal bundle and the COZYSTACK_ENABLED_PACKAGES wiring, because the design moved to select-install.sh --disabled in #4022. select-install.sh is still not invoked by any workflow, so its closure has never been checked against a real install.

The PR lanes changed under this epic. #4020 (merged 2026-09-07) moved the PR lane and the fork lane to Talos containers and they run the full suite there, QEMU stays in nightly and e2e-tag. Install takes about 28 min on the container lane, not the ~18 min this epic started from. I measured 62 PR e2e jobs from 2026-09-28 to 09-30 (install step median 1684 s), and Run E2E tests was full-shaped in 73% of them, scoped in 23% and skipped in 5%, classified by step duration. Install is paid in all three cases. The replay in #3817 of the last 150 merges to main agrees, 70.7% full-suite after its change, 80.0% before. So most runs escalate and install selection can only save on the scoped quarter. The window is three days and heavy on re-runs, so read it as a rough number.

That answers the measurement the track was waiting for, at least roughly. The "~60% of PRs touch one app" payoff does not hold. What is left to decide is whether a saving on a quarter of runs pays for the wiring, and that needs a look at the escalation side first, #4008 (broad selector tier) is open for that.

Track B is #3276, still open, conflicting and CHANGES_REQUESTED (2026-09-29). It needs a rework on the container lane, not a rebase.

Rationale

Every E2E run installs the isp-full bundle before any app test. A diff-driven-install design proposed computing the minimal install set from the PR diff using per-app PackageSource dependency lists, targeting a drop from the install time for PRs that touch one app. The selector script and the test-selection foundation it builds on landed in #2559. This epic operationalizes that design and folds in the in-flight upgrade-test work so install, upgrade and app scenarios are tracked under one roof.

The "~60% of PRs touch one app" and "~6-8 min" numbers were the original design estimates and were never measured on their own. The measurements in the status above say most runs escalate to the full suite, as docs/agents/e2e-testing.md (the TIA section) already said.

Test selection is default-on since #2559, with full-e2e as the opt-out that forces the whole suite. There is no e2e-tia label and never was. Install selection, when it is wired, has to pick its own default.

Supersedes #98 and #759. Both predate the current Package/PackageSource/bundles.enabledPackages model, and their goals (a basic install smoke test, scenario-based regression coverage) are covered by the tasks below.

Tasks

Track A, diff-driven install

  • Land hack/e2e-apps/install.deps plus per-app .deps leaf files with a static validator. Superseded by test(e2e): diff-driven install selector select-install.sh #3279. The selector reuses the real PackageSource graph in packages/core/platform/sources/ directly, so there are no parallel dependency files to keep in sync.
  • Add hack/select-install.sh and hack/select-install_test.bats. Delivered in test(e2e): diff-driven install selector select-install.sh #3279. It maps the suite names select-e2e.sh emits back to their *-application PackageSource, walks spec.variants[].dependsOn forward to the transitive closure (seeding cozystack.cozystack-engine), and has a --validate mode for graph reachability, cycles and the suite-to-source mapping. It runs on every PR through make unit-tests, and hack/select-e2e_test.bats asserts the suite-to-source round trip in both directions (ci: select-e2e maps only *-application sources, so kuberture and securitygroup suites are never selected by dependency #3665).
  • Land feat(platform, tests): select E2E packages and declare controller dependencies #4022: select-install.sh --disabled <suites> emits the bundles.disabledPackages list for an ordinary variant, plus the mongodb-application and seaweedfs-application dependsOn edges it needs and the kubernetes-nodes-application mapping. Open, CHANGES_REQUESTED. The 2026-09-25 review asked for a body that mentions the two edges and the mapping change, the head was pushed again on 2026-10-01 and no check is failing on it now.
  • Add the test-minimal bundle variant and the bundles.testMinimal knob. Superseded by feat(platform, tests): select E2E packages and declare controller dependencies #4022. packages/core/platform/templates/bundles/ still holds only iaas, naas, paas and system, and nothing needs a new one.
  • Wire hack/e2e-install-cozystack.bats to read COZYSTACK_ENABLED_PACKAGES. Obsolete mechanism. The install Package is generated by hack/e2e-platform-packages.sh now, and it already emits a disabledPackages list for the container lane (LINSTOR and kubevirt-cdi). The wiring task is the next one.
  • Wire select-install.sh --disabled into hack/e2e-platform-packages.sh and add a Select install components step to the PR and fork workflows. Nothing under .github/ references select-install yet. Five workflows run Chainsaw now (pull-requests, e2e-fork, e2e-tag, nightly and e2e-proxmox), so the task has to say which lanes get it. The PR and fork lanes are where install time is paid on every push. full_suite_pattern in hack/select-e2e.sh lists four of the five workflows and not e2e-proxmox. A full-suite answer from select-e2e.sh still has to become an empty disable list, which needs an escalation signal out of the selector.
  • Capture install timing durably: hack/install-summary.sh or a step in cozyreport.sh writing install.duration_seconds and the HR timings, with a regression detector. Not started, hack/install-summary.sh does not exist. The 62-job number above was read by hand from step durations (gh run view --json jobs), so it is not reproducible from the repo. Keep this task only if we want the number to stay visible.
  • Document install-selection semantics in .github/PULL_REQUEST_TEMPLATE.md and docs/agents/e2e-testing.md. Test-selection semantics are already in the TIA section of that doc, including the escalation lists, the full-e2e label and the per-path coverage rule. The PR template has no e2e section.
  • Soak (no code change, ~2 weeks): median install time on scoped versus full runs, require at least 50% reduction on app-only runs and zero green-on-full / red-on-minimal divergences before promotion. Blocked on the wiring task above.
  • Promote to default in a separate PR after soak data is published. Test selection is already default-on, so this is about the install side only.

Track B, upgrade scenario

Track C, install smoke scenario (replaces #98)

  • hack/e2e-install-cozystack.bats is the canonical install smoke scenario that Add simple test with kind #98 asked for. docs/agents/e2e-testing.md (the "install gate must have teeth" section) names it as the install gate with the fail-if-any-HR-not-Ready contract, implemented by cozy_wait_all_helmreleases_ready. The kind + paas-hosted approach from Add simple test with kind #98 is obsolete.

Related work tracked elsewhere

Prerequisites

Out of scope

  • Rewriting the BATS harness or the Talos-based runner provisioning.
  • Production install-path behaviour: the default, isp-full, isp-hosted and isp-full-generic variants are untouched.

Activity

  1. added
    kind/featureCategorizes issue or PR as related to a new feature
    epicA large development increment that brings definite value to Cozystack users
    area/ciIssues or PRs related to CI workflows, GitHub Actions, automation
    area/testingIssues or PRs related to testing (e2e, bats, unit tests)
    on Jun 8, 2026
  2. added
    triage/acceptedIndicates an issue is ready to be actively worked on
    priority/important-longtermImportant over the long term, but may not be staffed and/or may need multiple releases to complete
    on Jul 1, 2026
  3. myasnikovdaniil commented on Jul 8, 2026

    @myasnikovdaniil
    ContributorAuthor

    Status update (2026-07-08)

    Track C (install smoke) — effectively done: hack/e2e-install-cozystack.bats exists; only the doc-as-canonical step remains.

    BATS → Chainsaw migration — split out of this epic into its own tracking issue #2979 with PR #2826 (approved, still a draft — needs un-drafting + merge).

    Track A (diff-driven install) — still greenfield. Verified against main: hack/select-e2e.sh (the test-selection selector) exists, but none of the install-side artifacts do — no hack/select-install.sh, no hack/e2e-apps/install.deps / per-app *.deps, no test-minimal bundle. The data model is ready (select-e2e.sh already walks the PackageSource dependsOn graph), so the first deliverable is install.deps + a static validator, which then unblocks select-install.sh.

    Track B (upgrade scenario) — #2401 still a draft (CHANGES_REQUESTED), stalled.

  4. myasnikovdaniil commented on Aug 14, 2026

    @myasnikovdaniil
    ContributorAuthor

    State refresh, 2026-08-13

    Body re-verified against main at 09dc7f47f. Three of the twelve tasks are done (the .deps pivot, select-install.sh in #3279, and Track C's install smoke doc) and one is obsolete: #2401 was closed without merge, so Track B is now #3276, which is open, CHANGES_REQUESTED and currently conflicting. Two premises in the original body were wrong and are corrected inline: there is no e2e-tia label and never was (git log -S'e2e-tia' returns nothing) because #2559 shipped test selection default-on with full-e2e as the opt-out, and the LINSTOR/MetalLB post-install work has moved out of the bats @test bodies into hack/e2e-post-install-prep.sh. The one fact worth acting on: hack/select-install.sh is not reachable from CI, nothing under .github/ invokes it, so its closure is unit-tested but has never been validated against a real install. Track A is therefore re-ordered rather than re-scoped. The install-telemetry task becomes a prerequisite for the three implementation tasks, because the "~60% of PRs touch one app" payoff has never been measured and §7 of docs/agents/e2e-testing.md records that most PRs legitimately escalate to the full suite. The escalation surface moved three times in the six days to 2026-08-10 and settled when #3434 closed on 2026-08-13, so any measurement should record the commit it was taken at. Also folded in: the selector correctness bugs #3392, #3330 and #3665 (fixed by #3670 and #3441) and the fact that the suite now runs in three lanes, which changes what the CI wiring task has to cover. Nothing new is being added to scope here.

  5. myasnikovdaniil commented on Oct 2, 2026

    @myasnikovdaniil
    ContributorAuthor

    State refresh, 2026-10-01

    Body re-checked against main at bc400dff1. test-minimal and the COZYSTACK_ENABLED_PACKAGES wiring are obsolete, the vehicle for Track A is #4022 (select-install.sh --disabled). select-install.sh is still not invoked by any workflow.

    The measurement the track waited on is in the body now. On the container lane install takes about 28 min (median of 62 PR jobs, 2026-09-28 to 09-30), and the suite step was full-shaped in 73% of those jobs, scoped in 23% and skipped in 5%, with install paid in all of them. #3817 found the same from the other side, 70.7% of the last 150 merges to main still run the full suite. So the "~60% of PRs touch one app" figure does not hold and install selection can only save on the scoped quarter. As I noted in #3278, narrowing what an escalation escalates to comes first, #4008 is open for that. I read the numbers by hand from step durations, the window is three days and heavy on re-runs.

    Track B: #3276 needs a rework on the container lane, details are in the body.

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

Metadata

Metadata

Labels

area/ciIssues or PRs related to CI workflows, GitHub Actions, automationarea/testingIssues or PRs related to testing (e2e, bats, unit tests)epicA large development increment that brings definite value to Cozystack userskind/featureCategorizes issue or PR as related to a new featurepriority/important-longtermImportant over the long term, but may not be staffed and/or may need multiple releases to completetriage/acceptedIndicates an issue is ready to be actively worked on

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions