Skip to content

Commit bb1ca7a

Browse files
committed
cmd/go, testing: add TB.ArtifactDir and -artifacts flag
Add TB.ArtifactDir, which returns a directory for a test to store output files in. Add a -artifacts testflag which enables persistent storage of artifacts in the output directory (-outputdir, or the current directory by default). Fixes golang#71287 Change-Id: I5f6515a6cd6c103f88588f4c033d5ea11ffd0c3c Reviewed-on: https://go-review.googlesource.com/c/go/+/696399 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 1623927 commit bb1ca7a

File tree

11 files changed

+333
-71
lines changed

11 files changed

+333
-71
lines changed

api/next/71287.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pkg testing, method (*B) ArtifactDir() string #71287
2+
pkg testing, method (*F) ArtifactDir() string #71287
3+
pkg testing, method (*T) ArtifactDir() string #71287
4+
pkg testing, type TB interface, ArtifactDir() string #71287
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
The new methods [T.ArtifactDir], [B.ArtifactDir], and [F.ArtifactDir]
2+
return a directory in which to write test output files (artifacts).
3+
4+
When the `-artifacts` flag is provided to `go test`,
5+
this directory will be located under the output directory
6+
(specified with `-outputdir`, or the current directory by default).
7+
Otherwise, artifacts are stored in a temporary directory
8+
which is removed after the test completes.
9+
10+
The first call to `ArtifactDir` when `-artifacts` is provided
11+
writes the location of the directory to the test log.
12+
13+
For example, in a test named `TestArtifacts`,
14+
`t.ArtifactDir()` emits:
15+
16+
```
17+
=== ARTIFACTS Test /path/to/artifact/dir
18+
```

src/cmd/go/alldocs.go

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/go/internal/load/test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,14 @@ func (t *testFuncs) ImportPath() string {
649649
return pkg
650650
}
651651

652+
func (t *testFuncs) ModulePath() string {
653+
m := t.Package.Module
654+
if m == nil {
655+
return ""
656+
}
657+
return m.Path
658+
}
659+
652660
// Covered returns a string describing which packages are being tested for coverage.
653661
// If the covered package is the same as the tested package, it returns the empty string.
654662
// Otherwise it is a comma-separated human-readable list of packages beginning with
@@ -836,6 +844,7 @@ func init() {
836844
testdeps.CoverMarkProfileEmittedFunc = cfile.MarkProfileEmitted
837845
838846
{{end}}
847+
testdeps.ModulePath = {{.ModulePath | printf "%q"}}
839848
testdeps.ImportPath = {{.ImportPath | printf "%q"}}
840849
}
841850

src/cmd/go/internal/test/flagdefs.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/go/internal/test/test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ and -show_bytes options of pprof control how the information is presented.
192192
The following flags are recognized by the 'go test' command and
193193
control the execution of any test:
194194
195+
-artifacts
196+
Save test artifacts in the directory specified by -outputdir.
197+
See 'go doc testing.T.ArtifactDir'.
198+
195199
-bench regexp
196200
Run only those benchmarks matching a regular expression.
197201
By default, no benchmarks are run.
@@ -286,6 +290,10 @@ control the execution of any test:
286290
This will only list top-level tests. No subtest or subbenchmarks will be
287291
shown.
288292
293+
-outputdir directory
294+
Place output files from profiling and test artifacts in the
295+
specified directory, by default the directory in which "go test" is running.
296+
289297
-parallel n
290298
Allow parallel execution of test functions that call t.Parallel, and
291299
fuzz targets that call t.Parallel when running the seed corpus.
@@ -397,10 +405,6 @@ profile the tests during execution:
397405
Sample 1 in n stack traces of goroutines holding a
398406
contended mutex.
399407
400-
-outputdir directory
401-
Place output files from profiling in the specified directory,
402-
by default the directory in which "go test" is running.
403-
404408
-trace trace.out
405409
Write an execution trace to the specified file before exiting.
406410
@@ -540,6 +544,7 @@ See the documentation of the testing package for more information.
540544
}
541545

