carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package hostbox
2
3import (
4 "bytes"
5 "context"
6 "database/sql"
7 "github.com/carlosframework/platform/internal/hostguard"
8 "os"
9 "path/filepath"
10 "testing"
11)
12
13// A pool replacement must not open a different inode under a checked name.
14// Regression: the replaced database must remain untouched when a pool reopens.
15func TestPlan9JournalReplacementRemainsUntouched(t *testing.T) {
16 dir := t.TempDir()
17 path := filepath.Join(dir, "launches.db")
18 replacement := filepath.Join(dir, "unrelated.db")
19 db, err := sql.Open("sqlite", replacement)
20 if err != nil {
21 t.Fatal(err)
22 }
23 if _, err = db.Exec("CREATE TABLE launches (identity TEXT PRIMARY KEY, body BLOB NOT NULL)"); err != nil {
24 t.Fatal(err)
25 }
26 if err = db.Close(); err != nil {
27 t.Fatal(err)
28 }
29 before, err := os.ReadFile(replacement)
30 if err != nil {
31 t.Fatal(err)
32 }
33 j, err := OpenLaunchJournal(path)
34 if err != nil {
35 t.Fatal(err)
36 }
37 defer j.Close()
38 j.db.SetMaxIdleConns(0)
39 if err := os.Rename(path, path+".pinned"); err != nil {
40 t.Fatal(err)
41 }
42 if err := os.Rename(replacement, path); err != nil {
43 t.Fatal(err)
44 }
45 in := LaunchInventory{Target: hostguard.FenceTarget{Host: "app.example", Incarnation: "inc", Stamp: 1, Session: 1, Box: "box", Enrollment: "enrollment", BootID: "boot", ControllerID: "controller"}, ControllerPID: 1, ProcessStart: "1", NoState: true, Groups: []LaunchGroup{{RelativePath: "session", Device: 1, Inode: 2}}}
46 writeErr := j.Create(context.Background(), in)
47 after, err := os.ReadFile(path)
48 if err != nil {
49 t.Fatal(err)
50 }
51 if !bytes.Equal(before, after) {
52 t.Fatalf("replacement database modified: write error=%v", writeErr)
53 }
54 if writeErr == nil {
55 t.Fatal("replacement inode accepted")
56 }
57}
58