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 hostfiles
4
5import (
6 "context"
7 "errors"
8 "os"
9 "path/filepath"
10 "strings"
11 "testing"
12 "time"
13
14 "github.com/carlosframework/platform/internal/release"
15)
16
17// Fix 4 (Astra confirming P2): a deep path within the byte cap (257
18// one-byte components, 513 bytes) travels the whole way: published by a
19// walk, accepted by every reader, restored and found present.
20func TestADeepPathWithinTheCapPublishesAndRestores(t *testing.T) {
21 ctx := context.Background()
22 rel := strings.Repeat("d/", 256) + "f"
23 src := t.TempDir()
24 root, err := os.OpenRoot(src)
25 if err != nil {
26 t.Fatal(err)
27 }
28 if err := root.MkdirAll(strings.TrimSuffix(strings.Repeat("d/", 256), "/"), 0o700); err != nil {
29 t.Fatal(err)
30 }
31 if err := root.WriteFile(rel, []byte("deep"), 0o600); err != nil {
32 t.Fatal(err)
33 }
34 root.Close()
35 s := release.NewDirStore(t.TempDir())
36 p := open(t, s)
37 if _, err := SyncDir(ctx, p, src, nil); err != nil {
38 t.Fatal(err)
39 }
40 commit(t, p)
41 m, _, err := Load(ctx, s, pfx)
42 if err != nil {
43 t.Fatal(err)
44 }
45 if err := ValidateManifest(m, []string{pfx}); err != nil {
46 t.Fatalf("ValidateManifest refused what the writer published: %v", err)
47 }
48 dst := t.TempDir()
49 if _, st, err := Restore(ctx, s, pfx, dst, nil); err != nil || st.Written != 1 {
50 t.Fatalf("Restore: %+v %v", st, err)
51 }
52 r2, err := os.OpenRoot(dst)
53 if err != nil {
54 t.Fatal(err)
55 }
56 defer r2.Close()
57 if b, err := r2.ReadFile(rel); err != nil || string(b) != "deep" {
58 t.Fatalf("restored %q %v", b, err)
59 }
60 if ok, err := Present(dst, filepath.Join(t.TempDir(), "shop.example.env"), m, true); err != nil || !ok {
61 t.Fatalf("Present: %v %v", ok, err)
62 }
63}
64
65// Every writer refuses a path past the byte cap, exactly where the readers
66// do, and accepts one at it; Commit never writes a manifest that holds one.
67func TestTheWritersRefuseAPathPastTheCapAsTheReadersDo(t *testing.T) {
68 ctx := context.Background()
69 at, past := pathOfBytes(MaxPathBytes), pathOfBytes(MaxPathBytes+1)
70 p := open(t, release.NewDirStore(t.TempDir()))
71 if err := p.Stage(ctx, at, []byte("x"), 0o600, false); err != nil {
72 t.Fatalf("Stage at the cap: %v", err)
73 }
74 if err := p.Stage(ctx, past, []byte("x"), 0o600, false); !errors.Is(err, ErrTooDeep) {
75 t.Fatalf("Stage past the cap: %v", err)
76 }
77 if err := p.StageSkipped(past, "too-large"); !errors.Is(err, ErrTooDeep) {
78 t.Fatalf("StageSkipped past the cap: %v", err)
79 }
80 if err := p.StageDelete(past); !errors.Is(err, ErrTooDeep) {
81 t.Fatalf("StageDelete past the cap: %v", err)
82 }
83 // A manifest the publisher continued that already holds such a path
84 // (written before the cap) is refused at Commit, never written again.
85 s := release.NewDirStore(t.TempDir())
86 q := open(t, s)
87 q.mu.Lock()
88 q.next++
89 q.man.Entries[past], q.dirty = Entry{Seq: q.next, Skipped: "too-large"}, true
90 q.mu.Unlock()
91 if _, err := q.Commit(ctx); !errors.Is(err, ErrTooDeep) {
92 t.Fatalf("Commit of a manifest holding a path past the cap: %v", err)
93 }
94 if _, found, err := Load(ctx, s, pfx); found || err != nil {
95 t.Fatalf("a refused Commit wrote a manifest: %v %v", found, err)
96 }
97 // And the readers draw the line at the same byte.
98 sha := strings.Repeat("a", 64)
99 e := Entry{Object: pfx + objectKey(1, sha), SHA256: sha, Seq: 1, Size: 1}
100 for path, ok := range map[string]bool{at: true, past: false} {
101 err := ValidateManifest(Manifest{V: ManifestVersion, Seq: 1, Entries: map[string]Entry{path: e}, Platform: map[string]Entry{}}, []string{pfx})
102 if ok != (err == nil) || !ok && !errors.Is(err, ErrTooDeep) {
103 t.Fatalf("ValidateManifest of %d bytes: %v", len(path), err)
104 }
105 }
106}
107
108// The watcher skips a path past the cap for good: it is never staged, so
109// no manifest a reader refuses is committed; it is not retried; and it
110// costs one log line however often it is touched. Other paths publish.
111func TestRunSkipsAPathPastTheCapAndLogsItOnce(t *testing.T) {
112 logs := captureLog(t)
113 s, dir, w := release.NewDirStore(t.TempDir()), t.TempDir(), newFake()
114 p := open(t, s)
115 stop := startRun(t, p, dir, w, eventsOnly)
116 past := pathOfBytes(MaxPathBytes + 1)
117 root, err := os.OpenRoot(dir)
118 if err != nil {
119 t.Fatal(err)
120 }
121 if err := root.MkdirAll(filepath.Dir(past), 0o700); err != nil {
122 t.Fatal(err)
123 }
124 if err := root.WriteFile(past, []byte("x"), 0o600); err != nil {
125 t.Fatal(err)
126 }
127 root.Close()
128 w.ch <- event{rel: past}
129 write(t, dir, "ok", "ok")
130 w.ch <- event{rel: "ok"}
131 eventually(t, "ok published", func() bool { return manifestHas(s, "ok", sum([]byte("ok"))) })
132 w.ch <- event{rel: past}
133 w.ch <- event{rel: "ok"}
134 eventually(t, "the second touch handled", func() bool { return logs.count("past the 4095-byte cap") >= 1 })
135 // Long enough for a retry at every deadline to have logged again.
136 time.Sleep(10 * eventsOnly.Deadline)
137 stopErr := stop()
138 if !errors.Is(stopErr, context.Canceled) {
139 t.Fatalf("run ended with %v; a path past the cap must be skipped, not fatal", stopErr)
140 }
141 if got := logs.count("past the 4095-byte cap"); got != 1 {
142 t.Fatalf("logged %d times, want once", got)
143 }
144 m, _, err := Load(context.Background(), s, pfx)
145 if err != nil {
146 t.Fatal(err)
147 }
148 if _, ok := m.Entries[past]; ok {
149 t.Fatal("the watcher published a path past the cap")
150 }
151 if err := ValidateManifest(m, []string{pfx}); err != nil {
152 t.Fatalf("the watcher committed a manifest a reader refuses: %v", err)
153 }
154}
155