oficina / home Public

Clone
git clone https://amadan.net/oficina/home

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package provisioner
4
5import (
6 "bytes"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "testing"
11)
12
13func persistentDirectory(t *testing.T) string {
14 t.Helper()
15 // The native backend deliberately rejects /tmp when it is tmpfs. Exercise
16 // durable operations on this checkout's persistent filesystem instead.
17 path, err := os.MkdirTemp(".", ".provisioner-test-")
18 if err != nil {
19 t.Fatal(err)
20 }
21 path, err = filepath.Abs(path)
22 if err != nil {
23 t.Fatal(err)
24 }
25 t.Cleanup(func() { os.RemoveAll(path) })
26 if err = os.Chmod(path, 0700); err != nil {
27 t.Fatal(err)
28 }
29 return path
30}
31func TestNativeStorageExclusiveDurableRecords(t *testing.T) {
32 path := persistentDirectory(t)
33 d, err := openPrivateDirectory(path)
34 if err != nil {
35 t.Fatal("native filesystem required", err)
36 }
37 body := []byte("synthetic signed record")
38 if err = d.create("00000001", body); err != nil {
39 t.Fatal(err)
40 }
41 if err = d.create("00000001", []byte("replacement")); err != ErrRefused {
42 t.Fatal("immutable record replaced", err)
43 }
44 d.close()
45 d, err = openPrivateDirectory(path)
46 if err != nil {
47 t.Fatal(err)
48 }
49 defer d.close()
50 got, err := d.read("00000001", 128)
51 if err != nil || !bytes.Equal(got, body) {
52 t.Fatal("durable reopen", err)
53 }
54 if _, err = d.read("00000001", 2); err != ErrRefused {
55 t.Fatal("unbounded read", err)
56 }
57 if err = os.Link(filepath.Join(path, "00000001"), filepath.Join(path, "alias")); err != nil {
58 t.Fatal(err)
59 }
60 if _, err = d.read("00000001", 128); err != ErrRefused {
61 t.Fatal("hardlink accepted", err)
62 }
63}
64func TestNativeStorageRefusesSymlinksAndPermissions(t *testing.T) {
65 path := persistentDirectory(t)
66 real := filepath.Join(path, "real")
67 if err := os.Mkdir(real, 0700); err != nil {
68 t.Fatal(err)
69 }
70 alias := filepath.Join(path, "alias")
71 if err := os.Symlink(real, alias); err != nil {
72 t.Fatal(err)
73 }
74 if _, err := openPrivateDirectory(alias); err != ErrRefused {
75 t.Fatal("symlink directory", err)
76 }
77 if err := os.Mkdir(filepath.Join(real, "nested"), 0700); err != nil {
78 t.Fatal(err)
79 }
80 if _, err := openPrivateDirectory(filepath.Join(alias, "nested")); err != ErrRefused {
81 t.Fatal("symlink ancestor", err)
82 }
83 d, err := openPrivateDirectory(real)
84 if err != nil {
85 t.Fatal(err)
86 }
87 defer d.close()
88 if err = os.Symlink("target", filepath.Join(real, "record")); err != nil {
89 t.Fatal(err)
90 }
91 if err = d.create("record", []byte("x")); err != ErrRefused {
92 t.Fatal("followed record symlink", err)
93 }
94 if _, err = d.read("record", 128); err != ErrRefused {
95 t.Fatal("read record symlink", err)
96 }
97 if err = os.Chmod(real, 0755); err != nil {
98 t.Fatal(err)
99 }
100 if _, err = openPrivateDirectory(real); err != ErrRefused {
101 t.Fatal("public directory", err)
102 }
103}
104func TestNativeStorageProcessLock(t *testing.T) {
105 if path := os.Getenv("OFICINA_TEST_LOCK_PATH"); path != "" {
106 d, err := openPrivateDirectory(path)
107 if err != nil {
108 t.Fatal(err)
109 }
110 defer d.close()
111 lock, err := d.lock()
112 if lock != nil {
113 lock.Close()
114 }
115 if err != ErrRefused {
116 t.Fatal("second process acquired lock", err)
117 }
118 return
119 }
120 path := persistentDirectory(t)
121 d, err := openPrivateDirectory(path)
122 if err != nil {
123 t.Fatal(err)
124 }
125 defer d.close()
126 lock, err := d.lock()
127 if err != nil {
128 t.Fatal(err)
129 }
130 cmd := exec.Command(os.Args[0], "-test.run=^TestNativeStorageProcessLock$")
131 cmd.Env = append(os.Environ(), "OFICINA_TEST_LOCK_PATH="+path)
132 if output, err := cmd.CombinedOutput(); err != nil {
133 t.Fatalf("child: %s: %v", output, err)
134 }
135 lock.Close()
136 lock, err = d.lock()
137 if err != nil {
138 t.Fatal("lock did not release", err)
139 }
140 lock.Close()
141}
142