//go:build linux package host import ( "context" "os" "path/filepath" "slices" "strings" "testing" ) var plan9Fix2RuntimeMaskDefault = claimEdgeRuntimeMask // plan9Fix2Systemctl fakes systemctl for a stopped edge whose unit file state // is enabled. It records every call. func plan9Fix2Systemctl(t *testing.T, enabled string, calls *[]string) { t.Helper() if claimEdgeRuntimeMask == plan9Fix2RuntimeMaskDefault { restoreMask := claimEdgeRuntimeMask t.Cleanup(func() { claimEdgeRuntimeMask = restoreMask }) claimEdgeRuntimeMask = filepath.Join(t.TempDir(), "carlos-edge.service") } if enabled == "masked-runtime" { if _, err := os.Lstat(claimEdgeRuntimeMask); os.IsNotExist(err) { if err = os.Symlink("/dev/null", claimEdgeRuntimeMask); err != nil { t.Fatal(err) } } else if err != nil { t.Fatal(err) } } restore := claimSystemctl t.Cleanup(func() { claimSystemctl = restore }) restoreOwner := claimQuiesceOwner t.Cleanup(func() { claimQuiesceOwner = restoreOwner }) claimQuiesceOwner = func() (int, int, error) { return 1 << 30, 1 << 30, nil } claimSystemctl = func(_ context.Context, args ...string) ([]byte, error) { *calls = append(*calls, strings.Join(args, " ")) switch args[0] { case "is-enabled": return []byte(enabled + "\n"), nil case "show": return []byte("inactive\n"), nil case "mask": return nil, os.Symlink("/dev/null", claimEdgeRuntimeMask) case "unmask": err := os.Remove(claimEdgeRuntimeMask) if os.IsNotExist(err) { err = nil } return nil, err } return nil, nil } } func plan9Fix2MaskOwner(t *testing.T) string { t.Helper() restore := claimEdgeMaskOwner t.Cleanup(func() { claimEdgeMaskOwner = restore }) claimEdgeMaskOwner = filepath.Join(t.TempDir(), "edge-mask") return claimEdgeMaskOwner } func plan9Fix2Boot(t *testing.T) string { t.Helper() boot, err := os.ReadFile("/proc/sys/kernel/random/boot_id") if err != nil { t.Fatal(err) } return strings.TrimSpace(string(boot)) } func plan11Rev4WriteOwnedMask(t *testing.T, owner string) claimEdgeMaskRecord { t.Helper() token := strings.Repeat("a", 32) anchor := claimEdgeMaskAnchor(token) if err := os.Link(claimEdgeRuntimeMask, 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 owner != claimEdgeMaskOwner { t.Fatalf("owner fixture drifted: %q != %q", owner, claimEdgeMaskOwner) } return record } // m-7: a runtime mask left by a migration that was killed while masked is // recognised as the migration's own and lifted by the next attempt. func TestPlan9Fix2QuiesceLiftsMaskLeftByCrashedAttempt(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "masked-runtime", &calls) owner := plan9Fix2MaskOwner(t) plan11Rev4WriteOwnedMask(t, owner) release, err := quiesceLegacyClaimJournals(t.Context()) if err != nil { t.Fatal(err) } release() if !slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("mask left by a crashed migration not lifted: %v", calls) } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("mask record kept after the mask was lifted: %v", err) } } // The durable record identifies the exact private anchor that is linked into // the unit name before systemd reloads its view. func TestPlan9Fix2QuiesceRecordsConcreteMaskObject(t *testing.T) { var calls []string plan9Fix2Systemctl(t, "enabled", &calls) owner := plan9Fix2MaskOwner(t) restore := claimSystemctl claimSystemctl = func(ctx context.Context, args ...string) ([]byte, error) { if args[0] == "daemon-reload" { raw, err := os.ReadFile(owner) record, recorded := decodeClaimEdgeMaskRecord(raw, plan9Fix2Boot(t)) if err != nil || !recorded { t.Errorf("mask identity not recorded before reload: %q %v", raw, err) } else if ours, identityErr := claimEdgeMaskStillOwned(record); identityErr != nil || !ours { t.Errorf("record does not own concrete mask: %v %v", ours, identityErr) } } return restore(ctx, args...) } release, err := quiesceLegacyClaimJournals(t.Context()) if err != nil { t.Fatal(err) } release() if !slices.Contains(calls, "daemon-reload") || !slices.Contains(calls, "unmask --runtime carlos-edge.service") { t.Fatalf("calls: %v", calls) } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("mask record kept: %v", err) } } // m-7: an operator's runtime mask, or one with a record from another boot, // is never lifted. func TestPlan9Fix2QuiesceKeepsOperatorMask(t *testing.T) { for _, record := range []string{"", "another-boot"} { var calls []string plan9Fix2Systemctl(t, "masked-runtime", &calls) owner := plan9Fix2MaskOwner(t) if record != "" { if err := os.WriteFile(owner, []byte(record), 0600); err != nil { t.Fatal(err) } } release, err := quiesceLegacyClaimJournals(t.Context()) if err != nil { t.Fatal(err) } release() for _, call := range calls { if strings.HasPrefix(call, "unmask") || strings.HasPrefix(call, "mask") { t.Fatalf("record %q: operator mask touched: %v", record, calls) } } if _, err = os.Stat(owner); !os.IsNotExist(err) { t.Fatalf("stale record kept: %v", err) } } }