//go:build linux package host import ( "os" "path/filepath" "slices" "strings" "testing" ) func plan11Rev4ReplaceRuntimeMask(t *testing.T) { t.Helper() replacement := filepath.Join(filepath.Dir(claimEdgeRuntimeMask), "operator-mask") if err := os.Symlink("/dev/null", replacement); err != nil { t.Fatal(err) } if err := os.Rename(replacement, claimEdgeRuntimeMask); err != nil { t.Fatal(err) } } // A same-boot boot-ID record can be an intent written before mask(2), not // proof that the migration created the mask now at the unit path. Recovery // must leave that ambiguous runtime mask in place. func TestPlan11Rev4IntentBeforeMaskCrashKeepsLaterOperatorMask(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "masked-runtime", &calls) owner := plan9Fix2MaskOwner(t) if err := os.WriteFile(owner, []byte(plan9Fix2Boot(t)), 0600); err != nil { t.Fatal(err) } if err := recoverLegacyClaimEdgeMask(t.Context()); err != nil { t.Fatal(err) } for _, call := range calls { if strings.HasPrefix(call, "unmask ") { t.Fatalf("ambiguous operator mask was lifted: %v", calls) } } if target, err := os.Readlink(claimEdgeRuntimeMask); err != nil || target != "/dev/null" { t.Fatalf("operator mask changed: %q %v", target, err) } } func TestPlan11Rev4IdentityIntentBeforeLinkKeepsLaterOperatorMask(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "masked-runtime", &calls) owner := plan9Fix2MaskOwner(t) token := strings.Repeat("b", 32) anchor := claimEdgeMaskAnchor(token) if err := os.Symlink("/dev/null", anchor); err != nil { t.Fatal(err) } record, err := currentClaimEdgeMask(anchor, plan9Fix2Boot(t), token) if err != nil { t.Fatal(err) } if err = writeClaimEdgeMaskRecord(record); err != nil { t.Fatal(err) } if err = recoverLegacyClaimEdgeMask(t.Context()); err != nil { t.Fatal(err) } if slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("intent authorised a later operator mask: %v", calls) } if target, err := os.Readlink(claimEdgeRuntimeMask); err != nil || target != "/dev/null" { t.Fatalf("operator mask changed: %q %v", target, err) } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("stale intent remains: %v", err) } if _, err = os.Lstat(anchor); !os.IsNotExist(err) { t.Fatalf("stale intent anchor remains: %v", err) } } func TestPlan11Rev4ReleaseKeepsSameTargetOperatorReplacement(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "enabled", &calls) owner := plan9Fix2MaskOwner(t) release, err := quiesceLegacyClaimJournals(t.Context()) if err != nil { t.Fatal(err) } plan11Rev4ReplaceRuntimeMask(t) calls = nil release() if slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("replacement mask was lifted: %v", calls) } if target, err := os.Readlink(claimEdgeRuntimeMask); err != nil || target != "/dev/null" { t.Fatalf("replacement mask changed: %q %v", target, err) } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("stale ownership record remains: %v", err) } } func TestPlan11Rev4CompletedRecoveryKeepsSameTargetReplacement(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "masked-runtime", &calls) owner := plan9Fix2MaskOwner(t) plan11Rev4WriteOwnedMask(t, owner) plan11Rev4ReplaceRuntimeMask(t) calls = nil if err := recoverLegacyClaimEdgeMask(t.Context()); err != nil { t.Fatal(err) } if slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("completed recovery lifted replacement mask: %v", calls) } if target, err := os.Readlink(claimEdgeRuntimeMask); err != nil || target != "/dev/null" { t.Fatalf("replacement mask changed: %q %v", target, err) } } func TestPlan11Rev4OwnedIdentityIsDurableAndCleansUp(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "enabled", &calls) owner := plan9Fix2MaskOwner(t) release, err := quiesceLegacyClaimJournals(t.Context()) if err != nil { t.Fatal(err) } raw, err := os.ReadFile(owner) if err != nil { t.Fatal(err) } record, recorded := decodeClaimEdgeMaskRecord(raw, plan9Fix2Boot(t)) if !recorded { t.Fatalf("ownership record is not a concrete identity: %q", raw) } if ours, identityErr := claimEdgeMaskStillOwned(record); identityErr != nil || !ours { t.Fatalf("ownership does not name the live mask: %v %v", ours, identityErr) } info, err := os.Stat(owner) if err != nil { t.Fatal(err) } if info.Mode().Perm() != 0600 { t.Fatalf("ownership mode = %o, want 0600", info.Mode().Perm()) } if _, err = os.Stat(owner + ".tmp"); !os.IsNotExist(err) { t.Fatalf("durable-write temporary remains: %v", err) } release() if !slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("owned mask was not lifted: %v", calls) } if _, err = os.Lstat(claimEdgeRuntimeMask); !os.IsNotExist(err) { t.Fatalf("owned runtime mask remains: %v", err) } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("owned mask record remains: %v", err) } if _, err = os.Lstat(claimEdgeMaskAnchor(record.Token)); !os.IsNotExist(err) { t.Fatalf("owned mask anchor remains: %v", err) } }