Skip to content

e2e: the mirror resolver derives "could not ask" five different ways, and caches the answer for the whole sandbox #3682

Closed as not planned

Description

Every cluster call in the e2e mirror resolver has three outcomes: the cluster says no, the cluster says yes, and the call could not be made. A shell exit code carries two. So the third outcome has to be derived at each call site, and because the available signal differs per verb, it is derived differently every time.

In hack/e2e-chainsaw/_lib/ghcr-mirror.sh as it stands, five sites derive it five ways:

  • get deploy distinguishes it by the text of stderr, matching NotFound
  • rollout status distinguished it by exit code, which was wrong: that command also exits non-zero on a broken or interrupted watch
  • the follow-up get -o jsonpath distinguishes it by field value, reading Available as True / False / empty
  • apply distinguished it by exit code with the reason discarded to /dev/null, and now returns the reason as text
  • logs in the diagnostics distinguishes it by separating the read's exit code from the filter's

Each of those five has produced a defect at some point, and each was fixed on its own terms. That is the tell: the problem is not attention. The construction requires inventing the signal again at every call, so the failure recurs wherever the next call is added.

Two things make it expensive rather than untidy.

The decision is cached for the whole sandbox. A misclassified "no" is therefore not a mistake in one step, it is a permanent property of the run: every later suite reads the cached answer and never re-asks. This is what makes all five sites load-bearing rather than cosmetic.

The tri-state is implicit and spread across branches. It is encoded today by two variables, an endpoint that is either empty or a URL, and a cache flag that is 0 or 1. "Could not ask" is not a value but a combination, endpoint="" together with cache=0, assembled by hand in each branch. State spread across branches produces branch-specific bugs the same way a decision spread across branches produces branch-specific errors.

A shape where the question does not arise: one probe that returns yes / no / unknown and knows internally how to derive the third outcome for its own kind of call, plus one caching rule stated once, that yes and no are cached and unknown never is. Execution branches would then execute rather than decide, and there would be one place to get it wrong instead of five. It moves the question out of the branches and into the type.

Not urgent: the current code is green and covered, and each patch so far has been correct on its own terms. Worth doing before the sixth call site is added, since every addition pays the derivation cost again.

Activity

  1. added
    kind/cleanupCategorizes issue or PR as related to cleanup of code, process, or technical debt
    area/testingIssues or PRs related to testing (e2e, bats, unit tests)
    triage/not-reproducibleIndicates an issue can not be reproduced as described
    and removed
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 23, 2026
  2. lexfrei commented on Sep 23, 2026

    @lexfrei
    ContributorAuthor

    The mirror resolver is gone: #4020 deleted hack/e2e-chainsaw/_lib/ghcr-mirror.sh together with the mirror, so none of these call sites exist anymore.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/testingIssues or PRs related to testing (e2e, bats, unit tests)kind/cleanupCategorizes issue or PR as related to cleanup of code, process, or technical debttriage/not-reproducibleIndicates an issue can not be reproduced as described

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions