testing: implement testing.TempDir
TODO: enable test on windows and wasi once os.Readdir and os.RemoveAll are implemented there
Этот коммит содержится в:
родитель
b406422277
коммит
b24af78327
4 изменённых файлов: 204 добавлений и 0 удалений
10
src/testing/is_wasi_no_test.go
Обычный файл
10
src/testing/is_wasi_no_test.go
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
//go:build !wasi
|
||||
// +build !wasi
|
||||
|
||||
package testing_test
|
||||
|
||||
const isWASI = false
|
10
src/testing/is_wasi_test.go
Обычный файл
10
src/testing/is_wasi_test.go
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
//go:build wasi
|
||||
// +build wasi
|
||||
|
||||
package testing_test
|
||||
|
||||
const isWASI = true
|
|
@ -15,6 +15,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Testing flags.
|
||||
|
@ -58,6 +60,10 @@ type common struct {
|
|||
name string // Name of test or benchmark.
|
||||
start time.Time // Time test or benchmark started
|
||||
duration time.Duration
|
||||
|
||||
tempDir string
|
||||
tempDirErr error
|
||||
tempDirSeq int32
|
||||
}
|
||||
|
||||
// Short reports whether the -test.short flag is set.
|
||||
|
@ -258,6 +264,70 @@ func (c *common) Cleanup(f func()) {
|
|||
c.cleanups = append(c.cleanups, f)
|
||||
}
|
||||
|
||||
// TempDir returns a temporary directory for the test to use.
|
||||
// The directory is automatically removed by Cleanup when the test and
|
||||
// all its subtests complete.
|
||||
// Each subsequent call to t.TempDir returns a unique directory;
|
||||
// if the directory creation fails, TempDir terminates the test by calling Fatal.
|
||||
func (c *common) TempDir() string {
|
||||
// Use a single parent directory for all the temporary directories
|
||||
// created by a test, each numbered sequentially.
|
||||
var nonExistent bool
|
||||
if c.tempDir == "" { // Usually the case with js/wasm
|
||||
nonExistent = true
|
||||
} else {
|
||||
_, err := os.Stat(c.tempDir)
|
||||
nonExistent = os.IsNotExist(err)
|
||||
if err != nil && !nonExistent {
|
||||
c.Fatalf("TempDir: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if nonExistent {
|
||||
c.Helper()
|
||||
|
||||
// Drop unusual characters (such as path separators or
|
||||
// characters interacting with globs) from the directory name to
|
||||
// avoid surprising os.MkdirTemp behavior.
|
||||
mapper := func(r rune) rune {
|
||||
if r < utf8.RuneSelf {
|
||||
const allowed = "!#$%&()+,-.=@^_{}~ "
|
||||
if '0' <= r && r <= '9' ||
|
||||
'a' <= r && r <= 'z' ||
|
||||
'A' <= r && r <= 'Z' {
|
||||
return r
|
||||
}
|
||||
if strings.ContainsRune(allowed, r) {
|
||||
return r
|
||||
}
|
||||
} else if unicode.IsLetter(r) || unicode.IsNumber(r) {
|
||||
return r
|
||||
}
|
||||
return -1
|
||||
}
|
||||
pattern := strings.Map(mapper, c.Name())
|
||||
c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
|
||||
if c.tempDirErr == nil {
|
||||
c.Cleanup(func() {
|
||||
if err := os.RemoveAll(c.tempDir); err != nil {
|
||||
c.Errorf("TempDir RemoveAll cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if c.tempDirErr != nil {
|
||||
c.Fatalf("TempDir: %v", c.tempDirErr)
|
||||
}
|
||||
seq := c.tempDirSeq
|
||||
c.tempDirSeq++
|
||||
dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq)
|
||||
if err := os.Mkdir(dir, 0777); err != nil {
|
||||
c.Fatalf("TempDir: %v", err)
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
// runCleanup is called at the end of the test.
|
||||
func (c *common) runCleanup() {
|
||||
for {
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
// TODO: implement readdir for windows, then enable this file
|
||||
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
@ -6,6 +11,7 @@ package testing_test
|
|||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -16,3 +22,111 @@ import (
|
|||
func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestTempDirInCleanup(t *testing.T) {
|
||||
if isWASI {
|
||||
t.Log("Skipping. TODO: implement RemoveAll for wasi")
|
||||
return
|
||||
}
|
||||
|
||||
var dir string
|
||||
|
||||
t.Run("test", func(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
dir = t.TempDir()
|
||||
})
|
||||
_ = t.TempDir()
|
||||
})
|
||||
|
||||
fi, err := os.Stat(dir)
|
||||
if fi != nil {
|
||||
t.Fatalf("Directory %q from user Cleanup still exists", dir)
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTempDirInBenchmark(t *testing.T) {
|
||||
testing.Benchmark(func(b *testing.B) {
|
||||
if !b.Run("test", func(b *testing.B) {
|
||||
// Add a loop so that the test won't fail. See issue 38677.
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = b.TempDir()
|
||||
}
|
||||
}) {
|
||||
t.Fatal("Sub test failure in a benchmark")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTempDir(t *testing.T) {
|
||||
if isWASI {
|
||||
t.Log("Skipping. TODO: implement RemoveAll for wasi")
|
||||
return
|
||||
}
|
||||
|
||||
testTempDir(t)
|
||||
t.Run("InSubtest", testTempDir)
|
||||
t.Run("test/subtest", testTempDir)
|
||||
t.Run("test\\subtest", testTempDir)
|
||||
t.Run("test:subtest", testTempDir)
|
||||
t.Run("test/..", testTempDir)
|
||||
t.Run("../test", testTempDir)
|
||||
t.Run("test[]", testTempDir)
|
||||
t.Run("test*", testTempDir)
|
||||
t.Run("äöüéè", testTempDir)
|
||||
}
|
||||
|
||||
func testTempDir(t *testing.T) {
|
||||
dirCh := make(chan string, 1)
|
||||
t.Cleanup(func() {
|
||||
// Verify directory has been removed.
|
||||
select {
|
||||
case dir := <-dirCh:
|
||||
fi, err := os.Stat(dir)
|
||||
if os.IsNotExist(err) {
|
||||
// All good
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Errorf("directory %q still exists: %v, isDir=%v", dir, fi, fi.IsDir())
|
||||
default:
|
||||
if !t.Failed() {
|
||||
t.Fatal("never received dir channel")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
dir := t.TempDir()
|
||||
if dir == "" {
|
||||
t.Fatal("expected dir")
|
||||
}
|
||||
dir2 := t.TempDir()
|
||||
if dir == dir2 {
|
||||
t.Fatal("subsequent calls to TempDir returned the same directory")
|
||||
}
|
||||
if filepath.Dir(dir) != filepath.Dir(dir2) {
|
||||
t.Fatalf("calls to TempDir do not share a parent; got %q, %q", dir, dir2)
|
||||
}
|
||||
dirCh <- dir
|
||||
fi, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
t.Errorf("dir %q is not a dir", dir)
|
||||
}
|
||||
|
||||
glob := filepath.Join(dir, "*.txt")
|
||||
if _, err := filepath.Glob(glob); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = os.Remove(dir)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected files in TempDir")
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче