f62a115891
New internal/offsiteheal, the sibling of pbsdrheal: it acts ONLY on the state the box declares, sustained across two distinct reports, re-staging the stored credential before ever minting a new one. A healthy box is a pure no-op; it never blind-timer-reissues and never re-runs a provisioning step. RESTAGE IS POSSIBLE because the stored value survives a consume — established from the schema and ConsumeOneTimeSecret (which stamps consumed_at and nothing else), not inherited from the PBS analogy, and pinned by a test that asserts the SAME value comes back. reportHasOffsite is TIGHTENED to require enabled:true. Its comment asserted that presence == applied-on-the-box, and the declaration deliberately breaks that premise; left alone it would have read a request for help as proof the tier was applied. Provably a no-op for every report shape that existed before, because an attached object has always carried enabled:true. R-192's guard half is CLOSED BY REPLACEMENT: the delivery checker's counting inference read the OLDEST 500 reports after a consume — all predating a rebuild, which is why demo-hp sat stranded for 108 reports under a confident regressed-shape verdict. A declaration outranks both inferred shapes, and the checker stands down with a record so the two mechanisms cannot double-issue. No escrow ceremony is ever run or requested: credential automatic, key customer-present.
48 lines
2.4 KiB
Go
48 lines
2.4 KiB
Go
package monitor
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/offsite"
|
|
"gitea.dooplex.hu/admin/felhom-hub/internal/offsiteheal"
|
|
)
|
|
|
|
// R-192's guard half, closed by REPLACEMENT (R-204 item 4).
|
|
//
|
|
// The counting guard inferred the situation from how many of the OLDEST 500 reports after a consume
|
|
// carried an offbox target. On demo-hp all 500 predated the rebuild, so the checker confidently
|
|
// reported the REGRESSED shape and declined to heal — for 108 reports, while the box sat stranded.
|
|
// A declaration needs no window and no count, and it OUTRANKS both inferred shapes.
|
|
|
|
func TestShapeOf_DeclarationOutranksBothInferredShapes(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
status offsite.DeliveryStatus
|
|
declared bool
|
|
want deliveryShape
|
|
}{
|
|
{"burned, undeclared", offsite.DeliveryStatus{OffsiteReportsSinceConsume: 0, ReportsSinceConsume: 9}, false, shapeBurned},
|
|
{"regressed, undeclared", offsite.DeliveryStatus{OffsiteReportsSinceConsume: 500, ReportsSinceConsume: 500}, false, shapeRegressed},
|
|
// THE demo-hp SHAPE: the counts say "regressed" from a window that predates the rebuild, and
|
|
// the box says it needs a credential. The declaration wins.
|
|
{"regressed counts BUT the box declares", offsite.DeliveryStatus{OffsiteReportsSinceConsume: 500, ReportsSinceConsume: 500}, true, shapeDeclared},
|
|
{"burned counts AND the box declares", offsite.DeliveryStatus{OffsiteReportsSinceConsume: 0, ReportsSinceConsume: 9}, true, shapeDeclared},
|
|
}
|
|
for _, tc := range cases {
|
|
if got := shapeOf(tc.status, tc.declared); got != tc.want {
|
|
t.Errorf("%s: shapeOf = %q, want %q", tc.name, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The declared-state string is duplicated in three packages (the controller declares it, this checker
|
|
// recognises it, the reconciler acts on it). A silent drift between them would make the whole feature
|
|
// inert with every test still green — so the two hub-side copies are pinned to each other here. The
|
|
// controller's copy is pinned by its own report-shape test and by the live validation.
|
|
func TestDeclaredStateStringMatchesTheReconciler(t *testing.T) {
|
|
if declaredNeedsCredential != offsiteheal.StateNeedsCredential {
|
|
t.Fatalf("declared-state drift: monitor has %q, offsiteheal has %q — the checker would never stand down and both mechanisms would heal the same customer",
|
|
declaredNeedsCredential, offsiteheal.StateNeedsCredential)
|
|
}
|
|
}
|