|
1 | 1 | package policy |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "os" |
5 | 6 | "path/filepath" |
6 | 7 | "slices" |
7 | 8 | "testing" |
| 9 | + "testing/fstest" |
8 | 10 |
|
9 | 11 | "github.com/TykTechnologies/gromit/config" |
10 | 12 | ) |
@@ -85,6 +87,49 @@ func TestBundleRender(t *testing.T) { |
85 | 87 | } |
86 | 88 | } |
87 | 89 |
|
| 90 | +// TestFsTreeWalkBasenameCollision guards against parse-list leakage |
| 91 | +// between bundle files that share a base name. text/template names |
| 92 | +// templates by base name and the last duplicate parsed wins, so if the |
| 93 | +// parse list accumulates across the walk, .github/zizmor.yml (zizmor |
| 94 | +// config) and .github/workflows/zizmor.yml (caller workflow) would |
| 95 | +// render identical content. |
| 96 | +func TestFsTreeWalkBasenameCollision(t *testing.T) { |
| 97 | + tfs := fstest.MapFS{ |
| 98 | + "templates/test/.github/zizmor.yml": &fstest.MapFile{Data: []byte("kind: config")}, |
| 99 | + "templates/test/.github/workflows/zizmor.yml": &fstest.MapFile{Data: []byte("kind: workflow")}, |
| 100 | + } |
| 101 | + b := &Bundle{Name: "test", tree: &bundleNode{}} |
| 102 | + if err := fsTreeWalk(b, tfs, "templates/test", nil); err != nil { |
| 103 | + t.Fatalf("fsTreeWalk: %v", err) |
| 104 | + } |
| 105 | + |
| 106 | + got := make(map[string]string) |
| 107 | + var walk func(n *bundleNode) |
| 108 | + walk = func(n *bundleNode) { |
| 109 | + for _, c := range n.Children { |
| 110 | + walk(c) |
| 111 | + } |
| 112 | + if len(n.Children) == 0 && n.template != nil { |
| 113 | + var buf bytes.Buffer |
| 114 | + if err := n.template.Execute(&buf, nil); err != nil { |
| 115 | + t.Fatalf("rendering %s: %v", n.path, err) |
| 116 | + } |
| 117 | + got[n.path] = buf.String() |
| 118 | + } |
| 119 | + } |
| 120 | + walk(b.tree) |
| 121 | + |
| 122 | + want := map[string]string{ |
| 123 | + ".github/zizmor.yml": "kind: config", |
| 124 | + ".github/workflows/zizmor.yml": "kind: workflow", |
| 125 | + } |
| 126 | + for path, content := range want { |
| 127 | + if got[path] != content { |
| 128 | + t.Errorf("%s rendered %q, want %q", path, got[path], content) |
| 129 | + } |
| 130 | + } |
| 131 | +} |
| 132 | + |
88 | 133 | func countFiles(tmpDir string) (int, error) { |
89 | 134 | count := 0 |
90 | 135 | err := filepath.Walk(tmpDir, func(path string, info os.FileInfo, err error) error { |
|
0 commit comments