Skip to content

Commit 29fc933

Browse files
committed
fileinfo: detect benchmark tests
modify our current parser to detect benchmark tests
1 parent 99af6b3 commit 29fc933

File tree

2 files changed

+94
-8
lines changed

2 files changed

+94
-8
lines changed

language/go/fileinfo.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ type fileInfo struct {
6161
// name ends with "_test"
6262
isExternalTest bool
6363

64+
// hasBenchmarkTests is true if the file contains benchmark tests.
65+
hasBenchmarkTests bool
66+
6467
// imports is a list of packages imported by a file. It does not include
6568
// "C" or anything from the standard library.
6669
imports []string
@@ -214,6 +217,7 @@ func otherFileInfo(path string) fileInfo {
214217
func goFileInfo(path, srcdir string) fileInfo {
215218
info := fileNameInfo(path)
216219
fset := token.NewFileSet()
220+
// parse the file for imports and comments (for CGO)
217221
pf, err := parser.ParseFile(fset, info.path, nil, parser.ImportsOnly|parser.ParseComments)
218222
if err != nil {
219223
log.Printf("%s: error reading go file: %v", info.path, err)
@@ -274,8 +278,8 @@ func goFileInfo(path, srcdir string) fileInfo {
274278
}
275279
info.tags = tags
276280

277-
if importsEmbed || info.packageName == "main" {
278-
pf, err = parser.ParseFile(fset, info.path, nil, parser.ParseComments)
281+
if importsEmbed || info.packageName == "main" || info.isTest {
282+
pf, err = parser.ParseFile(fset, info.path, nil, parser.ParseComments|parser.SkipObjectResolution)
279283
if err != nil {
280284
log.Printf("%s: error reading go file: %v", info.path, err)
281285
return info
@@ -309,6 +313,27 @@ func goFileInfo(path, srcdir string) fileInfo {
309313
}
310314
}
311315
}
316+
if info.isTest {
317+
for _, decl := range pf.Decls {
318+
fdecl, ok := decl.(*ast.FuncDecl)
319+
if !ok || !strings.HasPrefix(fdecl.Name.Name, "Benchmark") || fdecl.Type.Params.NumFields() != 1 {
320+
continue
321+
}
322+
// validate that the only param is of type *testing.B
323+
starExpr, ok := fdecl.Type.Params.List[0].Type.(*ast.StarExpr)
324+
if !ok {
325+
continue
326+
}
327+
selector, ok := starExpr.X.(*ast.SelectorExpr)
328+
if !ok || selector.Sel.String() != "B" {
329+
continue
330+
}
331+
if pkgIdent, ok := selector.X.(*ast.Ident); ok && pkgIdent.Name == "testing" {
332+
info.hasBenchmarkTests = true
333+
break
334+
}
335+
}
336+
}
312337
}
313338

314339
return info

language/go/fileinfo_go_test.go

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,66 @@ func TestGoFileInfo(t *testing.T) {
6565
isTest: false,
6666
},
6767
},
68+
{
69+
"hash bench test",
70+
"foo_test.go",
71+
`package foo_test
72+
73+
func BenchmarkFoo(b *testing.B) {}`,
74+
fileInfo{
75+
packageName: "foo",
76+
isTest: true,
77+
hasBenchmarkTests: true,
78+
},
79+
},
80+
{
81+
"invalid bench test 1",
82+
"foo_test.go",
83+
`package foo_test
84+
85+
func BenchmarkFoo(b *testing.B, a string) {}`,
86+
fileInfo{
87+
packageName: "foo",
88+
isTest: true,
89+
hasBenchmarkTests: false,
90+
},
91+
},
92+
{
93+
"invalid bench test 2",
94+
"foo_test.go",
95+
`package foo_test
96+
97+
func CenchmarkFoo(b *testing.B) {}`,
98+
fileInfo{
99+
packageName: "foo",
100+
isTest: true,
101+
hasBenchmarkTests: false,
102+
},
103+
},
104+
{
105+
"invalid bench test 3",
106+
"foo_test.go",
107+
`package foo_test
108+
109+
func BenchmarkFoo(b testing.B) {}`,
110+
fileInfo{
111+
packageName: "foo",
112+
isTest: true,
113+
hasBenchmarkTests: false,
114+
},
115+
},
116+
{
117+
"invalid bench test 4",
118+
"foo_test.go",
119+
`package foo_test
120+
121+
func BenchmarkFoo(c *testing.C) {}`,
122+
fileInfo{
123+
packageName: "foo",
124+
isTest: true,
125+
hasBenchmarkTests: false,
126+
},
127+
},
68128
{
69129
"single import",
70130
"foo.go",
@@ -183,12 +243,13 @@ var src string
183243
got := goFileInfo(path, "")
184244
// Clear fields we don't care about for testing.
185245
got = fileInfo{
186-
packageName: got.packageName,
187-
isTest: got.isTest,
188-
imports: got.imports,
189-
embeds: got.embeds,
190-
isCgo: got.isCgo,
191-
tags: got.tags,
246+
packageName: got.packageName,
247+
isTest: got.isTest,
248+
imports: got.imports,
249+
embeds: got.embeds,
250+
isCgo: got.isCgo,
251+
tags: got.tags,
252+
hasBenchmarkTests: got.hasBenchmarkTests,
192253
}
193254
for i := range got.embeds {
194255
got.embeds[i] = fileEmbed{path: got.embeds[i].path}

0 commit comments

Comments
 (0)