carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package host
4
5import (
6 "os"
7 "path/filepath"
8 "reflect"
9 "testing"
10
11 "github.com/carlosframework/platform/internal/hostbox"
12)
13
14func TestServingParkIncompleteRecoveryRechecksEnrollment(t *testing.T) {
15 for _, change := range []string{"enrollment", "binding"} {
16 t.Run(change, func(t *testing.T) {
17 f := newServingRootFixture(t, true)
18 a, err := f.park()
19 if err != nil {
20 t.Fatal(err)
21 }
22 f.tags(a.Successor.Stamp)
23 before, err := f.p.ledger.read(a.ID)
24 if err != nil || before.Complete || !before.Parked {
25 t.Fatal("expected pending completion", err)
26 }
27 actor := f.actor
28 if change == "enrollment" {
29 f.actor.Enrollment = "new-enrollment"
30 } else {
31 f.actor.Binding = "8"
32 }
33 // Reconstruct the authority object, retaining only durable journals.
34 root := &servingParkRoot{root: f.p.root, ledger: &servingParkLedger{state: f.p.ledger.state, fs: f.p.ledger.fs, journal: f.f.journal, now: f.p.ledger.now}}
35 if err := root.completeServingDatabasePark(t.Context(), f.conn, a.ID, a.Successor); err == nil {
36 t.Fatal("changed deployment identity completed old park")
37 }
38 if _, err := root.parkServingDatabase(t.Context(), f.conn, a.Successor, hostbox.ServingArtifactIdentity{}); err == nil {
39 t.Fatal("changed deployment identity replayed old park")
40 }
41 after, err := root.ledger.read(a.ID)
42 if err != nil || !reflect.DeepEqual(before, after) {
43 t.Fatal("refusal rewrote pending evidence", err)
44 }
45 // Restoring the recorded identity permits the ordinary completion.
46 // A real enrollment change needs separately established root evidence.
47 f.actor = actor
48 if err := root.completeServingDatabasePark(t.Context(), f.conn, a.ID, a.Successor); err != nil {
49 t.Fatal(err)
50 }
51 after, err = root.ledger.read(a.ID)
52 if err != nil || !after.Complete {
53 t.Fatal("completion did not recover", err)
54 }
55 after.Complete = before.Complete
56 if !reflect.DeepEqual(before, after) {
57 t.Fatal("completion changed source, receipts or retention clock")
58 }
59 for suffix, want := range map[string]string{"": "served bytes", ".gen": "G", "-wal": "WAL", "-shm": "SHM"} {
60 body, err := os.ReadFile(filepath.Join(f.f.guard.DataDir, "instances", ".serving-parked", a.ID, filepath.Base(f.db)+suffix))
61 if err != nil || string(body) != want {
62 t.Fatalf("retained %s: %q %v", suffix, body, err)
63 }
64 }
65 })
66 }
67}
68