ca78c17b29
gates / gates (push) Successful in 19s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
56 lines
2.1 KiB
Go
56 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.dooplex.hu/admin/felhom-agent/internal/hub"
|
|
"gitea.dooplex.hu/admin/felhom-agent/internal/osupdate"
|
|
)
|
|
|
|
type r866Fetcher struct{ err error }
|
|
|
|
func (f r866Fetcher) FetchDesiredState(context.Context) (*hub.DesiredStateResponse, error) {
|
|
if f.err != nil {
|
|
return nil, f.err
|
|
}
|
|
r := &hub.DesiredStateResponse{}
|
|
r.DesiredState.OSUpdate = &hub.WireOSUpdate{Ring: 1, Enabled: true}
|
|
return r, nil
|
|
}
|
|
|
|
// R-866 (v0.144.0). THE NIGHT'S SHAPE (A3, Tester 1 box, hub blocked): `selftest=os-update: desired state: hub:
|
|
// transport error … connect: invalid argument` — the debug pass could not run at all. Now it runs from the block the
|
|
// daemon saved, and its header says so.
|
|
// COMPANION RED-PROOF: return at once on a fetch error in selftestOSBlock → "the pass did not run from the saved block".
|
|
func TestR866_DebugPassUsesTheSavedBlockWhenTheHubIsAway(t *testing.T) {
|
|
dir := t.TempDir()
|
|
leg := &osupdate.Leg{PlanDir: dir}
|
|
r := &hub.DesiredStateResponse{}
|
|
r.DesiredState.OSUpdate = &hub.WireOSUpdate{Ring: 0, Enabled: true}
|
|
leg.OnDesiredState(context.Background(), r) // the daemon received a block and saved it
|
|
away := r866Fetcher{err: errors.New("hub: transport error: connect: invalid argument")}
|
|
b, src, ok := selftestOSBlock(context.Background(), away, dir)
|
|
if !ok || b == nil || b.Ring != 0 {
|
|
t.Fatalf("the pass did not run from the saved block: ok=%v block=%+v src=%q", ok, b, src)
|
|
}
|
|
if !strings.HasPrefix(src, "SAVED(") || !strings.Contains(src, "hub unreachable") {
|
|
t.Fatalf("the header must say the block is the saved one: %q", src)
|
|
}
|
|
// the hub reachable: its block wins, and the header says "hub"
|
|
b, src, ok = selftestOSBlock(context.Background(), r866Fetcher{}, dir)
|
|
if !ok || b.Ring != 1 || src != "hub" {
|
|
t.Fatalf("hub block not used: %+v %q", b, src)
|
|
}
|
|
}
|
|
|
|
// No hub and nothing saved: the pass does not run on a guessed block.
|
|
func TestR866_NoHubNoSavedBlockDoesNotRun(t *testing.T) {
|
|
_, why, ok := selftestOSBlock(context.Background(), r866Fetcher{err: errors.New("down")}, t.TempDir())
|
|
if ok || !strings.Contains(why, "no saved block") {
|
|
t.Fatalf("ok=%v why=%q", ok, why)
|
|
}
|
|
}
|