diff options
| author | Than McIntosh <thanm@google.com> | 2024-07-25 17:15:35 +0000 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2024-07-29 16:13:04 +0000 |
| commit | 0d8aa5737ecdc03b2723a2af35cb7394335e5411 (patch) | |
| tree | 91e075eec22ec01378f117a17c454f97ad93f71d /src/cmd/internal/script/scripttest/setup.go | |
| parent | 32b55eda5e6956e7ee2f913ae79e1e2a3414c9ed (diff) | |
| download | go-0d8aa5737ecdc03b2723a2af35cb7394335e5411.tar.xz | |
cmd/internal/script/scriptest: add new apis for tool test use
Add top level apis to provide a general-purpose "script test" runner
for clients within cmd, e.g. tools such as compile, link, nm, and so
on. This patch doesn't add any uses of the new apis, this will
happen in follow-on CLs.
Updates #68606.
Change-Id: Ib7200a75d4dc7dc50897628f1a6269937be15a76
Reviewed-on: https://go-review.googlesource.com/c/go/+/601359
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/internal/script/scripttest/setup.go')
| -rw-r--r-- | src/cmd/internal/script/scripttest/setup.go | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/cmd/internal/script/scripttest/setup.go b/src/cmd/internal/script/scripttest/setup.go new file mode 100644 index 0000000000..d430367c12 --- /dev/null +++ b/src/cmd/internal/script/scripttest/setup.go @@ -0,0 +1,105 @@ +// Copyright 2024 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. + +// Package scripttest adapts the script engine for use in tests. +package scripttest + +import ( + "io" + "os" + "path/filepath" + "runtime" + "testing" +) + +// SetupTestGoRoot sets up a temporary GOROOT for use with script test +// execution. It copies the existing goroot bin and pkg dirs using +// symlinks (if possible) or raw copying. Return value is the path to +// the newly created testgoroot dir. +func SetupTestGoRoot(t *testing.T, tmpdir string, goroot string) string { + mustMkdir := func(path string) { + if err := os.MkdirAll(path, 0777); err != nil { + t.Fatalf("SetupTestGoRoot mkdir %s failed: %v", path, err) + } + } + + replicateDir := func(srcdir, dstdir string) { + files, err := os.ReadDir(srcdir) + if err != nil { + t.Fatalf("inspecting %s: %v", srcdir, err) + } + for _, file := range files { + fn := file.Name() + linkOrCopy(t, filepath.Join(srcdir, fn), filepath.Join(dstdir, fn)) + } + } + + // Create various dirs in testgoroot. + toolsub := filepath.Join("tool", runtime.GOOS+"_"+runtime.GOARCH) + tomake := []string{ + "bin", + "src", + "pkg", + filepath.Join("pkg", "include"), + filepath.Join("pkg", toolsub), + } + made := []string{} + tgr := filepath.Join(tmpdir, "testgoroot") + mustMkdir(tgr) + for _, targ := range tomake { + path := filepath.Join(tgr, targ) + mustMkdir(path) + made = append(made, path) + } + + // Replicate selected portions of the content. + replicateDir(filepath.Join(goroot, "bin"), made[0]) + replicateDir(filepath.Join(goroot, "src"), made[1]) + replicateDir(filepath.Join(goroot, "pkg", "include"), made[3]) + replicateDir(filepath.Join(goroot, "pkg", toolsub), made[4]) + + return tgr +} + +// ReplaceGoToolInTestGoRoot replaces the go tool binary toolname with +// an alternate executable newtoolpath within a test GOROOT directory +// previously created by SetupTestGoRoot. +func ReplaceGoToolInTestGoRoot(t *testing.T, testgoroot, toolname, newtoolpath string) { + toolsub := filepath.Join("pkg", "tool", runtime.GOOS+"_"+runtime.GOARCH) + exename := toolname + if runtime.GOOS == "windows" { + exename += ".exe" + } + toolpath := filepath.Join(testgoroot, toolsub, exename) + if err := os.Remove(toolpath); err != nil { + t.Fatalf("removing %s: %v", toolpath, err) + } + linkOrCopy(t, newtoolpath, toolpath) +} + +// linkOrCopy creates a link to src at dst, or if the symlink fails +// (platform doesn't support) then copies src to dst. +func linkOrCopy(t *testing.T, src, dst string) { + err := os.Symlink(src, dst) + if err == nil { + return + } + srcf, err := os.Open(src) + if err != nil { + t.Fatalf("copying %s to %s: %v", src, dst, err) + } + defer srcf.Close() + perm := os.O_WRONLY | os.O_CREATE | os.O_EXCL + dstf, err := os.OpenFile(dst, perm, 0o777) + if err != nil { + t.Fatalf("copying %s to %s: %v", src, dst, err) + } + _, err = io.Copy(dstf, srcf) + if closeErr := dstf.Close(); err == nil { + err = closeErr + } + if err != nil { + t.Fatalf("copying %s to %s: %v", src, dst, err) + } +} |
