Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catchup #8

Merged
merged 5 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions exe.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,37 +139,3 @@ func copyBinary(from, to string) error {
_, err = io.Copy(writer, reader)
return err
}

type nopTestDeps struct{}

func (nopTestDeps) MatchString(pat, str string) (result bool, err error) {
return false, nil
}

func (nopTestDeps) StartCPUProfile(w io.Writer) error {
return nil
}

func (nopTestDeps) StopCPUProfile() {}

func (nopTestDeps) WriteProfileTo(name string, w io.Writer, debug int) error {
return nil
}

func (nopTestDeps) ImportPath() string {
return ""
}
func (nopTestDeps) StartTestLog(w io.Writer) {}

func (nopTestDeps) StopTestLog() error {
return nil
}

// Note: WriteHeapProfile is needed for Go 1.10 but not Go 1.11.
func (nopTestDeps) WriteHeapProfile(io.Writer) error {
// Not needed for Go 1.10.
return nil
}

// Note: SetPanicOnExit0 was added in Go 1.16.
func (nopTestDeps) SetPanicOnExit0(bool) {}
48 changes: 0 additions & 48 deletions exe_go118.go

This file was deleted.

4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module fortio.org/testscript
go 1.20

require (
golang.org/x/sys v0.8.0
golang.org/x/tools v0.8.0
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
golang.org/x/tools v0.1.12
)
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
174 changes: 174 additions & 0 deletions gotooltest/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Copyright 2015 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 gotooltest implements functionality useful for testing
// tools that use the go command.
package gotooltest

import (
"bytes"
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"sync"

"github.com/rogpeppe/go-internal/testscript"

Check failure on line 21 in gotooltest/setup.go

View workflow job for this annotation

GitHub Actions / test (1.20.x, ubuntu-latest)

no required module provides package github.com/rogpeppe/go-internal/testscript; to add it:

Check failure on line 21 in gotooltest/setup.go

View workflow job for this annotation

GitHub Actions / test (1.20.x, macos-latest)

no required module provides package github.com/rogpeppe/go-internal/testscript; to add it:

Check failure on line 21 in gotooltest/setup.go

View workflow job for this annotation

GitHub Actions / test (1.20.x, windows-latest)

no required module provides package github.com/rogpeppe/go-internal/testscript; to add it:

Check failure on line 21 in gotooltest/setup.go

View workflow job for this annotation

GitHub Actions / test (1.20.x, windows-latest)

no required module provides package github.com/rogpeppe/go-internal/testscript; to add it:
)

var (
goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.([1-9][0-9]*)$`)

goEnv struct {
GOROOT string
GOCACHE string
GOPROXY string
goversion string
releaseTags []string
once sync.Once
err error
}
)

// initGoEnv initialises goEnv. It should only be called using goEnv.once.Do,
// as in Setup.
//
// Run all of these probe commands in a temporary directory, so as not to make
// any assumptions about the caller's working directory.
func initGoEnv() (err error) {
td, err := os.MkdirTemp("", "gotooltest-initGoEnv")
if err != nil {
return fmt.Errorf("failed to create temporary directory for go command tests: %w", err)
}
defer func() {
if rerr := os.RemoveAll(td); rerr != nil && err == nil {
err = fmt.Errorf("failed to remove temporary directory for go command tests: %w", rerr)
}
}()

// Write a temporary go.mod file in td. This ensures that we create
// a porcelain environment in which to run these probe commands.
if err := os.WriteFile(filepath.Join(td, "go.mod"), []byte("module gotooltest"), 0600); err != nil {
return fmt.Errorf("failed to write temporary go.mod file: %w", err)
}

run := func(args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
var stdout, stderr bytes.Buffer
cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = td
cmd.Stdout = &stdout
cmd.Stderr = &stderr
return &stdout, &stderr, cmd.Run()
}

lout, stderr, err := run("go", "list", "-f={{context.ReleaseTags}}", "runtime")
if err != nil {
return fmt.Errorf("failed to determine release tags from go command: %v\n%v", err, stderr.String())
}
tagStr := strings.TrimSpace(lout.String())
tagStr = strings.Trim(tagStr, "[]")
goEnv.releaseTags = strings.Split(tagStr, " ")

eout, stderr, err := run("go", "env", "-json",
"GOROOT",
"GOCACHE",
"GOPROXY",
)
if err != nil {
return fmt.Errorf("failed to determine environment from go command: %v\n%v", err, stderr)
}
if err := json.Unmarshal(eout.Bytes(), &goEnv); err != nil {
return fmt.Errorf("failed to unmarshal GOROOT and GOCACHE tags from go command out: %v\n%v", err, eout)
}

version := goEnv.releaseTags[len(goEnv.releaseTags)-1]
if !goVersionRegex.MatchString(version) {
return fmt.Errorf("invalid go version %q", version)
}
goEnv.goversion = version[2:]

return nil
}

// Setup sets up the given test environment for tests that use the go
// command. It adds support for go tags to p.Condition and adds the go
// command to p.Cmds. It also wraps p.Setup to set up the environment
// variables for running the go command appropriately.
//
// It checks go command can run, but not that it can build or run
// binaries.
func Setup(p *testscript.Params) error {
goEnv.once.Do(func() {
goEnv.err = initGoEnv()
})
if goEnv.err != nil {
return goEnv.err
}

origSetup := p.Setup
p.Setup = func(e *testscript.Env) error {
e.Vars = goEnviron(e.Vars)
if origSetup != nil {
return origSetup(e)
}
return nil
}
if p.Cmds == nil {
p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string))
}
p.Cmds["go"] = cmdGo
return nil
}

func goEnviron(env0 []string) []string {
env := environ(env0)
workdir := env.get("WORK")
return append(env, []string{
"GOPATH=" + filepath.Join(workdir, ".gopath"),
"CCACHE_DISABLE=1", // ccache breaks with non-existent HOME
"GOARCH=" + runtime.GOARCH,
"GOOS=" + runtime.GOOS,
"GOROOT=" + goEnv.GOROOT,
"GOCACHE=" + goEnv.GOCACHE,
"GOPROXY=" + goEnv.GOPROXY,
"goversion=" + goEnv.goversion,
}...)
}

func cmdGo(ts *testscript.TestScript, neg bool, args []string) {
if len(args) < 1 {
ts.Fatalf("usage: go subcommand ...")
}
err := ts.Exec("go", args...)
if err != nil {
ts.Logf("[%v]\n", err)
if !neg {
ts.Fatalf("unexpected go command failure")
}
} else {
if neg {
ts.Fatalf("unexpected go command success")
}
}
}

type environ []string

func (e0 *environ) get(name string) string {
e := *e0
for i := len(e) - 1; i >= 0; i-- {
v := e[i]
if len(v) <= len(name) {
continue
}
if strings.HasPrefix(v, name) && v[len(name)] == '=' {
return v[len(name)+1:]
}
}
return ""
}
Loading
Loading