Skip to content

Commit 09f8d73

Browse files
author
Bryan C. Mills
committed
message/pipeline: avoid writing to the testdata directory
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 4b67af8 commit 09f8d73

File tree

11 files changed

+108
-721
lines changed

11 files changed

+108
-721
lines changed

message/pipeline/generate.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,14 @@ func (s *State) Generate() error {
4949
return err
5050
}
5151
if !isDir {
52-
gopath := build.Default.GOPATH
53-
path = filepath.Join(gopath, filepath.FromSlash(pkgs[0].Pkg.Path()))
52+
gopath := filepath.SplitList(build.Default.GOPATH)[0]
53+
path = filepath.Join(gopath, "src", filepath.FromSlash(pkgs[0].Pkg.Path()))
54+
}
55+
if filepath.IsAbs(s.Config.GenFile) {
56+
path = s.Config.GenFile
57+
} else {
58+
path = filepath.Join(path, s.Config.GenFile)
5459
}
55-
path = filepath.Join(path, s.Config.GenFile)
5660
cw.WriteGoFile(path, pkg) // TODO: WriteGoFile should return error.
5761
return err
5862
}

message/pipeline/pipeline_test.go

Lines changed: 97 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import (
1010
"encoding/json"
1111
"flag"
1212
"fmt"
13+
"go/build"
1314
"io/ioutil"
1415
"os"
1516
"os/exec"
1617
"path"
1718
"path/filepath"
19+
"reflect"
1820
"runtime"
1921
"strings"
2022
"testing"
@@ -35,28 +37,59 @@ func TestFullCycle(t *testing.T) {
3537
t.Skipf("skipping because 'go' command is unavailable: %v", err)
3638
}
3739

38-
const path = "./testdata"
39-
dirs, err := ioutil.ReadDir(path)
40+
GOPATH, err := ioutil.TempDir("", "pipeline_test")
41+
if err != nil {
42+
t.Fatal(err)
43+
}
44+
defer os.RemoveAll(GOPATH)
45+
testdata := filepath.Join(GOPATH, "src", "testdata")
46+
47+
// Copy the testdata contents into a new module.
48+
copyTestdata(t, testdata)
49+
initTestdataModule(t, testdata)
50+
51+
// Several places hard-code the use of build.Default.
52+
// Adjust it to match the test's temporary GOPATH.
53+
defer func(prev string) { build.Default.GOPATH = prev }(build.Default.GOPATH)
54+
build.Default.GOPATH = GOPATH + string(filepath.ListSeparator) + build.Default.GOPATH
55+
if wd := reflect.ValueOf(&build.Default).Elem().FieldByName("WorkingDir"); wd.IsValid() {
56+
defer func(prev string) { wd.SetString(prev) }(wd.String())
57+
wd.SetString(testdata)
58+
}
59+
60+
// To work around https://golang.org/issue/34860, execute the commands
61+
// that (transitively) use go/build in the working directory of the
62+
// corresponding module.
63+
wd, _ := os.Getwd()
64+
defer os.Chdir(wd)
65+
66+
dirs, err := ioutil.ReadDir(testdata)
4067
if err != nil {
4168
t.Fatal(err)
4269
}
4370
for _, f := range dirs {
71+
if !f.IsDir() {
72+
continue
73+
}
4474
t.Run(f.Name(), func(t *testing.T) {
4575
chk := func(t *testing.T, err error) {
4676
setHelper(t)
4777
if err != nil {
4878
t.Fatal(err)
4979
}
5080
}
51-
dir := filepath.Join(path, f.Name())
52-
pkgPath := fmt.Sprintf("%s/%s", path, f.Name())
81+
dir := filepath.Join(testdata, f.Name())
82+
pkgPath := "testdata/" + f.Name()
5383
config := Config{
5484
SourceLanguage: language.AmericanEnglish,
5585
Packages: []string{pkgPath},
5686
Dir: filepath.Join(dir, "locales"),
5787
GenFile: "catalog_gen.go",
5888
GenPackage: pkgPath,
5989
}
90+
91+
os.Chdir(dir)
92+
6093
// TODO: load config if available.
6194
s, err := Extract(&config)
6295
chk(t, err)
@@ -69,34 +102,82 @@ func TestFullCycle(t *testing.T) {
69102
chk(t, s.Export())
70103
chk(t, s.Generate())
71104

105+
os.Chdir(wd)
106+
72107
writeJSON(t, filepath.Join(dir, "extracted.gotext.json"), s.Extracted)
73-
checkOutput(t, dir)
108+
checkOutput(t, dir, f.Name())
74109
})
75110
}
76111
}
77112

78-
func checkOutput(t *testing.T, p string) {
79-
filepath.Walk(p, func(p string, f os.FileInfo, err error) error {
113+
func copyTestdata(t *testing.T, dst string) {
114+
err := filepath.Walk("testdata", func(p string, f os.FileInfo, err error) error {
115+
if p == "testdata" || strings.HasSuffix(p, ".want") {
116+
return nil
117+
}
118+
119+
rel := strings.TrimPrefix(p, "testdata"+string(filepath.Separator))
120+
if f.IsDir() {
121+
return os.MkdirAll(filepath.Join(dst, rel), 0755)
122+
}
123+
124+
data, err := ioutil.ReadFile(p)
125+
if err != nil {
126+
return err
127+
}
128+
return ioutil.WriteFile(filepath.Join(dst, rel), data, 0644)
129+
})
130+
if err != nil {
131+
t.Fatal(err)
132+
}
133+
}
134+
135+
func initTestdataModule(t *testing.T, dst string) {
136+
xTextDir, err := filepath.Abs("../..")
137+
if err != nil {
138+
t.Fatal(err)
139+
}
140+
141+
goMod := fmt.Sprintf(`module testdata
142+
go 1.11
143+
require golang.org/x/text v0.0.0-00010101000000-000000000000
144+
replace golang.org/x/text v0.0.0-00010101000000-000000000000 => %s
145+
`, xTextDir)
146+
if err := ioutil.WriteFile(filepath.Join(dst, "go.mod"), []byte(goMod), 0644); err != nil {
147+
t.Fatal(err)
148+
}
149+
150+
data, err := ioutil.ReadFile(filepath.Join(xTextDir, "go.sum"))
151+
if err := ioutil.WriteFile(filepath.Join(dst, "go.sum"), data, 0644); err != nil {
152+
t.Fatal(err)
153+
}
154+
}
155+
156+
func checkOutput(t *testing.T, gen string, testdataDir string) {
157+
err := filepath.Walk(gen, func(gotFile string, f os.FileInfo, err error) error {
80158
if f.IsDir() {
81159
return nil
82160
}
83-
if filepath.Ext(p) != ".want" {
161+
rel := strings.TrimPrefix(gotFile, gen+string(filepath.Separator))
162+
163+
wantFile := filepath.Join("testdata", testdataDir, rel+".want")
164+
if _, err := os.Stat(wantFile); os.IsNotExist(err) {
84165
return nil
85166
}
86-
gotFile := p[:len(p)-len(".want")]
167+
87168
got, err := ioutil.ReadFile(gotFile)
88169
if err != nil {
89-
t.Errorf("failed to read %q", p)
170+
t.Errorf("failed to read %q", gotFile)
90171
return nil
91172
}
92173
if *genFiles {
93-
if err := ioutil.WriteFile(p, got, 0644); err != nil {
174+
if err := ioutil.WriteFile(wantFile, got, 0644); err != nil {
94175
t.Fatal(err)
95176
}
96177
}
97-
want, err := ioutil.ReadFile(p)
178+
want, err := ioutil.ReadFile(wantFile)
98179
if err != nil {
99-
t.Errorf("failed to read %q", p)
180+
t.Errorf("failed to read %q", wantFile)
100181
} else {
101182
scanGot := bufio.NewScanner(bytes.NewReader(got))
102183
scanWant := bufio.NewScanner(bytes.NewReader(want))
@@ -122,6 +203,9 @@ func checkOutput(t *testing.T, p string) {
122203
}
123204
return nil
124205
})
206+
if err != nil {
207+
t.Fatal(err)
208+
}
125209
}
126210

127211
func writeJSON(t *testing.T, path string, x interface{}) {

message/pipeline/testdata/test1/catalog_gen.go

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)