carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/release"
9 "github.com/carlosframework/platform/internal/rootstate"
10)
11
12func TestPlan14IdenticalVersionKeepsRollbackEvidence(t *testing.T) {
13 if !plan14RootFixture(t) {
14 return
15 }
16 e, rt, u, c, _ := plan14AdoptionFixture(t)
17 if err := os.MkdirAll("/var/lib", 0755); err != nil {
18 t.Fatal(err)
19 }
20 if err := rootstate.EnsurePublicDir(release.RootHealthyDir); err != nil {
21 t.Fatal(err)
22 }
23 evidence := release.ReadHealthy(e.bake, rt.Account, rt.App)[0]
24 if err := release.RecordHealthy(release.RootHealthyDir, rt.Account, rt.App, evidence); err != nil {
25 t.Fatal(err)
26 }
27 original, err := os.ReadFile(filepath.Join(release.RootHealthyDir, "healthy", rt.Account, rt.App+".json"))
28 if err != nil {
29 t.Fatal(err)
30 }
31 raw, err := os.ReadFile(u.exe)
32 if err != nil {
33 t.Fatal(err)
34 }
35 v2 := release.VersionPath(u.opt, rt.Account, "v2", rt.App)
36 if err := os.MkdirAll(filepath.Dir(v2), 0755); err != nil {
37 t.Fatal(err)
38 }
39 if err := os.WriteFile(v2, raw, 0755); err != nil {
40 t.Fatal(err)
41 }
42 if err := release.PointLive(u.opt, rt.Host, rt.Account, "v2", rt.App); err != nil {
43 t.Fatal(err)
44 }
45 u.exe = v2
46 makeProofAncestorsPublic(t, u.exe)
47 makeProofAncestorsPublic(t, u.props.FragmentPath)
48 s := productionProofBindingSource(e.store, u, u.opt)
49 s.unitDirs = []string{filepath.Dir(u.props.FragmentPath)}
50 c.resolve, c.host, c.rollback, c.prepareRollback, c.targetFile = s.resolve, s.forHost, s.rollback, s.prepareRollback, rootstate.OpenTrustedFile
51 c.attempts = productionRootRestartChecks(u, u.opt).attempts
52 e.root.obs.resolve = s.resolve
53 e.bake = release.RootHealthyDir
54 if err := e.root.obs.recordSettled(e.bake)(rt); err != nil {
55 t.Fatal(err)
56 }
57 b, err := s.resolve(t.Context(), rt)
58 if err != nil {
59 t.Fatal(err)
60 }
61 if b.Version != "v2" || !b.Historical || b.History == nil || *b.History != evidence {
62 t.Fatalf("binding: %+v", b)
63 }
64 captured := false
65 u.afterRestart = func() {
66 state, err := c.attempts()
67 if err != nil {
68 t.Fatal(err)
69 }
70 defer state.Close()
71 _, b, err := loadRollback(state, rt.Host, c.now())
72 if err != nil {
73 t.Fatal(err)
74 }
75 if b.Version != "v2" || b.History.Version != "v1" {
76 t.Fatal("evidence rewritten", b)
77 }
78 if _, err := s.prepareRollback(t.Context(), b); err != nil {
79 t.Fatal("v2 rollback not authorized", err)
80 }
81 captured = true
82 }
83 if err := checkedUnitRestart(u, u.opt, func(string) string { return "5s" }, e.root.obs.recordSettled(e.bake), c)(rt); err != nil {
84 t.Fatal(err)
85 }
86 if !captured || len(u.effects) != 1 {
87 t.Fatal("restart not captured", u.effects)
88 }
89 after, err := os.ReadFile(filepath.Join(release.RootHealthyDir, "healthy", rt.Account, rt.App+".json"))
90 if err != nil {
91 t.Fatal(err)
92 }
93 if string(after) != string(original) {
94 t.Fatal("B4 evidence changed")
95 }
96}
97