| 1 | //go:build linux |
| 2 | |
| 3 | package sandbox |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "os" |
| 8 | "path/filepath" |
| 9 | "testing" |
| 10 | ) |
| 11 | |
| 12 | func TestBwrapGitMetadataArgsPinDirectoriesThenMountReadOnly(t *testing.T) { |
| 13 | requireGit(t) |
| 14 | ws := filepath.Join(realTempDir(t), "ws") |
| 15 | newRepo(t, ws) |
| 16 | git := filepath.Join(ws, ".git") |
| 17 | spec := Spec{Mode: "enforce", WriteRoots: []string{ws}, MinimalWrites: true} |
| 18 | args := bwrapBaseArgs(spec) |
| 19 | root := indexArgs(args, "--bind", ws, ws) |
| 20 | pin := indexArgs(args, "--bind", git, git) |
| 21 | config := indexArgs(args, "--ro-bind", filepath.Join(git, "config"), filepath.Join(git, "config")) |
| 22 | hooks := indexArgs(args, "--ro-bind", filepath.Join(git, "hooks"), filepath.Join(git, "hooks")) |
| 23 | if root < 0 || pin <= root || config <= pin || hooks <= pin { |
| 24 | t.Fatalf("want write root, then .git pinned, then config and hooks read-only: %v", args) |
| 25 | } |
| 26 | if indexArgs(args[root+3:], "--bind", ws, ws) >= 0 { |
| 27 | t.Fatalf("the write root must not be bound again over its own mounts: %v", args) |
| 28 | } |
| 29 | if indexArgs(args, "--ro-bind", filepath.Join(git, "config.worktree"), filepath.Join(git, "config.worktree")) >= 0 { |
| 30 | t.Fatalf("an absent path cannot be a mount destination: %v", args) |
| 31 | } |
| 32 | if got := bwrapGitMetadataArgs(Spec{Mode: "enforce", ReadOnly: true, WriteRoots: []string{ws}}); len(got) != 0 { |
| 33 | t.Fatalf("read-only spec needs no git mounts: %v", got) |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | func TestBwrapGitMetadataArgsStayBoundedWithManySubmodules(t *testing.T) { |
| 38 | requireGit(t) |
| 39 | ws := filepath.Join(realTempDir(t), "ws") |
| 40 | newRepo(t, ws) |
| 41 | for i := range 2000 { |
| 42 | m := filepath.Join(ws, ".git", "modules", fmt.Sprintf("g%d", i%20), fmt.Sprintf("m%d", i)) |
| 43 | if err := os.MkdirAll(filepath.Join(m, "hooks"), 0o755); err != nil { |
| 44 | t.Fatal(err) |
| 45 | } |
| 46 | if err := os.WriteFile(filepath.Join(m, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644); err != nil { |
| 47 | t.Fatal(err) |
| 48 | } |
| 49 | } |
| 50 | args := bwrapGitMetadataArgs(Spec{Mode: "enforce", WriteRoots: []string{ws}, MinimalWrites: true}) |
| 51 | modules := filepath.Join(ws, ".git", "modules") |
| 52 | if len(args) > 100 || indexArgs(args, "--ro-bind", modules, modules) < 0 { |
| 53 | t.Fatalf("an over-budget modules/ must collapse to one read-only bind: %d args", len(args)) |
| 54 | } |
| 55 | } |
| 56 |