Source file
src/cmd/gofmt/long_test.go
1
2
3
4
5
6
7
8
9 package main
10
11 import (
12 "bytes"
13 "flag"
14 "fmt"
15 "go/ast"
16 "go/printer"
17 "go/token"
18 "internal/testenv"
19 "io"
20 "io/fs"
21 "os"
22 "path/filepath"
23 "runtime"
24 "strings"
25 "testing"
26 )
27
28 var (
29 root = flag.String("root", runtime.GOROOT(), "test root directory")
30 files = flag.String("files", "", "comma-separated list of files to test")
31 ngo = flag.Int("n", runtime.NumCPU(), "number of goroutines used")
32 verbose = flag.Bool("verbose", false, "verbose mode")
33 nfiles int
34 )
35
36 func gofmt(fset *token.FileSet, filename string, src *bytes.Buffer) error {
37 f, _, _, err := parse(fset, filename, src.Bytes(), false)
38 if err != nil {
39 return err
40 }
41 ast.SortImports(fset, f)
42 src.Reset()
43 return (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(src, fset, f)
44 }
45
46 func testFile(t *testing.T, b1, b2 *bytes.Buffer, filename string) {
47
48 f, err := os.Open(filename)
49 if err != nil {
50 t.Error(err)
51 return
52 }
53
54
55 b1.Reset()
56 _, err = io.Copy(b1, f)
57 f.Close()
58 if err != nil {
59 t.Error(err)
60 return
61 }
62
63
64 fset := token.NewFileSet()
65 if _, _, _, err = parse(fset, filename, b1.Bytes(), false); err != nil {
66 if *verbose {
67 fmt.Fprintf(os.Stderr, "ignoring %s\n", err)
68 }
69 return
70 }
71
72
73 if err = gofmt(fset, filename, b1); err != nil {
74 t.Errorf("1st gofmt failed: %v", err)
75 return
76 }
77
78
79 b2.Reset()
80 b2.Write(b1.Bytes())
81
82
83 if err = gofmt(fset, filename, b2); err != nil {
84 t.Errorf("2nd gofmt failed: %v", err)
85 return
86 }
87
88
89 if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
90
91
92 if strings.HasSuffix(filename, "issue22662.go") {
93 t.Log("known gofmt idempotency bug (Issue #24472)")
94 return
95 }
96 t.Errorf("gofmt %s not idempotent", filename)
97 }
98 }
99
100 func testFiles(t *testing.T, filenames <-chan string, done chan<- int) {
101 b1 := new(bytes.Buffer)
102 b2 := new(bytes.Buffer)
103 for filename := range filenames {
104 testFile(t, b1, b2, filename)
105 }
106 done <- 0
107 }
108
109 func genFilenames(t *testing.T, filenames chan<- string) {
110 defer close(filenames)
111
112 handleFile := func(filename string, d fs.DirEntry, err error) error {
113 if err != nil {
114 t.Error(err)
115 return nil
116 }
117
118 if isGoFile(d) && !strings.Contains(filepath.ToSlash(filename), "/testdata/") {
119 filenames <- filename
120 nfiles++
121 }
122 return nil
123 }
124
125
126 if *files != "" {
127 for _, filename := range strings.Split(*files, ",") {
128 fi, err := os.Stat(filename)
129 handleFile(filename, fs.FileInfoToDirEntry(fi), err)
130 }
131 return
132 }
133
134
135 goroot := *root
136 if goroot == "" {
137 goroot = testenv.GOROOT(t)
138 }
139 filepath.WalkDir(goroot, handleFile)
140 }
141
142 func TestAll(t *testing.T) {
143 if testing.Short() {
144 return
145 }
146
147 if *ngo < 1 {
148 *ngo = 1
149 }
150 if *verbose {
151 fmt.Printf("running test using %d goroutines\n", *ngo)
152 }
153
154
155 filenames := make(chan string, 32)
156 go genFilenames(t, filenames)
157
158
159 done := make(chan int)
160 for i := 0; i < *ngo; i++ {
161 go testFiles(t, filenames, done)
162 }
163
164
165 for i := 0; i < *ngo; i++ {
166 <-done
167 }
168
169 if *verbose {
170 fmt.Printf("processed %d files\n", nfiles)
171 }
172 }
173
View as plain text