console test: each capability field absent or false on its own, keyed, blocks eligibility (final review Task 10)
The older unknown-field fixtures also lacked the secrets key, so a permissive nil (absent read as yes) would have been hidden behind the key check. These are otherwise-eligible, keyed boxes with hibernation_configured, serves_shared_pool and accepts_inbound each absent on its own and each explicitly false on its own; every one must be ineligible, with the C16 reason it earns. Checked against a mutant that reads absent as yes: the three absent cases fail it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+39
−0
internal/console/regioncandidates_test.go+39 −0
diff --git a/internal/console/regioncandidates_test.go b/internal/console/regioncandidates_test.go| index 84cce3f3a..9731dee64 100644 |
| --- a/internal/console/regioncandidates_test.go |
| +++ b/internal/console/regioncandidates_test.go |
| @@ -261,6 +261,45 @@ func TestRegionCandidatesNeedPositiveEligibility(t *testing.T) { |
| } |
| } |
| +// Task 10 (final review, MUST FIX): each capability field ABSENT on its |
| +// own, and each explicitly FALSE on its own, with everything else eligible |
| +// and the key present. The older fixtures that left fields absent also |
| +// lacked the key, so a permissive nil (absent read as yes) would have been |
| +// hidden behind the key check. Unknown is not yes (spec §6.1). |
| +func TestEachCapabilityFieldAloneBlocksEligibility(t *testing.T) { |
| + cases := []struct { |
| + name string |
| + o edgeOpts |
| + reason string |
| + }{ |
| + {"hibernation absent", edgeOpts{shared: bp(true), inbound: bp(true), fp: testKeyFP}, "not-eligible"}, |
| + {"hibernation false", edgeOpts{hib: bp(false), shared: bp(true), inbound: bp(true), fp: testKeyFP}, "not-hosting"}, |
| + {"shared pool absent", edgeOpts{hib: bp(true), inbound: bp(true), fp: testKeyFP}, "not-eligible"}, |
| + {"shared pool false", edgeOpts{hib: bp(true), shared: bp(false), inbound: bp(true), fp: testKeyFP}, "not-eligible"}, |
| + {"inbound absent", edgeOpts{hib: bp(true), shared: bp(true), fp: testKeyFP}, "not-eligible"}, |
| + {"inbound false", edgeOpts{hib: bp(true), shared: bp(true), inbound: bp(false), fp: testKeyFP}, "not-eligible"}, |
| + } |
| + for _, c := range cases { |
| + box := edgeJSON("uk-box", "1.2.3.4", "eu-west-2", "uk", c.o) |
| + cands := regionCandidates(views(t, homeBox, box), "ie", testKeyFP) |
| + uk, ok := findCandidate(cands, "uk") |
| + if !ok { |
| + t.Fatalf("%s: no uk candidate", c.name) |
| + } |
| + if uk.Eligible || uk.unavailableReason() != c.reason { |
| + t.Errorf("%s: uk = %+v (reason %q), want ineligible with reason %q", c.name, uk, uk.unavailableReason(), c.reason) |
| + } |
| + if n := eligibleCount(cands); n != 1 { |
| + t.Errorf("%s: %d eligible candidates, want the home alone", c.name, n) |
| + } |
| + } |
| + // The control: the same box with every field present and true is |
| + // eligible, so the cases above fail on the one field they vary. |
| + if uk, _ := findCandidate(regionCandidates(views(t, homeBox, ukEligible), "ie", testKeyFP), "uk"); !uk.Eligible { |
| + t.Fatalf("control: uk = %+v, want eligible", uk) |
| + } |
| +} |
| + |
| // R9: a box must hold the deployment's secrets key to receive placed |
| // instances, and only a CURRENT writer can prove it does not. |
| func TestRegionCandidatesSecretsKey(t *testing.T) { |