mirror of
https://github.com/burrowers/garble.git
synced 2025-10-08 17:20:18 +08:00

We use 'go list -json -export' to locate required modules. This works fine to locate direct module dependencies; since we're building in the current module, we run 'go list' in the correct directory. However, if we're building one of those module dependencies, and it has other module dependencies of its own, we would fail with cryptic errors like: typecheck error: [...] go list error: updates to go.sum needed, disabled by -mod=readonly This is because we would try to run 'go list' outside of the main module, probably inside the module cache. Instead, use a $GARBLE_DIR env var from the top-level 'garble build' call to always run 'go list' in the original directory. We add a few small modules to properly test this. Updates #9.
153 lines
4.0 KiB
Go
153 lines
4.0 KiB
Go
// Copyright (c) 2019, Daniel Martí <mvdan@mvdan.cc>
|
|
// See LICENSE for licensing information
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/rogpeppe/go-internal/goproxytest"
|
|
"github.com/rogpeppe/go-internal/gotooltest"
|
|
"github.com/rogpeppe/go-internal/testscript"
|
|
)
|
|
|
|
var proxyURL string
|
|
|
|
func TestMain(m *testing.M) {
|
|
os.Exit(testscript.RunMain(garbleMain{m}, map[string]func() int{
|
|
"garble": main1,
|
|
}))
|
|
}
|
|
|
|
type garbleMain struct {
|
|
m *testing.M
|
|
}
|
|
|
|
func (m garbleMain) Run() int {
|
|
// Start the Go proxy server running for all tests.
|
|
srv, err := goproxytest.NewServer("testdata/mod", "")
|
|
if err != nil {
|
|
panic(fmt.Sprintf("cannot start proxy: %v", err))
|
|
}
|
|
proxyURL = srv.URL
|
|
|
|
return m.m.Run()
|
|
}
|
|
|
|
var update = flag.Bool("u", false, "update testscript output files")
|
|
|
|
func TestScripts(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p := testscript.Params{
|
|
Dir: filepath.Join("testdata", "scripts"),
|
|
Setup: func(env *testscript.Env) error {
|
|
env.Vars = append(env.Vars,
|
|
"GOPROXY="+proxyURL,
|
|
"GONOSUMDB=*",
|
|
)
|
|
bindir := filepath.Join(env.WorkDir, ".bin")
|
|
if err := os.Mkdir(bindir, 0777); err != nil {
|
|
return err
|
|
}
|
|
binfile := filepath.Join(bindir, "garble")
|
|
if runtime.GOOS == "windows" {
|
|
binfile += ".exe"
|
|
}
|
|
if err := os.Symlink(os.Args[0], binfile); err != nil {
|
|
return err
|
|
}
|
|
env.Vars = append(env.Vars, fmt.Sprintf("PATH=%s%c%s", bindir, filepath.ListSeparator, os.Getenv("PATH")))
|
|
env.Vars = append(env.Vars, "TESTSCRIPT_COMMAND=garble")
|
|
return nil
|
|
},
|
|
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
|
|
"binsubstr": binsubstr,
|
|
"bincmp": bincmp,
|
|
},
|
|
UpdateScripts: *update,
|
|
}
|
|
if err := gotooltest.Setup(&p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testscript.Run(t, p)
|
|
}
|
|
|
|
func binsubstr(ts *testscript.TestScript, neg bool, args []string) {
|
|
if len(args) < 2 {
|
|
ts.Fatalf("usage: binsubstr file substr...")
|
|
}
|
|
data := ts.ReadFile(args[0])
|
|
for _, substr := range args[1:] {
|
|
match := strings.Contains(data, substr)
|
|
if match && neg {
|
|
ts.Fatalf("unexpected match for %q in %s", substr, args[0])
|
|
} else if !match && !neg {
|
|
ts.Fatalf("expected match for %q in %s", substr, args[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
func bincmp(ts *testscript.TestScript, neg bool, args []string) {
|
|
if neg {
|
|
ts.Fatalf("unsupported: ! bincmp")
|
|
}
|
|
if len(args) != 2 {
|
|
ts.Fatalf("usage: bincmp file1 file2")
|
|
}
|
|
data1 := ts.ReadFile(args[0])
|
|
data2 := ts.ReadFile(args[1])
|
|
if data1 != data2 {
|
|
if _, err := exec.LookPath("diffoscope"); err != nil {
|
|
ts.Logf("diffoscope is not installing; skipping binary diff")
|
|
} else {
|
|
// We'll error below; ignore the exec error here.
|
|
ts.Exec("diffoscope", ts.MkAbs(args[0]), ts.MkAbs(args[1]))
|
|
}
|
|
sizeDiff := len(data2) - len(data1)
|
|
ts.Fatalf("%s and %s differ; diffoscope above, size diff: %+d",
|
|
args[0], args[1], sizeDiff)
|
|
}
|
|
}
|
|
|
|
func TestFlagValue(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
flags []string
|
|
flagName string
|
|
want string
|
|
}{
|
|
{"BoolAlone", []string{"-std"}, "-std", "true"},
|
|
{"BoolFollowed", []string{"-std", "-foo"}, "-std", "true"},
|
|
{"BoolFalse", []string{"-std=false"}, "-std", "false"},
|
|
{"BoolMissing", []string{"-foo"}, "-std", ""},
|
|
{"BoolEmpty", []string{"-std="}, "-std", ""},
|
|
{"StrSpace", []string{"-buildid", "bar"}, "-buildid", "bar"},
|
|
{"StrSpaceDash", []string{"-buildid", "-bar"}, "-buildid", "-bar"},
|
|
{"StrEqual", []string{"-buildid=bar"}, "-buildid", "bar"},
|
|
{"StrEqualDash", []string{"-buildid=-bar"}, "-buildid", "-bar"},
|
|
{"StrMissing", []string{"-foo"}, "-buildid", ""},
|
|
{"StrNotFollowed", []string{"-buildid"}, "-buildid", ""},
|
|
{"StrEmpty", []string{"-buildid="}, "-buildid", ""},
|
|
}
|
|
for _, test := range tests {
|
|
test := test
|
|
t.Run(test.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
got := flagValue(test.flags, test.flagName)
|
|
if got != test.want {
|
|
t.Fatalf("flagValue(%q, %q) got %q, want %q",
|
|
test.flags, test.flagName, got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|