Skip to content

test: no test pins the exact boundary of 18 named bounds #1111

Open

Description

@OmarAlJarrah

Problem

A named bound (maxX or MaxX) caps a walk, a chain or a count. For 18 of the 38 comparisons against one outside test files, moving the comparison one off (> to >=, >= to >, < to <=, <= to <) leaves go test ./... green. A bound documented as N can then admit N−1 or N+1 unnoticed, and a change that moves where a bound cuts cannot show what it moved.

Two examples:

  • operation/multipart.go:189, if hops > maxPartRefHops (16). The multipart tests build chains within the bound and past it, and none of them notices the walk cutting one hop earlier.
  • schema/discriminator.go:367, depth < maxDiscriminatorAncestorDepth (256). TestAllOf_DiscriminatorValueChainDeeperThanCap straddles the cap at 255 and 260 links, not at the cap and one past it.

The comparisons that survive, under compilers/openapi/internal/ except the last; where a line compares twice, the one against the bound is the one moved:

  • annotation/rawjson.go:72: if depth > maxRawDepth
  • annotation/unknown.go:250: if len(fresh) > MaxUnknownKeys
  • bind/documents.go:268: if d.cfg.Through == nil || passes >= maxPasses
  • diag/diag.go:493: for rest := err.Error(); rest != "" && out.Len() < MaxQuotedErrorBytes;
  • merge/canonical.go:17: if depth > maxJudgeDepth
  • merge/fold.go:47: if len(decls) > maxFoldDeclarations
  • merge/typejudge.go:81: if depth > maxJudgeDepth
  • merge/typejudge.go:567: if !ok || depth > maxJudgeDepth
  • nodeview/nodeview.go:268: if v.cachedPairs+held > maxCachedPairs
  • nodeview/nodeview.go:611: for i := 0; n != nil && n.Kind == yaml.AliasNode && i <= maxAliasChain; i++
  • oas/engine.go:124: if depth <= MaxDepth && w.budget >= 0
  • openapitest/corpus.go:115: if depth >= MaxTreeDepth
  • operation/multipart.go:189: if hops > maxPartRefHops
  • operation/multipart.go:283: if depth > maxBodyAliasHops
  • overlay/sequence.go:263: if depth > maxWeighDepth || w.onPath[n]
  • schema/discriminator.go:367: for depth := 0; depth < maxDiscriminatorAncestorDepth && len(level) > 0; depth++
  • sourceindex/sourceindex.go:173: if depth <= maxTrackedDepth
  • ir/types.go:142: for depth := 0; depth < maxDomainDepth && len(frontier) > 0; depth++

The other 20 redden at least one test when moved one off.

Cause

Boundary tests straddle a bound with a margin instead of sitting on it and one past it, or no committed fixture reaches the bound at all.

Direction

A proposal: give each bound a case at exactly the bound and one past it, reading the constant (through export_test.go where it is unexported) rather than spelling its value. Where the exact value has no observable effect, as for a guard that only has to stop a hostile input somewhere, the bound's comment says so and the site is left unpinned on purpose.

Out of scope

Bounds compared without a max name (literal limits, budgets counted down to zero) were not swept. Tests that pin a diagnostic's wording, including the bound's value it names, are a separate matter: they fail loudly when a bound changes.

Related: #919

Priority: P4, rule 1: a test task that changes no lowering, validation, IR or emit-contract behaviour. Each of the 38 lines git grep -nE '[^=!<>](<=|>=|<|>) ?[a-z]*[mM]ax[A-Z]\w*|[mM]ax[A-Z]\w* ?(<=|>=|<|>)[^=<>-]' -- '*.go' ':!*_test.go' ':!internal/lintrules/testdata' lists, moved one off in turn, then go test -count=1 ./... → 18 green (morphic @49fb350b, PR #1110's head; the 15 files holding those 18 lines are identical on main @ff3fff4d).

Activity

  1. added
    priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formats
    on Oct 24, 2026
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

    priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatstype:testTests only

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions