Skip to content

Commit

Permalink
message/pipeline: avoid writing to the testdata directory
Browse files Browse the repository at this point in the history
If this test is run as a dependency of some other module, the testdata
directory will be read-only. Moreover, if temporary files are written
to the working directory they are likely to interfere with concurrent
version-control operations, such as 'git commit -a'.

Updates golang/go#28387

Change-Id: I15cd9408c63f9b6aed50facbfefa26299392052f
Reviewed-on: https://go-review.googlesource.com/c/text/+/208123
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
Bryan C. Mills committed Nov 22, 2019
1 parent 4b67af8 commit 09f8d73
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 721 deletions.
10 changes: 7 additions & 3 deletions message/pipeline/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ func (s *State) Generate() error {
return err
}
if !isDir {
gopath := build.Default.GOPATH
path = filepath.Join(gopath, filepath.FromSlash(pkgs[0].Pkg.Path()))
gopath := filepath.SplitList(build.Default.GOPATH)[0]
path = filepath.Join(gopath, "src", filepath.FromSlash(pkgs[0].Pkg.Path()))
}
if filepath.IsAbs(s.Config.GenFile) {
path = s.Config.GenFile
} else {
path = filepath.Join(path, s.Config.GenFile)
}
path = filepath.Join(path, s.Config.GenFile)
cw.WriteGoFile(path, pkg) // TODO: WriteGoFile should return error.
return err
}
Expand Down
110 changes: 97 additions & 13 deletions message/pipeline/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
"encoding/json"
"flag"
"fmt"
"go/build"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"reflect"
"runtime"
"strings"
"testing"
Expand All @@ -35,28 +37,59 @@ func TestFullCycle(t *testing.T) {
t.Skipf("skipping because 'go' command is unavailable: %v", err)
}

const path = "./testdata"
dirs, err := ioutil.ReadDir(path)
GOPATH, err := ioutil.TempDir("", "pipeline_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(GOPATH)
testdata := filepath.Join(GOPATH, "src", "testdata")

// Copy the testdata contents into a new module.
copyTestdata(t, testdata)
initTestdataModule(t, testdata)

// Several places hard-code the use of build.Default.
// Adjust it to match the test's temporary GOPATH.
defer func(prev string) { build.Default.GOPATH = prev }(build.Default.GOPATH)
build.Default.GOPATH = GOPATH + string(filepath.ListSeparator) + build.Default.GOPATH
if wd := reflect.ValueOf(&build.Default).Elem().FieldByName("WorkingDir"); wd.IsValid() {
defer func(prev string) { wd.SetString(prev) }(wd.String())
wd.SetString(testdata)
}

// To work around https://golang.org/issue/34860, execute the commands
// that (transitively) use go/build in the working directory of the
// corresponding module.
wd, _ := os.Getwd()
defer os.Chdir(wd)

dirs, err := ioutil.ReadDir(testdata)
if err != nil {
t.Fatal(err)
}
for _, f := range dirs {
if !f.IsDir() {
continue
}
t.Run(f.Name(), func(t *testing.T) {
chk := func(t *testing.T, err error) {
setHelper(t)
if err != nil {
t.Fatal(err)
}
}
dir := filepath.Join(path, f.Name())
pkgPath := fmt.Sprintf("%s/%s", path, f.Name())
dir := filepath.Join(testdata, f.Name())
pkgPath := "testdata/" + f.Name()
config := Config{
SourceLanguage: language.AmericanEnglish,
Packages: []string{pkgPath},
Dir: filepath.Join(dir, "locales"),
GenFile: "catalog_gen.go",
GenPackage: pkgPath,
}

os.Chdir(dir)

// TODO: load config if available.
s, err := Extract(&config)
chk(t, err)
Expand All @@ -69,34 +102,82 @@ func TestFullCycle(t *testing.T) {
chk(t, s.Export())
chk(t, s.Generate())

os.Chdir(wd)

writeJSON(t, filepath.Join(dir, "extracted.gotext.json"), s.Extracted)
checkOutput(t, dir)
checkOutput(t, dir, f.Name())
})
}
}

func checkOutput(t *testing.T, p string) {
filepath.Walk(p, func(p string, f os.FileInfo, err error) error {
func copyTestdata(t *testing.T, dst string) {
err := filepath.Walk("testdata", func(p string, f os.FileInfo, err error) error {
if p == "testdata" || strings.HasSuffix(p, ".want") {
return nil
}

rel := strings.TrimPrefix(p, "testdata"+string(filepath.Separator))
if f.IsDir() {
return os.MkdirAll(filepath.Join(dst, rel), 0755)
}

data, err := ioutil.ReadFile(p)
if err != nil {
return err
}
return ioutil.WriteFile(filepath.Join(dst, rel), data, 0644)
})
if err != nil {
t.Fatal(err)
}
}

func initTestdataModule(t *testing.T, dst string) {
xTextDir, err := filepath.Abs("../..")
if err != nil {
t.Fatal(err)
}

goMod := fmt.Sprintf(`module testdata
go 1.11
require golang.org/x/text v0.0.0-00010101000000-000000000000
replace golang.org/x/text v0.0.0-00010101000000-000000000000 => %s
`, xTextDir)
if err := ioutil.WriteFile(filepath.Join(dst, "go.mod"), []byte(goMod), 0644); err != nil {
t.Fatal(err)
}

data, err := ioutil.ReadFile(filepath.Join(xTextDir, "go.sum"))
if err := ioutil.WriteFile(filepath.Join(dst, "go.sum"), data, 0644); err != nil {
t.Fatal(err)
}
}

func checkOutput(t *testing.T, gen string, testdataDir string) {
err := filepath.Walk(gen, func(gotFile string, f os.FileInfo, err error) error {
if f.IsDir() {
return nil
}
if filepath.Ext(p) != ".want" {
rel := strings.TrimPrefix(gotFile, gen+string(filepath.Separator))

wantFile := filepath.Join("testdata", testdataDir, rel+".want")
if _, err := os.Stat(wantFile); os.IsNotExist(err) {
return nil
}
gotFile := p[:len(p)-len(".want")]

got, err := ioutil.ReadFile(gotFile)
if err != nil {
t.Errorf("failed to read %q", p)
t.Errorf("failed to read %q", gotFile)
return nil
}
if *genFiles {
if err := ioutil.WriteFile(p, got, 0644); err != nil {
if err := ioutil.WriteFile(wantFile, got, 0644); err != nil {
t.Fatal(err)
}
}
want, err := ioutil.ReadFile(p)
want, err := ioutil.ReadFile(wantFile)
if err != nil {
t.Errorf("failed to read %q", p)
t.Errorf("failed to read %q", wantFile)
} else {
scanGot := bufio.NewScanner(bytes.NewReader(got))
scanWant := bufio.NewScanner(bytes.NewReader(want))
Expand All @@ -122,6 +203,9 @@ func checkOutput(t *testing.T, p string) {
}
return nil
})
if err != nil {
t.Fatal(err)
}
}

func writeJSON(t *testing.T, path string, x interface{}) {
Expand Down
85 changes: 0 additions & 85 deletions message/pipeline/testdata/test1/catalog_gen.go

This file was deleted.

Loading

0 comments on commit 09f8d73

Please sign in to comment.