542546
var (
547+
testArtifacts bool // -artifacts flag
543548
testBench string // -bench flag
544549
testC bool // -c flag
545550
testCoverPkgs []*load.Package // -coverpkg flag

src/cmd/go/internal/test/testflag.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func init() {
4444
// some of them so that cmd/go knows what to do with the test output, or knows
4545
// to build the test in a way that supports the use of the flag.
4646

47+
cf.BoolVar(&testArtifacts, "artifacts", false, "")
4748
cf.StringVar(&testBench, "bench", "", "")
4849
cf.Bool("benchmem", false, "")
4950
cf.String("benchtime", "", "")
@@ -392,7 +393,8 @@ func testFlags(args []string) (packageNames, passToTest []string) {
392393
// directory, but 'go test' defaults it to the working directory of the 'go'
393394
// command. Set it explicitly if it is needed due to some other flag that
394395
// requests output.
395-
if testProfile() != "" && !outputDirSet {
396+
needOutputDir := testProfile() != "" || testArtifacts
397+
if needOutputDir && !outputDirSet {
396398
injectedFlags = append(injectedFlags, "-test.outputdir="+testOutputDir.getAbs())
397399
}
398400

src/cmd/internal/test2json/test2json.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type event struct {
3838
FailedBuild string `json:",omitempty"`
3939
Key string `json:",omitempty"`
4040
Value string `json:",omitempty"`
41+
Path string `json:",omitempty"`
4142
}
4243

4344
// textBytes is a hack to get JSON to emit a []byte as a string
@@ -180,6 +181,7 @@ var (
180181
[]byte("=== FAIL "),
181182
[]byte("=== SKIP "),
182183
[]byte("=== ATTR "),
184+
[]byte("=== ARTIFACTS "),
183185
}
184186

185187
reports = [][]byte{
@@ -251,7 +253,6 @@ func (c *Converter) handleInputLine(line []byte) {
251253
// "=== RUN "
252254
// "=== PAUSE "
253255
// "=== CONT "
254-
actionColon := false
255256
origLine := line
256257
ok := false
257258
indent := 0
@@ -273,7 +274,6 @@ func (c *Converter) handleInputLine(line []byte) {
273274
}
274275
for _, magic := range reports {
275276
if bytes.HasPrefix(line, magic) {
276-
actionColon = true
277277
ok = true
278278
break
279279
}
@@ -296,16 +296,11 @@ func (c *Converter) handleInputLine(line []byte) {
296296
return
297297
}
298298

299-
// Parse out action and test name.
300-
i := 0
301-
if actionColon {
302-
i = bytes.IndexByte(line, ':') + 1
303-
}
304-
if i == 0 {
305-
i = len(updates[0])
306-
}
307-
action := strings.ToLower(strings.TrimSuffix(strings.TrimSpace(string(line[4:i])), ":"))
308-
name := strings.TrimSpace(string(line[i:]))
299+
// Parse out action and test name from "=== ACTION: Name".
300+
action, name, _ := strings.Cut(string(line[len("=== "):]), " ")
301+
action = strings.TrimSuffix(action, ":")
302+
action = strings.ToLower(action)
303+
name = strings.TrimSpace(name)
309304

310305
e := &event{Action: action}
311306
if line[0] == '-' { // PASS or FAIL report
@@ -336,7 +331,10 @@ func (c *Converter) handleInputLine(line []byte) {
336331
c.output.write(origLine)
337332
return
338333
}
339-
if action == "attr" {
334+
switch action {
335+
case "artifacts":
336+
name, e.Path, _ = strings.Cut(name, " ")
337+
case "attr":
340338
var rest string
341339
name, rest, _ = strings.Cut(name, " ")
342340
e.Key, e.Value, _ = strings.Cut(rest, " ")

src/testing/internal/testdeps/deps.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ func (TestDeps) ImportPath() string {
6666
return ImportPath
6767
}
6868

69+
var ModulePath string
70+
71+
func (TestDeps) ModulePath() string {
72+
return ModulePath
73+
}
74+
6975
// testLog implements testlog.Interface, logging actions by package os.
7076
type testLog struct {
7177
mu sync.Mutex

0 commit comments

Comments
 (0)