1
2
3
4
5 package ssa
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "os"
12 "path/filepath"
13 "testing"
14 )
15
16 const expectedHeader = "// Code generated from _gen/"
17
18
19
20
21
22
23 func TestGeneratedFilesUpToDate(t *testing.T) {
24 testenv.MustHaveGoRun(t)
25 wd, err := os.Getwd()
26 if err != nil {
27 t.Fatalf("Failed to get current working directory: %v", err)
28 }
29 genDir := filepath.Join(wd, "_gen")
30 if _, err := os.Stat(genDir); os.IsNotExist(err) {
31 t.Fatalf("_gen directory not found")
32 }
33
34 tmpdir := t.TempDir()
35
36
37
38
39 genFiles := make(map[string]bool)
40 genPrefix := []byte(expectedHeader)
41 ssaFiles, err := filepath.Glob(filepath.Join(wd, "*.go"))
42 if err != nil {
43 t.Fatalf("could not glob for .go files in ssa directory: %v", err)
44 }
45 for _, f := range ssaFiles {
46 contents, err := os.ReadFile(f)
47 if err != nil {
48 t.Fatalf("could not read source file from ssa directory: %v", err)
49 }
50
51
52
53 if bytes.HasPrefix(contents, genPrefix) {
54 genFiles[filepath.Base(f)] = true
55 }
56 }
57
58 goFiles, err := filepath.Glob(filepath.Join(genDir, "*.go"))
59 if err != nil {
60 t.Fatalf("could not glob for .go files in _gen: %v", err)
61 }
62 if len(goFiles) == 0 {
63 t.Fatal("no .go files found in _gen")
64 }
65
66
67
68
69 args := []string{"run", "-C", genDir}
70 for _, f := range goFiles {
71 args = append(args, filepath.Base(f))
72 }
73 args = append(args, "-outdir", tmpdir)
74
75 logArgs := fmt.Sprintf("%v", args)
76 logArgs = logArgs[1 : len(logArgs)-2]
77 t.Logf("%s %v", testenv.GoToolPath(t), logArgs)
78 output, err := testenv.Command(t, testenv.GoToolPath(t), args...).CombinedOutput()
79
80 if err != nil {
81 t.Fatalf("go run in _gen failed: %v\n%s", err, output)
82 }
83
84
85 files, err := os.ReadDir(tmpdir)
86 if err != nil {
87 t.Fatalf("could not read tmpdir %s: %v", tmpdir, err)
88 }
89
90 for _, file := range files {
91 if file.IsDir() {
92 continue
93 }
94 filename := file.Name()
95
96
97 if !genFiles[filename] {
98 t.Errorf("%s does not start with the expected header '%s' (if the header was changed the test needs to be updated)",
99 filename, expectedHeader)
100 }
101 genFiles[filename] = false
102
103 generatedPath := filepath.Join(tmpdir, filename)
104 originalPath := filepath.Join(wd, filename)
105
106 generatedData, err := os.ReadFile(generatedPath)
107 if err != nil {
108 t.Errorf("could not read generated file %s: %v", generatedPath, err)
109 continue
110 }
111
112
113 originalData, err := os.ReadFile(originalPath)
114 if err != nil {
115 if os.IsNotExist(err) {
116 t.Errorf("generated file %s was created, but does not exist in the ssa directory. It may need to be added to the repository.", filename)
117 } else {
118 t.Errorf("could not read original file %s: %v", originalPath, err)
119 }
120 continue
121 }
122
123
124 if !bytes.Equal(originalData, generatedData) {
125 t.Errorf("%s is out of date. Please run 'go generate'.", filename)
126 }
127 }
128
129
130 for file, notGenerated := range genFiles {
131 if notGenerated {
132 t.Errorf("%s has the header of a generated file but was not generated", file)
133 }
134 }
135 }
136
View as plain text