Commit 4d5bf3cc authored by Russ Cox's avatar Russ Cox

cmd/go: convert more module tests to scripts

Change-Id: I8a36fad061bdf9a19f40531511f3f5717db13b60
Reviewed-on: https://go-review.googlesource.com/124697
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: default avatarBryan C. Mills <bcmills@google.com>
parent d286d4b1
...@@ -972,70 +972,6 @@ func TestModInitLegacy(t *testing.T) { ...@@ -972,70 +972,6 @@ func TestModInitLegacy(t *testing.T) {
tg.grepStderrNot("copying requirements from .*Gopkg.lock", "should not copy Gopkg.lock again") tg.grepStderrNot("copying requirements from .*Gopkg.lock", "should not copy Gopkg.lock again")
} }
func TestModQueryExcluded(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.must(os.MkdirAll(tg.path("x"), 0777))
tg.must(ioutil.WriteFile(tg.path("x/x.go"), []byte(`package x; import _ "github.com/gorilla/mux"`), 0666))
gomod := []byte(`
module x
exclude rsc.io/quote v1.5.0
`)
tg.setenv(homeEnvName(), tg.path("home"))
tg.cd(tg.path("x"))
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), gomod, 0666))
tg.runFail("get", "rsc.io/quote@v1.5.0")
tg.grepStderr("rsc.io/quote@v1.5.0 excluded", "print version excluded")
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), gomod, 0666))
tg.run("get", "rsc.io/quote@v1.5.1")
tg.grepStderr("rsc.io/quote v1.5.1", "find version 1.5.1")
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), gomod, 0666))
tg.run("get", "rsc.io/quote@>=v1.5")
tg.run("list", "-m", "...quote")
tg.grepStdout("rsc.io/quote v1.5.[1-9]", "expected version 1.5.1 or later")
}
func TestModRequireExcluded(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.must(os.MkdirAll(tg.path("x"), 0777))
tg.must(ioutil.WriteFile(tg.path("x/x.go"), []byte(`package x; import _ "rsc.io/quote"`), 0666))
tg.setenv(homeEnvName(), tg.path("home"))
tg.cd(tg.path("x"))
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
module x
exclude rsc.io/sampler latest
require rsc.io/sampler latest
`), 0666))
tg.runFail("build")
tg.grepStderr("no newer version available", "only available version excluded")
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
module x
exclude rsc.io/quote v1.5.1
require rsc.io/quote v1.5.1
`), 0666))
tg.run("build")
tg.grepStderr("rsc.io/quote v1.5.2", "find version 1.5.2")
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
module x
exclude rsc.io/quote v1.5.2
require rsc.io/quote v1.5.1
`), 0666))
tg.run("build")
tg.grepStderr("rsc.io/quote v1.5.1", "find version 1.5.1")
}
func TestModInitLegacy2(t *testing.T) { func TestModInitLegacy2(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
if _, err := exec.LookPath("git"); err != nil { if _, err := exec.LookPath("git"); err != nil {
...@@ -1215,73 +1151,6 @@ func TestModFileProxy(t *testing.T) { ...@@ -1215,73 +1151,6 @@ func TestModFileProxy(t *testing.T) {
tg.mustExist(tg.path("gp2/src/mod/cache/download/rsc.io/quote/@v/list")) tg.mustExist(tg.path("gp2/src/mod/cache/download/rsc.io/quote/@v/list"))
} }
func TestModVendorNoDeps(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.must(os.MkdirAll(tg.path("x"), 0777))
tg.must(ioutil.WriteFile(tg.path("x/main.go"), []byte(`package x`), 0666))
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`module x`), 0666))
tg.cd(tg.path("x"))
tg.run("mod", "-vendor")
tg.grepStderr("go: no dependencies to vendor", "print vendor info")
}
func TestModVersionNoModule(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.cd(tg.path("."))
tg.run("version")
}
func TestModImportDomainRoot(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.setenv("GOPATH", tg.path("."))
tg.must(os.MkdirAll(tg.path("x"), 0777))
tg.must(ioutil.WriteFile(tg.path("x/main.go"), []byte(`
package x
import _ "example.com"`), 0666))
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte("module x"), 0666))
tg.cd(tg.path("x"))
tg.run("build")
}
func TestModSyncPrintJson(t *testing.T) {
tg := testGoModules(t)
defer tg.cleanup()
tg.setenv("GOPATH", tg.path("."))
tg.must(os.MkdirAll(tg.path("x"), 0777))
tg.must(ioutil.WriteFile(tg.path("x/main.go"), []byte(`
package x
import "rsc.io/quote"
func main() {
_ = mux.NewRouter()
}`), 0666))
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte("module x"), 0666))
tg.cd(tg.path("x"))
tg.run("mod", "-sync", "-json")
count := tg.grepCountBoth(`"Path": "rsc.io/quote",`)
if count != 1 {
t.Fatal("produces duplicate imports")
}
// test quoted module path
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
module x
require (
"rsc.io/sampler" v1.3.0
"rsc.io/quote" v1.5.2
)`), 0666))
tg.run("mod", "-sync", "-json")
count = tg.grepCountBoth(`"Path": "rsc.io/quote",`)
if count != 1 {
t.Fatal("produces duplicate imports")
}
}
func TestModMultiVersion(t *testing.T) { func TestModMultiVersion(t *testing.T) {
tg := testGoModules(t) tg := testGoModules(t)
defer tg.cleanup() defer tg.cleanup()
......
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
...@@ -288,6 +289,7 @@ var scriptCmds = map[string]func(*testScript, bool, []string){ ...@@ -288,6 +289,7 @@ var scriptCmds = map[string]func(*testScript, bool, []string){
"exec": (*testScript).cmdExec, "exec": (*testScript).cmdExec,
"exists": (*testScript).cmdExists, "exists": (*testScript).cmdExists,
"go": (*testScript).cmdGo, "go": (*testScript).cmdGo,
"grep": (*testScript).cmdGrep,
"mkdir": (*testScript).cmdMkdir, "mkdir": (*testScript).cmdMkdir,
"rm": (*testScript).cmdRm, "rm": (*testScript).cmdRm,
"skip": (*testScript).cmdSkip, "skip": (*testScript).cmdSkip,
...@@ -406,8 +408,13 @@ func (ts *testScript) cmdExec(neg bool, args []string) { ...@@ -406,8 +408,13 @@ func (ts *testScript) cmdExec(neg bool, args []string) {
// exists checks that the list of files exists. // exists checks that the list of files exists.
func (ts *testScript) cmdExists(neg bool, args []string) { func (ts *testScript) cmdExists(neg bool, args []string) {
var readonly bool
if len(args) > 0 && args[0] == "-readonly" {
readonly = true
args = args[1:]
}
if len(args) == 0 { if len(args) == 0 {
ts.fatalf("usage: exists file...") ts.fatalf("usage: exists [-readonly] file...")
} }
for _, file := range args { for _, file := range args {
...@@ -423,6 +430,9 @@ func (ts *testScript) cmdExists(neg bool, args []string) { ...@@ -423,6 +430,9 @@ func (ts *testScript) cmdExists(neg bool, args []string) {
if err != nil && !neg { if err != nil && !neg {
ts.fatalf("%s does not exist", file) ts.fatalf("%s does not exist", file)
} }
if err == nil && !neg && readonly && info.Mode()&0222 != 0 {
ts.fatalf("%s exists but is writable", file)
}
} }
} }
...@@ -521,20 +531,63 @@ func (ts *testScript) cmdStderr(neg bool, args []string) { ...@@ -521,20 +531,63 @@ func (ts *testScript) cmdStderr(neg bool, args []string) {
scriptMatch(ts, neg, args, ts.stderr, "stderr") scriptMatch(ts, neg, args, ts.stderr, "stderr")
} }
// grep checks that file content matches a regexp.
// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
func (ts *testScript) cmdGrep(neg bool, args []string) {
scriptMatch(ts, neg, args, "", "grep")
}
// scriptMatch implements both stdout and stderr. // scriptMatch implements both stdout and stderr.
func scriptMatch(ts *testScript, neg bool, args []string, text, name string) { func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
if len(args) != 1 { n := 0
ts.fatalf("usage: %s 'pattern' (%q)", name, args) if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
if neg {
ts.fatalf("cannot use -count= with negated match")
}
var err error
n, err = strconv.Atoi(args[0][len("-count="):])
if err != nil {
ts.fatalf("bad -count=: %v", err)
}
if n < 1 {
ts.fatalf("bad -count=: must be at least 1")
}
args = args[1:]
} }
re, err := regexp.Compile(`(?m)` + args[0])
extraUsage := ""
want := 1
if name == "grep" {
extraUsage = " file"
want = 2
}
if len(args) != want {
ts.fatalf("usage: %s [-count=N] 'pattern' file%s", name, extraUsage)
}
pattern := args[0]
re, err := regexp.Compile(`(?m)` + pattern)
ts.check(err) ts.check(err)
if name == "grep" {
data, err := ioutil.ReadFile(ts.mkabs(args[1]))
ts.check(err)
text = string(data)
}
if neg { if neg {
if re.MatchString(text) { if re.MatchString(text) {
ts.fatalf("unexpected match for %#q found in %s: %s %q", args[0], name, text, re.FindString(text)) ts.fatalf("unexpected match for %#q found in %s: %s %q", pattern, name, text, re.FindString(text))
} }
} else { } else {
if !re.MatchString(text) { if !re.MatchString(text) {
ts.fatalf("no match for %#q found in %s", args[0], name) ts.fatalf("no match for %#q found in %s", pattern, name)
}
if n > 0 {
count := len(re.FindAllString(text, -1))
if count != n {
ts.fatalf("have %d matches for %#q, want %d", count, pattern, n)
}
} }
} }
} }
......
...@@ -97,13 +97,18 @@ The commands are: ...@@ -97,13 +97,18 @@ The commands are:
It must (or must not) succeed. It must (or must not) succeed.
Note that 'exec' does not terminate the script (unlike in Unix shells). Note that 'exec' does not terminate the script (unlike in Unix shells).
- [!] exists file... - [!] exists [-readonly] file...
Each of the listed files must (or must not) exist. (Directories are allowed.) Each of the listed files or directories must (or must not) exist.
If -readonly is given, the files or directories must be unwritable.
- [!] go args... - [!] go args...
Run the (test copy of the) go command with the given arguments. Run the (test copy of the) go command with the given arguments.
It must (or must not) succeed. It must (or must not) succeed.
- [!] grep [-count=N] pattern file
The file's content must (or must not) match the regular expression pattern.
For positive matches, -count=N specifies an exact number of matches to require.
- mkdir path... - mkdir path...
Create the listed directories, if they do not already exists. Create the listed directories, if they do not already exists.
...@@ -117,13 +122,13 @@ The commands are: ...@@ -117,13 +122,13 @@ The commands are:
The packages named by the path arguments must (or must not) The packages named by the path arguments must (or must not)
be reported as "stale" by the go command. be reported as "stale" by the go command.
- [!] stderr pattern - [!] stderr [-count=N] pattern
Standard error from the most recent exec or go command Apply the grep command (see above) to the standard error
must (or must not) match the regular expression pattern. from the most recent exec or go command.
- [!] stdout pattern - [!] stdout [-count=N] pattern
Standard output from the most recent exec or go command Apply the grep command (see above) to the standard output
must (or must not) match the regular expression pattern. from the most recent exec or go command.
- stop [message] - stop [message]
Stop the test early (marking it as passing), including the message if given. Stop the test early (marking it as passing), including the message if given.
......
# Module paths that are domain roots should resolve.
# (example.com not example.com/something)
env GO111MODULE=on
go build
-- go.mod --
module x
-- x.go --
package x
import _ "example.com"
env GO111MODULE=on
# get excluded version
cp go.mod1 go.mod
! go get rsc.io/quote@v1.5.0
stderr 'rsc.io/quote@v1.5.0 excluded'
# get non-excluded version
cp go.mod1 go.mod
go get rsc.io/quote@v1.5.1
stderr 'rsc.io/quote v1.5.1'
# get range with excluded version
cp go.mod1 go.mod
go get rsc.io/quote@>=v1.5
go list -m ...quote
stdout 'rsc.io/quote v1.5.[1-9]'
-- go.mod1 --
module x
exclude rsc.io/quote v1.5.0
-- x.go --
package x
import _ "rsc.io/quote"
# build with no newer version to satisfy exclude
env GO111MODULE=on
! go list -m all
stderr 'no newer version available'
# build with newer version available
cp go.mod2 go.mod
go list -m all
stdout 'rsc.io/quote v1.5.2'
# build with excluded newer version
cp go.mod3 go.mod
go list -m all
stdout 'rsc.io/quote v1.5.1'
-- x.go --
package x
import _ "rsc.io/quote"
-- go.mod --
module x
exclude rsc.io/sampler latest
require rsc.io/sampler latest
-- go.mod2 --
module x
exclude rsc.io/quote v1.5.1
require rsc.io/quote v1.5.1
-- go.mod3 --
module x
exclude rsc.io/quote v1.5.2
require rsc.io/quote v1.5.1
# Check that mod -sync does not introduce repeated
# require statements when input go.mod has quoted requirements.
env GO111MODULE=on
go mod -sync -json
stdout -count=1 '"Path": "rsc.io/quote"'
cp go.mod2 go.mod
go mod -sync -json
stdout -count=1 '"Path": "rsc.io/quote"'
-- go.mod --
module x
-- x.go --
package x
import "rsc.io/quote"
func main() { _ = quote.Hello }
-- go.mod2 --
module x
require (
"rsc.io/sampler" v1.3.0
"rsc.io/quote" v1.5.2
)
env GO111MODULE=on
go mod -vendor
stderr '^go: no dependencies to vendor'
-- go.mod --
module x
-- x.go --
package x
# Test go version with no module.
env GO111MODULE=on
! go mod -json
go version
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment