diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:16:40 +0000 |
commit | 47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch) | |
tree | a61a0ffd83f4a3def4b36e5c8e99630c559aa723 /src/cmd/go/testdata | |
parent | Initial commit. (diff) | |
download | golang-1.18-upstream.tar.xz golang-1.18-upstream.zip |
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/go/testdata')
870 files changed, 43737 insertions, 0 deletions
diff --git a/src/cmd/go/testdata/addmod.go b/src/cmd/go/testdata/addmod.go new file mode 100644 index 0000000..eac2a7a --- /dev/null +++ b/src/cmd/go/testdata/addmod.go @@ -0,0 +1,155 @@ +// Copyright 2018 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. + +//go:build ignore +// +build ignore + +// Addmod adds a module as a txtar archive to the testdata/mod directory. +// +// Usage: +// +// go run addmod.go path@version... +// +// It should only be used for very small modules - we do not want to check +// very large files into testdata/mod. +// +// It is acceptable to edit the archive afterward to remove or shorten files. +// See mod/README for more information. +// +package main + +import ( + "bytes" + "flag" + "fmt" + exec "internal/execabs" + "io/fs" + "log" + "os" + "path/filepath" + "strings" + + "golang.org/x/tools/txtar" +) + +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run addmod.go path@version...\n") + os.Exit(2) +} + +var tmpdir string + +func fatalf(format string, args ...any) { + os.RemoveAll(tmpdir) + log.Fatalf(format, args...) +} + +const goCmd = "go" + +func main() { + flag.Usage = usage + flag.Parse() + if flag.NArg() == 0 { + usage() + } + + log.SetPrefix("addmod: ") + log.SetFlags(0) + + var err error + tmpdir, err = os.MkdirTemp("", "addmod-") + if err != nil { + log.Fatal(err) + } + + run := func(command string, args ...string) string { + cmd := exec.Command(command, args...) + cmd.Dir = tmpdir + var stderr bytes.Buffer + cmd.Stderr = &stderr + out, err := cmd.Output() + if err != nil { + fatalf("%s %s: %v\n%s", command, strings.Join(args, " "), err, stderr.Bytes()) + } + return string(out) + } + + gopath := strings.TrimSpace(run("go", "env", "GOPATH")) + if gopath == "" { + fatalf("cannot find GOPATH") + } + + exitCode := 0 + for _, arg := range flag.Args() { + if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { + fatalf("%v", err) + } + run(goCmd, "get", "-d", arg) + path := arg + if i := strings.Index(path, "@"); i >= 0 { + path = path[:i] + } + out := run(goCmd, "list", "-m", "-f={{.Path}} {{.Version}} {{.Dir}}", path) + f := strings.Fields(out) + if len(f) != 3 { + log.Printf("go list -m %s: unexpected output %q", arg, out) + exitCode = 1 + continue + } + path, vers, dir := f[0], f[1], f[2] + mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + + a := new(txtar.Archive) + title := arg + if !strings.Contains(arg, "@") { + title += "@" + vers + } + a.Comment = []byte(fmt.Sprintf("module %s\n\n", title)) + a.Files = []txtar.File{ + {Name: ".mod", Data: mod}, + {Name: ".info", Data: info}, + } + dir = filepath.Clean(dir) + err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { + if !info.Type().IsRegular() { + return nil + } + name := info.Name() + if name == "go.mod" || strings.HasSuffix(name, ".go") { + data, err := os.ReadFile(path) + if err != nil { + return err + } + a.Files = append(a.Files, txtar.File{Name: strings.TrimPrefix(path, dir+string(filepath.Separator)), Data: data}) + } + return nil + }) + if err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + + data := txtar.Format(a) + target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt") + if err := os.WriteFile(target, data, 0666); err != nil { + log.Printf("%s: %v", arg, err) + exitCode = 1 + continue + } + } + os.RemoveAll(tmpdir) + os.Exit(exitCode) +} diff --git a/src/cmd/go/testdata/failssh/ssh b/src/cmd/go/testdata/failssh/ssh new file mode 100755 index 0000000..ecdbef9 --- /dev/null +++ b/src/cmd/go/testdata/failssh/ssh @@ -0,0 +1,2 @@ +#!/bin/sh +exit 1 diff --git a/src/cmd/go/testdata/mod/README b/src/cmd/go/testdata/mod/README new file mode 100644 index 0000000..43ddf77 --- /dev/null +++ b/src/cmd/go/testdata/mod/README @@ -0,0 +1,36 @@ +This directory holds Go modules served by a Go module proxy +that runs on localhost during tests, both to make tests avoid +requiring specific network servers and also to make them +significantly faster. + +A small go get'able test module can be added here by running + + cd cmd/go/testdata + go run addmod.go path@vers + +where path and vers are the module path and version to add here. + +For interactive experimentation using this set of modules, run: + + cd cmd/go + go test -proxy=localhost:1234 & + export GOPROXY=http://localhost:1234/mod + +and then run go commands as usual. + +Modules saved to this directory should be small: a few kilobytes at most. +It is acceptable to edit the archives created by addmod.go to remove +or shorten files. It is also acceptable to write module archives by hand: +they need not be backed by some public git repo. + +Each module archive is named path_vers.txt, where slashes in path +have been replaced with underscores. The archive must contain +two files ".info" and ".mod", to be served as the info and mod files +in the proxy protocol (see https://research.swtch.com/vgo-module). +The remaining files are served as the content of the module zip file. +The path@vers prefix required of files in the zip file is added +automatically by the proxy: the files in the archive have names without +the prefix, like plain "go.mod", "x.go", and so on. + +See ../addmod.go and ../savedir.go for tools to generate txtar files, +although again it is also fine to write them by hand. diff --git a/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt b/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt new file mode 100644 index 0000000..a869519 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_ambiguous_a_b_v0.0.0-empty.txt @@ -0,0 +1,12 @@ +Module example.com/ambiguous/a/b is a suffix of example.com/a. +This version contains no package. +-- .mod -- +module example.com/ambiguous/a/b + +go 1.16 +-- .info -- +{"Version":"v0.0.0-empty"} +-- go.mod -- +module example.com/ambiguous/a/b + +go 1.16 diff --git a/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt new file mode 100644 index 0000000..bb43826 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_ambiguous_a_v1.0.0.txt @@ -0,0 +1,18 @@ +Module example.com/ambiguous/a is a prefix of example.com/a/b. +It contains package example.com/a/b. +-- .mod -- +module example.com/ambiguous/a + +go 1.16 + +require example.com/ambiguous/a/b v0.0.0-empty +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/ambiguous/a + +go 1.16 + +require example.com/ambiguous/a/b v0.0.0-empty +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/mod/example.com_badchain_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_a_v1.0.0.txt new file mode 100644 index 0000000..d7bf647 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_a_v1.0.0.txt @@ -0,0 +1,12 @@ +example.com/badchain/a v1.0.0 + +-- .mod -- +module example.com/badchain/a + +require example.com/badchain/b v1.0.0 +-- .info -- +{"Version":"v1.0.0"} +-- a.go -- +package a + +import _ "example.com/badchain/b" diff --git a/src/cmd/go/testdata/mod/example.com_badchain_a_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_a_v1.1.0.txt new file mode 100644 index 0000000..92190d8 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_a_v1.1.0.txt @@ -0,0 +1,12 @@ +example.com/badchain/a v1.1.0 + +-- .mod -- +module example.com/badchain/a + +require example.com/badchain/b v1.1.0 +-- .info -- +{"Version":"v1.1.0"} +-- a.go -- +package a + +import _ "example.com/badchain/b" diff --git a/src/cmd/go/testdata/mod/example.com_badchain_b_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_b_v1.0.0.txt new file mode 100644 index 0000000..d42b8aa --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_b_v1.0.0.txt @@ -0,0 +1,12 @@ +example.com/badchain/b v1.0.0 + +-- .mod -- +module example.com/badchain/b + +require example.com/badchain/c v1.0.0 +-- .info -- +{"Version":"v1.0.0"} +-- b.go -- +package b + +import _ "example.com/badchain/c" diff --git a/src/cmd/go/testdata/mod/example.com_badchain_b_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_b_v1.1.0.txt new file mode 100644 index 0000000..6648184 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_b_v1.1.0.txt @@ -0,0 +1,12 @@ +example.com/badchain/b v1.1.0 + +-- .mod -- +module example.com/badchain/b + +require example.com/badchain/c v1.1.0 +-- .info -- +{"Version":"v1.1.0"} +-- b.go -- +package b + +import _ "example.com/badchain/c" diff --git a/src/cmd/go/testdata/mod/example.com_badchain_c_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_c_v1.0.0.txt new file mode 100644 index 0000000..9c717cb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_c_v1.0.0.txt @@ -0,0 +1,8 @@ +example.com/badchain/c v1.0.0 + +-- .mod -- +module example.com/badchain/c +-- .info -- +{"Version":"v1.0.0"} +-- c.go -- +package c diff --git a/src/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt new file mode 100644 index 0000000..36bc2c6 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_badchain_c_v1.1.0.txt @@ -0,0 +1,8 @@ +example.com/badchain/c v1.1.0 + +-- .mod -- +module badchain.example.com/c +-- .info -- +{"Version":"v1.1.0"} +-- c.go -- +package c diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt new file mode 100644 index 0000000..c883d8a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-exclude.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-exclude"} +-- .mod -- +module example.com/cmd + +go 1.16 + +exclude rsc.io/quote v1.5.2 +-- go.mod -- +module example.com/cmd + +go 1.16 + +exclude rsc.io/quote v1.5.2 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt new file mode 100644 index 0000000..7670f29 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-newerself.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-newerself"} +-- .mod -- +module example.com/cmd + +go 1.16 + +require example.com/cmd v1.0.0 +-- go.mod -- +module example.com/cmd + +go 1.16 + +require example.com/cmd v1.0.0 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt new file mode 100644 index 0000000..581a496 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0-replace.txt @@ -0,0 +1,28 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.0.0-replace"} +-- .mod -- +module example.com/cmd + +go 1.16 + +replace rsc.io/quote => rsc.io/quote v1.5.2 +-- go.mod -- +module example.com/cmd + +go 1.16 + +replace rsc.io/quote => rsc.io/quote v1.5.2 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt new file mode 100644 index 0000000..c198139 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.0.0.txt @@ -0,0 +1,31 @@ +example.com/cmd contains main packages. + +v1.0.0 is the latest non-retracted version. Other versions contain errors or +detectable problems. + +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/cmd + +go 1.16 +-- go.mod -- +module example.com/cmd + +go 1.16 +-- a/a.go -- +package main + +import "fmt" + +func main() { fmt.Println("a@v1.0.0") } +-- b/b.go -- +package main + +import "fmt" + +func main() { fmt.Println("b@v1.0.0") } +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt new file mode 100644 index 0000000..9298afb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_cmd_v1.9.0.txt @@ -0,0 +1,30 @@ +example.com/cmd contains main packages. + +-- .info -- +{"Version":"v1.9.0"} +-- .mod -- +module example.com/cmd + +go 1.16 + +// this is a bad version +retract v1.9.0 +-- go.mod -- +module example.com/cmd + +go 1.16 + +// this is a bad version +retract v1.9.0 +-- a/a.go -- +package main + +func main() {} +-- b/b.go -- +package main + +func main() {} +-- err/err.go -- +package err + +var X = DoesNotCompile diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt new file mode 100644 index 0000000..7c29621 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/deprecated/a + +go 1.17 +-- go.mod -- +module example.com/deprecated/a + +go 1.17 +-- a.go -- +package a diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt new file mode 100644 index 0000000..0613389 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_deprecated_a_v1.9.0.txt @@ -0,0 +1,14 @@ +-- .info -- +{"Version":"v1.9.0"} +-- .mod -- +// Deprecated: in example.com/deprecated/a@v1.9.0 +module example.com/deprecated/a + +go 1.17 +-- go.mod -- +// Deprecated: in example.com/deprecated/a@v1.9.0 +module example.com/deprecated/a + +go 1.17 +-- a.go -- +package a diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt new file mode 100644 index 0000000..50006ae --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/deprecated/b + +go 1.17 +-- go.mod -- +module example.com/deprecated/b + +go 1.17 +-- b.go -- +package b diff --git a/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt new file mode 100644 index 0000000..163d6b5 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_deprecated_b_v1.9.0.txt @@ -0,0 +1,14 @@ +-- .info -- +{"Version":"v1.9.0"} +-- .mod -- +// Deprecated: in example.com/deprecated/b@v1.9.0 +module example.com/deprecated/b + +go 1.17 +-- go.mod -- +// Deprecated: in example.com/deprecated/b@v1.9.0 +module example.com/deprecated/b + +go 1.17 +-- b.go -- +package b diff --git a/src/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt new file mode 100644 index 0000000..4f7f4d7 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt @@ -0,0 +1,16 @@ +This module's path ends with ".go". +Based on github.com/nats-io/nats.go. +Used in regression tests for golang.org/issue/32483. + +-- .mod -- +module example.com/dotgo.go + +go 1.13 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/dotgo.go + +go 1.13 +-- dotgo.go -- +package dotgo diff --git a/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt new file mode 100644 index 0000000..2ada3a3 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_dotname_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/dotname + +go 1.16 +-- go.mod -- +module example.com/dotname + +go 1.16 +-- .dot/dot.go -- +package dot diff --git a/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt b/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt new file mode 100644 index 0000000..88d50e5 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_downgrade_v2.0.0.txt @@ -0,0 +1,9 @@ +example.com/downgrade v2.0.0 +written by hand + +-- .mod -- +module example.com/downgrade + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v2.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt b/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt new file mode 100644 index 0000000..a4d665f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_downgrade_v2_v2.0.1.txt @@ -0,0 +1,13 @@ +example.com/downgrade/v2 v2.0.1 +written by hand + +-- .mod -- +module example.com/downgrade/v2 + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v2.0.1"} +-- go.mod -- +module example.com/downgrade/v2 + +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.1.0.txt new file mode 100644 index 0000000..af005ff --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.1.0.txt @@ -0,0 +1,20 @@ +-- .mod -- +module example.com/fuzzfail + +go 1.18 +-- .info -- +{"Version":"v0.1.0"} +-- go.mod -- +module example.com/fuzzfail + +go 1.18 +-- fuzzfail_test.go -- +package fuzzfail + +import "testing" + +func FuzzFail(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + t.Fatalf("oops: %q", b) + }) +} diff --git a/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.2.0.txt b/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.2.0.txt new file mode 100644 index 0000000..ea599aa --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_fuzzfail_v0.2.0.txt @@ -0,0 +1,23 @@ +-- .mod -- +module example.com/fuzzfail + +go 1.18 +-- .info -- +{"Version":"v0.2.0"} +-- go.mod -- +module example.com/fuzzfail + +go 1.18 +-- fuzzfail_test.go -- +package fuzzfail + +import "testing" + +func FuzzFail(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + t.Fatalf("oops: %q", b) + }) +} +-- testdata/fuzz/FuzzFail/bbb0c2d22aa1a24617301566dc7486f8b625d38024603ba62757c1124013b49a -- +go test fuzz v1 +[]byte("\x05") diff --git a/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v1.0.0.txt new file mode 100644 index 0000000..435578d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v1.0.0.txt @@ -0,0 +1,8 @@ +Module example.com/incompatiblewithsub has an incompatible version +and a package in a subdirectory. +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +module example.com/incompatiblewithsub +-- sub/sub.go -- +package sub diff --git a/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v2.0.0+incompatible.txt new file mode 100644 index 0000000..198ec17 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_incompatiblewithsub_v2.0.0+incompatible.txt @@ -0,0 +1,8 @@ +Module example.com/incompatiblewithsub has an incompatible version +and a package in a subdirectory. +-- .info -- +{"Version":"v2.0.0+incompatible"} +-- .mod -- +module example.com/incompatiblewithsub +-- sub/sub.go -- +package sub diff --git a/src/cmd/go/testdata/mod/example.com_invalidpath_v1_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_invalidpath_v1_v1.0.0.txt new file mode 100644 index 0000000..7d9d130 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_invalidpath_v1_v1.0.0.txt @@ -0,0 +1,13 @@ +example.com/invalidpath/v1 v1.0.0 +written by hand + +-- .mod -- +module example.com/invalidpath/v1 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/invalidpath/v1 +-- version.go -- +package version + +const V = "v1.0.0" diff --git a/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.0.0.txt new file mode 100644 index 0000000..1ecfa0b --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.0.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for package moved into a parent module. + +-- .mod -- +module example.com/join/subpkg +-- .info -- +{"Version": "v1.0.0"} +-- x.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.1.0.txt new file mode 100644 index 0000000..9eb823a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_join_subpkg_v1.1.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for package moved into a parent module. + +-- .mod -- +module example.com/join/subpkg + +require example.com/join v1.1.0 +-- .info -- +{"Version": "v1.1.0"} diff --git a/src/cmd/go/testdata/mod/example.com_join_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_join_v1.0.0.txt new file mode 100644 index 0000000..84c68b1 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_join_v1.0.0.txt @@ -0,0 +1,7 @@ +Written by hand. +Test case for package moved into a parent module. + +-- .mod -- +module example.com/join +-- .info -- +{"Version": "v1.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_join_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_join_v1.1.0.txt new file mode 100644 index 0000000..5f92036 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_join_v1.1.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for package moved into a parent module. + +-- .mod -- +module example.com/join +-- .info -- +{"Version": "v1.1.0"} +-- subpkg/x.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt new file mode 100644 index 0000000..25bd3d9 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.0.txt @@ -0,0 +1,14 @@ +example.com/latemigrate/v2 v2.0.0 +written by hand + +This repository migrated to modules in v2.0.1 after v2.0.0 was already tagged. +All versions require rsc.io/quote so we can test downgrades. + +v2.0.0 is technically part of example.com/latemigrate as v2.0.0+incompatible. +Proxies may serve it as part of the version list for example.com/latemigrate/v2. +'go get' must be able to ignore these versions. + +-- .mod -- +module example.com/latemigrate +-- .info -- +{"Version":"v2.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt new file mode 100644 index 0000000..be427a3 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_latemigrate_v2_v2.0.1.txt @@ -0,0 +1,20 @@ +example.com/latemigrate/v2 v2.0.1 +written by hand + +This repository migrated to modules in v2.0.1 after v2.0.0 was already tagged. +All versions require rsc.io/quote so we can test downgrades. + +v2.0.1 belongs to example.com/latemigrate/v2. + +-- .mod -- +module example.com/latemigrate/v2 + +require rsc.io/quote v1.3.0 +-- .info -- +{"Version":"v2.0.1"} +-- go.mod -- +module example.com/latemigrate/v2 + +require rsc.io/quote v1.3.0 +-- late.go -- +package late diff --git a/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.0.txt new file mode 100644 index 0000000..15f3f69 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.0.txt @@ -0,0 +1,11 @@ +The deprecated package is present in this version (which is @latest) but +is deleted in a newer prerelease version. + +-- .mod -- +module example.com/missingpkg +-- .info -- +{"Version":"v1.0.0"} +-- lib.go -- +package lib +-- deprecated/deprecated.go -- +package deprecated diff --git a/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.1-beta.txt b/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.1-beta.txt new file mode 100644 index 0000000..44580fe --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_missingpkg_v1.0.1-beta.txt @@ -0,0 +1,8 @@ +The deprecated package is deleted in this version. + +-- .mod -- +module example.com/missingpkg +-- .info -- +{"Version":"v1.0.1-beta"} +-- lib.go -- +package lib diff --git a/src/cmd/go/testdata/mod/example.com_nest_sub_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_nest_sub_v1.0.0.txt new file mode 100644 index 0000000..90f1459 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_nest_sub_v1.0.0.txt @@ -0,0 +1,12 @@ +Written by hand. +Test case for nested modules without an explicit relationship. +This is nested below the top-level module. + +-- .mod -- +module example.com/nest/sub +-- .info -- +{"Version": "v1.0.0"} +-- go.mod -- +module example.com/nest/sub +-- y/y.go -- +package y diff --git a/src/cmd/go/testdata/mod/example.com_nest_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_nest_v1.0.0.txt new file mode 100644 index 0000000..593caf1 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_nest_v1.0.0.txt @@ -0,0 +1,12 @@ +Written by hand. +Test case for nested modules without an explicit relationship. +This is the top-level module. + +-- .mod -- +module example.com/nest +-- .info -- +{"Version": "v1.0.0"} +-- go.mod -- +module example.com/nest +-- sub/x/x.go -- +package x diff --git a/src/cmd/go/testdata/mod/example.com_nest_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_nest_v1.1.0.txt new file mode 100644 index 0000000..5a01550 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_nest_v1.1.0.txt @@ -0,0 +1,12 @@ +Written by hand. +Test case for nested modules without an explicit relationship. +This is the top-level module. + +-- .mod -- +module example.com/nest +-- .info -- +{"Version": "v1.1.0"} +-- go.mod -- +module example.com/nest +-- sub/x/x.go -- +package x diff --git a/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.0.txt new file mode 100644 index 0000000..829065d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.0.txt @@ -0,0 +1,10 @@ +example.com/newcycle/a v1.0.0 + +Transitively requires v1.0.1 of itself via example.com/newcycle/b + +-- .mod -- +module example.com/newcycle/a + +require example.com/newcycle/b v1.0.0 +-- .info -- +{"Version":"v1.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.1.txt new file mode 100644 index 0000000..a03f4b4 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_newcycle_a_v1.0.1.txt @@ -0,0 +1,10 @@ +example.com/newcycle/a v1.0.1 + +Transitively requires itself via example.com/newcycle/b + +-- .mod -- +module example.com/newcycle/a + +require example.com/newcycle/b v1.0.0 +-- .info -- +{"Version":"v1.0.1"} diff --git a/src/cmd/go/testdata/mod/example.com_newcycle_b_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_newcycle_b_v1.0.0.txt new file mode 100644 index 0000000..ff9e1f5 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_newcycle_b_v1.0.0.txt @@ -0,0 +1,8 @@ +example.com/newcycle/b v1.0.0 + +-- .mod -- +module example.com/newcycle/b + +require example.com/newcycle/a v1.0.1 +-- .info -- +{"Version":"v1.0.0"} diff --git a/src/cmd/go/testdata/mod/example.com_noroot_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_noroot_v1.0.0.txt new file mode 100644 index 0000000..aa5febf --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_noroot_v1.0.0.txt @@ -0,0 +1,8 @@ +A module which has no root package. + +-- .mod -- +module example.com/noroot +-- .info -- +{"Version":"v1.0.0"} +-- pkg/pkg.go -- +package pkg diff --git a/src/cmd/go/testdata/mod/example.com_noroot_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_noroot_v1.0.1.txt new file mode 100644 index 0000000..9b93717 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_noroot_v1.0.1.txt @@ -0,0 +1,8 @@ +A module which has no root package. + +-- .mod -- +module example.com/noroot +-- .info -- +{"Version":"v1.0.1"} +-- pkg/pkg.go -- +package pkg diff --git a/src/cmd/go/testdata/mod/example.com_notags_v0.0.0-20190507143103-cc8cbe209b64.txt b/src/cmd/go/testdata/mod/example.com_notags_v0.0.0-20190507143103-cc8cbe209b64.txt new file mode 100644 index 0000000..259774d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_notags_v0.0.0-20190507143103-cc8cbe209b64.txt @@ -0,0 +1,9 @@ +Written by hand. +The "latest" version of a module without any tags. + +-- .mod -- +module example.com/notags +-- .info -- +{"Version":"v0.0.0-20190507143103-cc8cbe209b64","Time":"2019-05-07T07:31:03-07:00"} +-- notags.go -- +package notags diff --git a/src/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt new file mode 100644 index 0000000..606322a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_printversion_v0.1.0.txt @@ -0,0 +1,33 @@ +example.com/printversion v0.1.0 + +-- .mod -- +module example.com/printversion +-- .info -- +{"Version":"v0.1.0"} +-- README.txt -- +There is no go.mod file for this version of the module. +-- printversion.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, _ := debug.ReadBuildInfo() + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + if r := info.Main.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + if r := m.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } + } +} diff --git a/src/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt new file mode 100644 index 0000000..b9b71e9 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_printversion_v1.0.0.txt @@ -0,0 +1,41 @@ +example.com/printversion v1.0.0 + +-- .mod -- +module example.com/printversion + +require example.com/version v1.0.0 +replace example.com/version v1.0.0 => ../oops v0.0.0 +exclude example.com/version v1.1.0 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/printversion + +require example.com/version v1.0.0 +replace example.com/version v1.0.0 => ../oops v0.0.0 +exclude example.com/version v1.0.1 +-- printversion.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, _ := debug.ReadBuildInfo() + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + if r := info.Main.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + if r := m.Replace; r != nil { + fmt.Fprintf(os.Stdout, "\t(replaced by %s %s)\n", r.Path, r.Version) + } + } +} diff --git a/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.0.0-20190430073000-30950c05d534.txt b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.0.0-20190430073000-30950c05d534.txt new file mode 100644 index 0000000..047ceb6 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.0.0-20190430073000-30950c05d534.txt @@ -0,0 +1,13 @@ +example.com/pseudoupgrade v0.0.0-20190429073000-30950c05d534 +written by hand + +-- .mod -- +module example.com/pseudoupgrade + +-- .info -- +{"Version":"v0.0.0-20190430073000-30950c05d534","Name":"v0.0.0-20190430073000-30950c05d534","Short":"30950c05d534","Time":"2019-04-30T07:30:00Z"} + +-- pseudoupgrade.go -- +package pseudoupgrade + +const X = 1 diff --git a/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.0.txt new file mode 100644 index 0000000..7ddb0dc --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.0.txt @@ -0,0 +1,13 @@ +example.com/pseudoupgrade v0.1.0 +written by hand + +-- .mod -- +module example.com/pseudoupgrade + +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2019-04-29T07:30:30Z"} + +-- pseudoupgrade.go -- +package pseudoupgrade + +const X = 1 diff --git a/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.1-0.20190429073117-b5426c86b553.txt b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.1-0.20190429073117-b5426c86b553.txt new file mode 100644 index 0000000..b3f48bb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_pseudoupgrade_v0.1.1-0.20190429073117-b5426c86b553.txt @@ -0,0 +1,13 @@ +example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553 +written by hand + +-- .mod -- +module example.com/pseudoupgrade + +-- .info -- +{"Version":"v0.1.1-0.20190429073117-b5426c86b553","Name":"v0.1.1-0.20190429073117-b5426c86b553","Short":"b5426c86b553","Time":"2019-04-29T07:31:00Z"} + +-- pseudoupgrade.go -- +package pseudoupgrade + +const X = 1 diff --git a/src/cmd/go/testdata/mod/example.com_quote_v1.5.2.txt b/src/cmd/go/testdata/mod/example.com_quote_v1.5.2.txt new file mode 100644 index 0000000..05f7ae2 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_quote_v1.5.2.txt @@ -0,0 +1,9 @@ +This module is a replacement for rsc.io/quote, but its go.mod file declares +a module path different from its location and the original module. + +-- .mod -- +module rsc.io/Quote + +go 1.14 +-- .info -- +{"Version":"v1.5.2"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt new file mode 100644 index 0000000..f8e623d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_nested_v1.9.0-bad.txt @@ -0,0 +1,10 @@ +-- .mod -- +module example.com/retract/ambiguous/nested + +go 1.16 + +retract v1.9.0-bad // nested modules are bad +-- .info -- +{"Version":"v1.9.0-bad"} +-- nested.go -- +package nested diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt new file mode 100644 index 0000000..5ee0139 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_other_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .mod -- +module example.com/retract/ambiguous/other + +go 1.16 + +require example.com/retract/ambiguous v1.0.0 +-- .info -- +{"Version":"v1.0.0"} +-- other.go -- +package other + +import _ "example.com/retract/ambiguous/nested" diff --git a/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt new file mode 100644 index 0000000..c8eeb16 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_ambiguous_v1.0.0.txt @@ -0,0 +1,9 @@ +-- .mod -- +module example.com/retract/ambiguous + +go 1.16 +-- .info -- +{"Version":"v1.0.0"} +-- nested/nested.go -- +package nested + diff --git a/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt new file mode 100644 index 0000000..a987685 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v1.0.0.txt @@ -0,0 +1,19 @@ +The v1.0.0 release of example.com/retract/incompatible retracts +v2.0.0+incompatible. + +-- .mod -- +module example.com/retract/incompatible + +go 1.16 + +retract v2.0.0+incompatible +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/retract/incompatible + +go 1.16 + +retract v2.0.0+incompatible +-- incompatible.go -- +package incompatible diff --git a/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt new file mode 100644 index 0000000..c668dbb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_incompatible_v2.0.0+incompatible.txt @@ -0,0 +1,9 @@ +The v1.0.0 release of example.com/retract/incompatible retracts +v2.0.0+incompatible. + +-- .mod -- +module example.com/retract/incompatible +-- .info -- +{"Version":"v2.0.0+incompatible"} +-- incompatible.go -- +package incompatible diff --git a/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt new file mode 100644 index 0000000..1d8d810 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.0.0.txt @@ -0,0 +1,10 @@ +This version should be retracted, but the go.mod file for the version that would +contain the retraction is not available. +-- .mod -- +module example.com/retract/missingmod + +go 1.14 +-- .info -- +{"Version":"v1.0.0"} +-- missingmod.go -- +package missingmod diff --git a/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt new file mode 100644 index 0000000..bba919e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_missingmod_v1.9.0.txt @@ -0,0 +1,4 @@ +The go.mod file at this version will be loaded to check for retractions +of earlier versions. However, the .mod file is not available. +-- .info -- +{"Version":"v1.9.0"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt new file mode 100644 index 0000000..c4a53e1 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-block.txt @@ -0,0 +1,6 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-block"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt new file mode 100644 index 0000000..92573b6 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-blockwithcomment.txt @@ -0,0 +1,6 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-blockwithcomment"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt new file mode 100644 index 0000000..1f0894a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-empty.txt @@ -0,0 +1,8 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-empty"} +-- empty.go -- +package empty diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt new file mode 100644 index 0000000..1b5e753 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-long.txt @@ -0,0 +1,8 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-long"} +-- empty.go -- +package empty diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt new file mode 100644 index 0000000..b1ffe27 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline1.txt @@ -0,0 +1,8 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-multiline1"} +-- empty.go -- +package empty diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt new file mode 100644 index 0000000..72f80b3 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-multiline2.txt @@ -0,0 +1,8 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-multiline2"} +-- empty.go -- +package empty diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt new file mode 100644 index 0000000..1b04504 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-order.txt @@ -0,0 +1,6 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-order"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt new file mode 100644 index 0000000..9496124 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.0-unprintable.txt @@ -0,0 +1,8 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.0-unprintable"} +-- empty.go -- +package empty diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt new file mode 100644 index 0000000..3be7d5b --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.0.1-order.txt @@ -0,0 +1,6 @@ +-- .mod -- +module example.com/retract/rationale + +go 1.14 +-- .info -- +{"Version":"v1.0.1-order"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt new file mode 100644 index 0000000..6975d4e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rationale_v1.9.0.txt @@ -0,0 +1,48 @@ +Module example.com/retract/description retracts all versions of itself. +The rationale comments have various problems. + +-- .mod -- +module example.com/retract/rationale + +go 1.14 + +retract ( + v1.0.0-empty + + // short description + // more + // + // detail + v1.0.0-multiline1 // suffix + // after not included +) + +// short description +// more +// +// detail +retract v1.0.0-multiline2 // suffix + +// loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong +retract v1.0.0-long + +// Ends with a BEL character. Beep! +retract v1.0.0-unprintable + +// block comment +retract ( + v1.0.0-block + + // inner comment + v1.0.0-blockwithcomment +) + +retract ( + [v1.0.0-order, v1.0.0-order] // degenerate range + v1.0.0-order // single version + + v1.0.1-order // single version + [v1.0.1-order, v1.0.1-order] // degenerate range +) +-- .info -- +{"Version":"v1.9.0"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt new file mode 100644 index 0000000..25c4ff1 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.0.0-bad.txt @@ -0,0 +1,16 @@ +Module example.com/retract/rename is renamed in a later version. + +This happens frequently when a repository is renamed or when a go.mod file +is added for the first time with a custom module path. +-- .info -- +{"Version":"v1.0.0-bad"} +-- .mod -- +module example.com/retract/rename + +go 1.16 +-- go.mod -- +module example.com/retract/rename + +go 1.16 +-- rename.go -- +package rename diff --git a/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt new file mode 100644 index 0000000..9c08f71 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_rename_v1.9.0-new.txt @@ -0,0 +1,22 @@ +Module example.com/retract/rename is renamed in this version. + +This happens frequently when a repository is renamed or when a go.mod file +is added for the first time with a custom module path. +-- .info -- +{"Version":"v1.9.0-new"} +-- .mod -- +module example.com/retract/newname + +go 1.16 + +// bad +retract v1.0.0-bad +-- go.mod -- +module example.com/retract/newname + +go 1.16 + +// bad +retract v1.0.0-bad +-- newname.go -- +package newname diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt new file mode 100644 index 0000000..4dc486b --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_all_v1.9.0.txt @@ -0,0 +1,14 @@ +Module example.com/retract/self/prev is a module that retracts its own +latest version. + +No unretracted versions are available. + +-- .mod -- +module example.com/retract/self/all + +go 1.15 + +retract v1.9.0 // bad + +-- .info -- +{"Version":"v1.9.0"} diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt new file mode 100644 index 0000000..04c2845 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.0.0.txt @@ -0,0 +1,16 @@ +Module example.com/retract/self/prerelease is a module that retracts its own +latest version and all other release version. + +A pre-release version higher than the highest release version is still +available, and that should be matched by @latest. + +-- .mod -- +module example.com/retract/self/prerelease + +go 1.15 + +-- .info -- +{"Version":"v1.0.0"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt new file mode 100644 index 0000000..7c1c047 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.0.txt @@ -0,0 +1,19 @@ +Module example.com/retract/self/prerelease is a module that retracts its own +latest version and all other release version. + +A pre-release version higher than the highest release version is still +available, and that should be matched by @latest. + +-- .mod -- +module example.com/retract/self/prerelease + +go 1.15 + +retract v1.0.0 // bad +retract v1.9.0 // self + +-- .info -- +{"Version":"v1.9.0"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt new file mode 100644 index 0000000..abf44fd --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prerelease_v1.9.1-pre.txt @@ -0,0 +1,16 @@ +Module example.com/retract/self/prerelease is a module that retracts its own +latest version and all other release version. + +A pre-release version higher than the highest release version is still +available, and that should be matched by @latest. + +-- .mod -- +module example.com/retract/self/prerelease + +go 1.15 + +-- .info -- +{"Version":"v1.9.1-pre"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt new file mode 100644 index 0000000..095063d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.0.0-bad.txt @@ -0,0 +1,14 @@ +See example.com_retract_self_prev_v1.9.0.txt. + +This version is retracted. + +-- .mod -- +module example.com/retract/self/prev + +go 1.15 + +-- .info -- +{"Version":"v1.0.0-bad"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt new file mode 100644 index 0000000..27c3a39 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.1.0.txt @@ -0,0 +1,14 @@ +See example.com_retract_self_pref_v1.9.0.txt. + +This version is the latest (only) non-retracted version. + +-- .mod -- +module example.com/retract/self/prev + +go 1.15 + +-- .info -- +{"Version":"v1.1.0"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt new file mode 100644 index 0000000..03d6168 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_prev_v1.9.0.txt @@ -0,0 +1,18 @@ +Module example.com/retract/self/prev is a module that retracts its own +latest version, as well as an earlier version. + +A previous unretracted release version, v1.1.0, is still available. + +-- .mod -- +module example.com/retract/self/prev + +go 1.15 + +retract v1.0.0-bad // bad +retract v1.9.0 // self + +-- .info -- +{"Version":"v1.9.0"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab new file mode 100644 index 0000000..f9ab41e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v0.0.0-20200325131415-0123456789ab @@ -0,0 +1,20 @@ +See example.com_retract_self_pseudo_v1.9.0.txt. + +This version is not retracted. It should be returned by the proxy's +@latest endpoint. It should match the @latest version query. + +TODO(golang.org/issue/24031): the proxy and proxy.golang.org both return +the highest release version from the @latest endpoint, even if that +version is retracted, so there is no way for the go command to +discover an unretracted pseudo-version. + +-- .mod -- +module example.com/retract/self/pseudo + +go 1.15 + +-- .info -- +{"Version":"v0.0.0-20200325131415-01234567890ab"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt new file mode 100644 index 0000000..d47eda0 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.0.0-bad.txt @@ -0,0 +1,14 @@ +See example.com_retract_self_pseudo_v1.9.0.txt. + +This version is retracted. + +-- .mod -- +module example.com/retract/self/pseudo + +go 1.15 + +-- .info -- +{"Version":"v1.0.0-bad"} + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt new file mode 100644 index 0000000..db09cc6 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_self_pseudo_v1.9.0.txt @@ -0,0 +1,16 @@ +Module example.com/retract/self/pseudo is a module that retracts its own +latest version, as well as an earlier version. + +An unretracted pseudo-version is available. + +-- .mod -- +module example.com/retract/self/pseudo + +go 1.15 + +retract v1.0.0-bad // bad +retract v1.9.0 // self + +-- .info -- +{"Version":"v1.9.0"} + diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt new file mode 100644 index 0000000..2f996cf --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-bad.txt @@ -0,0 +1,10 @@ +-- .mod -- +module example.com/retract + +go 1.15 + +-- .info -- +{"Version":"v1.0.0-bad"} + +-- retract.go -- +package retract diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt new file mode 100644 index 0000000..78152bb --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-good.txt @@ -0,0 +1,10 @@ +-- .mod -- +module example.com/retract + +go 1.15 + +-- .info -- +{"Version":"v1.0.0-good"} + +-- retract.go -- +package retract diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt new file mode 100644 index 0000000..3bc9e35 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_v1.0.0-unused.txt @@ -0,0 +1,10 @@ +-- .mod -- +module example.com/retract + +go 1.15 + +-- .info -- +{"Version":"v1.0.0-unused"} + +-- retract.go -- +package retract diff --git a/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt new file mode 100644 index 0000000..18d6d83 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_retract_v1.1.0.txt @@ -0,0 +1,13 @@ +-- .mod -- +module example.com/retract + +go 1.15 + +retract v1.0.0-bad // bad +retract v1.0.0-unused // bad + +-- .info -- +{"Version":"v1.1.0"} + +-- retract.go -- +package retract diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt new file mode 100644 index 0000000..edf5d48 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_subpkg_v0.1.0.txt @@ -0,0 +1,14 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible version (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible/subpkg +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.com/split-incompatible/subpkg + +go 1.16 +-- subpkg.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt new file mode 100644 index 0000000..00076d7 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.0.0+incompatible.txt @@ -0,0 +1,10 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible version (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible +-- .info -- +{"Version": "v2.0.0+incompatible"} +-- subpkg/subpkg.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt new file mode 100644 index 0000000..bb1c1fe --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split-incompatible_v2.1.0-pre+incompatible.txt @@ -0,0 +1,10 @@ +Written by hand. +Test case for getting a package that has been moved to a nested module, +with a +incompatible version (and thus no go.mod file) at the root module. + +-- .mod -- +module example.com/split-incompatible +-- .info -- +{"Version": "v2.1.0-pre+incompatible"} +-- README.txt -- +subpkg has moved to module example.com/split-incompatible/subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split_subpkg_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_split_subpkg_v1.1.0.txt new file mode 100644 index 0000000..b197b66 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split_subpkg_v1.1.0.txt @@ -0,0 +1,11 @@ +Written by hand. +Test case for getting a package that has been moved to a different module. + +-- .mod -- +module example.com/split/subpkg + +require example.com/split v1.1.0 +-- .info -- +{"Version": "v1.1.0"} +-- x.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_split_v1.0.0.txt new file mode 100644 index 0000000..b706e59 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split_v1.0.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for getting a package that has been moved to a different module. + +-- .mod -- +module example.com/split +-- .info -- +{"Version": "v1.0.0"} +-- subpkg/x.go -- +package subpkg diff --git a/src/cmd/go/testdata/mod/example.com_split_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_split_v1.1.0.txt new file mode 100644 index 0000000..d38971f --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_split_v1.1.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for getting a package that has been moved to a different module. + +-- .mod -- +module example.com/split + +require example.com/split/subpkg v1.1.0 +-- .info -- +{"Version": "v1.1.0"} diff --git a/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt new file mode 100644 index 0000000..787b7ae --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt @@ -0,0 +1,18 @@ +Module with a function that prints file name for the top stack frame. +Different versions of this module are identical, but they should return +different file names with -trimpath. +-- .mod -- +module example.com/stack + +go 1.14 +-- .info -- +{"Version":"v1.0.0"} +-- stack.go -- +package stack + +import "runtime" + +func TopFile() string { + _, file, _, _ := runtime.Caller(0) + return file +} diff --git a/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt new file mode 100644 index 0000000..c715dd2 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt @@ -0,0 +1,18 @@ +Module with a function that prints file name for the top stack frame. +Different versions of this module are identical, but they should return +different file names with -trimpath. +-- .mod -- +module example.com/stack + +go 1.14 +-- .info -- +{"Version":"v1.0.1"} +-- stack.go -- +package stack + +import "runtime" + +func TopFile() string { + _, file, _, _ := runtime.Caller(0) + return file +} diff --git a/src/cmd/go/testdata/mod/example.com_tools_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_tools_v1.0.0.txt new file mode 100644 index 0000000..22e36b9 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_tools_v1.0.0.txt @@ -0,0 +1,12 @@ +-- .info -- +{"Version": "v1.0.0"} +-- .mod -- +module example.com/tools +-- cmd/hello/hello.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello") +} diff --git a/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt new file mode 100644 index 0000000..a68588e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.0.txt @@ -0,0 +1,14 @@ +-- .info -- +{"Version":"v1.0.0"} +-- .mod -- +// Deprecated: in v1.0.0 +module example.com/undeprecated + +go 1.17 +-- go.mod -- +// Deprecated: in v1.0.0 +module example.com/undeprecated + +go 1.17 +-- undeprecated.go -- +package undeprecated diff --git a/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt new file mode 100644 index 0000000..ecabf32 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_undeprecated_v1.0.1.txt @@ -0,0 +1,14 @@ +-- .info -- +{"Version":"v1.0.1"} +-- .mod -- +// no longer deprecated +module example.com/undeprecated + +go 1.17 +-- go.mod -- +// no longer deprecated +module example.com/undeprecated + +go 1.17 +-- undeprecated.go -- +package undeprecated diff --git a/src/cmd/go/testdata/mod/example.com_usemissingpre_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_usemissingpre_v1.0.0.txt new file mode 100644 index 0000000..5e1c5c8 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_usemissingpre_v1.0.0.txt @@ -0,0 +1,13 @@ +This module requires example.com/missingpkg at a prerelease version, which +is newer than @latest. + +-- .mod -- +module example.com/usemissingpre + +require example.com/missingpkg v1.0.1-beta +-- .info -- +{"Version":"v1.0.0"} +-- use.go -- +package use + +import _ "example.com/missingpkg" diff --git a/src/cmd/go/testdata/mod/example.com_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_v1.0.0.txt new file mode 100644 index 0000000..263287d --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_v1.0.0.txt @@ -0,0 +1,9 @@ +Written by hand. +Test case for module at root of domain. + +-- .mod -- +module example.com +-- .info -- +{"Version": "v1.0.0"} +-- x.go -- +package x diff --git a/src/cmd/go/testdata/mod/example.com_version_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_version_v1.0.0.txt new file mode 100644 index 0000000..d8c45b5 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_version_v1.0.0.txt @@ -0,0 +1,11 @@ +example.com/version v1.0.0 +written by hand + +-- .mod -- +module example.com/version +-- .info -- +{"Version":"v1.0.0"} +-- version.go -- +package version + +const V = "v1.0.0" diff --git a/src/cmd/go/testdata/mod/example.com_version_v1.0.1.txt b/src/cmd/go/testdata/mod/example.com_version_v1.0.1.txt new file mode 100644 index 0000000..3bfdb0e --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_version_v1.0.1.txt @@ -0,0 +1,11 @@ +example.com/version v1.0.1 +written by hand + +-- .mod -- +module example.com/version +-- .info -- +{"Version":"v1.0.1"} +-- version.go -- +package version + +const V = "v1.0.1" diff --git a/src/cmd/go/testdata/mod/example.com_version_v1.1.0.txt b/src/cmd/go/testdata/mod/example.com_version_v1.1.0.txt new file mode 100644 index 0000000..8109a9a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.com_version_v1.1.0.txt @@ -0,0 +1,11 @@ +example.com/version v1.1.0 +written by hand + +-- .mod -- +module example.com/version +-- .info -- +{"Version":"v1.1.0"} +-- version.go -- +package version + +const V = "v1.1.0" diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt new file mode 100644 index 0000000..8c9de7a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_nested_v0.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous/nested + +go 1.16 +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.net/ambiguous/nested + +go 1.16 +-- pkg/pkg.go -- +// Package pkg exists in both example.net/ambiguous v0.1.0 +// and example.net/ambiguous/nested v0.1.0 +package pkg diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt new file mode 100644 index 0000000..8fa6d83 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous + +go 1.16 +-- .info -- +{"Version": "v0.1.0"} +-- go.mod -- +module example.net/ambiguous + +go 1.16 +-- nested/pkg/pkg.go -- +// Package pkg exists in both example.net/ambiguous v0.1.0 +// and example.net/ambiguous/nested v0.1.0 +package pkg diff --git a/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt new file mode 100644 index 0000000..7589ad7 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_ambiguous_v0.2.0.txt @@ -0,0 +1,18 @@ +Written by hand. + +Test module containing a package that is also provided by a nested module tagged +with the same version. + +-- .mod -- +module example.net/ambiguous + +go 1.16 +-- .info -- +{"Version": "v0.2.0"} +-- go.mod -- +module example.net/ambiguous + +go 1.16 +-- nested/pkg/README.txt -- +// Package pkg no longer exists in this module at v0.2.0. +// Find it in module example.net/ambiguous/nested instead. diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt new file mode 100644 index 0000000..207e86a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.0.0.txt @@ -0,0 +1,17 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- README.txt -- +We will add the package example.net/pkgadded in v1.1.0, +and example.net/pkgadded/subpkg in v1.2.0. diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt new file mode 100644 index 0000000..1c88de2 --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.1.0.txt @@ -0,0 +1,19 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.1.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- README.txt -- +We will add the package example.net/pkgadded/subpkg in v1.2.0. +-- pkgadded.go -- +// Package pkgadded was added in v1.1.0. +package pkgadded diff --git a/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt new file mode 100644 index 0000000..922951a --- /dev/null +++ b/src/cmd/go/testdata/mod/example.net_pkgadded_v1.2.0.txt @@ -0,0 +1,20 @@ +Written by hand. +Test module with a root package added in v1.1.0 +and a subpackage added in v1.2.0. + +-- .mod -- +module example.net/pkgadded + +go 1.16 +-- .info -- +{"Version":"v1.2.0"} +-- go.mod -- +module example.net/pkgadded + +go 1.16 +-- pkgadded.go -- +// Package pkgadded was added in v1.1.0. +package pkgadded +-- subpkg/subpkg.go -- +// Package subpkg was added in v1.2.0. +package subpkg diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt new file mode 100644 index 0000000..c2709c1 --- /dev/null +++ b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.0.0-20190619020302-197a620e0c9a.txt @@ -0,0 +1,10 @@ +module github.com/dmitshur-test/modtest5@v0.0.0-20190619020302-197a620e0c9a + +-- .mod -- +module github.com/dmitshur-test/modtest5 +-- .info -- +{"Version":"v0.0.0-20190619020302-197a620e0c9a","Time":"2019-06-18T19:03:02-07:00"} +-- p.go -- +package p + +const v = 1 diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt new file mode 100644 index 0000000..22e47f3 --- /dev/null +++ b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.0.20190619023908-3da23a9deb9e.txt @@ -0,0 +1,10 @@ +module github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e + +-- .mod -- +module github.com/dmitshur-test/modtest5 +-- .info -- +{"Version":"v0.5.0-alpha.0.20190619023908-3da23a9deb9e","Time":"2019-06-18T19:39:08-07:00"} +-- p.go -- +package p + +const v = 3 diff --git a/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt new file mode 100644 index 0000000..4f088cc --- /dev/null +++ b/src/cmd/go/testdata/mod/github.com_dmitshur-test_modtest5_v0.5.0-alpha.txt @@ -0,0 +1,10 @@ +module github.com/dmitshur-test/modtest5@v0.5.0-alpha + +-- .mod -- +module github.com/dmitshur-test/modtest5 +-- .info -- +{"Version":"v0.5.0-alpha","Time":"2019-06-18T19:04:46-07:00"} +-- p.go -- +package p + +const v = 2 diff --git a/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt new file mode 100644 index 0000000..0420a1a --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_notx_useinternal_v0.1.0.txt @@ -0,0 +1,13 @@ +written by hand — attempts to use a prohibited internal package +(https://golang.org/s/go14internal) + +-- .mod -- +module golang.org/notx/useinternal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/notx/useinternal +-- useinternal.go -- +package useinternal + +import _ "golang.org/x/internal/subtle" diff --git a/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt new file mode 100644 index 0000000..5737e95 --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_internal_v0.1.0.txt @@ -0,0 +1,43 @@ +written by hand — loosely derived from golang.org/x/crypto/internal/subtle, +but splitting the internal package across a module boundary + +-- .mod -- +module golang.org/x/internal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/x/internal +-- subtle/aliasing.go -- +// Copyright 2018 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. + +// +build !appengine + +// This is a tiny version of golang.org/x/crypto/internal/subtle. + +package subtle + +import "unsafe" + +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && + uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) +} +-- subtle/aliasing_appengine.go -- +// Copyright 2018 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. + +// +build appengine + +package subtle + +import "reflect" + +func AnyOverlap(x, y []byte) bool { + return len(x) > 0 && len(y) > 0 && + reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() && + reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer() +} diff --git a/src/cmd/go/testdata/mod/golang.org_x_text_v0.0.0-20170915032832-14c0d48ead0c.txt b/src/cmd/go/testdata/mod/golang.org_x_text_v0.0.0-20170915032832-14c0d48ead0c.txt new file mode 100644 index 0000000..f4f50cd --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_text_v0.0.0-20170915032832-14c0d48ead0c.txt @@ -0,0 +1,47 @@ +written by hand - just enough to compile rsc.io/sampler, rsc.io/quote + +-- .mod -- +module golang.org/x/text +-- .info -- +{"Version":"v0.0.0-20170915032832-14c0d48ead0c","Name":"v0.0.0-20170915032832-14c0d48ead0c","Short":"14c0d48ead0c","Time":"2017-09-15T03:28:32Z"} +-- go.mod -- +module golang.org/x/text +-- unused/unused.go -- +package unused +-- language/lang.go -- +// Copyright 2018 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. + +// This is a tiny version of golang.org/x/text. + +package language + +import "strings" + +type Tag string + +func Make(s string) Tag { return Tag(s) } + +func (t Tag) String() string { return string(t) } + +func NewMatcher(tags []Tag) Matcher { return &matcher{tags} } + +type Matcher interface { + Match(...Tag) (Tag, int, int) +} + +type matcher struct { + tags []Tag +} + +func (m *matcher) Match(prefs ...Tag) (Tag, int, int) { + for _, pref := range prefs { + for _, tag := range m.tags { + if tag == pref || strings.HasPrefix(string(pref), string(tag+"-")) || strings.HasPrefix(string(tag), string(pref+"-")) { + return tag, 0, 0 + } + } + } + return m.tags[0], 0, 0 +} diff --git a/src/cmd/go/testdata/mod/golang.org_x_text_v0.3.0.txt b/src/cmd/go/testdata/mod/golang.org_x_text_v0.3.0.txt new file mode 100644 index 0000000..5561afa --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_text_v0.3.0.txt @@ -0,0 +1,47 @@ +written by hand - just enough to compile rsc.io/sampler, rsc.io/quote + +-- .mod -- +module golang.org/x/text +-- .info -- +{"Version":"v0.3.0","Name":"","Short":"","Time":"2017-09-16T03:28:32Z"} +-- go.mod -- +module golang.org/x/text +-- unused/unused.go -- +package unused +-- language/lang.go -- +// Copyright 2018 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. + +// This is a tiny version of golang.org/x/text. + +package language + +import "strings" + +type Tag string + +func Make(s string) Tag { return Tag(s) } + +func (t Tag) String() string { return string(t) } + +func NewMatcher(tags []Tag) Matcher { return &matcher{tags} } + +type Matcher interface { + Match(...Tag) (Tag, int, int) +} + +type matcher struct { + tags []Tag +} + +func (m *matcher) Match(prefs ...Tag) (Tag, int, int) { + for _, pref := range prefs { + for _, tag := range m.tags { + if tag == pref || strings.HasPrefix(string(pref), string(tag+"-")) || strings.HasPrefix(string(tag), string(pref+"-")) { + return tag, 0, 0 + } + } + } + return m.tags[0], 0, 0 +} diff --git a/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt b/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt new file mode 100644 index 0000000..3fcba44 --- /dev/null +++ b/src/cmd/go/testdata/mod/golang.org_x_useinternal_v0.1.0.txt @@ -0,0 +1,13 @@ +written by hand — uses an internal package from another module +(https://golang.org/s/go14internal) + +-- .mod -- +module golang.org/x/useinternal +-- .info -- +{"Version":"v0.1.0","Name":"","Short":"","Time":"2018-07-25T17:24:00Z"} +-- go.mod -- +module golang.org/x/useinternal +-- useinternal.go -- +package useinternal + +import _ "golang.org/x/internal/subtle" diff --git a/src/cmd/go/testdata/mod/gopkg.in_dummy.v2-unstable_v2.0.0.txt b/src/cmd/go/testdata/mod/gopkg.in_dummy.v2-unstable_v2.0.0.txt new file mode 100644 index 0000000..f174159 --- /dev/null +++ b/src/cmd/go/testdata/mod/gopkg.in_dummy.v2-unstable_v2.0.0.txt @@ -0,0 +1,9 @@ +gopkg.in/dummy.v2-unstable v2.0.0 +written by hand + +-- .mod -- +module gopkg.in/dummy.v2-unstable +-- .info -- +{"Version":"v2.0.0"} +-- dummy.go -- +package dummy diff --git a/src/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt b/src/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt new file mode 100644 index 0000000..efff088 --- /dev/null +++ b/src/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt @@ -0,0 +1,59 @@ +Constructed by hand. +(derived from rsc.io/quote@e7a685a342, but without an explicit go.mod file.) + +-- .mod -- +module "not-rsc.io/quote" +-- .info -- +{"Version":"v0.1.0-nomod","Time":"2018-02-14T00:51:33Z"} +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory. Share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} diff --git a/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.0.txt b/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.0.txt new file mode 100644 index 0000000..40616c6 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.0.txt @@ -0,0 +1,11 @@ +patch.example.com/depofdirectpatch v1.0.0 +written by hand + +-- .mod -- +module patch.example.com/depofdirectpatch +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module patch.example.com/depofdirectpatch +-- depofdirectpatch.go -- +package depofdirectpatch diff --git a/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.1.txt b/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.1.txt new file mode 100644 index 0000000..e075028 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_depofdirectpatch_v1.0.1.txt @@ -0,0 +1,11 @@ +patch.example.com/depofdirectpatch v1.0.1 +written by hand + +-- .mod -- +module patch.example.com/depofdirectpatch +-- .info -- +{"Version":"v1.0.1"} +-- go.mod -- +module patch.example.com/depofdirectpatch +-- depofdirectpatch.go -- +package depofdirectpatch diff --git a/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.0.txt b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.0.txt new file mode 100644 index 0000000..1e775fb --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.0.txt @@ -0,0 +1,21 @@ +patch.example.com/direct v1.0.0 +written by hand + +-- .mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 +) +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 +) +-- direct.go -- +package direct + +import _ "patch.example.com/indirect" diff --git a/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.1.txt b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.1.txt new file mode 100644 index 0000000..64912b7 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.0.1.txt @@ -0,0 +1,27 @@ +patch.example.com/direct v1.0.1 +written by hand + +-- .mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 + patch.example.com/depofdirectpatch v1.0.0 +) +-- .info -- +{"Version":"v1.0.1"} +-- go.mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 + patch.example.com/depofdirectpatch v1.0.0 +) +-- direct.go -- +package direct + +import _ "patch.example.com/indirect" +-- usedepofdirectpatch/unused.go -- +package usedepofdirectpatch + +import _ "patch.example.com/depofdirectpatch" diff --git a/src/cmd/go/testdata/mod/patch.example.com_direct_v1.1.0.txt b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.1.0.txt new file mode 100644 index 0000000..406e3b9 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_direct_v1.1.0.txt @@ -0,0 +1,21 @@ +patch.example.com/direct v1.1.0 +written by hand + +-- .mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 +) +-- .info -- +{"Version":"v1.1.0"} +-- go.mod -- +module patch.example.com/direct + +require ( + patch.example.com/indirect v1.0.0 +) +-- direct.go -- +package direct + +import _ "patch.example.com/indirect" diff --git a/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.0.txt b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.0.txt new file mode 100644 index 0000000..ea7f5e2 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.0.txt @@ -0,0 +1,11 @@ +patch.example.com/indirect v1.0.0 +written by hand + +-- .mod -- +module patch.example.com/indirect +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module patch.example.com/indirect +-- direct.go -- +package indirect diff --git a/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.1.txt b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.1.txt new file mode 100644 index 0000000..8c6cf8e --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.0.1.txt @@ -0,0 +1,11 @@ +patch.example.com/indirect v1.0.1 +written by hand + +-- .mod -- +module patch.example.com/indirect +-- .info -- +{"Version":"v1.0.1"} +-- go.mod -- +module patch.example.com/indirect +-- direct.go -- +package indirect diff --git a/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.1.0.txt b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.1.0.txt new file mode 100644 index 0000000..f7229d4 --- /dev/null +++ b/src/cmd/go/testdata/mod/patch.example.com_indirect_v1.1.0.txt @@ -0,0 +1,11 @@ +patch.example.com/indirect v1.1.0 +written by hand + +-- .mod -- +module patch.example.com/indirect +-- .info -- +{"Version":"v1.1.0"} +-- go.mod -- +module patch.example.com/indirect +-- direct.go -- +package indirect diff --git a/src/cmd/go/testdata/mod/rsc.io_!c!g!o_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_!c!g!o_v1.0.0.txt new file mode 100644 index 0000000..6276147 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_!c!g!o_v1.0.0.txt @@ -0,0 +1,19 @@ +rsc.io/CGO v1.0.0 + +-- .mod -- +module rsc.io/CGO +-- .info -- +{"Version":"v1.0.0","Name":"","Short":"","Time":"2018-08-01T18:23:45Z"} +-- go.mod -- +module rsc.io/CGO +-- cgo.go -- +// Copyright 2018 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 CGO + +// #cgo CFLAGS: -I${SRCDIR} +import "C" + +var V = 0 diff --git a/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.2.txt b/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.2.txt new file mode 100644 index 0000000..21185c3 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.2.txt @@ -0,0 +1,88 @@ +rsc.io/QUOTE v1.5.2 + +-- .mod -- +module rsc.io/QUOTE + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v1.5.2","Name":"","Short":"","Time":"2018-07-15T16:25:34Z"} +-- go.mod -- +module rsc.io/QUOTE + +require rsc.io/quote v1.5.2 +-- QUOTE/quote.go -- +// Copyright 2018 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 QUOTE COLLECTS LOUD SAYINGS. +package QUOTE + +import ( + "strings" + + "rsc.io/quote" +) + +// HELLO RETURNS A GREETING. +func HELLO() string { + return strings.ToUpper(quote.Hello()) +} + +// GLASS RETURNS A USEFUL PHRASE FOR WORLD TRAVELERS. +func GLASS() string { + return strings.ToUpper(quote.GLASS()) +} + +// GO RETURNS A GO PROVERB. +func GO() string { + return strings.ToUpper(quote.GO()) +} + +// OPT RETURNS AN OPTIMIZATION TRUTH. +func OPT() string { + return strings.ToUpper(quote.OPT()) +} +-- QUOTE/quote_test.go -- +// Copyright 2018 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 QUOTE + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHELLO(t *testing.T) { + hello := "HELLO, WORLD" + if out := HELLO(); out != hello { + t.Errorf("HELLO() = %q, want %q", out, hello) + } +} + +func TestGLASS(t *testing.T) { + glass := "I CAN EAT GLASS AND IT DOESN'T HURT ME." + if out := GLASS(); out != glass { + t.Errorf("GLASS() = %q, want %q", out, glass) + } +} + +func TestGO(t *testing.T) { + go1 := "DON'T COMMUNICATE BY SHARING MEMORY, SHARE MEMORY BY COMMUNICATING." + if out := GO(); out != go1 { + t.Errorf("GO() = %q, want %q", out, go1) + } +} + +func TestOPT(t *testing.T) { + opt := "IF A PROGRAM IS TOO SLOW, IT MUST HAVE A LOOP." + if out := OPT(); out != opt { + t.Errorf("OPT() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.3-!p!r!e.txt b/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.3-!p!r!e.txt new file mode 100644 index 0000000..54bac2d --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_!q!u!o!t!e_v1.5.3-!p!r!e.txt @@ -0,0 +1,88 @@ +rsc.io/QUOTE v1.5.3-PRE (sigh) + +-- .mod -- +module rsc.io/QUOTE + +require rsc.io/quote v1.5.2 +-- .info -- +{"Version":"v1.5.3-PRE","Name":"","Short":"","Time":"2018-07-15T16:25:34Z"} +-- go.mod -- +module rsc.io/QUOTE + +require rsc.io/quote v1.5.2 +-- QUOTE/quote.go -- +// Copyright 2018 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 QUOTE COLLECTS LOUD SAYINGS. +package QUOTE + +import ( + "strings" + + "rsc.io/quote" +) + +// HELLO RETURNS A GREETING. +func HELLO() string { + return strings.ToUpper(quote.Hello()) +} + +// GLASS RETURNS A USEFUL PHRASE FOR WORLD TRAVELERS. +func GLASS() string { + return strings.ToUpper(quote.GLASS()) +} + +// GO RETURNS A GO PROVERB. +func GO() string { + return strings.ToUpper(quote.GO()) +} + +// OPT RETURNS AN OPTIMIZATION TRUTH. +func OPT() string { + return strings.ToUpper(quote.OPT()) +} +-- QUOTE/quote_test.go -- +// Copyright 2018 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 QUOTE + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHELLO(t *testing.T) { + hello := "HELLO, WORLD" + if out := HELLO(); out != hello { + t.Errorf("HELLO() = %q, want %q", out, hello) + } +} + +func TestGLASS(t *testing.T) { + glass := "I CAN EAT GLASS AND IT DOESN'T HURT ME." + if out := GLASS(); out != glass { + t.Errorf("GLASS() = %q, want %q", out, glass) + } +} + +func TestGO(t *testing.T) { + go1 := "DON'T COMMUNICATE BY SHARING MEMORY, SHARE MEMORY BY COMMUNICATING." + if out := GO(); out != go1 { + t.Errorf("GO() = %q, want %q", out, go1) + } +} + +func TestOPT(t *testing.T) { + opt := "IF A PROGRAM IS TOO SLOW, IT MUST HAVE A LOOP." + if out := OPT(); out != opt { + t.Errorf("OPT() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_badfile1_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badfile1_v1.0.0.txt new file mode 100644 index 0000000..9d23e7d --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badfile1_v1.0.0.txt @@ -0,0 +1,14 @@ +rsc.io/badfile1 v1.0.0 +written by hand +this is part of the badfile test but is a valid zip file. + +-- .mod -- +module rsc.io/badfile1 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module rsc.io/badfile1 +-- α.go -- +package α +-- .gitignore -- +-- x/y/z/.gitignore -- diff --git a/src/cmd/go/testdata/mod/rsc.io_badfile2_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badfile2_v1.0.0.txt new file mode 100644 index 0000000..58e1e1c --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badfile2_v1.0.0.txt @@ -0,0 +1,12 @@ +rsc.io/badfile1 v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badfile2 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module rsc.io/badfile2 +-- ☺.go -- +package smiley + diff --git a/src/cmd/go/testdata/mod/rsc.io_badfile3_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badfile3_v1.0.0.txt new file mode 100644 index 0000000..a008448 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badfile3_v1.0.0.txt @@ -0,0 +1,12 @@ +rsc.io/badfile3 v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badfile3 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module rsc.io/badfile3 +-- x?y.go -- +package x + diff --git a/src/cmd/go/testdata/mod/rsc.io_badfile4_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badfile4_v1.0.0.txt new file mode 100644 index 0000000..e28844d --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badfile4_v1.0.0.txt @@ -0,0 +1,15 @@ +rsc.io/badfile4 v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badfile4 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module rsc.io/badfile4 +-- x/Y.go -- +package x +-- x/y.go -- +package x + + diff --git a/src/cmd/go/testdata/mod/rsc.io_badfile5_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badfile5_v1.0.0.txt new file mode 100644 index 0000000..3c7903a --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badfile5_v1.0.0.txt @@ -0,0 +1,13 @@ +rsc.io/badfile5 v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badfile5 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module rsc.io/badfile5 +-- x/y/z/w.go -- +package z +-- x/Y/zz/ww.go -- +package zz diff --git a/src/cmd/go/testdata/mod/rsc.io_badmod_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badmod_v1.0.0.txt new file mode 100644 index 0000000..993ceb7 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badmod_v1.0.0.txt @@ -0,0 +1,11 @@ +rsc.io/badmod v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badmod +hello world +-- .info -- +{"Version":"v1.0.0"} +-- x.go -- +package x + diff --git a/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.0.txt new file mode 100644 index 0000000..d62db26 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.0.txt @@ -0,0 +1,14 @@ +rsc.io/badsum@v1.0.0 + +This module would match the hard-coded hash for rsc.io/badsum v1.0.0 +in modfetch/notary.go if not for the "break hash" line. + +-- .mod -- +module "rsc.io/badsum" +-- .info -- +{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"} +-- go.mod -- +module "rsc.io/badsum" +-- badsum.go -- +package badsum +// break hash diff --git a/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.1.txt b/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.1.txt new file mode 100644 index 0000000..5fea50a --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badsum_v1.0.1.txt @@ -0,0 +1,14 @@ +rsc.io/badsum@v1.0.1 + +This module would match the hard-coded hash for rsc.io/badsum v1.0.1/go.mod +in modfetch/notary.go if not for the "break hash" line. + +-- .mod -- +module "rsc.io/badsum" +# break hash +-- .info -- +{"Version":"v1.0.1","Time":"2018-02-14T00:45:20Z"} +-- go.mod -- +module "rsc.io/badsum" +-- badsum.go -- +package badsum diff --git a/src/cmd/go/testdata/mod/rsc.io_badzip_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_badzip_v1.0.0.txt new file mode 100644 index 0000000..07a38fa --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_badzip_v1.0.0.txt @@ -0,0 +1,11 @@ +rsc.io/badzip v1.0.0 +written by hand + +-- .mod -- +module rsc.io/badzip +-- .info -- +{"Version":"v1.0.0"} +-- x.go -- +package x +-- /rsc.io/badzip@v1.0.0.txt -- +This file should not be here. diff --git a/src/cmd/go/testdata/mod/rsc.io_breaker_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_breaker_v1.0.0.txt new file mode 100644 index 0000000..a103e3f --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_breaker_v1.0.0.txt @@ -0,0 +1,11 @@ +rsc.io/breaker v1.0.0 +written by hand + +-- .mod -- +module rsc.io/breaker +-- .info -- +{"Version":"v1.0.0"} +-- breaker.go -- +package breaker + +const X = 1 diff --git a/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0+incompatible.txt b/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0+incompatible.txt new file mode 100644 index 0000000..59d8bac --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0+incompatible.txt @@ -0,0 +1,11 @@ +rsc.io/breaker v2.0.0+incompatible +written by hand + +-- .mod -- +module rsc.io/breaker +-- .info -- +{"Version":"v2.0.0+incompatible", "Name": "7307b307f4f0dde421900f8e5126fadac1e13aed", "Short": "7307b307f4f0"} +-- breaker.go -- +package breaker + +const XX = 2 diff --git a/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0.txt new file mode 100644 index 0000000..59d8bac --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_breaker_v2.0.0.txt @@ -0,0 +1,11 @@ +rsc.io/breaker v2.0.0+incompatible +written by hand + +-- .mod -- +module rsc.io/breaker +-- .info -- +{"Version":"v2.0.0+incompatible", "Name": "7307b307f4f0dde421900f8e5126fadac1e13aed", "Short": "7307b307f4f0"} +-- breaker.go -- +package breaker + +const XX = 2 diff --git a/src/cmd/go/testdata/mod/rsc.io_fortune_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_fortune_v1.0.0.txt new file mode 100644 index 0000000..d8a71f3 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_fortune_v1.0.0.txt @@ -0,0 +1,15 @@ +rsc.io/fortune v1.0.0 +written by hand + +-- .mod -- +module rsc.io/fortune +-- .info -- +{"Version":"v1.0.0"} +-- fortune.go -- +package main + +import "rsc.io/quote" + +func main() { + println(quote.Hello()) +} diff --git a/src/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt new file mode 100644 index 0000000..3acd637 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt @@ -0,0 +1,21 @@ +rsc.io/fortune v2.0.0 +written by hand + +-- .mod -- +module rsc.io/fortune/v2 +-- .info -- +{"Version":"v2.0.0"} +-- fortune.go -- +package main + +import "rsc.io/quote" + +func main() { + println(quote.Hello()) +} +-- fortune_test.go -- +package main + +import "testing" + +func TestFortuneV2(t *testing.T) {} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005133-e7a685a342c0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005133-e7a685a342c0.txt new file mode 100644 index 0000000..8ae173e --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005133-e7a685a342c0.txt @@ -0,0 +1,60 @@ +rsc.io/quote@e7a685a342 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v0.0.0-20180214005133-e7a685a342c0","Name":"e7a685a342c001acc3eb7f5eafa82980480042c7","Short":"e7a685a342c0","Time":"2018-02-14T00:51:33Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory. Share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005840-23179ee8a569.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005840-23179ee8a569.txt new file mode 100644 index 0000000..bc626ba --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180214005840-23179ee8a569.txt @@ -0,0 +1,86 @@ +rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180214005840-23179ee8a569","Name":"23179ee8a569bb05d896ae05c6503ec69a19f99f","Short":"23179ee8a569","Time":"2018-02-14T00:58:40Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180628003336-dd9747d19b04.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180628003336-dd9747d19b04.txt new file mode 100644 index 0000000..bbc8097 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180628003336-dd9747d19b04.txt @@ -0,0 +1,100 @@ +rsc.io/quote@dd9747d + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180628003336-dd9747d19b04","Name":"dd9747d19b041365fbddf0399ddba6bff5eb1b3e","Short":"dd9747d19b04","Time":"2018-06-28T00:33:36Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +AN EVEN WORSE CHANGE! + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709153244-fd906ed3b100.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709153244-fd906ed3b100.txt new file mode 100644 index 0000000..e461ed4 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709153244-fd906ed3b100.txt @@ -0,0 +1,86 @@ +rsc.io/quote@v2.0.0 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180709153244-fd906ed3b100","Name":"fd906ed3b100e47181ffa9ec36d82294525c9109","Short":"fd906ed3b100","Time":"2018-07-09T15:32:44Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV2() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV2() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func GoV2() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func OptV2() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709160352-0d003b9c4bfa.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709160352-0d003b9c4bfa.txt new file mode 100644 index 0000000..c1d511f --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709160352-0d003b9c4bfa.txt @@ -0,0 +1,98 @@ +rsc.io/quote@v0.0.0-20180709160352-0d003b9c4bfa + +-- .mod -- +module rsc.io/quote + +require rsc.io/sampler v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180709160352-0d003b9c4bfa","Name":"0d003b9c4bfac881641be8eb1598b782a467a97f","Short":"0d003b9c4bfa","Time":"2018-07-09T16:03:52Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module rsc.io/quote + +require rsc.io/sampler v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/quote/v2" + +// Hello returns a greeting. +func Hello() string { + return quote.HelloV2() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return quote.GlassV2() +} + +// Go returns a Go proverb. +func Go() string { + return quote.GoV2() +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return quote.OptV2() +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162749-b44a0b17b2d1.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162749-b44a0b17b2d1.txt new file mode 100644 index 0000000..f7f794d --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162749-b44a0b17b2d1.txt @@ -0,0 +1,104 @@ +rsc.io/quote@v0.0.0-20180709162749-b44a0b17b2d1 + +-- .mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v2 v2.0.1 + rsc.io/sampler v1.3.0 +) +-- .info -- +{"Version":"v0.0.0-20180709162749-b44a0b17b2d1","Name":"b44a0b17b2d1fe4c98a8d0e7a68c9bf9e762799a","Short":"b44a0b17b2d1","Time":"2018-07-09T16:27:49Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v2 v2.0.1 + rsc.io/sampler v1.3.0 +) +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/quote/v2" + +// Hello returns a greeting. +func Hello() string { + return quote.HelloV2() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return quote.GlassV2() +} + +// Go returns a Go proverb. +func Go() string { + return quote.GoV2() +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return quote.OptV2() +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162816-fe488b867524.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162816-fe488b867524.txt new file mode 100644 index 0000000..2d5d8b4 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162816-fe488b867524.txt @@ -0,0 +1,104 @@ +rsc.io/quote@v0.0.0-20180709162816-fe488b867524 + +-- .mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v2 v2.0.1 + rsc.io/sampler v1.3.0 +) +-- .info -- +{"Version":"v0.0.0-20180709162816-fe488b867524","Name":"fe488b867524806e861c3f4f43ae6946a42ca3f1","Short":"fe488b867524","Time":"2018-07-09T16:28:16Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v2 v2.0.1 + rsc.io/sampler v1.3.0 +) +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/quote/v2" + +// Hello returns a greeting. +func Hello() string { + return quote.HelloV2() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return quote.GlassV2() +} + +// Go returns a Go proverb. +func Go() string { + return quote.GoV2() +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return quote.OptV2() +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162918-a91498bed0a7.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162918-a91498bed0a7.txt new file mode 100644 index 0000000..853a8c2 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180709162918-a91498bed0a7.txt @@ -0,0 +1,98 @@ +rsc.io/quote@v0.0.0-20180709162918-a91498bed0a7 + +-- .mod -- +module rsc.io/quote + +require rsc.io/sampler v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180709162918-a91498bed0a7","Name":"a91498bed0a73d4bb9c1fb2597925f7883bc40a7","Short":"a91498bed0a7","Time":"2018-07-09T16:29:18Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module rsc.io/quote + +require rsc.io/sampler v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/quote/v3" + +// Hello returns a greeting. +func Hello() string { + return quote.HelloV3() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return quote.GlassV3() +} + +// Go returns a Go proverb. +func Go() string { + return quote.GoV3() +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return quote.OptV3() +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180710144737-5d9f230bcfba.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180710144737-5d9f230bcfba.txt new file mode 100644 index 0000000..2ebeac3 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v0.0.0-20180710144737-5d9f230bcfba.txt @@ -0,0 +1,104 @@ +rsc.io/quote@v0.0.0-20180710144737-5d9f230bcfba + +-- .mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v3 v3.0.0 + rsc.io/sampler v1.3.0 +) +-- .info -- +{"Version":"v0.0.0-20180710144737-5d9f230bcfba","Name":"5d9f230bcfbae514bb6c2215694c2ce7273fc604","Short":"5d9f230bcfba","Time":"2018-07-10T14:47:37Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module rsc.io/quote + +require ( + rsc.io/quote/v3 v3.0.0 + rsc.io/sampler v1.3.0 +) +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/quote/v3" + +// Hello returns a greeting. +func Hello() string { + return quote.HelloV3() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return quote.GlassV3() +} + +// Go returns a Go proverb. +func Go() string { + return quote.GoV3() +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return quote.OptV3() +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.0.0.txt new file mode 100644 index 0000000..9a07937 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.0.0.txt @@ -0,0 +1,35 @@ +rsc.io/quote@v1.0.0 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v1.0.0","Name":"f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6","Short":"f488df80bcdb","Time":"2018-02-14T00:45:20Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.1.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.1.0.txt new file mode 100644 index 0000000..0c41605 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.1.0.txt @@ -0,0 +1,48 @@ +rsc.io/quote@v1.1.0 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v1.1.0","Name":"cfd7145f43f92a8d56b4a3dd603795a3291381a9","Short":"cfd7145f43f9","Time":"2018-02-14T00:46:44Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.0.txt new file mode 100644 index 0000000..e714f0b --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.0.txt @@ -0,0 +1,61 @@ +rsc.io/quote@v1.2.0 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v1.2.0","Name":"d8a3de91045c932a1c71e545308fe97571d6d65c","Short":"d8a3de91045c","Time":"2018-02-14T00:47:51Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +// Go returns a Go proverb. +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory. Share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.1.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.1.txt new file mode 100644 index 0000000..89d5191 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.2.1.txt @@ -0,0 +1,60 @@ +rsc.io/quote@v1.2.1 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v1.2.1","Name":"5c1f03b64ab7aa958798a569a31924655dc41e76","Short":"5c1f03b64ab7","Time":"2018-02-14T00:54:20Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.3.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.3.0.txt new file mode 100644 index 0000000..d62766c --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.3.0.txt @@ -0,0 +1,73 @@ +rsc.io/quote@v1.3.0 + +-- .mod -- +module "rsc.io/quote" +-- .info -- +{"Version":"v1.3.0","Name":"84de74b35823c1e49634f2262f1a58cfc951ebae","Short":"84de74b35823","Time":"2018-02-14T00:54:53Z"} +-- go.mod -- +module "rsc.io/quote" +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.4.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.4.0.txt new file mode 100644 index 0000000..698ff8d --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.4.0.txt @@ -0,0 +1,79 @@ +rsc.io/quote@v1.4.0 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.0.0 +-- .info -- +{"Version":"v1.4.0","Name":"19e8b977bd2f437798c2cc2dcfe8a1c0f169481b","Short":"19e8b977bd2f","Time":"2018-02-14T00:56:05Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.0.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.0.txt new file mode 100644 index 0000000..e7fcdbc --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.0.txt @@ -0,0 +1,79 @@ +rsc.io/quote@v1.5.0 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v1.5.0","Name":"3ba1e30dc83bd52c990132b9dfb1688a9d22de13","Short":"3ba1e30dc83b","Time":"2018-02-14T00:58:15Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.1.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.1.txt new file mode 100644 index 0000000..eed051b --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.1.txt @@ -0,0 +1,86 @@ +rsc.io/quote@23179ee8a569 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v1.5.1","Name":"23179ee8a569bb05d896ae05c6503ec69a19f99f","Short":"23179ee8a569","Time":"2018-02-14T00:58:40Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.2.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.2.txt new file mode 100644 index 0000000..8671f6f --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.2.txt @@ -0,0 +1,98 @@ +rsc.io/quote@v1.5.2 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v1.5.2","Name":"c4d4236f92427c64bfbcf1cc3f8142ab18f30b22","Short":"c4d4236f9242","Time":"2018-02-14T15:44:20Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.3-pre1.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.3-pre1.txt new file mode 100644 index 0000000..212ef13 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v1.5.3-pre1.txt @@ -0,0 +1,100 @@ +rsc.io/quote@v1.5.3-pre1 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v1.5.3-pre1","Name":"2473dfd877c95382420e47686aa9076bf58c79e0","Short":"2473dfd877c9","Time":"2018-06-28T00:32:53Z"} +-- buggy/buggy_test.go -- +// Copyright 2018 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 buggy + +import "testing" + +func Test(t *testing.T) { + t.Fatal("buggy!") +} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// A CHANGE! + +// Hello returns a greeting. +func Hello() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func Opt() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v2.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v2.0.0.txt new file mode 100644 index 0000000..e461ed4 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v2.0.0.txt @@ -0,0 +1,86 @@ +rsc.io/quote@v2.0.0 + +-- .mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- .info -- +{"Version":"v0.0.0-20180709153244-fd906ed3b100","Name":"fd906ed3b100e47181ffa9ec36d82294525c9109","Short":"fd906ed3b100","Time":"2018-07-09T15:32:44Z"} +-- go.mod -- +module "rsc.io/quote" + +require "rsc.io/sampler" v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV2() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV2() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func GoV2() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func OptV2() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v2_v2.0.1.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v2_v2.0.1.txt new file mode 100644 index 0000000..d51128c --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v2_v2.0.1.txt @@ -0,0 +1,86 @@ +rsc.io/quote/v2@v2.0.1 + +-- .mod -- +module rsc.io/quote/v2 + +require rsc.io/sampler v1.3.0 +-- .info -- +{"Version":"v2.0.1","Name":"754f68430672776c84704e2d10209a6ec700cd64","Short":"754f68430672","Time":"2018-07-09T16:25:34Z"} +-- go.mod -- +module rsc.io/quote/v2 + +require rsc.io/sampler v1.3.0 +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV2() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV2() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func GoV2() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func OptV2() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} +-- quote_test.go -- +// Copyright 2018 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 quote + +import ( + "os" + "testing" +) + +func init() { + os.Setenv("LC_ALL", "en") +} + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory, share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} + +func TestOpt(t *testing.T) { + opt := "If a program is too slow, it must have a loop." + if out := Opt(); out != opt { + t.Errorf("Opt() = %q, want %q", out, opt) + } +} diff --git a/src/cmd/go/testdata/mod/rsc.io_quote_v3_v3.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_quote_v3_v3.0.0.txt new file mode 100644 index 0000000..0afe1f0 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_quote_v3_v3.0.0.txt @@ -0,0 +1,45 @@ +rsc.io/quote/v3@v3.0.0 + +-- .mod -- +module rsc.io/quote/v3 + +require rsc.io/sampler v1.3.0 + +-- .info -- +{"Version":"v3.0.0","Name":"d88915d7e77ed0fd35d0a022a2f244e2202fd8c8","Short":"d88915d7e77e","Time":"2018-07-09T15:34:46Z"} +-- go.mod -- +module rsc.io/quote/v3 + +require rsc.io/sampler v1.3.0 + +-- quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote // import "rsc.io/quote" + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV3() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV3() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func GoV3() string { + return "Don't communicate by sharing memory, share memory by communicating." +} + +// Opt returns an optimization truth. +func OptV3() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.0.0.txt new file mode 100644 index 0000000..c4b6a71 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.0.0.txt @@ -0,0 +1,20 @@ +rsc.io/sampler@v1.0.0 + +-- .mod -- +module "rsc.io/sampler" +-- .info -- +{"Version":"v1.0.0","Name":"60bef405c52117ad21d2adb10872b95cf17f8fca","Short":"60bef405c521","Time":"2018-02-13T18:05:54Z"} +-- go.mod -- +module "rsc.io/sampler" +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts. +package sampler // import "rsc.io/sampler" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.0.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.0.txt new file mode 100644 index 0000000..98c35fa --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.0.txt @@ -0,0 +1,138 @@ +rsc.io/sampler@v1.2.0 + +-- .mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- .info -- +{"Version":"v1.2.0","Name":"25f24110b153246056eccc14a3a4cd81afaff586","Short":"25f24110b153","Time":"2018-02-13T18:13:45Z"} +-- go.mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- hello.go -- +// Copyright 2018 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. + +// Translations by Google Translate. + +package sampler + +var hello = newText(` + +English: en: Hello, world. +French: fr: Bonjour le monde. +Spanish: es: Hola Mundo. + +`) +-- hello_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var helloTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "Hello, world.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Bonjour la monde.", + }, +} + +func TestHello(t *testing.T) { + for _, tt := range helloTests { + text := Hello(tt.prefs...) + if text != tt.text { + t.Errorf("Hello(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts. +package sampler // import "rsc.io/sampler" + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// DefaultUserPrefs returns the default user language preferences. +// It consults the $LC_ALL, $LC_MESSAGES, and $LANG environment +// variables, in that order. +func DefaultUserPrefs() []language.Tag { + var prefs []language.Tag + for _, k := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if env := os.Getenv(k); env != "" { + prefs = append(prefs, language.Make(env)) + } + } + return prefs +} + +// Hello returns a localized greeting. +// If no prefs are given, Hello uses DefaultUserPrefs. +func Hello(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return hello.find(prefs) +} + +// A text is a localized text. +type text struct { + byTag map[string]string + matcher language.Matcher +} + +// newText creates a new localized text, given a list of translations. +func newText(s string) *text { + t := &text{ + byTag: make(map[string]string), + } + var tags []language.Tag + for _, line := range strings.Split(s, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + f := strings.Split(line, ": ") + if len(f) != 3 { + continue + } + tag := language.Make(f[1]) + tags = append(tags, tag) + t.byTag[tag.String()] = f[2] + } + t.matcher = language.NewMatcher(tags) + return t +} + +// find finds the text to use for the given language tag preferences. +func (t *text) find(prefs []language.Tag) string { + tag, _, _ := t.matcher.Match(prefs...) + s := t.byTag[tag.String()] + if strings.HasPrefix(s, "RTL ") { + s = "\u200F" + strings.TrimPrefix(s, "RTL ") + "\u200E" + } + return s +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt new file mode 100644 index 0000000..7982ccc --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt @@ -0,0 +1,134 @@ +generated by ./addmod.bash rsc.io/sampler@v1.2.1 + +-- .mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- .info -- +{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"} +-- hello.go -- +// Copyright 2018 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. + +// Translations by Google Translate. + +package sampler + +var hello = newText(` + +English: en: Hello, world. +French: fr: Bonjour le monde. +Spanish: es: Hola Mundo. + +`) +-- hello_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var helloTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "Hello, world.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Bonjour le monde.", + }, +} + +func TestHello(t *testing.T) { + for _, tt := range helloTests { + text := Hello(tt.prefs...) + if text != tt.text { + t.Errorf("Hello(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts. +package sampler // import "rsc.io/sampler" + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// DefaultUserPrefs returns the default user language preferences. +// It consults the $LC_ALL, $LC_MESSAGES, and $LANG environment +// variables, in that order. +func DefaultUserPrefs() []language.Tag { + var prefs []language.Tag + for _, k := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if env := os.Getenv(k); env != "" { + prefs = append(prefs, language.Make(env)) + } + } + return prefs +} + +// Hello returns a localized greeting. +// If no prefs are given, Hello uses DefaultUserPrefs. +func Hello(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return hello.find(prefs) +} + +// A text is a localized text. +type text struct { + byTag map[string]string + matcher language.Matcher +} + +// newText creates a new localized text, given a list of translations. +func newText(s string) *text { + t := &text{ + byTag: make(map[string]string), + } + var tags []language.Tag + for _, line := range strings.Split(s, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + f := strings.Split(line, ": ") + if len(f) != 3 { + continue + } + tag := language.Make(f[1]) + tags = append(tags, tag) + t.byTag[tag.String()] = f[2] + } + t.matcher = language.NewMatcher(tags) + return t +} + +// find finds the text to use for the given language tag preferences. +func (t *text) find(prefs []language.Tag) string { + tag, _, _ := t.matcher.Match(prefs...) + s := t.byTag[tag.String()] + if strings.HasPrefix(s, "RTL ") { + s = "\u200F" + strings.TrimPrefix(s, "RTL ") + "\u200E" + } + return s +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.0.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.0.txt new file mode 100644 index 0000000..febe51f --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.0.txt @@ -0,0 +1,202 @@ +rsc.io/sampler@v1.3.0 + +-- .mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- .info -- +{"Version":"v1.3.0","Name":"0cc034b51e57ed7832d4c67d526f75a900996e5c","Short":"0cc034b51e57","Time":"2018-02-13T19:05:03Z"} +-- glass.go -- +// Copyright 2018 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. + +// Translations from Frank da Cruz, Ethan Mollick, and many others. +// See http://kermitproject.org/utf8.html. +// http://www.oocities.org/nodotus/hbglass.html +// https://en.wikipedia.org/wiki/I_Can_Eat_Glass + +package sampler + +var glass = newText(` + +English: en: I can eat glass and it doesn't hurt me. +French: fr: Je peux manger du verre, ça ne me fait pas mal. +Spanish: es: Puedo comer vidrio, no me hace daño. + +`) +-- glass_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" + _ "rsc.io/testonly" +) + +var glassTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "I can eat glass and it doesn't hurt me.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Je peux manger du verre, ça ne me fait pas mal.", + }, +} + +func TestGlass(t *testing.T) { + for _, tt := range glassTests { + text := Glass(tt.prefs...) + if text != tt.text { + t.Errorf("Glass(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- go.mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- hello.go -- +// Copyright 2018 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. + +// Translations by Google Translate. + +package sampler + +var hello = newText(` + +English: en: Hello, world. +French: fr: Bonjour le monde. +Spanish: es: Hola Mundo. + +`) +-- hello_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var helloTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "Hello, world.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Bonjour le monde.", + }, +} + +func TestHello(t *testing.T) { + for _, tt := range helloTests { + text := Hello(tt.prefs...) + if text != tt.text { + t.Errorf("Hello(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts. +package sampler // import "rsc.io/sampler" + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// DefaultUserPrefs returns the default user language preferences. +// It consults the $LC_ALL, $LC_MESSAGES, and $LANG environment +// variables, in that order. +func DefaultUserPrefs() []language.Tag { + var prefs []language.Tag + for _, k := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if env := os.Getenv(k); env != "" { + prefs = append(prefs, language.Make(env)) + } + } + return prefs +} + +// Hello returns a localized greeting. +// If no prefs are given, Hello uses DefaultUserPrefs. +func Hello(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return hello.find(prefs) +} + +// Glass returns a localized silly phrase. +// If no prefs are given, Glass uses DefaultUserPrefs. +func Glass(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return glass.find(prefs) +} + +// A text is a localized text. +type text struct { + byTag map[string]string + matcher language.Matcher +} + +// newText creates a new localized text, given a list of translations. +func newText(s string) *text { + t := &text{ + byTag: make(map[string]string), + } + var tags []language.Tag + for _, line := range strings.Split(s, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + f := strings.Split(line, ": ") + if len(f) != 3 { + continue + } + tag := language.Make(f[1]) + tags = append(tags, tag) + t.byTag[tag.String()] = f[2] + } + t.matcher = language.NewMatcher(tags) + return t +} + +// find finds the text to use for the given language tag preferences. +func (t *text) find(prefs []language.Tag) string { + tag, _, _ := t.matcher.Match(prefs...) + s := t.byTag[tag.String()] + if strings.HasPrefix(s, "RTL ") { + s = "\u200F" + strings.TrimPrefix(s, "RTL ") + "\u200E" + } + return s +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.1.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.1.txt new file mode 100644 index 0000000..a293f10 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.3.1.txt @@ -0,0 +1,201 @@ +rsc.io/sampler@v1.3.1 + +-- .mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- .info -- +{"Version":"v1.3.1","Name":"f545d0289d06e2add4556ea6a15fc4938014bf87","Short":"f545d0289d06","Time":"2018-02-14T16:34:12Z"} +-- glass.go -- +// Copyright 2018 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. + +// Translations from Frank da Cruz, Ethan Mollick, and many others. +// See http://kermitproject.org/utf8.html. +// http://www.oocities.org/nodotus/hbglass.html +// https://en.wikipedia.org/wiki/I_Can_Eat_Glass + +package sampler + +var glass = newText(` + +English: en: I can eat glass and it doesn't hurt me. +French: fr: Je peux manger du verre, ça ne me fait pas mal. +Spanish: es: Puedo comer vidrio, no me hace daño. + +`) +-- glass_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var glassTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "I can eat glass and it doesn't hurt me.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Je peux manger du verre, ça ne me fait pas mal.", + }, +} + +func TestGlass(t *testing.T) { + for _, tt := range glassTests { + text := Glass(tt.prefs...) + if text != tt.text { + t.Errorf("Glass(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- go.mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- hello.go -- +// Copyright 2018 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. + +// Translations by Google Translate. + +package sampler + +var hello = newText(` + +English: en: Hello, world. +French: fr: Bonjour le monde. +Spanish: es: Hola Mundo. + +`) +-- hello_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var helloTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "Hello, world.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Bonjour le monde.", + }, +} + +func TestHello(t *testing.T) { + for _, tt := range helloTests { + text := Hello(tt.prefs...) + if text != tt.text { + t.Errorf("Hello(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts in a variety of languages. +package sampler // import "rsc.io/sampler" + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// DefaultUserPrefs returns the default user language preferences. +// It consults the $LC_ALL, $LC_MESSAGES, and $LANG environment +// variables, in that order. +func DefaultUserPrefs() []language.Tag { + var prefs []language.Tag + for _, k := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if env := os.Getenv(k); env != "" { + prefs = append(prefs, language.Make(env)) + } + } + return prefs +} + +// Hello returns a localized greeting. +// If no prefs are given, Hello uses DefaultUserPrefs. +func Hello(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return hello.find(prefs) +} + +// Glass returns a localized silly phrase. +// If no prefs are given, Glass uses DefaultUserPrefs. +func Glass(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return glass.find(prefs) +} + +// A text is a localized text. +type text struct { + byTag map[string]string + matcher language.Matcher +} + +// newText creates a new localized text, given a list of translations. +func newText(s string) *text { + t := &text{ + byTag: make(map[string]string), + } + var tags []language.Tag + for _, line := range strings.Split(s, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + f := strings.Split(line, ": ") + if len(f) != 3 { + continue + } + tag := language.Make(f[1]) + tags = append(tags, tag) + t.byTag[tag.String()] = f[2] + } + t.matcher = language.NewMatcher(tags) + return t +} + +// find finds the text to use for the given language tag preferences. +func (t *text) find(prefs []language.Tag) string { + tag, _, _ := t.matcher.Match(prefs...) + s := t.byTag[tag.String()] + if strings.HasPrefix(s, "RTL ") { + s = "\u200F" + strings.TrimPrefix(s, "RTL ") + "\u200E" + } + return s +} diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.99.99.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.99.99.txt new file mode 100644 index 0000000..5036d20 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.99.99.txt @@ -0,0 +1,140 @@ +rsc.io/sampler@v1.99.99 + +-- .mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- .info -- +{"Version":"v1.99.99","Name":"732a3c400797d8835f2af34a9561f155bef85435","Short":"732a3c400797","Time":"2018-02-13T22:20:19Z"} +-- go.mod -- +module "rsc.io/sampler" + +require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c +-- hello.go -- +// Copyright 2018 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. + +// Translations by Google Translate. + +package sampler + +var hello = newText(` + +English: en: 99 bottles of beer on the wall, 99 bottles of beer, ... + +`) +-- hello_test.go -- +// Copyright 2018 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 sampler + +import ( + "testing" + + "golang.org/x/text/language" +) + +var helloTests = []struct { + prefs []language.Tag + text string +}{ + { + []language.Tag{language.Make("en-US"), language.Make("fr")}, + "Hello, world.", + }, + { + []language.Tag{language.Make("fr"), language.Make("en-US")}, + "Bonjour le monde.", + }, +} + +func TestHello(t *testing.T) { + for _, tt := range helloTests { + text := Hello(tt.prefs...) + if text != tt.text { + t.Errorf("Hello(%v) = %q, want %q", tt.prefs, text, tt.text) + } + } +} +-- sampler.go -- +// Copyright 2018 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 sampler shows simple texts. +package sampler // import "rsc.io/sampler" + +import ( + "os" + "strings" + + "golang.org/x/text/language" +) + +// DefaultUserPrefs returns the default user language preferences. +// It consults the $LC_ALL, $LC_MESSAGES, and $LANG environment +// variables, in that order. +func DefaultUserPrefs() []language.Tag { + var prefs []language.Tag + for _, k := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if env := os.Getenv(k); env != "" { + prefs = append(prefs, language.Make(env)) + } + } + return prefs +} + +// Hello returns a localized greeting. +// If no prefs are given, Hello uses DefaultUserPrefs. +func Hello(prefs ...language.Tag) string { + if len(prefs) == 0 { + prefs = DefaultUserPrefs() + } + return hello.find(prefs) +} + +func Glass() string { + return "I can eat glass and it doesn't hurt me." +} + +// A text is a localized text. +type text struct { + byTag map[string]string + matcher language.Matcher +} + +// newText creates a new localized text, given a list of translations. +func newText(s string) *text { + t := &text{ + byTag: make(map[string]string), + } + var tags []language.Tag + for _, line := range strings.Split(s, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + f := strings.Split(line, ": ") + if len(f) != 3 { + continue + } + tag := language.Make(f[1]) + tags = append(tags, tag) + t.byTag[tag.String()] = f[2] + } + t.matcher = language.NewMatcher(tags) + return t +} + +// find finds the text to use for the given language tag preferences. +func (t *text) find(prefs []language.Tag) string { + tag, _, _ := t.matcher.Match(prefs...) + s := t.byTag[tag.String()] + if strings.HasPrefix(s, "RTL ") { + s = "\u200F" + strings.TrimPrefix(s, "RTL ") + "\u200E" + } + return s +} diff --git a/src/cmd/go/testdata/mod/rsc.io_testonly_v1.0.0.txt b/src/cmd/go/testdata/mod/rsc.io_testonly_v1.0.0.txt new file mode 100644 index 0000000..dfb8ca2 --- /dev/null +++ b/src/cmd/go/testdata/mod/rsc.io_testonly_v1.0.0.txt @@ -0,0 +1,9 @@ +rsc.io/testonly v1.0.0 +written by hand + +-- .mod -- +module rsc.io/testonly +-- .info -- +{"Version":"v1.0.0"} +-- testonly.go -- +package testonly diff --git a/src/cmd/go/testdata/modlegacy/src/new/go.mod b/src/cmd/go/testdata/modlegacy/src/new/go.mod new file mode 100644 index 0000000..d0dd46d --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/go.mod @@ -0,0 +1 @@ +module "new/v2" diff --git a/src/cmd/go/testdata/modlegacy/src/new/new.go b/src/cmd/go/testdata/modlegacy/src/new/new.go new file mode 100644 index 0000000..e99c47a --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/new.go @@ -0,0 +1,3 @@ +package new + +import _ "new/v2/p2" diff --git a/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go b/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go new file mode 100644 index 0000000..4539f40 --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go @@ -0,0 +1,7 @@ +package p1 + +import _ "old/p2" +import _ "new/v2" +import _ "new/v2/p2" +import _ "new/sub/v2/x/v1/y" // v2 is module, v1 is directory in module +import _ "new/sub/inner/x" // new/sub/inner/go.mod overrides new/sub/go.mod diff --git a/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go b/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go new file mode 100644 index 0000000..9b9052f --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go @@ -0,0 +1 @@ +package p2 diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod b/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod new file mode 100644 index 0000000..484d20c --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod @@ -0,0 +1 @@ +module new/sub/v2 diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod new file mode 100644 index 0000000..ba39345 --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod @@ -0,0 +1 @@ +module new/sub/inner diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go new file mode 100644 index 0000000..823aafd --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go @@ -0,0 +1 @@ +package x diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go b/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go new file mode 100644 index 0000000..789ca71 --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go @@ -0,0 +1 @@ +package y diff --git a/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go b/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go new file mode 100644 index 0000000..9052748 --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go @@ -0,0 +1,5 @@ +package p1 + +import _ "old/p2" +import _ "new/p1" +import _ "new" diff --git a/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go b/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go new file mode 100644 index 0000000..9b9052f --- /dev/null +++ b/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go @@ -0,0 +1 @@ +package p2 diff --git a/src/cmd/go/testdata/savedir.go b/src/cmd/go/testdata/savedir.go new file mode 100644 index 0000000..53c78cf --- /dev/null +++ b/src/cmd/go/testdata/savedir.go @@ -0,0 +1,80 @@ +// Copyright 2018 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. + +//go:build ignore +// +build ignore + +// Savedir archives a directory tree as a txtar archive printed to standard output. +// +// Usage: +// +// go run savedir.go /path/to/dir >saved.txt +// +// Typically the tree is later extracted during a test with tg.extract("testdata/saved.txt"). +// +package main + +import ( + "flag" + "fmt" + "io/fs" + "log" + "os" + "path/filepath" + "strings" + "unicode/utf8" + + "golang.org/x/tools/txtar" +) + +func usage() { + fmt.Fprintf(os.Stderr, "usage: go run savedir.go dir >saved.txt\n") + os.Exit(2) +} + +const goCmd = "vgo" + +func main() { + flag.Usage = usage + flag.Parse() + if flag.NArg() != 1 { + usage() + } + + log.SetPrefix("savedir: ") + log.SetFlags(0) + + dir := flag.Arg(0) + + a := new(txtar.Archive) + dir = filepath.Clean(dir) + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { + if path == dir { + return nil + } + name := info.Name() + if strings.HasPrefix(name, ".") { + if info.IsDir() { + return filepath.SkipDir + } + return nil + } + if !info.Type().IsRegular() { + return nil + } + data, err := os.ReadFile(path) + if err != nil { + log.Fatal(err) + } + if !utf8.Valid(data) { + log.Printf("%s: ignoring invalid UTF-8 data", path) + return nil + } + a.Files = append(a.Files, txtar.File{Name: strings.TrimPrefix(path, dir+string(filepath.Separator)), Data: data}) + return nil + }) + + data := txtar.Format(a) + os.Stdout.Write(data) +} diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README new file mode 100644 index 0000000..b2a7fd1 --- /dev/null +++ b/src/cmd/go/testdata/script/README @@ -0,0 +1,317 @@ +This directory holds test scripts *.txt run during 'go test cmd/go'. +To run a specific script foo.txt + + go test cmd/go -run=Script/^foo$ + +In general script files should have short names: a few words, not whole sentences. +The first word should be the general category of behavior being tested, +often the name of a go subcommand (list, build, test, ...) or concept (vendor, pattern). + +Each script is a text archive (go doc cmd/go/internal/txtar). +The script begins with an actual command script to run +followed by the content of zero or more supporting files to +create in the script's temporary file system before it starts executing. + +As an example, run_hello.txt says: + + # hello world + go run hello.go + stderr 'hello world' + ! stdout . + + -- hello.go -- + package main + func main() { println("hello world") } + +Each script runs in a fresh temporary work directory tree, available to scripts as $WORK. +Scripts also have access to these other environment variables: + + GOARCH=<target GOARCH> + GOCACHE=<actual GOCACHE being used outside the test> + GOEXE=<executable file suffix: .exe on Windows, empty on other systems> + GOOS=<target GOOS> + GOPATH=$WORK/gopath + GOPROXY=<local module proxy serving from cmd/go/testdata/mod> + GOROOT=<actual GOROOT> + GOROOT_FINAL=<actual GOROOT_FINAL> + TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT> + HOME=/no-home + PATH=<actual PATH> + TMPDIR=$WORK/tmp + GODEBUG=<actual GODEBUG> + devnull=<value of os.DevNull> + goversion=<current Go version; for example, 1.12> + :=<OS-specific path list separator> + +The scripts' supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src) +and then the script begins execution in that directory as well. Thus the example above runs +in $WORK/gopath/src with GOPATH=$WORK/gopath and $WORK/gopath/src/hello.go +containing the listed contents. + +The lines at the top of the script are a sequence of commands to be executed +by a tiny script engine in ../../script_test.go (not the system shell). +The script stops and the overall test fails if any particular command fails. + +Each line is parsed into a sequence of space-separated command words, +with environment variable expansion and # marking an end-of-line comment. +Adding single quotes around text keeps spaces in that text from being treated +as word separators and also disables environment variable expansion. +Inside a single-quoted block of text, a repeated single quote indicates +a literal single quote, as in: + + 'Don''t communicate by sharing memory.' + +A line beginning with # is a comment and conventionally explains what is +being done or tested at the start of a new phase in the script. + +The command prefix ! indicates that the command on the rest of the line +(typically go or a matching predicate) must fail, not succeed. Only certain +commands support this prefix. They are indicated below by [!] in the synopsis. + +The command prefix ? indicates that the command on the rest of the line +may or may not succeed, but the test should continue regardless. +Commands that support this prefix are indicated by [?]. + +The command prefix [cond] indicates that the command on the rest of the line +should only run when the condition is satisfied. The available conditions are: + + - GOOS and GOARCH values, like [386], [windows], and so on. + - Compiler names, like [gccgo], [gc]. + - Test environment details: + - [short] for testing.Short() + - [cgo], [msan], [asan], [race] for whether cgo, msan, asan, and the race detector can be used + - [fuzz] for whether 'go test -fuzz' can be used at all + - [fuzz-instrumented] for whether 'go test -fuzz' uses coverage-instrumented binaries + - [net] for whether the external network can be used + - [link] for testenv.HasLink() + - [root] for os.Geteuid() == 0 + - [symlink] for testenv.HasSymlink() + - [case-sensitive] for whether the file system is case-sensitive + - [exec:prog] for whether prog is available for execution (found by exec.LookPath) + - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable + - [buildmode:value] for whether -buildmode=value is supported + +A condition can be negated: [!short] means to run the rest of the line +when testing.Short() is false. Multiple conditions may be given for a single +command, for example, '[linux] [amd64] skip'. The command will run if all conditions +are satisfied. + +The commands are: + +- [! | ?] cc args... [&] + Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be + added automatically before args. + +- cd dir + Change to the given directory for future commands. + The directory must use slashes as path separator. + +- chmod perm path... + Change the permissions of the files or directories named by the path arguments + to be equal to perm. Only numerical permissions are supported. + +- [! | ?] cmp file1 file2 + Check that the named files have (or do not have) the same content. + By convention, file1 is the actual data and file2 the expected data. + File1 can be "stdout" or "stderr" to use the standard output or standard error + from the most recent exec or go command. + (If the file contents differ and the command is not negated, + the failure prints a diff.) + +- [! | ?] cmpenv file1 file2 + Like cmp, but environment variables are substituted in the file contents + before the comparison. For example, $GOOS is replaced by the target GOOS. + +- [! | ?] cp src... dst + Copy the listed files to the target file or existing directory. + src can include "stdout" or "stderr" to use the standard output or standard error + from the most recent exec or go command. + +- env [-r] [key=value...] + With no arguments, print the environment to stdout + (useful for debugging and for verifying initial state). + Otherwise add the listed key=value pairs to the environment. + The -r flag causes the values to be escaped using regexp.QuoteMeta + before being recorded. + +- [! | ?] exec program [args...] [&] + Run the given executable program with the arguments. + It must (or must not) succeed. + Note that 'exec' does not terminate the script (unlike in Unix shells). + + If the last token is '&', the program executes in the background. The standard + output and standard error of the previous command is cleared, but the output + of the background process is buffered — and checking of its exit status is + delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the + test. If any background processes remain at the end of the test, they + are terminated using os.Interrupt (if supported) or os.Kill and the test + must not depend upon their exit status. + +- [!] exists [-readonly] [-exec] file... + Each of the listed files or directories must (or must not) exist. + If -readonly is given, the files or directories must be unwritable. + If -exec is given, the files or directories must be executable. + +- [! | ?] go args... [&] + Run the (test copy of the) go command with the given arguments. + It must (or must not) succeed. + +- [!] grep [-count=N] [-q] 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. + The -q flag disables printing the file content on a mismatch. + +- mkdir path... + Create the listed directories, if they do not already exists. + +- mv path1 path2 + Rename path1 to path2. OS-specific restrictions may apply when path1 and path2 + are in different directories. + +- rm file... + Remove the listed files or directories. + +- skip [message] + Mark the test skipped, including the message if given. + +- [!] stale path... + The packages named by the path arguments must (or must not) + be reported as "stale" by the go command. + +- [!] stderr [-count=N] pattern + Apply the grep command (see above) to the standard error + from the most recent exec, go, or wait command. + +- [!] stdout [-count=N] pattern + Apply the grep command (see above) to the standard output + from the most recent exec, go, wait, or env command. + +- stop [message] + Stop the test early (marking it as passing), including the message if given. + +- symlink file -> target + Create file as a symlink to target. The -> (like in ls -l output) is required. + +- wait + Wait for all 'exec' and 'go' commands started in the background (with the '&' + token) to exit, and display success or failure status for them. + After a call to wait, the 'stderr' and 'stdout' commands will apply to the + concatenation of the corresponding streams of the background commands, + in the order in which those commands were started. + +When TestScript runs a script and the script fails, by default TestScript shows +the execution of the most recent phase of the script (since the last # comment) +and only shows the # comments for earlier phases. For example, here is a +multi-phase script with a bug in it: + + # GOPATH with p1 in d2, p2 in d2 + env GOPATH=$WORK/d1${:}$WORK/d2 + + # build & install p1 + env + go install -i p1 + ! stale p1 + ! stale p2 + + # modify p2 - p1 should appear stale + cp $WORK/p2x.go $WORK/d2/src/p2/p2.go + stale p1 p2 + + # build & install p1 again + go install -i p11 + ! stale p1 + ! stale p2 + + -- $WORK/d1/src/p1/p1.go -- + package p1 + import "p2" + func F() { p2.F() } + -- $WORK/d2/src/p2/p2.go -- + package p2 + func F() {} + -- $WORK/p2x.go -- + package p2 + func F() {} + func G() {} + +The bug is that the final phase installs p11 instead of p1. The test failure looks like: + + $ go test -run=Script + --- FAIL: TestScript (3.75s) + --- FAIL: TestScript/install_rebuild_gopath (0.16s) + script_test.go:223: + # GOPATH with p1 in d2, p2 in d2 (0.000s) + # build & install p1 (0.087s) + # modify p2 - p1 should appear stale (0.029s) + # build & install p1 again (0.022s) + > go install -i p11 + [stderr] + can't load package: package p11: cannot find package "p11" in any of: + /Users/rsc/go/src/p11 (from $GOROOT) + $WORK/d1/src/p11 (from $GOPATH) + $WORK/d2/src/p11 + [exit status 1] + FAIL: unexpected go command failure + + script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src + + FAIL + exit status 1 + FAIL cmd/go 4.875s + $ + +Note that the commands in earlier phases have been hidden, so that the relevant +commands are more easily found, and the elapsed time for a completed phase +is shown next to the phase heading. To see the entire execution, use "go test -v", +which also adds an initial environment dump to the beginning of the log. + +Note also that in reported output, the actual name of the per-script temporary directory +has been consistently replaced with the literal string $WORK. + +The cmd/go test flag -testwork (which must appear on the "go test" command line after +standard test flags) causes each test to log the name of its $WORK directory and other +environment variable settings and also to leave that directory behind when it exits, +for manual debugging of failing tests: + + $ go test -run=Script -work + --- FAIL: TestScript (3.75s) + --- FAIL: TestScript/install_rebuild_gopath (0.16s) + script_test.go:223: + WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath + GOARCH= + GOCACHE=/Users/rsc/Library/Caches/go-build + GOOS= + GOPATH=$WORK/gopath + GOROOT=/Users/rsc/go + HOME=/no-home + TMPDIR=$WORK/tmp + exe= + + # GOPATH with p1 in d2, p2 in d2 (0.000s) + # build & install p1 (0.085s) + # modify p2 - p1 should appear stale (0.030s) + # build & install p1 again (0.019s) + > go install -i p11 + [stderr] + can't load package: package p11: cannot find package "p11" in any of: + /Users/rsc/go/src/p11 (from $GOROOT) + $WORK/d1/src/p11 (from $GOPATH) + $WORK/d2/src/p11 + [exit status 1] + FAIL: unexpected go command failure + + script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src + + FAIL + exit status 1 + FAIL cmd/go 4.875s + $ + + $ WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath + $ cd $WORK/d1/src/p1 + $ cat p1.go + package p1 + import "p2" + func F() { p2.F() } + $ + diff --git a/src/cmd/go/testdata/script/badgo.txt b/src/cmd/go/testdata/script/badgo.txt new file mode 100644 index 0000000..cf4e258 --- /dev/null +++ b/src/cmd/go/testdata/script/badgo.txt @@ -0,0 +1,50 @@ +go get example.net/badgo@v1.0.0 +go get example.net/badgo@v1.1.0 +go get example.net/badgo@v1.2.0 +go get example.net/badgo@v1.3.0 +go get example.net/badgo@v1.4.0 +go get example.net/badgo@v1.5.0 +! go get example.net/badgo@v1.6.0 +stderr 'invalid go version .X.Y.: must match format 1.23' + +-- go.mod -- +module m + +replace ( + example.net/badgo v1.0.0 => ./v1.0.0 + example.net/badgo v1.1.0 => ./v1.1.0 + example.net/badgo v1.2.0 => ./v1.2.0 + example.net/badgo v1.3.0 => ./v1.3.0 + example.net/badgo v1.4.0 => ./v1.4.0 + example.net/badgo v1.5.0 => ./v1.5.0 + example.net/badgo v1.6.0 => ./v1.6.0 +) + +-- v1.0.0/go.mod -- +module example.net/badgo +go 1.17.0 + +-- v1.1.0/go.mod -- +module example.net/badgo +go 1.17rc2 + +-- v1.2.0/go.mod -- +module example.net/badgo +go 1.17.1 + +-- v1.3.0/go.mod -- +module example.net/badgo +go v1.17.0 + +-- v1.4.0/go.mod -- +module example.net/badgo +go v1.17.0-rc.2 + +-- v1.5.0/go.mod -- +module example.net/badgo +go v1.17.1 + +-- v1.6.0/go.mod -- +module example.net/badgo +go X.Y + diff --git a/src/cmd/go/testdata/script/bug.txt b/src/cmd/go/testdata/script/bug.txt new file mode 100644 index 0000000..571d507 --- /dev/null +++ b/src/cmd/go/testdata/script/bug.txt @@ -0,0 +1,58 @@ +# Verify that go bug creates the appropriate URL issue body + +[!linux] skip +[short] skip + +go install +go build -o $TMPDIR/go ./go +env BROWSER=$GOPATH/bin/browser PATH=$TMPDIR:$PATH +go bug +exists $TMPDIR/browser +grep '^go version' $TMPDIR/browser +grep '^GOROOT/bin/go version: go version' $TMPDIR/browser +grep '^GOROOT/bin/go tool compile -V: compile version' $TMPDIR/browser +grep '^uname -sr: Linux' $TMPDIR/browser + +-- go.mod -- +module browser + +-- main.go -- +package main + +import ( + "fmt" + "net/url" + "os" + "path/filepath" +) + +func main() { + u, err := url.Parse(os.Args[1]) + if err != nil { + panic(err) + } + body, err := url.PathUnescape(u.Query().Get("body")) + if err != nil { + panic(err) + } + out := filepath.Join(os.TempDir(), "browser") + f, err := os.Create(out) + if err != nil { + panic(err) + } + fmt.Fprintln(f, body) + if err := f.Close(); err != nil { + panic(err) + } +} + +-- go/main.go -- +package main + +import ( + "os" +) + +func main() { + os.Exit(1) +} diff --git a/src/cmd/go/testdata/script/build_GOTMPDIR.txt b/src/cmd/go/testdata/script/build_GOTMPDIR.txt new file mode 100644 index 0000000..1073517 --- /dev/null +++ b/src/cmd/go/testdata/script/build_GOTMPDIR.txt @@ -0,0 +1,50 @@ +# Set GOCACHE to a clean directory to ensure that 'go build' has work to report. +[!windows] env GOCACHE=$WORK/gocache +[windows] env GOCACHE=$WORK\gocache + +# 'go build' should use GOTMPDIR if set. +[!windows] env GOTMPDIR=$WORK/my-favorite-tmpdir +[windows] env GOTMPDIR=$WORK\my-favorite-tmpdir +mkdir $GOTMPDIR +go build -x hello.go +stderr ^WORK=.*my-favorite-tmpdir + +# Make GOTMPDIR a regular file. This prevents the creation of work directories, +# so we can check that certain commands don't create them. +# This simulates running on a full disk or a read-only volume. +rm $GOTMPDIR +cp hello.go $GOTMPDIR # any file will do + +# 'go build' should fail if GOTMPDIR is read-only. +! go build -x . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go list' should only fail if it needs to build something. +go list -x . +! stderr 'creating work dir' +stdout m +go list -m all +stdout m +! go list -x -export . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go clean -cache' and 'go clean -modcache' should not fail. +go clean -x -cache +! stderr 'creating work dir' +go clean -x -modcache +! stderr 'creating work dir' + +# 'go env' should not fail for specific variables. +# Without arguments, it needs to initialize a builder to load cgo flags, and +# that uses a temporary directory. +! go env +stderr '^go: creating work dir: \w+ '$GOTMPDIR +go env GOROOT + +-- go.mod -- +module m + +go 1.15 +-- hello.go -- +package main +func main() { println("hello") } diff --git a/src/cmd/go/testdata/script/build_acl_windows.txt b/src/cmd/go/testdata/script/build_acl_windows.txt new file mode 100644 index 0000000..13a3ba2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_acl_windows.txt @@ -0,0 +1,44 @@ +[!windows] stop +[!exec:icacls] skip +[!exec:powershell] skip + +# Create $WORK\guest and give the Guests group full access. +# Files created within that directory will have different security attributes by default. +mkdir $WORK\guest +exec icacls $WORK\guest /grant '*S-1-5-32-546:(oi)(ci)f' + +env TMP=$WORK\guest +env TEMP=$WORK\guest + +# Build a binary using the guest directory as an intermediate +cd TestACL +go build -o main.exe main.go +# Build the same binary, but write it to the guest directory. +go build -o $TMP\main.exe main.go + +# Read ACLs for the files. +exec powershell -Command 'Get-Acl main.exe | Select -expand AccessToString' +cp stdout $WORK\exe-acl.txt +exec powershell -Command 'Get-Acl main.go | Select -expand AccessToString' +cp stdout $WORK\src-acl.txt +cd $TMP +exec powershell -Command 'Get-Acl main.exe | Select -expand AccessToString' +cp stdout $WORK\guest-acl.txt + +cd $WORK + +# The executable written to the source directory should have the same ACL as the source file. +cmp $WORK\exe-acl.txt $WORK\src-acl.txt + +# The file written to the guest-allowed directory should give Guests control. +grep 'BUILTIN\\Guests\s+Allow' $WORK\guest-acl.txt + +# The file written to the ordinary directory should not. +! grep 'BUILTIN\\Guests\s+Allow' $WORK\exe-acl.txt + + +-- TestACL/go.mod -- +module TestACL +-- TestACL/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_arm.txt b/src/cmd/go/testdata/script/build_arm.txt new file mode 100644 index 0000000..ff2a364 --- /dev/null +++ b/src/cmd/go/testdata/script/build_arm.txt @@ -0,0 +1,13 @@ +[short] skip 'skipping cross-compile in short mode' + +env GOARCH=arm +env GOOS=linux +env GOARM=5 + +go build hello.go +! stderr 'unable to find math.a' + +-- hello.go -- +package main + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_buildvcs_auto.txt b/src/cmd/go/testdata/script/build_buildvcs_auto.txt new file mode 100644 index 0000000..9eac568 --- /dev/null +++ b/src/cmd/go/testdata/script/build_buildvcs_auto.txt @@ -0,0 +1,87 @@ +# Regression test for https://go.dev/issue/51748: by default, 'go build' should +# not attempt to stamp VCS information when the VCS tool is not present. + +[short] skip +[!exec:git] skip + +cd sub +exec git init . +exec git add sub.go +exec git commit -m 'initial state' +cd .. + +exec git init +exec git submodule add ./sub +exec git add go.mod example.go +exec git commit -m 'initial state' + + +# Control case: with a git binary in $PATH, +# 'go build' on a package in the same git repo +# succeeds and stamps VCS metadata by default. + +go build -o example.exe . +go version -m example.exe +stdout '^\tbuild\tvcs=git$' +stdout '^\tbuild\tvcs.modified=false$' + + +# Building a binary from a different (nested) VCS repo should not stamp VCS +# info. It should be an error if VCS stamps are requested explicitly with +# '-buildvcs' (since we know the VCS metadata exists), but not an error +# with '-buildvcs=auto'. + +go build -o sub.exe ./sub +go version -m sub.exe +! stdout '^\tbuild\tvcs' + +! go build -buildvcs -o sub.exe ./sub +stderr '\Aerror obtaining VCS status: main package is in repository ".*" but current directory is in repository ".*"\n\tUse -buildvcs=false to disable VCS stamping.\n\z' + +cd ./sub +go build -o sub.exe . +go version -m sub.exe +! stdout '^\tbuild\tvcs' + +! go build -buildvcs -o sub.exe . +stderr '\Aerror obtaining VCS status: main module is in repository ".*" but current directory is in repository ".*"\n\tUse -buildvcs=false to disable VCS stamping.\n\z' +cd .. + + +# After removing 'git' from $PATH, 'go build -buildvcs' should fail... + +env PATH= +env path= +! go build -buildvcs -o example.exe . +stderr 'go: missing Git command\. See https://golang\.org/s/gogetcmd$' + +# ...but by default we should omit VCS metadata when the tool is missing. + +go build -o example.exe . +go version -m example.exe +! stdout '^\tbuild\tvcs' + +# The default behavior can be explicitly set with '-buildvcs=auto'. + +go build -buildvcs=auto -o example.exe . +go version -m example.exe +! stdout '^\tbuild\tvcs' + +# Other flag values should be rejected with a useful error message. + +! go build -buildvcs=hg -o example.exe . +stderr '\Ainvalid boolean value "hg" for -buildvcs: value is neither ''auto'' nor a valid bool\nusage: go build .*\nRun ''go help build'' for details.\n\z' + + +-- go.mod -- +module example + +go 1.18 +-- example.go -- +package main + +func main() {} +-- sub/sub.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_arch_mode.txt b/src/cmd/go/testdata/script/build_cache_arch_mode.txt new file mode 100644 index 0000000..931827f --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_arch_mode.txt @@ -0,0 +1,21 @@ +# Issue 9737: verify that GOARM affects the computed build ID + +[short] skip + +# arm +env GOOS=linux +env GOARCH=arm +env GOARM=5 +go install mycmd +env GOARM=7 +stale mycmd + + +-- go.mod -- +module mycmd + +go 1.16 +-- x.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_compile.txt b/src/cmd/go/testdata/script/build_cache_compile.txt new file mode 100644 index 0000000..64b391f --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_compile.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off +[short] skip + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building trivial non-main package should run compiler the first time. +go build -x lib.go +stderr '(compile|gccgo)( |\.exe).*lib\.go' + +# ... but not again ... +go build -x lib.go +! stderr '(compile|gccgo)( |\.exe).*lib\.go' + +# ... unless we use -a. +go build -a -x lib.go +stderr '(compile|gccgo)( |\.exe)' + +-- lib.go -- +package lib diff --git a/src/cmd/go/testdata/script/build_cache_disabled.txt b/src/cmd/go/testdata/script/build_cache_disabled.txt new file mode 100644 index 0000000..cb1a755 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_disabled.txt @@ -0,0 +1,50 @@ +# The build cache is required to build anything. It also may be needed to +# initialize the build system, which is needed for commands like 'go env'. +# However, there are lots of commands the cache is not needed for, and we +# shouldn't require it when it won't be used. +# +# TODO(golang.org/issue/39882): commands below should work, too. +# * go clean -modcache +# * go env +# * go fix +# * go fmt +# * go generate +# * go get +# * go list (without -export or -compiled) + +env GOCACHE=off + +# Commands that don't completely load packages should work. +go doc fmt +stdout Printf + +! go tool compile -h +stderr usage: + +go version +stdout '^go version' + + +# Module commands that don't load packages should work. +go mod init m +exists go.mod + +go mod edit -require rsc.io/quote@v1.5.2 + +go mod download rsc.io/quote + +go mod graph +stdout rsc.io/quote + +go mod verify + + +# Commands that load but don't build packages should work. +go fmt . + +go doc . + +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_gomips.txt b/src/cmd/go/testdata/script/build_cache_gomips.txt new file mode 100644 index 0000000..0cbf16a --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_gomips.txt @@ -0,0 +1,40 @@ +env GO111MODULE=off +[short] skip # rebuilds std for mips + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building for mipsle without setting GOMIPS will use floating point registers. +env GOARCH=mipsle +env GOOS=linux +go build -gcflags=-S f.go +stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Clean cache +go clean -cache + +# Building with GOMIPS=softfloat will not use floating point registers +env GOMIPS=softfloat +go build -gcflags=-S f.go +! stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Clean cache +go clean -cache + +# Build without setting GOMIPS +env GOMIPS= +go build -gcflags=-S f.go +stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +# Building with GOMIPS should still not use floating point registers. +env GOMIPS=softfloat +go build -gcflags=-S f.go +! stderr ADDD.F[0-9]+,.F[0-9]+,.F[0-9]+ + +-- f.go -- +package f + +func F(x float64) float64 { + return x + x +} diff --git a/src/cmd/go/testdata/script/build_cache_link.txt b/src/cmd/go/testdata/script/build_cache_link.txt new file mode 100644 index 0000000..b9c740a --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_link.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off +[short] skip + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building a main package should run the compiler and linker ... +go build -o $devnull -x main.go +stderr '(compile|gccgo)( |\.exe).*main\.go' +stderr '(link|gccgo)( |\.exe)' + +# ... and then the linker again ... +go build -o $devnull -x main.go +! stderr '(compile|gccgo)( |\.exe).*main\.go' +stderr '(link|gccgo)( |\.exe)' + +# ... but the output binary can serve as a cache. +go build -o main$GOEXE -x main.go +stderr '(link|gccgo)( |\.exe)' +go build -o main$GOEXE -x main.go +! stderr '(link|gccgo)( |\.exe)' + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_cache_output.txt b/src/cmd/go/testdata/script/build_cache_output.txt new file mode 100644 index 0000000..0d94bf6 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_output.txt @@ -0,0 +1,67 @@ +env GO111MODULE=off +env GODEBUG=gocachetest=1 + +[!gc] skip +[short] skip # clears cache, rebuilds too much + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Building a trivial non-main package should run compiler the first time. +go build -x -gcflags=-m lib.go +stderr 'compile( |\.exe"?)' +stderr 'lib.go:2.* can inline f' + +# ... but not the second, even though it still prints the compiler output. +go build -x -gcflags=-m lib.go +! stderr 'compile( |\.exe"?)' +stderr 'lib.go:2.* can inline f' + +# Building a trivial main package should run the compiler and linker the first time. +go build -x -gcflags=-m -ldflags='-v -w' main.go +stderr 'compile( |\.exe"?)' +stderr 'main.go:2.* can inline main' # from compiler +stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker + +# ... but not the second, even though it still prints the compiler and linker output. +go build -x -gcflags=-m -ldflags='-v -w' main.go +! stderr 'compile( |\.exe"?)' +stderr 'main.go:2.* can inline main' # from compiler +! stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker + +# Running a test should run the compiler, linker, and the test the first time. +go test -v -x -gcflags=-m -ldflags=-v p +stderr 'compile( |\.exe"?)' +stderr 'p_test.go:.*can inline Test' # from compile of p_test +stderr 'testmain\.go:.*inlin' # from compile of testmain +stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker +stderr 'p\.test( |\.exe"?)' +stdout 'TEST' # from test + +# ... but not the second, even though it still prints the compiler, linker, and test output. +go test -v -x -gcflags=-m -ldflags=-v p +! stderr 'compile( |\.exe"?)' +stderr 'p_test.go:.*can inline Test' # from compile of p_test +stderr 'testmain\.go:.*inlin' # from compile of testmain +! stderr 'link(\.exe"?)? -' +stderr '\d+ symbols' # from linker +! stderr 'p\.test( |\.exe"?)' +stdout 'TEST' # from test + + +-- lib.go -- +package p +func f(x *int) *int { return x } + +-- main.go -- +package main +func main() {} + +-- p/p_test.go -- +package p +import "testing" +func Test(t *testing.T) {println("TEST")} diff --git a/src/cmd/go/testdata/script/build_cache_trimpath.txt b/src/cmd/go/testdata/script/build_cache_trimpath.txt new file mode 100644 index 0000000..7ee3c3b --- /dev/null +++ b/src/cmd/go/testdata/script/build_cache_trimpath.txt @@ -0,0 +1,47 @@ +[short] skip +env GO111MODULE=on + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +cd $WORK +go build -o a.out + +# Varying -trimpath should cause a rebuild. +go build -x -o a.out -trimpath +stderr '(compile|gccgo)( |\.exe)' +stderr 'link( |\.exe)' + +# Two distinct versions of the same module with identical content should +# still be cached separately. +# Verifies golang.org/issue/35412. +go get example.com/stack@v1.0.0 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.0/stack.go$' +go get example.com/stack@v1.0.1 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.1/stack.go$' + +-- $WORK/hello.go -- +package main +func main() { println("hello") } + +-- $WORK/printstack.go -- +// +build ignore + +package main + +import ( + "fmt" + + "example.com/stack" +) + +func main() { + fmt.Println(stack.TopFile()) +} +-- $WORK/go.mod -- +module m + +go 1.14 diff --git a/src/cmd/go/testdata/script/build_cd_gopath_different.txt b/src/cmd/go/testdata/script/build_cd_gopath_different.txt new file mode 100644 index 0000000..a7a4bf4 --- /dev/null +++ b/src/cmd/go/testdata/script/build_cd_gopath_different.txt @@ -0,0 +1,73 @@ +[gccgo] skip 'gccgo does not support -ldflags -X' +env GO111MODULE=off +go build run_go.go + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH IDENTITY build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +[!windows] stop 'rest of the tests only apply to Windows' + +# Replace '\' with '/' in GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH REPLACE_SLASH build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH UPPER build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +# Apply identity function to GOPATH +exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH LOWER build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked +exec $WORK/tmp/a.exe +stderr 'linkXworked' +rm $WORK/tmp/a.exe + +-- run_go.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +func main() { + dir := os.Args[1] + gopath := os.Args[2] + switch os.Args[3] { + case "IDENTITY": + case "REPLACE_SLASH": gopath = strings.ReplaceAll(gopath, `\`, `/`) + case "UPPER": gopath = strings.ToUpper(gopath) + case "LOWER": gopath = strings.ToLower(gopath) + default: fmt.Fprintln(os.Stderr, "bad op"); os.Exit(1) + } + cmd := exec.Command("go", os.Args[4:]...) + cmd.Dir = dir + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +-- my.pkg/main/main.go -- +package main + +import "my.pkg" + +func main() { + println(pkg.Text) +} +-- my.pkg/pkg.go -- +package pkg + +var Text = "unset" diff --git a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt new file mode 100644 index 0000000..88a24de --- /dev/null +++ b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt @@ -0,0 +1,23 @@ +[short] skip +[!cgo] skip + +[solaris] skip "skipping on Solaris; see golang.org/issue/13247" +[illumos] skip "skipping on Solaris; see golang.org/issue/13247" + +go build -o $WORK/exe1$GOEXE cgotest +go build -x -o $WORK/exe2$GOEXE cgotest + +# TODO(matloob): skip if stderr does not contain '-fdebug-prefix-map=\$WORK' + +cmp $WORK/exe1$GOEXE $WORK/exe2$GOEXE + +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- +package cgotest + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/build_concurrent_backend.txt b/src/cmd/go/testdata/script/build_concurrent_backend.txt new file mode 100644 index 0000000..9cac635 --- /dev/null +++ b/src/cmd/go/testdata/script/build_concurrent_backend.txt @@ -0,0 +1,10 @@ +# Tests golang.org/issue/48490 +# cmd/go should enable concurrent compilation by default + +# Reset all experiments, since one of them can disable +# concurrent compilation, e.g: fieldtrack. +env GOEXPERIMENT=none + +env GOMAXPROCS=4 +go build -n -x -a fmt +stderr ' -c=4 ' diff --git a/src/cmd/go/testdata/script/build_darwin_cc_arch.txt b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt new file mode 100644 index 0000000..2b81b4c --- /dev/null +++ b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt @@ -0,0 +1,24 @@ +# Test that we pass -arch flag to C compiler on Darwin (issue 43692). + +[!darwin] skip +[!cgo] skip + +# clear CC, in case user sets it +env CC= + +env CGO_ENABLED=1 + +env GOARCH=amd64 +go build -n -x c.go +stderr 'clang.*-arch x86_64' + +env GOARCH=arm64 +go build -n -x c.go +stderr 'clang.*-arch arm64' + +-- c.go -- +package main + +import "C" + +func main() {} diff --git a/src/cmd/go/testdata/script/build_dash_n_cgo.txt b/src/cmd/go/testdata/script/build_dash_n_cgo.txt new file mode 100644 index 0000000..3f49ef6 --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_n_cgo.txt @@ -0,0 +1,18 @@ +# Tests golang.org/issue/14944 + +[!cgo] skip + +go build -n foo.go +! stderr 'os.Stat .* no such file or directory' # there shouldn't be a stat of the archive file + +-- foo.go -- +package main + +/* +#include <limits.h> +*/ +import "C" + +func main() { + println(C.INT_MAX) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_dash_o_dev_null.txt b/src/cmd/go/testdata/script/build_dash_o_dev_null.txt new file mode 100644 index 0000000..e415fc2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_o_dev_null.txt @@ -0,0 +1,13 @@ +# Issue #25579 + +[short] skip + +go build -o $devnull hello.go +! exists 'hello'$GOEXE + +-- hello.go -- +package main + +func main() { + println("hello, world") +} diff --git a/src/cmd/go/testdata/script/build_dash_x.txt b/src/cmd/go/testdata/script/build_dash_x.txt new file mode 100644 index 0000000..6fd5bbe --- /dev/null +++ b/src/cmd/go/testdata/script/build_dash_x.txt @@ -0,0 +1,49 @@ +[short] skip +[!cgo] skip + +[!exec:/usr/bin/env] skip +[!exec:bash] skip +[!exec:cat] skip + +mkdir $WORK/tmp/cache +env GOCACHE=$WORK/tmp/cache + +# Before building our test main.go, ensure that an up-to-date copy of +# runtime/cgo is present in the cache. If it isn't, the 'go build' step below +# will fail with "can't open import". See golang.org/issue/29004. +# +# (The fix in golang.org/issue/29004 didn't completely fix the underlying issue: +# cmd/go/internal/load adds a bunch of implicit dependencies +# based on various heuristics, and, due to a bug described in +# https://golang.org/issue/31544#issuecomment-490607180, +# those implicit dependencies are not added early enough during +# loading to properly affect the import graph.) +go build runtime/cgo + +go build -x -o main main.go +cp stderr commands.txt +exec cat header.txt commands.txt +cp stdout test.sh + +exec ./main +cmp stderr hello.txt +rm ./main + +exec /usr/bin/env bash -x test.sh +exec ./main +cmp stderr hello.txt + +grep '^WORK=(.*)\n' commands.txt + +-- main.go -- +package main + +import "C" + +func main() { + print("hello\n") +} +-- header.txt -- +set -e +-- hello.txt -- +hello diff --git a/src/cmd/go/testdata/script/build_exe.txt b/src/cmd/go/testdata/script/build_exe.txt new file mode 100644 index 0000000..a994d17 --- /dev/null +++ b/src/cmd/go/testdata/script/build_exe.txt @@ -0,0 +1,25 @@ +# go build with -o and -buildmode=exe should report an error on a non-main package. + +! go build -buildmode=exe -o out$GOEXE ./not_main +stderr '-buildmode=exe requires exactly one main package' +! exists out$GOEXE +! go build -buildmode=exe -o out$GOEXE ./main_one ./main_two +stderr '-buildmode=exe requires exactly one main package' +! exists out$GOEXE + +-- go.mod -- +module m + +go 1.16 +-- not_main/not_main.go -- +package not_main + +func F() {} +-- main_one/main_one.go -- +package main + +func main() {} +-- main_two/main_two.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/build_gcflags.txt b/src/cmd/go/testdata/script/build_gcflags.txt new file mode 100644 index 0000000..b472374 --- /dev/null +++ b/src/cmd/go/testdata/script/build_gcflags.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# Test that the user can override default code generation flags. + +[gccgo] skip # gccgo does not use -gcflags +[!cgo] skip +[!linux] skip # test only works if c-archive implies -shared +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. +go build -x -n -buildmode=c-archive -gcflags=all=-shared=false ./override.go +stderr '^.*/compile (.* )?-shared (.* )?-shared=false' + +-- override.go -- +package main + +import "C" + +//export GoFunc +func GoFunc() {} + +func main() {} diff --git a/src/cmd/go/testdata/script/build_gcflags_order.txt b/src/cmd/go/testdata/script/build_gcflags_order.txt new file mode 100644 index 0000000..0ffe157 --- /dev/null +++ b/src/cmd/go/testdata/script/build_gcflags_order.txt @@ -0,0 +1,20 @@ +# Tests golang.org/issue/47682 +# Flags specified with -gcflags should appear after other flags generated by cmd/go. + +cd m +go build -n -gcflags=-lang=go1.17 +stderr ' -lang=go1.16.* -lang=go1.17' + +-- m/go.mod -- +module example.com + +go 1.16 + +-- m/main.go -- +package main + +func main() { + var s = []int{1, 2, 3} + var pa = (*[2]int)(s[1:]) + println(pa[1]) +} diff --git a/src/cmd/go/testdata/script/build_gopath_order.txt b/src/cmd/go/testdata/script/build_gopath_order.txt new file mode 100644 index 0000000..caf2502 --- /dev/null +++ b/src/cmd/go/testdata/script/build_gopath_order.txt @@ -0,0 +1,36 @@ +# golang.org/issue/14176#issuecomment-179895769 +# golang.org/issue/14192 +# -I arguments to compiler could end up not in GOPATH order, +# leading to unexpected import resolution in the compiler. + +env GO111MODULE=off +env GOPATH=$WORK/p1${:}$WORK/p2 +mkdir $WORK/p1/src/foo $WORK/p2/src/baz +mkdir $WORK/p2/pkg/${GOOS}_${GOARCH} $WORK/p1/src/bar +cp foo.go $WORK/p1/src/foo/foo.go +cp baz.go $WORK/p2/src/baz/baz.go +cp foo.a $WORK/p2/pkg/${GOOS}_${GOARCH}/foo.a +cp bar.go $WORK/p1/src/bar/bar.go + +go install -x bar + +# add in baz.a to the mix +mkdir $WORK/p1/pkg/${GOOS}_${GOARCH} +cp baz.a $WORK/p1/pkg/${GOOS}_${GOARCH}/baz.a +env GOPATH=$WORK/p1${:}$WORK/p2 +go install -x bar +env GOPATH=$WORK/p2${:}$WORK/p1 +go install -x bar + +-- foo.go -- +package foo +-- baz.go -- +package baz +-- foo.a -- +bad +-- baz.a -- +bad +-- bar.go -- +package bar +import _ "baz" +import _ "foo" diff --git a/src/cmd/go/testdata/script/build_i.txt b/src/cmd/go/testdata/script/build_i.txt new file mode 100644 index 0000000..0e7ebed --- /dev/null +++ b/src/cmd/go/testdata/script/build_i.txt @@ -0,0 +1,41 @@ +env GO111MODULE=off + +# Test that 'go build -i' installs dependencies of the requested package. + +[short] skip + +# Since we are checking installation of dependencies, use a clean cache +# to ensure that multiple runs of the test do not interfere. +env GOCACHE=$WORK/cache + +# The initial 'go build -i' for bar should install its dependency foo. + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +# After modifying the source files, both packages should be rebuild. + +cp x/y/foo/foo.go.next x/y/foo/foo.go +cp x/y/bar/bar.go.next x/y/bar/bar.go + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +-- x/y/foo/foo.go -- +package foo +func F() {} +-- x/y/bar/bar.go -- +package bar +import "x/y/foo" +func F() { foo.F() } +-- x/y/foo/foo.go.next -- +package foo +func F() { F() } +-- x/y/bar/bar.go.next -- +package main +import "x/y/foo" +func main() { foo.F() } diff --git a/src/cmd/go/testdata/script/build_i_deprecate.txt b/src/cmd/go/testdata/script/build_i_deprecate.txt new file mode 100644 index 0000000..5c17995 --- /dev/null +++ b/src/cmd/go/testdata/script/build_i_deprecate.txt @@ -0,0 +1,24 @@ +# Check that deprecation warnings are printed when the -i flag is used. +# TODO(golang.org/issue/41696): remove the -i flag after Go 1.16, and this test. + +go build -n -i +stderr '^go: -i flag is deprecated$' + +go install -n -i +stderr '^go: -i flag is deprecated$' + +go test -n -i +stderr '^go: -i flag is deprecated$' + + +# 'go clean -i' should not print a deprecation warning. +# It will continue working. +go clean -i . +! stderr . + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m diff --git a/src/cmd/go/testdata/script/build_ignore_leading_bom.txt b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt new file mode 100644 index 0000000..37141f3 --- /dev/null +++ b/src/cmd/go/testdata/script/build_ignore_leading_bom.txt @@ -0,0 +1,27 @@ +# Per https://golang.org/ref/spec#Source_code_representation: +# a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF) +# if it is the first Unicode code point in the source text. + +go list -f 'Imports: {{.Imports}} EmbedFiles: {{.EmbedFiles}}' . +stdout '^Imports: \[embed m/hello\] EmbedFiles: \[.*file\]$' + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package main + +import ( + _ "embed" + + "m/hello" +) + +//go:embed file +var s string + +-- hello/hello.go -- +package hello + +-- file -- diff --git a/src/cmd/go/testdata/script/build_import_comment.txt b/src/cmd/go/testdata/script/build_import_comment.txt new file mode 100644 index 0000000..b500340 --- /dev/null +++ b/src/cmd/go/testdata/script/build_import_comment.txt @@ -0,0 +1,68 @@ +# Test in GOPATH mode first. +env GO111MODULE=off +cd m + +# Import comment matches +go build -n works.go + +# Import comment mismatch +! go build -n wrongplace.go +stderr 'wrongplace expects import "my/x"' + +# Import comment syntax error +! go build -n bad.go +stderr 'cannot parse import comment' + +# Import comment conflict +! go build -n conflict.go +stderr 'found import comments' + + +# Test in module mode. +# We ignore import comments, so these commands should succeed. +env GO111MODULE=on + +# Import comment matches +go build -n works.go + +# Import comment mismatch +go build -n wrongplace.go + +# Import comment syntax error +go build -n bad.go + +# Import comment conflict +go build -n conflict.go + +-- m/go.mod -- +module m + +go 1.16 +-- m/bad.go -- +package p + +import "m/bad" +-- m/conflict.go -- +package p + +import "m/conflict" +-- m/works.go -- +package p + +import _ "m/works/x" +-- m/wrongplace.go -- +package p + +import "m/wrongplace" +-- m/bad/bad.go -- +package bad // import +-- m/conflict/a.go -- +package conflict // import "a" +-- m/conflict/b.go -- +package conflict /* import "b" */ +-- m/works/x/x.go -- +package x // import "m/works/x" +-- m/works/x/x1.go -- +package x // important! not an import comment +-- m/wrongplace/x.go -- +package x // import "my/x" diff --git a/src/cmd/go/testdata/script/build_import_cycle.txt b/src/cmd/go/testdata/script/build_import_cycle.txt new file mode 100644 index 0000000..16e4e87 --- /dev/null +++ b/src/cmd/go/testdata/script/build_import_cycle.txt @@ -0,0 +1,13 @@ +# mod_import_cycle covers this error in module mode. +env GO111MODULE=off + +! go build selfimport +stderr -count=1 'import cycle not allowed' + +go list -e -f '{{.Error}}' selfimport # Don't hang forever +stdout -count=1 'import cycle not allowed' + +-- selfimport/selfimport.go -- +package selfimport + +import "selfimport" diff --git a/src/cmd/go/testdata/script/build_internal.txt b/src/cmd/go/testdata/script/build_internal.txt new file mode 100644 index 0000000..5b786f2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_internal.txt @@ -0,0 +1,65 @@ +# Test internal package errors are handled +cd testinternal3 +go list . +stdout 'testinternal3' + +# Test internal cache +cd ../testinternal4 +! go build testinternal4/p +stderr 'internal' + +# Test internal packages outside GOROOT are respected +cd ../testinternal2 +env GO111MODULE=off +! go build -v . +stderr 'p\.go:3:8: use of internal package .*internal/w not allowed' +env GO111MODULE='' + +[gccgo] skip # gccgo does not have GOROOT +cd ../testinternal +! go build -v . +stderr 'p\.go:3:8: use of internal package net/http/internal not allowed' + +-- testinternal/go.mod -- +module testinternal + +go 1.16 +-- testinternal/p.go -- +package p + +import _ "net/http/internal" +-- testinternal2/go.mod -- +module testinternal2 + +go 1.16 +-- testinternal2/p.go -- +package p + +import _ "./x/y/z/internal/w" +-- testinternal2/x/y/z/internal/w/w.go -- +package w +-- testinternal3/go.mod -- +module testinternal3 + +go 1.16 +-- testinternal3/t.go -- +package t + +import _ "internal/does-not-exist" +-- testinternal4/go.mod -- +module testinternal4 + +go 1.16 +-- testinternal4/p/p.go -- +package p + +import ( + _ "testinternal4/q/internal/x" + _ "testinternal4/q/j" +) +-- testinternal4/q/internal/x/x.go -- +package x +-- testinternal4/q/j/j.go -- +package j + +import _ "testinternal4/q/internal/x" diff --git a/src/cmd/go/testdata/script/build_issue48319.txt b/src/cmd/go/testdata/script/build_issue48319.txt new file mode 100644 index 0000000..3979247 --- /dev/null +++ b/src/cmd/go/testdata/script/build_issue48319.txt @@ -0,0 +1,47 @@ +# Regression test for https://go.dev/issue/48319: +# cgo builds should not include debug information from a stale GOROOT_FINAL. + +[short] skip +[!cgo] skip +[windows] skip # The Go Windows builders have an extremely out-of-date gcc that does not support reproducible builds; see https://go.dev/issue/50824. + +# This test is sensitive to cache invalidation, +# so use a separate build cache that we can control. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Build a binary using a specific value of GOROOT_FINAL. +env GOROOT_FINAL=$WORK${/}goroot1 +go build -o main.exe +mv main.exe main1.exe + +# Now clean the cache and build using a different GOROOT_FINAL. +# The resulting binaries should differ in their debug metadata. +go clean -cache +env GOROOT_FINAL=$WORK${/}goroot2 +go build -o main.exe +mv main.exe main2.exe +! cmp main2.exe main1.exe + +# Set GOROOT_FINAL back to the first value. +# If the build is properly reproducible, the two binaries should match. +env GOROOT_FINAL=$WORK${/}goroot1 +go build -o main.exe +cmp -q main.exe main1.exe + +-- go.mod -- +module main + +go 1.18 +-- main.go -- +package main + +import "C" + +import "runtime" + +var _ C.int + +func main() { + println(runtime.GOROOT()) +} diff --git a/src/cmd/go/testdata/script/build_issue6480.txt b/src/cmd/go/testdata/script/build_issue6480.txt new file mode 100644 index 0000000..cf1e9ea --- /dev/null +++ b/src/cmd/go/testdata/script/build_issue6480.txt @@ -0,0 +1,128 @@ +# "go test -c -test.bench=XXX errors" should not hang. +# "go test -c" should also produce reproducible binaries. +# "go test -c" should also appear to write a new binary every time, +# even if it's really just updating the mtime on an existing up-to-date binary. + +[gccgo] skip +[short] skip + +# Install some commands to compare mtimes +env GOBIN=$WORK/tmp/bin +go install m/now m/mtime m/before + +# Initial builds +go test -c -test.bench=XXX errors +go test -c -o errors2.test errors +cmp errors.test$GOEXE errors2.test # // errors2.test has no exeSuffix because -o above doesn't have it + +# Check errors.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -test.bench=XXX errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors.test$GOEXE +cp stdout errors1_mod_time.txt +exec $GOBIN/before start_time.txt errors1_mod_time.txt +rm start_time.txt errors1_mod_time.txt + +# Check errors2.test mtime is updated +exec $GOBIN/now +cp stdout start_time.txt +go test -x -c -o errors2.test errors +! stderr '[\\/]link|gccgo' # make sure up-to-date test binary is not relinked +exec $GOBIN/mtime errors2.test +cp stdout errors2_mod_time.txt +exec $GOBIN/before start_time.txt errors2_mod_time.txt + +-- go.mod -- +module m + +go 1.16 +-- now/now.go -- +// Writes time.Now() to a file +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +func main() { + if err := json.NewEncoder(os.Stdout).Encode(time.Now()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- mtime/mtime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" +) + +func main() { + info, err := os.Stat(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.NewEncoder(os.Stdout).Encode(info.ModTime()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- before/before.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +func truncateLike(t, p time.Time) time.Time { + nano := p.UnixNano() + d := 1 * time.Nanosecond + for nano%int64(d) == 0 && d < 1*time.Second { + d *= 10 + } + for nano%int64(d) == 0 && d < 2*time.Second { + d *= 2 + } + return t.Truncate(d) +} + +func main() { + var t1 time.Time + b1, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b1, &t1); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + var t2 time.Time + b2, err := os.ReadFile(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b2, &t2); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + t1 = truncateLike(t1, t2) + if !t1.Before(t2) { + fmt.Fprintf(os.Stderr, "time in %v (%v) is not before time in %v (%v)", os.Args[1], t1, os.Args[2], t2) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt new file mode 100644 index 0000000..f1de1e4 --- /dev/null +++ b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt @@ -0,0 +1,22 @@ +[gccgo] skip 'gccgo does not support -ldflags -X' + +go build -o linkx$GOEXE -ldflags -X=my.pkg.Text=linkXworked my.pkg/main +exec ./linkx$GOEXE +stderr '^linkXworked$' + +-- go.mod -- +module my.pkg + +go 1.16 +-- main/main.go -- +package main + +import "my.pkg" + +func main() { + println(pkg.Text) +} +-- pkg.go -- +package pkg + +var Text = "unset" diff --git a/src/cmd/go/testdata/script/build_multi_main.txt b/src/cmd/go/testdata/script/build_multi_main.txt new file mode 100644 index 0000000..8afd8b8 --- /dev/null +++ b/src/cmd/go/testdata/script/build_multi_main.txt @@ -0,0 +1,43 @@ +# Verify build -o can output multiple executables to a directory. + +mkdir $WORK/bin +go build -o $WORK/bin ./cmd/c1 ./cmd/c2 +! stderr 'multiple packages' + +! go build -o $WORK/bin ./pkg1 ./pkg1 +stderr 'no main packages' + +! go build ./cmd/c1 +stderr 'already exists and is a directory' + +# Verify build -o output correctly local packages +mkdir $WORK/local +go build -o $WORK/local ./exec.go +exists $WORK/local/exec$GOEXE + +-- go.mod -- +module exmod + +-- cmd/c1/main.go -- +package main + +func main() {} + +-- cmd/c2/main.go -- +package main + +func main() {} + +-- pkg1/pkg1.go -- +package pkg1 + +-- pkg2/pkg2.go -- +package pkg2 + +-- exec.go -- +package main + +func main() {} + +-- c1$GOEXE/keep.txt -- +Create c1 directory. diff --git a/src/cmd/go/testdata/script/build_n_cgo.txt b/src/cmd/go/testdata/script/build_n_cgo.txt new file mode 100644 index 0000000..7aa77ae --- /dev/null +++ b/src/cmd/go/testdata/script/build_n_cgo.txt @@ -0,0 +1,17 @@ +[!cgo] skip + +# Test that nothing is prepended to $WORK path prefix. +# See issue golang.org/issue/37012. +go build -n +! stderr '[/\\]\$WORK' + +-- go.mod -- +module m + +go 1.16 +-- main.go -- +package main + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/build_negative_p.txt b/src/cmd/go/testdata/script/build_negative_p.txt new file mode 100644 index 0000000..9123907 --- /dev/null +++ b/src/cmd/go/testdata/script/build_negative_p.txt @@ -0,0 +1,5 @@ +! go build -p=-1 example.go +stderr 'go: -p must be a positive integer: -1' + +-- example.go -- +package example
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_no_go.txt b/src/cmd/go/testdata/script/build_no_go.txt new file mode 100644 index 0000000..b61d752 --- /dev/null +++ b/src/cmd/go/testdata/script/build_no_go.txt @@ -0,0 +1,41 @@ +! go build ./empty/test +stderr 'no non-test Go files in ' + +! go build ./empty/xtest +stderr 'no non-test Go files in ' + +! go build ./empty/testxtest +stderr 'no non-test Go files in ' + +! go build ./exclude +stderr 'build constraints exclude all Go files in ' + +! go build ./exclude/ignore +stderr 'no Go files in ' + +! go build ./exclude/empty +stderr 'no Go files in ' + +-- go.mod -- +module m + +go 1.16 +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test +-- exclude/empty/x.txt -- +-- exclude/ignore/_x.go -- +package x +-- exclude/x.go -- +// +build linux,!linux + +package x +-- exclude/x_linux.go -- +// +build windows + +package x diff --git a/src/cmd/go/testdata/script/build_nocache.txt b/src/cmd/go/testdata/script/build_nocache.txt new file mode 100644 index 0000000..1059cad --- /dev/null +++ b/src/cmd/go/testdata/script/build_nocache.txt @@ -0,0 +1,40 @@ +env GO111MODULE=off + +# As of Go 1.12, the module cache is required. + +# If none of the variables we use to locate GOCACHE are set, the cache is off +# and we cannot build. +env GOCACHE= +env XDG_CACHE_HOME= +env HOME= +[plan9] env home= +[windows] env LocalAppData= +! go build -o triv triv.go +stderr 'build cache is required, but could not be located: GOCACHE is not defined and .*' + +# If GOCACHE is set but is not an absolute path, and we cannot build. +env GOCACHE=test +! go build -o triv triv.go +stderr 'build cache is required, but could not be located: GOCACHE is not an absolute path' + +# An explicit GOCACHE=off also disables builds. +env GOCACHE=off +! go build -o triv triv.go +stderr 'build cache is disabled by GOCACHE=off' + +# If GOCACHE is set to an unwritable directory, we should diagnose it as such. +[windows] stop # Does not support unwritable directories. +[root] skip # Can write to unwritable directories. + +mkdir $WORK/unwritable/home +chmod 0555 $WORK/unwritable/home +[!plan9] env HOME=$WORK/unwritable/home +[plan9] env home=$WORK/unwritable/home + +env GOCACHE=$WORK/unwritable/home +! go build -o triv triv.go +stderr 'failed to initialize build cache.* permission denied' + +-- triv.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/build_output.txt b/src/cmd/go/testdata/script/build_output.txt new file mode 100644 index 0000000..1e82950 --- /dev/null +++ b/src/cmd/go/testdata/script/build_output.txt @@ -0,0 +1,117 @@ +[gccgo] skip 'gccgo has no standard packages' +[short] skip + +[!windows] env NONEXE='.exe' +[windows] env NONEXE='' + +env GOBIN=$WORK/tmp/bin +go install m/isarchive & + +go build x.go +exists -exec x$GOEXE +rm x$GOEXE +! exists x$NONEXE + +go build -o myprog x.go +! exists x +! exists x.exe +exists -exec myprog +! exists myprogr.exe + +! exists bin +go build -o bin/x x.go +exists -exec bin/x +rm bin + +! exists bin +go build -o bin/ x.go +exists -exec bin/x$GOEXE +rm bin + +[windows] ! exists bin +[windows] go build -o bin\x x.go +[windows] exists -exec bin\x +[windows] rm bin + +[windows] ! exists bin +[windows] go build -o bin\ x.go +[windows] exists -exec bin\x.exe +[windows] rm bin + +! exists bin +mkdir bin +go build -o bin x.go +exists -exec bin/x$GOEXE +rm bin + +go build p.go +! exists p +! exists p.a +! exists p.o +! exists p.exe + +wait # for isarchive + +go build -o p.a p.go +exists p.a +exec $GOBIN/isarchive p.a + +go build cmd/gofmt +exists -exec gofmt$GOEXE +rm gofmt$GOEXE +! exists gofmt$NONEXE + +go build -o mygofmt cmd/gofmt +exists -exec mygofmt +! exists mygofmt.exe +! exists gofmt +! exists gofmt.exe + +go build sync/atomic +! exists atomic +! exists atomic.exe + +go build -o myatomic.a sync/atomic +exists myatomic.a +exec $GOBIN/isarchive myatomic.a +! exists atomic +! exists atomic.a +! exists atomic.exe + +! go build -o whatever cmd/gofmt sync/atomic +stderr 'multiple packages' + +-- go.mod -- +module m + +go 1.16 +-- x.go -- +package main + +func main() {} +-- p.go -- +package p +-- isarchive/isarchive.go -- +package main + +import ( + "bytes" + "fmt" + "io" + "os" +) + +func main() { + f, err := os.Open(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + buf := make([]byte, 100) + io.ReadFull(f, buf) + f.Close() + if !bytes.HasPrefix(buf, []byte("!<arch>\n")) { + fmt.Fprintf(os.Stderr, "file %s exists but is not an archive\n", os.Args[1]) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt new file mode 100644 index 0000000..56e812f --- /dev/null +++ b/src/cmd/go/testdata/script/build_overlay.txt @@ -0,0 +1,308 @@ +[short] skip + +# Test building in overlays. +# TODO(#39958): add a test case where the destination file in the replace map +# isn't a go file. Either completely exclude that case in fs.IsDirWithGoFiles +# if the compiler doesn't allow it, or test that it works all the way. +# TODO(#39958): add a test that both gc and gccgo assembly files can include .h +# files. + +# The main package (m) is contained in an overlay. It imports m/dir2 which has one +# file in an overlay and one file outside the overlay, which in turn imports m/dir, +# which only has source files in the overlay. + +cd m + +! go build . +go build -overlay overlay.json -o main$GOEXE . +exec ./main$goexe +stdout '^hello$' + +go build -overlay overlay.json -o print_abspath$GOEXE ./printpath +exec ./print_abspath$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath$GOEXE -trimpath ./printpath +exec ./print_trimpath$GOEXE +stdout ^m[/\\]printpath[/\\]main.go + +go build -overlay overlay.json -o print_trimpath_two_files$GOEXE printpath/main.go printpath/other.go +exec ./print_trimpath_two_files$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]other.go + +[cgo] go build -overlay overlay.json -o main_cgo_replace$GOEXE ./cgo_hello_replace +[cgo] exec ./main_cgo_replace$GOEXE +[cgo] stdout '^hello cgo\r?\n' + +[cgo] go build -overlay overlay.json -o main_cgo_quote$GOEXE ./cgo_hello_quote +[cgo] exec ./main_cgo_quote$GOEXE +[cgo] stdout '^hello cgo\r?\n' + +[cgo] go build -overlay overlay.json -o main_cgo_angle$GOEXE ./cgo_hello_angle +[cgo] exec ./main_cgo_angle$GOEXE +[cgo] stdout '^hello cgo\r?\n' + +go build -overlay overlay.json -o main_call_asm$GOEXE ./call_asm +exec ./main_call_asm$GOEXE +! stdout . + +# Change the contents of a file in the overlay and ensure that makes the target stale +go install -overlay overlay.json ./test_cache +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^false$' +cp overlay/test_cache_different.go overlay/test_cache.go +go list -overlay overlay.json -f '{{.Stale}}' ./test_cache +stdout '^true$' + +[cgo] go list -compiled -overlay overlay.json -f '{{range .CompiledGoFiles}}{{. | printf "%s\n"}}{{end}}' ./cgo_hello_replace +[cgo] cp stdout compiled_cgo_sources.txt +[cgo] go run ../print_line_comments.go compiled_cgo_sources.txt +[cgo] stdout $GOPATH[/\\]src[/\\]m[/\\]cgo_hello_replace[/\\]cgo_hello_replace.go +[cgo] ! stdout $GOPATH[/\\]src[/\\]m[/\\]overlay[/\\]hello.c + +# Run same tests but with gccgo. +env GO111MODULE=off +[!exec:gccgo] stop + +! go build -compiler=gccgo . +go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE . +exec ./main_gccgo$goexe +stdout '^hello$' + +go build -compiler=gccgo -overlay overlay.json -o print_abspath_gccgo$GOEXE ./printpath +exec ./print_abspath_gccgo$GOEXE +stdout $WORK[/\\]gopath[/\\]src[/\\]m[/\\]printpath[/\\]main.go + +go build -compiler=gccgo -overlay overlay.json -o print_trimpath_gccgo$GOEXE -trimpath ./printpath +exec ./print_trimpath_gccgo$GOEXE +stdout ^\.[/\\]printpath[/\\]main.go + + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_replace_gccgo$GOEXE ./cgo_hello_replace +exec ./main_cgo_replace_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_quote_gccgo$GOEXE ./cgo_hello_quote +exec ./main_cgo_quote_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_cgo_angle_gccgo$GOEXE ./cgo_hello_angle +exec ./main_cgo_angle_gccgo$GOEXE +stdout '^hello cgo\r?\n' + +go build -compiler=gccgo -overlay overlay.json -o main_call_asm_gccgo$GOEXE ./call_asm +exec ./main_call_asm_gccgo$GOEXE +! stdout . + + +-- m/go.mod -- +// TODO(matloob): how do overlays work with go.mod (especially if mod=readonly) +module m + +go 1.16 + +-- m/dir2/h.go -- +package dir2 + +func PrintMessage() { + printMessage() +} +-- m/dir/foo.txt -- +The build action code currently expects the package directory +to exist, so it can run the compiler in that directory. +TODO(matloob): Remove this requirement. +-- m/printpath/about.txt -- +the actual code is in the overlay +-- m/overlay.json -- +{ + "Replace": { + "f.go": "overlay/f.go", + "dir/g.go": "overlay/dir_g.go", + "dir2/i.go": "overlay/dir2_i.go", + "printpath/main.go": "overlay/printpath.go", + "printpath/other.go": "overlay2/printpath2.go", + "call_asm/asm_gc.s": "overlay/asm_gc.s", + "call_asm/asm_gccgo.s": "overlay/asm_gccgo.s", + "test_cache/main.go": "overlay/test_cache.go", + "cgo_hello_replace/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_replace/hello.c": "overlay/hello.c", + "cgo_hello_quote/cgo_hello.go": "overlay/cgo_hello_quote.go", + "cgo_hello_quote/cgo_header.h": "overlay/cgo_head.h", + "cgo_hello_angle/cgo_hello.go": "overlay/cgo_hello_angle.go", + "cgo_hello_angle/cgo_header.h": "overlay/cgo_head.h" + } +} +-- m/cgo_hello_replace/cgo_hello_replace.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/cgo_hello_replace/cgo_header.h -- + // Test that this header is replaced with one that has the proper declaration. +void say_goodbye(); + +-- m/cgo_hello_replace/hello.c -- +#include <stdio.h> + +void say_goodbye() { puts("goodbye cgo\n"); fflush(stdout); } + +-- m/overlay/f.go -- +package main + +import "m/dir2" + +func main() { + dir2.PrintMessage() +} +-- m/call_asm/main.go -- +package main + +func foo() // There will be a "missing function body" error if the assembly file isn't found. + +func main() { + foo() +} +-- m/overlay/dir_g.go -- +package dir + +import "fmt" + +func PrintMessage() { + fmt.Println("hello") +} +-- m/overlay/printpath.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func main() { + _, file, _, _ := runtime.Caller(0) + + // Since https://golang.org/cl/214286, the runtime's debug paths are + // slash-separated regardless of platform, so normalize them to system file + // paths. + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay2/printpath2.go -- +package main + +import ( + "fmt" + "path/filepath" + "runtime" +) + +func init() { + _, file, _, _ := runtime.Caller(0) + fmt.Println(filepath.FromSlash(file)) +} +-- m/overlay/dir2_i.go -- +package dir2 + +import "m/dir" + +func printMessage() { + dir.PrintMessage() +} +-- m/overlay/cgo_hello_quote.go -- +package main + +// #include "cgo_header.h" +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_hello_angle.go -- +package main + +// #include <cgo_header.h> +import "C" + +func main() { + C.say_hello() +} +-- m/overlay/cgo_head.h -- +void say_hello(); +-- m/overlay/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/overlay/asm_gc.s -- +// +build gc + +TEXT ·foo(SB),0,$0 + RET + +-- m/overlay/asm_gccgo.s -- +// +build gccgo + +.globl main.foo +.text +main.foo: + ret + +-- m/overlay/test_cache.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("something") +} +-- m/overlay/test_cache_different.go -- +package foo + +import "fmt" + +func bar() { + fmt.Println("different") +} +-- m/cgo_hello_quote/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } +-- m/cgo_hello_angle/hello.c -- +#include <stdio.h> + +void say_hello() { puts("hello cgo\n"); fflush(stdout); } + +-- print_line_comments.go -- +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "strings" +) + +func main() { + compiledGoFilesArg := os.Args[1] + b, err := ioutil.ReadFile(compiledGoFilesArg) + if err != nil { + log.Fatal(err) + } + compiledGoFiles := strings.Split(strings.TrimSpace(string(b)), "\n") + for _, f := range compiledGoFiles { + b, err := ioutil.ReadFile(f) + if err != nil { + log.Fatal(err) + } + for _, line := range strings.Split(string(b), "\n") { + if strings.HasPrefix(line, "#line") || strings.HasPrefix(line, "//line") { + fmt.Println(line) + } + } + } +} diff --git a/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt new file mode 100644 index 0000000..6a600cf --- /dev/null +++ b/src/cmd/go/testdata/script/build_patterns_outside_gopath.txt @@ -0,0 +1,36 @@ +# Tests issue #18778 +[short] skip + +cd pkgs + +env GO111MODULE=off +go build ./... +! stdout . +go test ./... +stdout '^ok' +go list ./... +stdout 'pkgs$' +stdout 'pkgs/a' + +-- pkgs/go.mod -- +module pkgs + +go 1.16 +-- pkgs/a.go -- +package x +-- pkgs/a_test.go -- +package x_test + +import "testing" + +func TestX(t *testing.T) { +} +-- pkgs/a/a.go -- +package a +-- pkgs/a/a_test.go -- +package a_test + +import "testing" + +func TestA(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/build_plugin_non_main.txt b/src/cmd/go/testdata/script/build_plugin_non_main.txt new file mode 100644 index 0000000..e0bbbef --- /dev/null +++ b/src/cmd/go/testdata/script/build_plugin_non_main.txt @@ -0,0 +1,13 @@ +# Plugins are not supported on all platforms. +[!buildmode:plugin] skip + +go build -n testdep +! go build -buildmode=plugin testdep +stderr '-buildmode=plugin requires exactly one main package' + +-- go.mod -- +module testdep + +go 1.16 +-- testdep.go -- +package p diff --git a/src/cmd/go/testdata/script/build_relative_pkgdir.txt b/src/cmd/go/testdata/script/build_relative_pkgdir.txt new file mode 100644 index 0000000..0716bcd --- /dev/null +++ b/src/cmd/go/testdata/script/build_relative_pkgdir.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# Regression test for golang.org/issue/21309: accept relative -pkgdir argument. + +[short] skip + +mkdir $WORK/gocache +env GOCACHE=$WORK/gocache +go build -i -pkgdir=. runtime diff --git a/src/cmd/go/testdata/script/build_relative_tmpdir.txt b/src/cmd/go/testdata/script/build_relative_tmpdir.txt new file mode 100644 index 0000000..3e98a67 --- /dev/null +++ b/src/cmd/go/testdata/script/build_relative_tmpdir.txt @@ -0,0 +1,18 @@ +env GO111MODULE=off + +# If GOTMPDIR is relative, 'go build' should derive an absolute $WORK directory. +cd $WORK +mkdir tmp +env GOTMPDIR=tmp +go build -work a +stderr 'WORK=\$WORK' # the test script itself converts the absolute directory back to $WORK + +# Similarly if TMP/TMPDIR is relative. +env GOTMPDIR= +env TMP=tmp # Windows +env TMPDIR=tmp # Unix +go build -work a +stderr 'WORK=\$WORK' + +-- a/a.go -- +package a diff --git a/src/cmd/go/testdata/script/build_runtime_gcflags.txt b/src/cmd/go/testdata/script/build_runtime_gcflags.txt new file mode 100644 index 0000000..c87e480 --- /dev/null +++ b/src/cmd/go/testdata/script/build_runtime_gcflags.txt @@ -0,0 +1,11 @@ +env GO111MODULE=off +[short] skip # rebuilds all of std + +# Set up fresh GOCACHE. +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +# Verify the standard library (specifically runtime/internal/atomic) can be +# built with -gcflags when -n is given. See golang.org/issue/29346. +go build -n -gcflags=all='-l' std +stderr 'compile.* runtime/internal/atomic .* -l' diff --git a/src/cmd/go/testdata/script/build_single_error.txt b/src/cmd/go/testdata/script/build_single_error.txt new file mode 100644 index 0000000..241cdb9 --- /dev/null +++ b/src/cmd/go/testdata/script/build_single_error.txt @@ -0,0 +1,18 @@ +# go test ./... with a bad package should report the error once (#44624). +! go test ./... +stderr -count=1 undefined + +-- go.mod -- +module example.com + +go 1.18 +-- a/a.go -- +package a + +import "example.com/b" +-- b/b.go -- +package b + +var X = Y +-- b/b_test.go -- +package b diff --git a/src/cmd/go/testdata/script/build_tag_goexperiment.txt b/src/cmd/go/testdata/script/build_tag_goexperiment.txt new file mode 100644 index 0000000..bee218f --- /dev/null +++ b/src/cmd/go/testdata/script/build_tag_goexperiment.txt @@ -0,0 +1,31 @@ +[short] skip +# Reset all experiments so fieldtrack is definitely off. +env GOEXPERIMENT=none +go run m +stderr 'fieldtrack off' +# Turn fieldtrack on. +env GOEXPERIMENT=none,fieldtrack +go run m +stderr 'fieldtrack on' + +-- ft_off.go -- +// +build !goexperiment.fieldtrack + +package main + +func main() { + println("fieldtrack off") +} + +-- ft_on.go -- +// +build goexperiment.fieldtrack + +package main + +func main() { + println("fieldtrack on") +} + +-- go.mod -- +module m +go 1.14 diff --git a/src/cmd/go/testdata/script/build_tags_no_comma.txt b/src/cmd/go/testdata/script/build_tags_no_comma.txt new file mode 100644 index 0000000..f3eb282 --- /dev/null +++ b/src/cmd/go/testdata/script/build_tags_no_comma.txt @@ -0,0 +1,4 @@ +[gccgo] skip 'gccgo has no standard packages' +go build -tags 'tag1 tag2' math +! go build -tags 'tag1,tag2 tag3' math +stderr 'space-separated list contains comma'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_test_only.txt b/src/cmd/go/testdata/script/build_test_only.txt new file mode 100644 index 0000000..8693a80 --- /dev/null +++ b/src/cmd/go/testdata/script/build_test_only.txt @@ -0,0 +1,19 @@ +# Named explicitly, test-only packages should be reported as +# unbuildable/uninstallable, even if there is a wildcard also matching. +! go build m/testonly m/testonly... +stderr 'no non-test Go files in' +! go install ./testonly +stderr 'no non-test Go files in' + +# Named through a wildcard, the test-only packages should be silently ignored. +go build m/testonly... +go install ./testonly... + +-- go.mod -- +module m + +go 1.16 +-- testonly/t_test.go -- +package testonly +-- testonly2/t.go -- +package testonly2 diff --git a/src/cmd/go/testdata/script/build_trimpath.txt b/src/cmd/go/testdata/script/build_trimpath.txt new file mode 100644 index 0000000..f36b123 --- /dev/null +++ b/src/cmd/go/testdata/script/build_trimpath.txt @@ -0,0 +1,163 @@ +[short] skip + +# If GOROOT_FINAL is set, 'go build -trimpath' bakes that into the resulting +# binary instead of GOROOT. Explicitly unset it here. +env GOROOT_FINAL= + +# Set up two identical directories that can be used as GOPATH. +env GO111MODULE=on +mkdir $WORK/a/src/paths $WORK/b/src/paths +cp paths.go $WORK/a/src/paths +cp paths.go $WORK/b/src/paths +cp overlay.json $WORK/a/src/paths +cp overlay.json $WORK/b/src/paths +cp go.mod $WORK/a/src/paths/ +cp go.mod $WORK/b/src/paths/ + + +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -o $WORK/paths-dbg.exe . +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -trimpath -o $WORK/paths-a.exe . +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# A binary from an external module built with -trimpath should not contain +# the current workspace or GOROOT. +go get rsc.io/fortune +go install -trimpath rsc.io/fortune +exec $WORK/paths-a.exe $GOPATH/bin/fortune$GOEXE +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' +go mod edit -droprequire rsc.io/fortune + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -trimpath -o $WORK/paths-b.exe +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + +# Same sequence of tests but with overlays. +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -overlay overlay.json -o $WORK/paths-dbg.exe ./overlaydir +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -overlay overlay.json -trimpath -o $WORK/paths-a.exe ./overlaydir +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -overlay overlay.json -trimpath -o $WORK/paths-b.exe ./overlaydir +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + +# Same sequence of tests but in GOPATH mode. +# A binary built without -trimpath should contain GOPATH and GOROOT. +env GO111MODULE=off +cd $WORK +env GOPATH=$WORK/a +go build -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain GOPATH or GOROOT. +go build -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different GOPATH roots +# should be identical. +env GOPATH=$WORK/b +go build -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + + +# Same sequence of tests but with gccgo. +# gccgo does not support builds in module mode. +[!exec:gccgo] stop +env GOPATH=$WORK/a + +# A binary built with gccgo without -trimpath should contain the current +# GOPATH and GOROOT. +go build -compiler=gccgo -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: false' # gccgo doesn't load std from GOROOT. + +# A binary built with gccgo with -trimpath should not contain GOPATH or GOROOT. +go build -compiler=gccgo -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +env GOPATH=$WORK/b +go build -compiler=gccgo -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + +-- paths.go -- +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + exe := os.Args[1] + data, err := ioutil.ReadFile(exe) + if err != nil { + log.Fatal(err) + } + + if os.Getenv("GO111MODULE") == "on" { + out, err := exec.Command("go", "env", "GOMOD").Output() + if err != nil { + log.Fatal(err) + } + modRoot := filepath.Dir(strings.TrimSpace(string(out))) + check(data, "module root", modRoot) + } else { + check(data, "GOPATH", os.Getenv("GOPATH")) + } + check(data, "GOROOT", os.Getenv("GOROOT")) +} + +func check(data []byte, desc, dir string) { + containsDir := bytes.Contains(data, []byte(dir)) + containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir))) + fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir) +} +-- overlay.json -- +{ "Replace": { "overlaydir/paths.go": "paths.go" } } +-- go.mod -- +module paths + +go 1.14 diff --git a/src/cmd/go/testdata/script/build_trimpath_cgo.txt b/src/cmd/go/testdata/script/build_trimpath_cgo.txt new file mode 100644 index 0000000..3187b4d --- /dev/null +++ b/src/cmd/go/testdata/script/build_trimpath_cgo.txt @@ -0,0 +1,184 @@ +# This test builds a cgo binary and verifies the source directory path +# does not appear in the binary, either literally or in compressed DWARF. +# TODO(golang.org/issue/36072): ideally we should build a binary from identical +# sources in different directories and verify the binary and all intermediate +# files are identical. + +[short] skip +[!cgo] skip + +# Check that the source path appears when -trimpath is not used. +go build -o hello.exe . +grep -q gopath[/\\]src hello.exe +go run ./list-dwarf hello.exe +stdout gopath[/\\]src + +# Check that the source path does not appear when -trimpath is used. +[aix] stop # can't inspect XCOFF binaries +go build -trimpath -o hello.exe . +! grep -q gopath[/\\]src hello.exe +go run ./list-dwarf hello.exe +! stdout gopath/src + + +# Do the above, with the cgo (but not .c) sources in an overlay +# Check that the source path appears when -trimpath is not used. +mkdir $WORK/overlay +cp hello.go $WORK/overlay/hello.go +mkdir hello_overlay +cp hello.c hello_overlay/hello.c +go build -overlay overlay.json -o hello_overlay.exe ./hello_overlay +grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +stdout gopath[/\\]src +! stdout $WORK[/\\]overlay + +# Check that the source path does not appear when -trimpath is used. +go build -overlay overlay.json -trimpath -o hello_overlay.exe ./hello_overlay +! grep -q gopath[/\\]src hello_overlay.exe +! grep -q $WORK[/\\]overlay hello_overlay.exe +go run ./list-dwarf hello_overlay.exe +! stdout gopath/src +! stdout $WORK[/\\]overlay + +-- go.mod -- +module m + +go 1.14 +-- overlay.json -- +{ + "Replace": { + "hello_overlay/hello.go": "../../overlay/hello.go" + } +} +-- hello.c -- +#include <stdio.h> + +void say_hello() { puts("Hello, world!\n"); } + +-- hello.go -- +package main + +// void say_hello(); +import "C" + +func main() { + C.say_hello() +} + +-- list-dwarf/list-dwarf.go -- +package main + +import ( + "debug/dwarf" + "fmt" + "io" + "log" + "os" + "sort" +) + +func main() { + files, err := run(os.Args[1]) + if err != nil { + log.Fatal(err) + } + for _, file := range files { + fmt.Println(file) + } +} + +func run(exePath string) ([]string, error) { + dwarfData, err := readDWARF(exePath) + if err != nil { + return nil, err + } + + dwarfReader := dwarfData.Reader() + files := make(map[string]bool) + for { + e, err := dwarfReader.Next() + if err != nil { + return nil, err + } + if e == nil { + break + } + lr, err := dwarfData.LineReader(e) + if err != nil { + return nil, err + } + if lr == nil { + continue + } + + var le dwarf.LineEntry + for { + if err := lr.Next(&le); err != nil { + if err == io.EOF { + break + } + return nil, err + } + files[le.File.Name] = true + } + } + + sortedFiles := make([]string, 0, len(files)) + for file := range files { + sortedFiles = append(sortedFiles, file) + } + sort.Strings(sortedFiles) + return sortedFiles, nil +} +-- list-dwarf/read_darwin.go -- +package main + +import ( + "debug/dwarf" + "debug/macho" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + machoFile, err := macho.Open(exePath) + if err != nil { + return nil, err + } + defer machoFile.Close() + return machoFile.DWARF() +} +-- list-dwarf/read_elf.go -- +// +build android dragonfly freebsd illumos linux netbsd openbsd solaris + +package main + +import ( + "debug/dwarf" + "debug/elf" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + elfFile, err := elf.Open(exePath) + if err != nil { + return nil, err + } + defer elfFile.Close() + return elfFile.DWARF() +} +-- list-dwarf/read_windows.go -- +package main + +import ( + "debug/dwarf" + "debug/pe" +) + +func readDWARF(exePath string) (*dwarf.Data, error) { + peFile, err := pe.Open(exePath) + if err != nil { + return nil, err + } + defer peFile.Close() + return peFile.DWARF() +} diff --git a/src/cmd/go/testdata/script/build_unsupported_goos.txt b/src/cmd/go/testdata/script/build_unsupported_goos.txt new file mode 100644 index 0000000..d61e420 --- /dev/null +++ b/src/cmd/go/testdata/script/build_unsupported_goos.txt @@ -0,0 +1,6 @@ +[gccgo] skip # gccgo assumes cross-compilation is always possible + +env GOOS=windwos + +! go build -n exclude +stderr 'unsupported GOOS/GOARCH pair'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/build_vendor.txt b/src/cmd/go/testdata/script/build_vendor.txt new file mode 100644 index 0000000..f430ff2 --- /dev/null +++ b/src/cmd/go/testdata/script/build_vendor.txt @@ -0,0 +1,42 @@ +# Build +env GO111MODULE=off +go build vend/x +! stdout . +! stderr . + +-- vend/dir1/dir1.go -- +package dir1 +-- vend/subdir/bad.go -- +package subdir + +import _ "r" +-- vend/subdir/good.go -- +package subdir + +import _ "p" +-- vend/vendor/p/p.go -- +package p +-- vend/vendor/q/q.go -- +package q +-- vend/vendor/vend/dir1/dir2/dir2.go -- +package dir2 +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" +-- vend/x/vendor/p/p.go -- +package p +-- vend/x/vendor/r/r.go -- +package r +-- vend/x/x.go -- +package x + +import _ "p" +import _ "q" +import _ "r" +import _ "vend/dir1" // not vendored +import _ "vend/dir1/dir2" // vendored diff --git a/src/cmd/go/testdata/script/cache_unix.txt b/src/cmd/go/testdata/script/cache_unix.txt new file mode 100644 index 0000000..0e07ba6 --- /dev/null +++ b/src/cmd/go/testdata/script/cache_unix.txt @@ -0,0 +1,36 @@ +env GO111MODULE=off + +# Integration test for cache directory calculation (cmd/go/internal/cache). + +[windows] skip +[darwin] skip +[plan9] skip + +mkdir $WORK/gocache +mkdir $WORK/xdg +mkdir $WORK/home + +# Set GOCACHE, XDG_CACHE_HOME, and HOME. +env GOCACHE=$WORK/gocache +env XDG_CACHE_HOME=$WORK/xdg +env HOME=$WORK/home + +# With all three set, we should prefer GOCACHE. +go env GOCACHE +stdout '\$WORK/gocache$' + +# Without GOCACHE, we should prefer XDG_CACHE_HOME over HOME. +env GOCACHE= +go env GOCACHE +stdout '\$WORK/xdg/go-build$$' + +# With only HOME set, we should use $HOME/.cache. +env XDG_CACHE_HOME= +go env GOCACHE +stdout '\$WORK/home/.cache/go-build$' + +# With no guidance from the environment, we must disable the cache, but that +# should not cause commands that do not write to the cache to fail. +env HOME= +go env GOCACHE +stdout 'off' diff --git a/src/cmd/go/testdata/script/cache_vet.txt b/src/cmd/go/testdata/script/cache_vet.txt new file mode 100644 index 0000000..928024e --- /dev/null +++ b/src/cmd/go/testdata/script/cache_vet.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +[short] skip +[GODEBUG:gocacheverify=1] skip +[gccgo] skip # gccgo has no standard packages + +# Start with a clean build cache: +# test failures may be masked if the cache has just the right entries already. +env GOCACHE=$WORK/cache + +# Run 'go vet os/user' once to warm up the cache. +go vet os/user + +# Check that second vet reuses cgo-derived inputs. +# The first command could be build instead of vet, +# except that if the cache is empty and there's a net.a +# in GOROOT/pkg, the build will not bother to regenerate +# and cache the cgo outputs, whereas vet always will. + +go vet -x os/user +! stderr '^(clang|gcc)' # should not have run compiler +! stderr '[\\/]cgo ' # should not have run cgo diff --git a/src/cmd/go/testdata/script/cgo_asm_error.txt b/src/cmd/go/testdata/script/cgo_asm_error.txt new file mode 100644 index 0000000..7aaa713 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_asm_error.txt @@ -0,0 +1,25 @@ +[!cgo] skip + +# Test that cgo package can't contain a go assembly file. + +# Ensure the build fails and reports that the package has a Go assembly file. +! go build cgoasm +stderr 'package using cgo has Go assembly file' + +-- go.mod -- +module cgoasm + +go 1.16 +-- p.go -- +package p + +/* +// hi +*/ +import "C" + +func F() {} +-- p.s -- +TEXT asm(SB),$0 + RET + diff --git a/src/cmd/go/testdata/script/cgo_bad_directives.txt b/src/cmd/go/testdata/script/cgo_bad_directives.txt new file mode 100644 index 0000000..6bf3beb --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_bad_directives.txt @@ -0,0 +1,129 @@ +[!cgo] skip +[short] skip + +cp x.go.txt x.go + +# Only allow //go:cgo_ldflag .* in cgo-generated code +[gc] cp x_gc.go.txt x.go +[gc] ! go build x +[gc] stderr '//go:cgo_ldflag .* only allowed in cgo-generated code' + +# Ignore _* files +rm x.go +! go build . +stderr 'no Go files' +cp cgo_yy.go.txt _cgo_yy.go +! go build . +stderr 'no Go files' #_* files are ignored... + +[gc] ! go build _cgo_yy.go # ... but if forced, the comment is rejected +# Actually, today there is a separate issue that _ files named +# on the command line are ignored. Once that is fixed, +# we want to see the cgo_ldflag error. +[gc] stderr '//go:cgo_ldflag only allowed in cgo-generated code|no Go files' + +rm _cgo_yy.go + +# Reject #cgo CFLAGS: -fplugin=foo.so +cp x.go.txt x.go +cp y_fplugin.go.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' + +# Reject #cgo CFLAGS: -lbar -fplugin=foo.so +cp y_lbar_fplugin.go.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -fplugin=foo.so' + +# Reject #cgo pkg-config: -foo +cp y_pkgconfig_dash_foo.txt y.go +! go build x +stderr 'invalid pkg-config package name: -foo' + +# Reject #cgo pkg-config: @foo +cp y_pkgconfig_at_foo.txt y.go +! go build x +stderr 'invalid pkg-config package name: @foo' + +# Reject #cgo CFLAGS: @foo +cp y_cflags_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: @foo' + +# Reject #cgo CFLAGS: -D +cp y_cflags_dash_d.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D without argument' + +# Note that -I @foo is allowed because we rewrite it into -I /path/to/src/@foo +# before the check is applied. There's no such rewrite for -D. + +# Reject #cgo CFLAGS: -D @foo +cp y_cflags_dash_d_space_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D @foo' + +# Reject #cgo CFLAGS -D@foo +cp y_cflags_dash_d_at_foo.txt y.go +! go build x +stderr 'invalid flag in #cgo CFLAGS: -D@foo' + +# Check for CFLAGS in commands +env CGO_CFLAGS=-D@foo +cp y_no_cflags.txt y.go +go build -n x +stderr '-D@foo' + +-- go.mod -- +module x + +go 1.16 +-- x_gc.go.txt -- +package x + +//go:cgo_ldflag "-fplugin=foo.so" + +import "C" +-- cgo_yy.go.txt -- +package x + +//go:cgo_ldflag "-fplugin=foo.so" + +import "C" +-- x.go.txt -- +package x +-- y_fplugin.go.txt -- +package x +// #cgo CFLAGS: -fplugin=foo.so +import "C" +-- y_lbar_fplugin.go.txt -- +package x +// #cgo CFLAGS: -Ibar -fplugin=foo.so +import "C" +-- y_pkgconfig_dash_foo.txt -- +package x +// #cgo pkg-config: -foo +import "C" +-- y_pkgconfig_at_foo.txt -- +package x +// #cgo pkg-config: @foo +import "C" +-- y_cflags_at_foo.txt -- +package x +// #cgo CFLAGS: @foo +import "C" +-- y_cflags_dash_d.txt -- +package x +// #cgo CFLAGS: -D +import "C" +-- y_cflags_dash_d_space_at_foo.txt -- +package x +// #cgo CFLAGS: -D @foo +import "C" +-- y_cflags_dash_d_at_foo.txt -- +package x +// #cgo CFLAGS: -D@foo +import "C" +-- y_no_cflags.txt -- +package x +import "C" diff --git a/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt new file mode 100644 index 0000000..bd4777c --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_depends_on_syscall.txt @@ -0,0 +1,15 @@ +[!cgo] skip +[!race] skip + +go list -race -deps foo +stdout syscall + +-- go.mod -- +module foo + +go 1.16 +-- foo.go -- +package foo + +// #include <stdio.h> +import "C" diff --git a/src/cmd/go/testdata/script/cgo_flag_contains_space.txt b/src/cmd/go/testdata/script/cgo_flag_contains_space.txt new file mode 100644 index 0000000..a3372bb --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_flag_contains_space.txt @@ -0,0 +1,16 @@ +[short] skip +[!cgo] skip + +env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache. +go build -x -n main.go +stderr '"-I[^"]+c flags"' # find quoted c flags +! stderr '"-I[^"]+c flags".*"-I[^"]+c flags"' # don't find too many quoted c flags per line +stderr '"-L[^"]+ld flags"' # find quoted ld flags +! stderr '"-L[^"]+c flags".*"-L[^"]+c flags"' # don't find too many quoted ld flags per line + +-- main.go -- +package main +// #cgo CFLAGS: -I"c flags" +// #cgo LDFLAGS: -L"ld flags" +import "C" +func main() {} diff --git a/src/cmd/go/testdata/script/cgo_path.txt b/src/cmd/go/testdata/script/cgo_path.txt new file mode 100644 index 0000000..be9609e --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_path.txt @@ -0,0 +1,43 @@ +[!cgo] skip + +# Set CC explicitly to something that requires a PATH lookup. +# Normally, the default is gcc or clang, but if CC was set during make.bash, +# that becomes the default. +[exec:clang] env CC=clang +[exec:gcc] env CC=gcc +[!exec:clang] [!exec:gcc] skip 'Unknown C compiler' + +env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache. +[!windows] env PATH=.:$PATH +[!windows] chmod 0755 p/gcc p/clang +[!windows] exists -exec p/gcc p/clang +[windows] exists -exec p/gcc.bat p/clang.bat +! exists p/bug.txt +! go build -x +stderr '^cgo: exec (clang|gcc): (clang|gcc) resolves to executable relative to current directory \(.[/\\](clang|gcc)(.bat)?\)$' +! exists p/bug.txt + +-- go.mod -- +module m + +-- m.go -- +package m + +import _ "m/p" + +-- p/p.go -- +package p + +// #define X 1 +import "C" + +-- p/gcc -- +#!/bin/sh +echo ran gcc >bug.txt +-- p/clang -- +#!/bin/sh +echo ran clang >bug.txt +-- p/gcc.bat -- +echo ran gcc >bug.txt +-- p/clang.bat -- +echo ran clang >bug.txt diff --git a/src/cmd/go/testdata/script/cgo_path_space.txt b/src/cmd/go/testdata/script/cgo_path_space.txt new file mode 100644 index 0000000..654295d --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_path_space.txt @@ -0,0 +1,56 @@ +# Check that if the PATH directory containing the C compiler has a space, +# we can still use that compiler with cgo. +# Verifies #43808. +[!cgo] skip + +# Set CC explicitly to something that requires a PATH lookup. +# Normally, the default is gcc or clang, but if CC was set during make.bash, +# that becomes the default. +[exec:clang] env CC=clang +[exec:gcc] env CC=gcc +[!exec:clang] [!exec:gcc] skip 'Unknown C compiler' + +[!windows] chmod 0755 $WORK/'program files'/clang +[!windows] chmod 0755 $WORK/'program files'/gcc +[!windows] exists -exec $WORK/'program files'/clang +[!windows] exists -exec $WORK/'program files'/gcc +[!windows] env PATH=$WORK/'program files':$PATH +[windows] exists -exec $WORK/'program files'/gcc.bat +[windows] exists -exec $WORK/'program files'/clang.bat +[windows] env PATH=$WORK\'program files';%PATH% + +! exists $WORK/log.txt +? go build -x +exists $WORK/log.txt +rm $WORK/log.txt + +# TODO(#41400, #43078): when CC is set explicitly, it should be allowed to +# contain spaces separating arguments, and it should be possible to quote +# arguments with spaces (including the path), as in CGO_CFLAGS and other +# variables. For now, this doesn't work. +[!windows] env CC=$WORK/'program files'/gcc +[windows] env CC=$WORK\'program files'\gcc.bat +! go build -x +! exists $WORK/log.txt + +-- go.mod -- +module m + +-- m.go -- +package m + +// #define X 1 +import "C" + +-- $WORK/program files/gcc -- +#!/bin/sh + +echo ok >$WORK/log.txt +-- $WORK/program files/clang -- +#!/bin/sh + +echo ok >$WORK/log.txt +-- $WORK/program files/gcc.bat -- +echo ok >%WORK%\log.txt +-- $WORK/program files/clang.bat -- +echo ok >%WORK%\log.txt diff --git a/src/cmd/go/testdata/script/cgo_path_space_quote.txt b/src/cmd/go/testdata/script/cgo_path_space_quote.txt new file mode 100644 index 0000000..9556101 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_path_space_quote.txt @@ -0,0 +1,58 @@ +# This test checks that the CC environment variable may contain quotes and +# spaces. Arguments are normally split on spaces, tabs, newlines. If an +# argument contains these characters, the entire argument may be quoted +# with single or double quotes. This is the same as -gcflags and similar +# options. + +[short] skip +[!exec:clang] [!exec:gcc] skip +[!cgo] skip + +env GOENV=$WORK/go.env +mkdir 'program files' +go build -o 'program files' './which cc/which cc.go' +[exec:clang] env CC='"'$PWD${/}program' 'files${/}which' 'cc"' 'clang +[!exec:clang] env CC='"'$PWD${/}program' 'files${/}which' 'cc"' 'gcc +go env CC +stdout 'program files[/\\]which cc" (clang|gcc)$' +go env -w CC=$CC +env CC= +go env CC +stdout 'program files[/\\]which cc" (clang|gcc)$' + +go run . +stdout 1 + +-- go.mod -- +module test + +go 1.17 +-- which cc/which cc.go -- +package main + +import ( + "fmt" + "os" + "os/exec" +) + +func main() { + args := append([]string{"-DWRAPPER_WAS_USED=1"}, os.Args[2:]...) + cmd := exec.Command(os.Args[1], args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- hello.go -- +package main + +// int x = WRAPPER_WAS_USED; +import "C" +import "fmt" + +func main() { + fmt.Println(C.x) +} diff --git a/src/cmd/go/testdata/script/cgo_stale.txt b/src/cmd/go/testdata/script/cgo_stale.txt new file mode 100644 index 0000000..9e46855 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_stale.txt @@ -0,0 +1,39 @@ +# golang.org/issue/46347: a stale runtime/cgo should only force a single rebuild + +[!cgo] skip +[short] skip + + +# If we set a unique CGO_CFLAGS, the installed copy of runtime/cgo +# should be reported as stale. + +env CGO_CFLAGS=-DTestScript_cgo_stale=true +stale runtime/cgo + + +# If we then build a package that uses cgo, runtime/cgo should be rebuilt and +# cached with the new flag, but not installed to GOROOT (and thus still stale). + +env GOCACHE=$WORK/cache # Use a fresh cache to avoid interference between runs. + +go build -x . +stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo' +stale runtime/cgo + + +# After runtime/cgo has been rebuilt and cached, it should not be rebuilt again +# even though it is still reported as stale. + +go build -x . +! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo' +stale runtime/cgo + + +-- go.mod -- +module example.com/m + +go 1.17 +-- m.go -- +package m + +import "C" diff --git a/src/cmd/go/testdata/script/cgo_stale_precompiled.txt b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt new file mode 100644 index 0000000..80ed751 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt @@ -0,0 +1,28 @@ +# Regression test for https://go.dev/issue/47215 and https://go.dev/issue/50183: +# A mismatched $GOROOT_FINAL or missing $CC caused the C dependencies of the net +# package to appear stale, and it could not be rebuilt due to a missing $CC. + +[!cgo] skip + +# This test may start with the runtime/cgo package already stale. +# Explicitly rebuild it to ensure that it is cached. +# (See https://go.dev/issue/50892.) +# +# If running in non-short mode, explicitly vary CGO_CFLAGS +# as a control case (to ensure that our regexps do catch rebuilds). + +[!short] env GOCACHE=$WORK/cache +[!short] env CGO_CFLAGS=-DTestScript_cgo_stale_precompiled=true +go build -x runtime/cgo +[!short] stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo' + +# https://go.dev/issue/47215: a missing $(go env CC) caused the precompiled net to be stale. +[!plan9] env PATH='' # Guaranteed not to include $(go env CC)! +[plan9] env path='' +go build -x runtime/cgo +! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo' + +# https://go.dev/issue/50183: a mismatched GOROOT_FINAL caused net to be stale. +env GOROOT_FINAL=$WORK${/}goroot +go build -x runtime/cgo +! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo' diff --git a/src/cmd/go/testdata/script/cgo_syso_issue29253.txt b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt new file mode 100644 index 0000000..4fb5cca --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off +[short] skip + +# This test tests that we can link in-package syso files that provides symbols +# for cgo. See issue 29253. +[!cgo] stop +[!gc] stop +cc -c -o pkg/o.syso ext.c +go build main.go + +-- ext.c -- +// +build ignore + +int f() { return 42; } +-- pkg/pkg.go -- +package pkg + +// extern int f(void); +import "C" + +func init() { + if v := C.f(); v != 42 { + panic(v) + } +} +-- main.go -- +package main + +import _ "pkg" + +func main() {} diff --git a/src/cmd/go/testdata/script/clean_binary.txt b/src/cmd/go/testdata/script/clean_binary.txt new file mode 100644 index 0000000..7335f8a --- /dev/null +++ b/src/cmd/go/testdata/script/clean_binary.txt @@ -0,0 +1,78 @@ +# Build something to create the executable, including several cases +[short] skip + +# --------------------- clean executables ------------------------- + +# case1: test file-named executable 'main' +env GO111MODULE=on + +! exists main$GOEXE +go build main.go +exists -exec main$GOEXE +go clean +! exists main$GOEXE + +# case2: test module-named executable 'a.b.c' +! exists a.b.c$GOEXE +go build +exists -exec a.b.c$GOEXE +go clean +! exists a.b.c$GOEXE + +# case3: directory-named executable 'src' +env GO111MODULE=off + +! exists src$GOEXE +go build +exists -exec src$GOEXE +go clean +! exists src$GOEXE + +# --------------------- clean test files ------------------------- + +# case1: test file-named test file +env GO111MODULE=on + +! exists main.test$GOEXE +go test -c main_test.go +exists -exec main.test$GOEXE +go clean +! exists main.test$GOEXE + +# case2: test module-named test file +! exists a.b.c.test$GOEXE +go test -c +exists -exec a.b.c.test$GOEXE +go clean +! exists a.b.c.test$GOEXE + +# case3: test directory-based test file +env GO111MODULE=off + +! exists src.test$GOEXE +go test -c +exists -exec src.test$GOEXE +go clean +! exists src.test$GOEXE + +-- main.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello!") +} + +-- main_test.go -- +package main + +import "testing" + +func TestSomething(t *testing.T) { +} + +-- go.mod -- +module example.com/a.b.c/v2 + +go 1.12
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/clean_cache_n.txt b/src/cmd/go/testdata/script/clean_cache_n.txt new file mode 100644 index 0000000..4497b36 --- /dev/null +++ b/src/cmd/go/testdata/script/clean_cache_n.txt @@ -0,0 +1,25 @@ +# We're testing cache behavior, so start with a clean GOCACHE. +env GOCACHE=$WORK/cache + +# Build something so that the cache gets populates +go build main.go + +# Check that cache contains directories before running +exists $GOCACHE/00 + +# Run go clean -cache -n and ensure that directories weren't deleted +go clean -cache -n +exists $GOCACHE/00 + +# Re-run go clean cache without the -n flag go ensure that directories were properly removed +go clean -cache +! exists $GOCACHE/00 + +-- main.go -- +package main + +import "fmt" + +func main() { + fmt.Println("hello!") +} diff --git a/src/cmd/go/testdata/script/clean_testcache.txt b/src/cmd/go/testdata/script/clean_testcache.txt new file mode 100644 index 0000000..b3f32fe --- /dev/null +++ b/src/cmd/go/testdata/script/clean_testcache.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off +[short] skip + +# go clean -testcache +# should work (see golang.org/issue/29757). +cd x +go test x_test.go +go clean -testcache +go test x_test.go +! stdout 'cached' + +# golang.org/issue/29100: 'go clean -testcache' should succeed +# if the cache directory doesn't exist at all. +# It should not write a testexpire.txt file, since there are no +# test results that need to be invalidated in the first place. +env GOCACHE=$WORK/nonexistent +go clean -testcache +! exists $WORK/nonexistent + +-- x/x_test.go -- +package x_test +import ( + "testing" +) +func TestMain(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/cmd_import_error.txt b/src/cmd/go/testdata/script/cmd_import_error.txt new file mode 100644 index 0000000..dea76f4 --- /dev/null +++ b/src/cmd/go/testdata/script/cmd_import_error.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/31031: +# Importing or loading a non-existent package in cmd/ should print +# a clear error in module mode. + +! go list cmd/unknown +stderr '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go +stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' + +-- x.go -- +package x + +import _ "cmd/unknown" diff --git a/src/cmd/go/testdata/script/cover_asm.txt b/src/cmd/go/testdata/script/cover_asm.txt new file mode 100644 index 0000000..57f76d6 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_asm.txt @@ -0,0 +1,33 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +# Test cover for a package that has an assembly function. + +go test -outputdir=$WORK -coverprofile=cover.out coverasm +go tool cover -func=$WORK/cover.out +stdout '\tg\t*100.0%' # Check g is 100% covered. +! stdout '\tf\t*[0-9]' # Check for no coverage on the assembly function + +-- go.mod -- +module coverasm + +go 1.16 +-- p.go -- +package p + +func f() + +func g() { + println("g") +} +-- p.s -- +// empty asm file, +// so go test doesn't complain about declaration of f in p.go. +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + g() +} diff --git a/src/cmd/go/testdata/script/cover_atomic_pkgall.txt b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt new file mode 100644 index 0000000..c3bc67d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[short] skip + +go test -coverpkg=all -covermode=atomic x +stdout ok[\s\S]+?coverage + +[!race] stop + +go test -coverpkg=all -race x +stdout ok[\s\S]+?coverage + +-- x/x.go -- +package x + +import _ "sync/atomic" + +func F() {} + +-- x/x_test.go -- +package x + +import "testing" + +func TestF(t *testing.T) { F() } diff --git a/src/cmd/go/testdata/script/cover_blank_func_decl.txt b/src/cmd/go/testdata/script/cover_blank_func_decl.txt new file mode 100644 index 0000000..e7d5250 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_blank_func_decl.txt @@ -0,0 +1,35 @@ +[short] skip +go test -cover coverblank +stdout 'coverage: 100.0% of statements' + + +-- go.mod -- +module coverblank + +go 1.16 +-- a.go -- +package coverblank + +func _() { + println("unreachable") +} + +type X int + +func (x X) Print() { + println(x) +} + +func (x X) _() { + println("unreachable") +} + +-- a_test.go -- +package coverblank + +import "testing" + +func TestX(t *testing.T) { + var x X + x.Print() +} diff --git a/src/cmd/go/testdata/script/cover_cgo.txt b/src/cmd/go/testdata/script/cover_cgo.txt new file mode 100644 index 0000000..9cf78f7 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo.txt @@ -0,0 +1,42 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. + +go test -short -cover cgocover +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- p_test.go -- +package p + +import "testing" + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt new file mode 100644 index 0000000..c53b979 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt @@ -0,0 +1,48 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. This test case includes an +# extra empty non-cgo file in the package being checked. + +go test -short -cover cgocover4 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover4 + +go 1.16 +-- notcgo.go -- +package p +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- x_test.go -- +package p_test + +import ( + . "cgocover4" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt new file mode 100644 index 0000000..b501ab0 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt @@ -0,0 +1,49 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test coverage on cgo code. This test case has an external +# test that tests the code and an in-package test file with +# no test cases. + +go test -short -cover cgocover3 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover3 + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- p_test.go -- +package p +-- x_test.go -- +package p_test + +import ( + . "cgocover3" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_cgo_xtest.txt b/src/cmd/go/testdata/script/cover_cgo_xtest.txt new file mode 100644 index 0000000..79cc08c --- /dev/null +++ b/src/cmd/go/testdata/script/cover_cgo_xtest.txt @@ -0,0 +1,45 @@ +[short] skip +[!cgo] skip +[gccgo] skip # gccgo has no cover tool + +# Test cgo coverage with an external test. + +go test -short -cover cgocover2 +stdout 'coverage:.*[1-9][0-9.]+%' +! stderr '[^0-9]0\.0%' + +-- go.mod -- +module cgocover2 + +go 1.16 +-- p.go -- +package p + +/* +void +f(void) +{ +} +*/ +import "C" + +var b bool + +func F() { + if b { + for { + } + } + C.f() +} +-- x_test.go -- +package p_test + +import ( + . "cgocover2" + "testing" +) + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_dash_c.txt b/src/cmd/go/testdata/script/cover_dash_c.txt new file mode 100644 index 0000000..8950f8d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dash_c.txt @@ -0,0 +1,31 @@ +[short] skip +[gccgo] skip + +# Test for issue 24588 + +go test -c -o $WORK/coverdep -coverprofile=$WORK/no/such/dir/cover.out coverdep +exists -exec $WORK/coverdep + +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- +package p + +import _ "coverdep/p1" + +func F() { +} +-- p1/p1.go -- +package p1 + +import _ "errors" +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cover_dep_loop.txt b/src/cmd/go/testdata/script/cover_dep_loop.txt new file mode 100644 index 0000000..36ea6e0 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dep_loop.txt @@ -0,0 +1,36 @@ +[short] skip +[gccgo] skip + +# coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1. +# Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2. + +go test -short -cover coverdep2/p1 +stdout 'coverage: 100.0% of statements' # expect 100.0% coverage + +-- go.mod -- +module coverdep2 + +go 1.16 +-- p1/p.go -- +package p1 + +func F() int { return 1 } +-- p1/p_test.go -- +package p1_test + +import ( + "coverdep2/p2" + "testing" +) + +func Test(t *testing.T) { + p2.F() +} +-- p2/p2.go -- +package p2 + +import "coverdep2/p1" + +func F() { + p1.F() +} diff --git a/src/cmd/go/testdata/script/cover_dot_import.txt b/src/cmd/go/testdata/script/cover_dot_import.txt new file mode 100644 index 0000000..d492e42 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_dot_import.txt @@ -0,0 +1,29 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -coverpkg=coverdot/a,coverdot/b coverdot/b +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +-- go.mod -- +module coverdot + +go 1.16 +-- a/a.go -- +package a + +func F() {} +-- b/b.go -- +package b + +import . "coverdot/a" + +func G() { F() } +-- b/b_test.go -- +package b + +import "testing" + +func TestG(t *testing.T) { + G() +} diff --git a/src/cmd/go/testdata/script/cover_error.txt b/src/cmd/go/testdata/script/cover_error.txt new file mode 100644 index 0000000..583a664 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_error.txt @@ -0,0 +1,74 @@ +[short] skip +[gccgo] skip + +# Test line numbers in cover errors. + +# Get errors from a go test into stderr.txt +! go test coverbad +stderr 'p\.go:4' # look for error at coverbad/p.go:4 +[cgo] stderr 'p1\.go:6' # look for error at coverbad/p.go:6 +! stderr $WORK # make sure temporary directory isn't in error + +cp stderr $WORK/stderr.txt + +# Clean out character positions from stderr.txt +# It's OK that stderr2 drops the character position in the error, +# because of the //line directive (see golang.org/issue/22662). +go run clean_charpos.go $WORK/stderr.txt & + +# Get errors from coverage into stderr2.txt +! go test -cover coverbad +cp stderr $WORK/stderr2.txt + +wait # for go run above + +cmp $WORK/stderr.txt $WORK/stderr2.txt + +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- +package p + +func f() { + g() +} +-- p1.go -- +package p + +import "C" + +func h() { + j() +} +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) {} +-- clean_charpos.go -- +// +build ignore + +package main + +import ( + "log" + "os" + "strings" +) + +func main() { + log.SetFlags(0) + b, err := os.ReadFile(os.Args[1]) + if err != nil { + log.Fatal(err) + } + s := strings.ReplaceAll(string(b), "p.go:4:2:", "p.go:4:") + s = strings.ReplaceAll(s, "p1.go:6:2:", "p1.go:6:") + os.WriteFile(os.Args[1], []byte(s), 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/cover_import_main_loop.txt b/src/cmd/go/testdata/script/cover_import_main_loop.txt new file mode 100644 index 0000000..eb6de67 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_import_main_loop.txt @@ -0,0 +1,26 @@ +[gccgo] skip # gccgo has no cover tool + +! go test -n importmain/test +stderr 'not an importable package' # check that import main was detected +! go test -n -cover importmain/test +stderr 'not an importable package' # check that import main was detected + +-- go.mod -- +module importmain + +go 1.16 +-- ismain/main.go -- +package main + +import _ "importmain/test" + +func main() {} +-- test/test.go -- +package test +-- test/test_test.go -- +package test_test + +import "testing" +import _ "importmain/ismain" + +func TestCase(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/cover_mod_empty.txt b/src/cmd/go/testdata/script/cover_mod_empty.txt new file mode 100644 index 0000000..3c45243 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_mod_empty.txt @@ -0,0 +1,9 @@ +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +go mod init golang.org/issue/33855 + +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +-- cover.out -- diff --git a/src/cmd/go/testdata/script/cover_modes.txt b/src/cmd/go/testdata/script/cover_modes.txt new file mode 100644 index 0000000..f8a399d --- /dev/null +++ b/src/cmd/go/testdata/script/cover_modes.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +# Coverage analysis should use 'set' mode by default, +# and should merge coverage profiles correctly. + +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -short -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: set$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out + +[!race] stop + +go test -short -race -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: atomic$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out diff --git a/src/cmd/go/testdata/script/cover_pattern.txt b/src/cmd/go/testdata/script/cover_pattern.txt new file mode 100644 index 0000000..ec0850c --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pattern.txt @@ -0,0 +1,41 @@ +[gccgo] skip + +# If coverpkg=m/sleepy... expands by package loading +# (as opposed to pattern matching on deps) +# then it will try to load sleepybad, which does not compile, +# and the test command will fail. +! go list m/sleepy... +go test -c -n -coverprofile=$TMPDIR/cover.out -coverpkg=m/sleepy... -run=^$ m/sleepy1 + +-- go.mod -- +module m + +go 1.16 +-- sleepy1/p_test.go -- +package p + +import ( + "testing" + "time" +) + +func Test1(t *testing.T) { + time.Sleep(200 * time.Millisecond) +} +-- sleepy2/p_test.go -- +package p + +import ( + "testing" + "time" +) + +func Test1(t *testing.T) { + time.Sleep(200 * time.Millisecond) +} +-- sleepybad/p.go -- +package p + +import ^ + +var _ = io.DoesNotExist diff --git a/src/cmd/go/testdata/script/cover_pkgall_imports.txt b/src/cmd/go/testdata/script/cover_pkgall_imports.txt new file mode 100644 index 0000000..4e51726 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pkgall_imports.txt @@ -0,0 +1,48 @@ +# This test checks that -coverpkg=all can be used +# when the package pattern includes packages +# which only have tests. +# Verifies golang.org/issue/27333, golang.org/issue/43242. + +[short] skip +cd $GOPATH/src/example.com/cov + +env GO111MODULE=on +go test -coverpkg=all ./... + +env GO111MODULE=off +go test -coverpkg=all ./... + +-- $GOPATH/src/example.com/cov/go.mod -- +module example.com/cov + +-- $GOPATH/src/example.com/cov/notest/notest.go -- +package notest + +func Foo() {} + +-- $GOPATH/src/example.com/cov/onlytest/onlytest_test.go -- +package onlytest_test + +import ( + "testing" + + "example.com/cov/notest" +) + +func TestFoo(t *testing.T) { + notest.Foo() +} + +-- $GOPATH/src/example.com/cov/withtest/withtest.go -- +package withtest + +func Bar() {} + +-- $GOPATH/src/example.com/cov/withtest/withtest_test.go -- +package withtest + +import "testing" + +func TestBar(t *testing.T) { + Bar() +} diff --git a/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt new file mode 100644 index 0000000..f21cd8b --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt @@ -0,0 +1,46 @@ +# This test checks that multiple main packages can be tested +# with -coverpkg=all without duplicate symbol errors. +# Verifies golang.org/issue/30374, golang.org/issue/34114. + +[short] skip +cd $GOPATH/src/example.com/cov + +env GO111MODULE=on +go test -coverpkg=all ./... + +env GO111MODULE=off +go test -coverpkg=all ./... + +-- $GOPATH/src/example.com/cov/go.mod -- +module example.com/cov + +-- $GOPATH/src/example.com/cov/mainonly/mainonly.go -- +package main + +func main() {} + +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest.go -- +package main + +func main() {} + +func Foo() {} + +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest_test.go -- +package main + +import "testing" + +func TestFoo(t *testing.T) { + Foo() +} + +-- $GOPATH/src/example.com/cov/xtest/x.go -- +package x + +-- $GOPATH/src/example.com/cov/xtest/x_test.go -- +package x_test + +import "testing" + +func TestX(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/cover_pkgall_runtime.txt b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt new file mode 100644 index 0000000..9927c30 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt @@ -0,0 +1,23 @@ +env GO111MODULE=off + +# Issue 23882 + +[short] skip + +go test -coverpkg=all x +stdout ok[\s\S]+?coverage + +[!race] stop + +go test -coverpkg=all -race x +stdout ok[\s\S]+?coverage + +-- x/x.go -- +package x +import _ "runtime" +func F() {} + +-- x/x_test.go -- +package x +import "testing" +func TestF(t *testing.T) { F() } diff --git a/src/cmd/go/testdata/script/cover_runs.txt b/src/cmd/go/testdata/script/cover_runs.txt new file mode 100644 index 0000000..38a7bb7 --- /dev/null +++ b/src/cmd/go/testdata/script/cover_runs.txt @@ -0,0 +1,13 @@ +[gccgo] skip 'gccgo has no cover tool' +[short] skip + +go test -short -coverpkg=strings strings regexp +! stdout '[^0-9]0\.0%' +stdout 'strings.*coverage:.*[1-9][0-9.]+%' +stdout 'regexp.*coverage:.*[1-9][0-9.]+%' + +go test -short -cover strings math regexp +! stdout '[^0-9]0\.0%' +stdout 'strings.*coverage:.*[1-9][0-9.]+%' +stdout 'math.*coverage:.*[1-9][0-9.]+%' +stdout 'regexp.*coverage:.*[1-9][0-9.]+%'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/cover_statements.txt b/src/cmd/go/testdata/script/cover_statements.txt new file mode 100644 index 0000000..4f3c9ca --- /dev/null +++ b/src/cmd/go/testdata/script/cover_statements.txt @@ -0,0 +1,61 @@ +[short] skip +go test -cover ./pkg1 ./pkg2 ./pkg3 ./pkg4 +stdout 'pkg1 \[no test files\]' +stdout 'pkg2 \S+ coverage: 0.0% of statements \[no tests to run\]' +stdout 'pkg3 \S+ coverage: 100.0% of statements' +stdout 'pkg4 \S+ coverage: \[no statements\]' + +-- go.mod -- +module m + +go 1.16 +-- pkg1/a.go -- +package pkg1 + +import "fmt" + +func F() { + fmt.Println("pkg1") +} +-- pkg2/a.go -- +package pkg2 + +import "fmt" + +func F() { + fmt.Println("pkg2") +} +-- pkg2/a_test.go -- +package pkg2 +-- pkg3/a.go -- +package pkg3 + +import "fmt" + +func F() { + fmt.Println("pkg3") +} +-- pkg3/a_test.go -- +package pkg3 + +import "testing" + +func TestF(t *testing.T) { + F() +} +-- pkg4/a.go -- +package pkg4 + +type T struct { + X bool +} +-- pkg4/a_test.go -- +package pkg4 + +import ( + "testing" +) + +func TestT(t *testing.T) { + _ = T{} +} diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt new file mode 100644 index 0000000..433af9a --- /dev/null +++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt @@ -0,0 +1,28 @@ +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep + +-- go.mod -- +module coverdep + +go 1.16 +-- p.go -- +package p + +import _ "coverdep/p1" + +func F() { +} +-- p1/p1.go -- +package p1 + +import _ "errors" +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/cpu_profile_twice.txt b/src/cmd/go/testdata/script/cpu_profile_twice.txt new file mode 100644 index 0000000..38d6439 --- /dev/null +++ b/src/cmd/go/testdata/script/cpu_profile_twice.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# Issue 23150 + +[short] skip + +go test -o=$WORK/x.test -cpuprofile=$WORK/cpu_profile_twice.out x +rm $WORK/cpu_profile_twice.out + +go test -o=$WORK/x.test -cpuprofile=$WORK/cpu_profile_twice.out x +exists $WORK/cpu_profile_twice.out + + +-- x/x_test.go -- +package x_test +import ( + "testing" + "time" +) +func TestSleep(t *testing.T) { + time.Sleep(10 * time.Millisecond) +} diff --git a/src/cmd/go/testdata/script/devnull.txt b/src/cmd/go/testdata/script/devnull.txt new file mode 100644 index 0000000..ccb866a --- /dev/null +++ b/src/cmd/go/testdata/script/devnull.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off + +# Issue 28035: go test -c -o NUL should work. +# Issue 28549: go test -c -o /dev/null should not overwrite /dev/null when run as root. +cd x +cmp $devnull $WORK/empty.txt +go test -o=$devnull -c +! exists x.test$GOEXE +cmp $devnull $WORK/empty.txt + +# Issue 12407: go build -o /dev/null should succeed. +cd .. +go build -o $devnull y +cmp $devnull $WORK/empty.txt + +-- x/x_test.go -- +package x_test +import ( + "testing" +) +func TestNUL(t *testing.T) { +} +-- y/y.go -- +package y +func main() {} +-- $WORK/empty.txt -- diff --git a/src/cmd/go/testdata/script/doc.txt b/src/cmd/go/testdata/script/doc.txt new file mode 100644 index 0000000..3ff1aab --- /dev/null +++ b/src/cmd/go/testdata/script/doc.txt @@ -0,0 +1,75 @@ +# go doc --help +! go doc --help +stderr 'go doc' +stderr 'go doc <pkg>' +stderr 'go doc <sym>\[\.<methodOrField>\]' +stderr 'go doc \[<pkg>\.\]<sym>\[\.<methodOrField>\]' +stderr 'go doc \[<pkg>\.\]\[<sym>\.\]<methodOrField>' +stderr 'go doc <pkg> <sym>\[\.<methodOrField>\]' + +# go help doc +go help doc +stdout 'go doc' +stdout 'go doc <pkg>' +stdout 'go doc <sym>\[\.<methodOrField>\]' +stdout 'go doc \[<pkg>\.\]<sym>\[\.<methodOrField>\]' +stdout 'go doc \[<pkg>\.\]\[<sym>\.\]<methodOrField>' +stdout 'go doc <pkg> <sym>\[\.<methodOrField>\]' + +# go doc <pkg> +go doc p/v2 +stdout . + +# go doc <pkg> <sym> +go doc p/v2 Symbol +stdout . + +# go doc <pkg> <sym> <method> +! go doc p/v2 Symbol Method +stderr . + +# go doc <pkg>.<sym> +go doc p/v2.Symbol +stdout . + +# go doc <pkg>.<sym>.<method> +go doc p/v2.Symbol.Method +stdout . + +# go doc <sym> +go doc Symbol +stdout . + +# go doc <sym> <method> +! go doc Symbol Method +stderr . + +# go doc <sym>.<method> +go doc Symbol.Method +stdout . + +# go doc <pkg>.<method> +go doc p/v2.Method +stdout . + +# go doc <pkg> <method> +go doc p/v2 Method +stdout . + +# go doc <method> +go doc Method +stdout . + +-- go.mod -- +module p/v2 + +go 1.13 + +-- p.go -- +package p + +type Symbol struct{} + +func (Symbol) Method() error { + return nil +} diff --git a/src/cmd/go/testdata/script/embed.txt b/src/cmd/go/testdata/script/embed.txt new file mode 100644 index 0000000..5f7f6ed --- /dev/null +++ b/src/cmd/go/testdata/script/embed.txt @@ -0,0 +1,130 @@ +# go list shows patterns and files +go list -f '{{.EmbedPatterns}}' +stdout '\[x\*t\*t\]' +go list -f '{{.EmbedFiles}}' +stdout '\[x.txt\]' +go list -test -f '{{.TestEmbedPatterns}}' +stdout '\[y\*t\*t\]' +go list -test -f '{{.TestEmbedFiles}}' +stdout '\[y.txt\]' +go list -test -f '{{.XTestEmbedPatterns}}' +stdout '\[z\*t\*t\]' +go list -test -f '{{.XTestEmbedFiles}}' +stdout '\[z.txt\]' + +# build embeds x.txt +go build -x +stderr 'x.txt' + +# build uses cache correctly +go build -x +! stderr 'x.txt' +cp x.txt2 x.txt +go build -x +stderr 'x.txt' + +# build rejects invalid names +cp x.go2 x.go +go build -x +cp x.txt .git +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed file [.]git: invalid name [.]git$' +rm .git + +# build rejects symlinks +[symlink] symlink x.tzt -> x.txt +[symlink] ! go build -x +[symlink] stderr 'pattern [*]t: cannot embed irregular file x.tzt' +[symlink] rm x.tzt + +# build rejects empty directories +mkdir t +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +# build ignores symlinks and invalid names in directories +cp x.txt t/.git +! go build -x +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' +go list -e -f '{{.Incomplete}}' +stdout 'true' +[symlink] symlink t/x.link -> ../x.txt +[symlink] ! go build -x +[symlink] stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +cp x.txt t/x.txt +go build -x + +# build reports errors with positions in imported packages +rm t/x.txt +! go build m/use +stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$' + +# all still ignores .git and symlinks +cp x.go3 x.go +! go build -x +stderr '^x.go:5:12: pattern all:t: cannot embed directory t: contains no embeddable files$' + +# all finds dot files and underscore files +cp x.txt t/.x.txt +go build -x +rm t/.x.txt +cp x.txt t/_x.txt +go build -x + +-- x.go -- +package p + +import "embed" + +//go:embed x*t*t +var X embed.FS + +-- x_test.go -- +package p + +import "embed" + +//go:embed y*t*t +var Y string + +-- x_x_test.go -- +package p_test + +import "embed" + +//go:embed z*t*t +var Z string + +-- x.go2 -- +package p + +import "embed" + +//go:embed *t +var X embed.FS + +-- x.go3 -- +package p + +import "embed" + +//go:embed all:t +var X embed.FS + +-- x.txt -- +hello + +-- y.txt -- +-- z.txt -- +-- x.txt2 -- +not hello + +-- use/use.go -- +package use + +import _ "m" +-- go.mod -- +module m + +go 1.16 diff --git a/src/cmd/go/testdata/script/embed_fmt.txt b/src/cmd/go/testdata/script/embed_fmt.txt new file mode 100644 index 0000000..8a16afe --- /dev/null +++ b/src/cmd/go/testdata/script/embed_fmt.txt @@ -0,0 +1,22 @@ +# go fmt ignores file not found +go fmt xnofmt.go +cmp xnofmt.go xfmt.ref +! go build xnofmt.go +stderr 'xnofmt.go:5:12: pattern missing.txt: no matching files found' + +-- xnofmt.go -- +package p + +import "embed" + +//go:embed missing.txt +var X embed.FS +-- xfmt.ref -- +package p + +import "embed" + +//go:embed missing.txt +var X embed.FS +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/env_cross_build.txt b/src/cmd/go/testdata/script/env_cross_build.txt new file mode 100644 index 0000000..3feeba6 --- /dev/null +++ b/src/cmd/go/testdata/script/env_cross_build.txt @@ -0,0 +1,29 @@ +# Test that the corect default GOEXPERIMENT is used when cross +# building with GOENV (#46815). + +# Unset variables set by the TestScript harness. Users typically won't +# explicitly configure these, and #46815 doesn't repro if they are. +env GOOS= +env GOARCH= +env GOEXPERIMENT= + +env GOENV=windows-amd64 +go build internal/abi + +env GOENV=ios-arm64 +go build internal/abi + +env GOENV=linux-mips +go build internal/abi + +-- windows-amd64 -- +GOOS=windows +GOARCH=amd64 + +-- ios-arm64 -- +GOOS=ios +GOARCH=arm64 + +-- linux-mips -- +GOOS=linux +GOARCH=mips diff --git a/src/cmd/go/testdata/script/env_exp.txt b/src/cmd/go/testdata/script/env_exp.txt new file mode 100644 index 0000000..681512d --- /dev/null +++ b/src/cmd/go/testdata/script/env_exp.txt @@ -0,0 +1,17 @@ +# Test GOEXPERIMENT variable + +# go env shows default empty GOEXPERIMENT +go env +stdout GOEXPERIMENT= + +# go env shows valid experiments +env GOEXPERIMENT=fieldtrack,staticlockranking +go env GOEXPERIMENT +stdout '.*fieldtrack.*staticlockranking.*' +go env +stdout 'GOEXPERIMENT=.*fieldtrack.*staticlockranking.*' + +# go env rejects unknown experiments +env GOEXPERIMENT=bad +! go env GOEXPERIMENT +stderr 'unknown GOEXPERIMENT bad' diff --git a/src/cmd/go/testdata/script/env_unset.txt b/src/cmd/go/testdata/script/env_unset.txt new file mode 100644 index 0000000..22bc845 --- /dev/null +++ b/src/cmd/go/testdata/script/env_unset.txt @@ -0,0 +1,30 @@ +# Test that we can unset variables, even if initially invalid, +# as long as resulting config is valid. + +env GOENV=badenv +env GOOS= +env GOARCH= +env GOEXPERIMENT= + +! go env +stderr '^go(\.exe)?: unknown GOEXPERIMENT badexp$' + +go env -u GOEXPERIMENT + +! go env +stderr '^go: unsupported GOOS/GOARCH pair bados/badarch$' + +! go env -u GOOS +stderr '^go: unsupported GOOS/GOARCH pair \w+/badarch$' + +! go env -u GOARCH +stderr '^go: unsupported GOOS/GOARCH pair bados/\w+$' + +go env -u GOOS GOARCH + +go env + +-- badenv -- +GOOS=bados +GOARCH=badarch +GOEXPERIMENT=badexp diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt new file mode 100644 index 0000000..132947c --- /dev/null +++ b/src/cmd/go/testdata/script/env_write.txt @@ -0,0 +1,187 @@ +env GO111MODULE=off + +# go env should default to the right places +env AppData=$HOME/windowsappdata +env home=$HOME/plan9home +go env GOENV +[aix] stdout $HOME/.config/go/env +[darwin] stdout $HOME'/Library/Application Support/go/env' +[freebsd] stdout $HOME/.config/go/env +[linux] stdout $HOME/.config/go/env +[netbsd] stdout $HOME/.config/go/env +[openbsd] stdout $HOME/.config/go/env +[plan9] stdout $HOME/plan9home/lib/go/env +[windows] stdout $HOME\\windowsappdata\\go\\env + +# Now override it to something writable. +env GOENV=$WORK/envdir/go/env +go env GOENV +stdout envdir[\\/]go[\\/]env + +# go env shows all variables +go env +stdout GOARCH= +stdout GOOS= +stdout GOROOT= + +# go env ignores invalid flag in GOFLAGS environment variable +env GOFLAGS='=true' +go env + +# checking errors +! go env -w +stderr 'go: no KEY=VALUE arguments given' +! go env -u +stderr 'go: ''go env -u'' requires an argument' + +# go env -w changes default setting +env root= +[windows] env root=c: +env GOPATH= +go env -w GOPATH=$root/non-exist/gopath +! stderr .+ +grep GOPATH=$root/non-exist/gopath $WORK/envdir/go/env +go env GOPATH +stdout /non-exist/gopath + +# go env -w does not override OS environment, and warns about that +env GOPATH=$root/other +go env -w GOPATH=$root/non-exist/gopath2 +stderr 'warning: go env -w GOPATH=... does not override conflicting OS environment variable' +go env GOPATH +stdout $root/other + +# but go env -w does do the update, and unsetting the env var exposes the change +env GOPATH= +go env GOPATH +stdout $root/non-exist/gopath2 + +# unsetting with go env -u does not warn about OS environment overrides, +# nor does it warn about variables that haven't been set by go env -w. +env GOPATH=$root/other +go env -u GOPATH +! stderr .+ +go env -u GOPATH +! stderr .+ + +# go env -w rejects unknown or bad variables +! go env -w GODEBUG=gctrace=1 +stderr 'unknown go command variable GODEBUG' +! go env -w GOEXE=.bat +stderr 'GOEXE cannot be modified' +! go env -w GOVERSION=customversion +stderr 'GOVERSION cannot be modified' +! go env -w GOENV=/env +stderr 'GOENV can only be set using the OS environment' + +# go env -w can set multiple variables +env CC= +go env CC +! stdout ^xyc$ +go env -w GOOS=$GOOS CC=xyc +grep CC=xyc $GOENV +# file is maintained in sorted order +grep 'CC=xyc\nGOOS=' $GOENV +go env CC +stdout ^xyc$ + +# go env -u unsets effect of go env -w. +go env -u CC +go env CC +! stdout ^xyc$ + +# go env -w rejects double-set variables +! go env -w GOOS=$GOOS GOOS=$GOOS +stderr 'multiple values for key: GOOS' + +# go env -w rejects missing variables +! go env -w GOOS +stderr 'arguments must be KEY=VALUE: invalid argument: GOOS' + +# go env -w rejects invalid GO111MODULE values, as otherwise cmd/go would break +! go env -w GO111MODULE=badvalue +stderr 'invalid GO111MODULE value "badvalue"' + +# go env -w rejects invalid GOPATH values +! go env -w GOPATH=~/go +stderr 'GOPATH entry cannot start with shell metacharacter' + +! go env -w GOPATH=./go +stderr 'GOPATH entry is relative; must be absolute path' + +# go env -w rejects invalid GOTMPDIR values +! go env -w GOTMPDIR=x +stderr 'go: GOTMPDIR must be an absolute path' + +# go env -w should accept absolute GOTMPDIR value +# and should not create it +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +! exists $WORK/x/y/z +# we should be able to clear an env +go env -u GOTMPDIR +go env GOTMPDIR +stdout ^$ + +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +go env -w GOTMPDIR= +go env GOTMPDIR +stdout ^$ + +# go env -w rejects relative CC values +[!windows] go env -w CC=/usr/bin/clang +go env -w CC=clang +[!windows] ! go env -w CC=./clang +[!windows] ! go env -w CC=bin/clang +[!windows] stderr 'go: CC entry is relative; must be absolute path' + +[windows] go env -w CC=$WORK\bin\clang +[windows] ! go env -w CC=.\clang +[windows] ! go env -w CC=bin\clang +[windows] stderr 'go: CC entry is relative; must be absolute path' + +# go env -w rejects relative CXX values +[!windows] go env -w CC=/usr/bin/cpp +go env -w CXX=cpp +[!windows] ! go env -w CXX=./cpp +[!windows] ! go env -w CXX=bin/cpp +[!windows] stderr 'go: CXX entry is relative; must be absolute path' + +[windows] go env -w CXX=$WORK\bin\cpp +[windows] ! go env -w CXX=.\cpp +[windows] ! go env -w CXX=bin\cpp +[windows] stderr 'go: CXX entry is relative; must be absolute path' + +# go env -w/-u checks validity of GOOS/ARCH combinations +env GOOS= +env GOARCH= +# check -w doesn't allow invalid GOOS +! go env -w GOOS=linuxx +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check -w doesn't allow invalid GOARCH +! go env -w GOARCH=amd644 +stderr 'unsupported GOOS/GOARCH.*/amd644$' +# check -w doesn't allow invalid GOOS with valid GOARCH +! go env -w GOOS=linuxx GOARCH=amd64 +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check a valid GOOS and GOARCH values but an incompatible combinations +! go env -w GOOS=android GOARCH=s390x +stderr 'unsupported GOOS/GOARCH pair android/s390x' +# check that -u considers explicit envs +go env -w GOOS=linux GOARCH=mips +env GOOS=windows +! go env -u GOOS +stderr 'unsupported GOOS/GOARCH.*windows/mips$' + +# go env -w should reject relative paths in GOMODCACHE environment. +! go env -w GOMODCACHE=~/test +stderr 'go: GOMODCACHE entry is relative; must be absolute path: "~/test"' +! go env -w GOMODCACHE=./test +stderr 'go: GOMODCACHE entry is relative; must be absolute path: "./test"' + +# go env -w checks validity of GOEXPERIMENT +env GOEXPERIMENT= +! go env -w GOEXPERIMENT=badexp +stderr 'unknown GOEXPERIMENT badexp' +go env -w GOEXPERIMENT=fieldtrack diff --git a/src/cmd/go/testdata/script/fileline.txt b/src/cmd/go/testdata/script/fileline.txt new file mode 100644 index 0000000..5cb35f0 --- /dev/null +++ b/src/cmd/go/testdata/script/fileline.txt @@ -0,0 +1,8 @@ +env GO111MODULE=off + +# look for short, relative file:line in error message +! go run ../../gopath/x/y/z/err.go +stderr ^..[\\/]x[\\/]y[\\/]z[\\/]err.go: + +-- ../x/y/z/err.go -- +package main; import "bar" diff --git a/src/cmd/go/testdata/script/fmt_load_errors.txt b/src/cmd/go/testdata/script/fmt_load_errors.txt new file mode 100644 index 0000000..84bf41c --- /dev/null +++ b/src/cmd/go/testdata/script/fmt_load_errors.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +! go fmt does-not-exist + +go fmt -n exclude +stdout 'exclude[/\\]x\.go' +stdout 'exclude[/\\]x_linux\.go' + +# Test edge cases with gofmt. +# Note that this execs GOROOT/bin/gofmt. + +! exec gofmt does-not-exist + +exec gofmt gofmt-dir/no-extension +stdout 'package x' + +exec gofmt gofmt-dir +! stdout 'package x' + +-- exclude/empty/x.txt -- +-- exclude/ignore/_x.go -- +package x +-- exclude/x.go -- +// +build linux,!linux + +package x +-- exclude/x_linux.go -- +// +build windows + +package x +-- gofmt-dir/no-extension -- +package x diff --git a/src/cmd/go/testdata/script/gccgo_link_c.txt b/src/cmd/go/testdata/script/gccgo_link_c.txt new file mode 100644 index 0000000..422adea --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_link_c.txt @@ -0,0 +1,16 @@ +# Issue #7573 +# cmd/cgo: undefined reference when linking a C-library using gccgo + +[!cgo] skip +[!gccgo] skip + +go build -r -compiler gccgo cgoref +stderr 'gccgo.*\-L [^ ]*alibpath \-lalib' # make sure that Go-inline "#cgo LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage + +-- cgoref/cgoref.go -- +package main +// #cgo LDFLAGS: -L alibpath -lalib +// void f(void) {} +import "C" + +func main() { C.f() }
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/gccgo_m.txt b/src/cmd/go/testdata/script/gccgo_m.txt new file mode 100644 index 0000000..b63ba46 --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_m.txt @@ -0,0 +1,19 @@ +# It's absurd, but builds with -compiler=gccgo used to fail to build module m. +# golang.org/issue/34358 + +env GO111MODULE=off + +[short] skip + +cd m +go build +exists m$GOEXE +rm m$GOEXE +[exec:gccgo] go build -compiler=gccgo +[exec:gccgo] exists m$GOEXE + +-- m/go.mod -- +module m +-- m/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/gccgo_mangle.txt b/src/cmd/go/testdata/script/gccgo_mangle.txt new file mode 100644 index 0000000..7a09a80 --- /dev/null +++ b/src/cmd/go/testdata/script/gccgo_mangle.txt @@ -0,0 +1,15 @@ +# Issue 33871. + +cd m/a.0 +go build + +-- m/go.mod -- +module m +-- m/a.0/a.go -- +package a + +type T int + +func (t T) M() int { + return int(t) +} diff --git a/src/cmd/go/testdata/script/gcflags_patterns.txt b/src/cmd/go/testdata/script/gcflags_patterns.txt new file mode 100644 index 0000000..24ec5aa --- /dev/null +++ b/src/cmd/go/testdata/script/gcflags_patterns.txt @@ -0,0 +1,91 @@ +env GO111MODULE=off + +[!gc] skip 'using -gcflags and -ldflags' +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + +# -gcflags=-e applies to named packages, not dependencies +go build -n -v -gcflags=-e z1 z2 +stderr 'compile.* -p z1.* -e ' +stderr 'compile.* -p z2.* -e ' +stderr 'compile.* -p y' +! stderr 'compile.* -p [^z].* -e ' + +# -gcflags can specify package=flags, and can be repeated; last match wins +go build -n -v -gcflags=-e -gcflags=z1=-N z1 z2 +stderr 'compile.* -p z1.* -N ' +! stderr 'compile.* -p z1.* -e ' +! stderr 'compile.* -p z2.* -N ' +stderr 'compile.* -p z2.* -e ' +stderr 'compile.* -p y' +! stderr 'compile.* -p [^z].* -e ' +! stderr 'compile.* -p [^z].* -N ' + +# -gcflags can have arbitrary spaces around the flags +go build -n -v -gcflags=' z1 = -e ' z1 +stderr 'compile.* -p z1.* -e ' + +# -gcflags='all=-e' should apply to all packages, even with go test +go test -c -n -gcflags='all=-e' z1 +stderr 'compile.* -p z3.* -e ' + +# this particular -gcflags argument made the compiler crash +! go build -gcflags=-d=ssa/ z1 +stderr 'PhaseOptions usage' + +# -ldflags for implicit test package applies to test binary +go test -c -n -gcflags=-N -ldflags=-X=x.y=z z1 +stderr 'compile.* -N .*z_test.go' +stderr 'link.* -X=x.y=z' + +# -ldflags for explicit test package applies to test binary +go test -c -n -gcflags=z1=-N -ldflags=z1=-X=x.y=z z1 +stderr 'compile.* -N .*z_test.go' +stderr 'link.* -X=x.y=z' + +# -ldflags applies to link of command +go build -n -ldflags=-X=math.pi=3 my/cmd/prog +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to link of command even with strange directory name +go build -n -ldflags=-X=math.pi=3 my/cmd/prog/ +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to current directory +cd my/cmd/prog +go build -n -ldflags=-X=math.pi=3 +stderr 'link.* -X=math.pi=3' + +# -ldflags applies to current directory even if GOPATH is funny +[!case-sensitive] cd $WORK/GoPath/src/my/cmd/prog +go build -n -ldflags=-X=math.pi=3 +stderr 'link.* -X=math.pi=3' + +# cgo.a should not be a dependency of internally-linked go package +go build -ldflags='-linkmode=external -linkmode=internal' -n prog.go +! stderr 'packagefile .*runtime/cgo.a' + +-- z1/z.go -- +package z1 +import _ "y" +import _ "z2" + +-- z1/z_test.go -- +package z1_test +import "testing" +import _ "z3" +func Test(t *testing.T) {} + +-- z2/z.go -- +package z2 + +-- z3/z.go -- +package z3 + +-- y/y.go -- +package y + +-- my/cmd/prog/prog.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/generate.txt b/src/cmd/go/testdata/script/generate.txt new file mode 100644 index 0000000..73f5bbd --- /dev/null +++ b/src/cmd/go/testdata/script/generate.txt @@ -0,0 +1,99 @@ +[short] skip + +# Install an echo command because Windows doesn't have it. +env GOBIN=$WORK/tmp/bin +go install echo.go +env PATH=$GOBIN${:}$PATH + +# Test go generate handles a simple command +go generate ./generate/simple.go +stdout 'Success' + +# Test go generate handles a command alias +go generate './generate/alias.go' +stdout 'Now is the time for all good men' + +# Test go generate's variable substitution +go generate './generate/substitution.go' +stdout $GOARCH' substitution.go:7 pabc xyzp/substitution.go/123' + +# Test go generate's run flag +go generate -run y.s './generate/flag.go' +stdout 'yes' # flag.go should select yes +! stdout 'no' # flag.go should not select no + +# Test go generate provides the right "$GOPACKAGE" name in an x_test +go generate './generate/env_test.go' +stdout 'main_test' + +# Test go generate provides the right "$PWD" +go generate './generate/env_pwd.go' +stdout $WORK'[/\\]gopath[/\\]src[/\\]generate' + +-- echo.go -- +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + fmt.Println(strings.Join(os.Args[1:], " ")) + fmt.Println() +} +-- generate/simple.go -- +// Copyright 2014 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. + +// Simple test for go generate. + +// We include a build tag that go generate should ignore. + +// +build ignore + +//go:generate echo Success + +package p +-- generate/alias.go -- +// Copyright 2014 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. + +// Test that go generate handles command aliases. + +//go:generate -command run echo Now is the time +//go:generate run for all good men + +package p +-- generate/substitution.go -- +// Copyright 2014 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. + +// Test go generate variable substitution. + +//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123 + +package p +-- generate/flag.go -- +// 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. + +// Test -run flag + +//go:generate echo oh yes my man +//go:generate echo no, no, a thousand times no + +package p +-- generate/env_test.go -- +package main_test + +//go:generate echo $GOPACKAGE +-- generate/env_pwd.go -- +package p + +//go:generate echo $PWD diff --git a/src/cmd/go/testdata/script/generate_bad_imports.txt b/src/cmd/go/testdata/script/generate_bad_imports.txt new file mode 100644 index 0000000..4d31573 --- /dev/null +++ b/src/cmd/go/testdata/script/generate_bad_imports.txt @@ -0,0 +1,15 @@ +[windows] skip # skip because windows has no echo command + +go generate gencycle +stdout 'hello world' # check go generate gencycle ran the generator + +-- go.mod -- +module gencycle + +go 1.16 +-- gencycle.go -- +//go:generate echo hello world + +package gencycle + +import _ "gencycle" diff --git a/src/cmd/go/testdata/script/generate_env.txt b/src/cmd/go/testdata/script/generate_env.txt new file mode 100644 index 0000000..2df1663 --- /dev/null +++ b/src/cmd/go/testdata/script/generate_env.txt @@ -0,0 +1,32 @@ +# Install an env command because Windows and plan9 don't have it. +env GOBIN=$WORK/tmp/bin +go install env.go +[plan9] env path=$GOBIN${:}$path +[!plan9] env PATH=$GOBIN${:}$PATH + +# Test generators have access to the environment +go generate ./printenv.go +stdout '^GOARCH='$GOARCH +stdout '^GOOS='$GOOS +stdout '^GOFILE=' +stdout '^GOLINE=' +stdout '^GOPACKAGE=' +stdout '^DOLLAR=' + +-- env.go -- +package main + +import ( + "fmt" + "os" +) + +func main() { + for _, v := range os.Environ() { + fmt.Println(v) + } +} +-- printenv.go -- +package main + +//go:generate env
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/generate_invalid.txt b/src/cmd/go/testdata/script/generate_invalid.txt new file mode 100644 index 0000000..e18e62c --- /dev/null +++ b/src/cmd/go/testdata/script/generate_invalid.txt @@ -0,0 +1,203 @@ +[short] skip + +# Install an echo command because Windows doesn't have it. +env GOBIN=$WORK/tmp/bin +go install echo.go +env PATH=$GOBIN${:}$PATH + +# Test go generate for directory with no go files +go generate ./nogo +! stdout 'Fail' + +# Test go generate for package where all .go files are excluded by build +# constraints +go generate -v ./excluded +! stdout 'Fail' +! stderr 'go' # -v shouldn't list any files + +# Test go generate for "package" with no package clause in any file +go generate ./nopkg +stdout 'Success a' +! stdout 'Fail' + +# Test go generate for package with inconsistent package clauses +# $GOPACKAGE should depend on each file's package clause +go generate ./inconsistent +stdout 'Success a' +stdout 'Success b' +stdout -count=2 'Success c' +! stdout 'Fail' + +# Test go generate for syntax errors before and after package clauses +go generate ./syntax +stdout 'Success a' +stdout 'Success b' +! stdout 'Fail' + +# Test go generate for files importing non-existent packages +go generate ./importerr +stdout 'Success a' +stdout 'Success b' +stdout 'Success c' + +-- echo.go -- +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + fmt.Println(strings.Join(os.Args[1:], " ")) + fmt.Println() +} + +-- go.mod -- +module m + +go 1.16 +-- nogo/foo.txt -- +Text file in a directory without go files. +Go generate should ignore this directory. +//go:generate echo Fail nogo + +-- excluded/a.go -- +// Include a build tag that go generate should exclude. +// Go generate should ignore this file. + +// +build a + +//go:generate echo Fail a + +package excluded + +-- excluded/b.go -- +// Include a build tag that go generate should exclude. +// Go generate should ignore this file. + +//go:generate echo Fail b + +// +build b + +package excluded + + +-- nopkg/a.go -- +// Go file with package clause after comment. +// Go generate should process this file. + +/* Pre-comment */ package nopkg +//go:generate echo Success a + +-- nopkg/b.go -- +// Go file with commented package clause. +// Go generate should ignore this file. + +//package nopkg + +//go:generate echo Fail b + +-- nopkg/c.go -- +// Go file with package clause inside multiline comment. +// Go generate should ignore this file. + +/* +package nopkg +*/ + +//go:generate echo Fail c + +-- nopkg/d.go -- +// Go file with package clause inside raw string literal. +// Go generate should ignore this file. + +const foo = ` +package nopkg +` +//go:generate echo Fail d + +-- nopkg/e.go -- +// Go file without package clause. +// Go generate should ignore this file. + +//go:generate echo Fail e + +-- inconsistent/a.go -- +// Valid go file with inconsistent package name. +// Go generate should process this file with GOPACKAGE=a + +package a +//go:generate echo Success $GOPACKAGE + +-- inconsistent/b.go -- +// Valid go file with inconsistent package name. +// Go generate should process this file with GOPACKAGE=b + +//go:generate echo Success $GOPACKAGE +package b + +-- inconsistent/c.go -- +// Go file with two package clauses. +// Go generate should process this file with GOPACKAGE=c + +//go:generate echo Success $GOPACKAGE +package c +// Invalid package clause, should be ignored: +package cinvalid +//go:generate echo Success $GOPACKAGE + +-- inconsistent/d.go -- +// Go file with invalid package name. +// Go generate should ignore this file. + +package +d+ +//go:generate echo Fail $GOPACKAGE + +-- syntax/a.go -- +// Go file with syntax error after package clause. +// Go generate should process this file. + +package syntax +123 +//go:generate echo Success a + +-- syntax/b.go -- +// Go file with syntax error after package clause. +// Go generate should process this file. + +package syntax; 123 +//go:generate echo Success b + +-- syntax/c.go -- +// Go file with syntax error before package clause. +// Go generate should ignore this file. + +foo +package syntax +//go:generate echo Fail c + +-- importerr/a.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +package importerr +//go:generate echo Success a +import "foo" + +-- importerr/b.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +//go:generate echo Success b +package importerr +import "bar" + +-- importerr/c.go -- +// Go file which imports non-existing package. +// Go generate should process this file. + +package importerr +import "moo" +//go:generate echo Success c diff --git a/src/cmd/go/testdata/script/get_404_meta.txt b/src/cmd/go/testdata/script/get_404_meta.txt new file mode 100644 index 0000000..29fc542 --- /dev/null +++ b/src/cmd/go/testdata/script/get_404_meta.txt @@ -0,0 +1,18 @@ +# golang.org/issue/13037: 'go get' was not parsing <meta> tags in 404 served over HTTPS. + +[!net] skip +[!exec:git] skip + +env GONOSUMDB=bazil.org,github.com,golang.org +env GO111MODULE=off +go get -d bazil.org/fuse/fs/fstestutil + +env GO111MODULE=on +env GOPROXY=direct +go get bazil.org/fuse/fs/fstestutil + + +-- go.mod -- +module m + +go 1.18 diff --git a/src/cmd/go/testdata/script/get_brace.txt b/src/cmd/go/testdata/script/get_brace.txt new file mode 100644 index 0000000..3449a0c --- /dev/null +++ b/src/cmd/go/testdata/script/get_brace.txt @@ -0,0 +1,51 @@ +env GO111MODULE=off + +[!exec:git] skip + +# Set up some empty repositories. +cd $WORK/_origin/foo +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +cd $WORK +cd '_origin/{confusing}' +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +# Clone the empty repositories into GOPATH. +# This tells the Go command where to find them: it takes the place of a user's meta-tag redirector. +mkdir $GOPATH/src/example.com +cd $GOPATH/src/example.com +exec git clone $WORK/_origin/foo +exec git clone $WORK/_origin/{confusing} + +# Commit contents to the repositories. +cd $WORK/_origin/foo +exec git add main.go +exec git commit -m 'add main' + +cd $WORK +cd '_origin/{confusing}' +exec git add confusing.go +exec git commit -m 'just try to delete this!' + +# 'go get' should refuse to download or update the confusingly-named repo. +cd $GOPATH/src/example.com/foo +! go get -u 'example.com/{confusing}' +stderr 'invalid char' +! go get -u example.com/foo +stderr 'invalid import path' +! exists example.com/{confusing} + +-- $WORK/_origin/foo/main.go -- +package main +import _ "example.com/{confusing}" + +func main() {} + +-- $WORK/_origin/{confusing}/confusing.go -- +package confusing diff --git a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt new file mode 100644 index 0000000..cda25e1 --- /dev/null +++ b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get -u rsc.io/pdf/... +exists $GOPATH/bin/pdfpasswd$GOEXE diff --git a/src/cmd/go/testdata/script/get_dash_t.txt b/src/cmd/go/testdata/script/get_dash_t.txt new file mode 100644 index 0000000..baac916 --- /dev/null +++ b/src/cmd/go/testdata/script/get_dash_t.txt @@ -0,0 +1,9 @@ +# Tests issue 8181 + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get -v -t github.com/rsc/go-get-issue-8181/a github.com/rsc/go-get-issue-8181/b +go list ... +stdout 'x/build/gerrit' diff --git a/src/cmd/go/testdata/script/get_domain_root.txt b/src/cmd/go/testdata/script/get_domain_root.txt new file mode 100644 index 0000000..9187848 --- /dev/null +++ b/src/cmd/go/testdata/script/get_domain_root.txt @@ -0,0 +1,20 @@ +# Tests issue #9357 +# go get foo.io (not foo.io/subdir) was not working consistently. + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# go-get-issue-9357.appspot.com is running +# the code at github.com/rsc/go-get-issue-9357, +# a trivial Go on App Engine app that serves a +# <meta> tag for the domain root. +go get -d go-get-issue-9357.appspot.com +go get go-get-issue-9357.appspot.com +go get -u go-get-issue-9357.appspot.com + +rm $GOPATH/src/go-get-issue-9357.appspot.com +go get go-get-issue-9357.appspot.com + +rm $GOPATH/src/go-get-issue-9357.appspot.com +go get -u go-get-issue-9357.appspot.com diff --git a/src/cmd/go/testdata/script/get_dot_slash_download.txt b/src/cmd/go/testdata/script/get_dot_slash_download.txt new file mode 100644 index 0000000..dbaf46c --- /dev/null +++ b/src/cmd/go/testdata/script/get_dot_slash_download.txt @@ -0,0 +1,10 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Tests Issues #9797 and #19769 + +mkdir $WORK/tmp/src/rsc.io +env GOPATH=$WORK/tmp +cd $WORK/tmp/src/rsc.io +go get ./pprof_mac_fix diff --git a/src/cmd/go/testdata/script/get_dotfiles.txt b/src/cmd/go/testdata/script/get_dotfiles.txt new file mode 100644 index 0000000..6757f9d --- /dev/null +++ b/src/cmd/go/testdata/script/get_dotfiles.txt @@ -0,0 +1,64 @@ +env GO111MODULE=off +[short] skip + +[!exec:git] skip + +# Set up a benign repository and a repository with a dotfile name. +cd $WORK/_origin/foo +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +cd $WORK/_origin/.hidden +exec git init +exec git config user.name 'Nameless Gopher' +exec git config user.email 'nobody@golang.org' +exec git commit --allow-empty -m 'create master branch' + +# Clone the empty repositories into GOPATH. +# This tells the Go command where to find them: it takes the place of a user's meta-tag redirector. +mkdir $GOPATH/src/example.com +cd $GOPATH/src/example.com +exec git clone $WORK/_origin/foo +exec git clone $WORK/_origin/.hidden + +# Add a benign commit. +cd $WORK/_origin/foo +cp _ok/main.go main.go +exec git add main.go +exec git commit -m 'add ok' + +# 'go get' should install the benign commit. +cd $GOPATH +go get -u example.com/foo + +# Now sneak in an import of a dotfile path. +cd $WORK/_origin/.hidden +exec git add hidden.go +exec git commit -m 'nothing to see here, move along' + +cd $WORK/_origin/foo +cp _sneaky/main.go main.go +exec git add main.go +exec git commit -m 'fix typo (heh heh heh)' + +# 'go get -u' should refuse to download or update the dotfile-named repo. +cd $GOPATH/src/example.com/foo +! go get -u example.com/foo +stderr 'leading dot' +! exists example.com/.hidden/hidden.go + +-- $WORK/_origin/foo/_ok/main.go -- +package main + +func main() {} + +-- $WORK/_origin/foo/_sneaky/main.go -- +package main +import _ "example.com/.hidden" + +func main() {} + +-- $WORK/_origin/.hidden/hidden.go -- +package hidden diff --git a/src/cmd/go/testdata/script/get_go_file.txt b/src/cmd/go/testdata/script/get_go_file.txt new file mode 100644 index 0000000..f6d0de4 --- /dev/null +++ b/src/cmd/go/testdata/script/get_go_file.txt @@ -0,0 +1,60 @@ +# Tests Issue #38478 +# Tests that go get in GOPATH mode returns a specific error if the argument +# ends with '.go', and either has no slash or refers to an existing file. + +env GO111MODULE=off + +# argument doesn't have .go suffix +go get -d test + +# argument has .go suffix, is a file and exists +! go get -d test.go +stderr 'go: test.go: arguments must be package or module paths' + +# argument has .go suffix, doesn't exist and has no slashes +! go get -d test_missing.go +stderr 'go: test_missing.go: arguments must be package or module paths' + +# argument has .go suffix, is a file and exists in sub-directory +! go get -d test/test.go +stderr 'go: test/test.go exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, doesn't exist and has slashes +! go get -d test/test_missing.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a symlink and exists +[symlink] symlink test_sym.go -> test.go +[symlink] ! go get -d test_sym.go +[symlink] stderr 'go: test_sym.go: arguments must be package or module paths' +[symlink] rm test_sym.go + +# argument has .go suffix, is a symlink and exists in sub-directory +[symlink] symlink test/test_sym.go -> test.go +[symlink] ! go get -d test/test_sym.go +[symlink] stderr 'go: test/test_sym.go exists as a file, but ''go get'' requires package arguments' +[symlink] rm test_sym.go + +# argument has .go suffix, is a directory and exists +mkdir test_dir.go +! go get -d test_dir.go +stderr 'go: test_dir.go: arguments must be package or module paths' +rm test_dir.go + +# argument has .go suffix, is a directory and exists in sub-directory +mkdir test/test_dir.go +! go get -d test/test_dir.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' +rm test/test_dir.go + + +-- test.go -- +package main +func main() {println("test")} + + +-- test/test.go -- +package main +func main() {println("test")} diff --git a/src/cmd/go/testdata/script/get_goroot.txt b/src/cmd/go/testdata/script/get_goroot.txt new file mode 100644 index 0000000..929435a --- /dev/null +++ b/src/cmd/go/testdata/script/get_goroot.txt @@ -0,0 +1,53 @@ +[!net] skip +env GO111MODULE=off + +# Issue 4186. go get cannot be used to download packages to $GOROOT. +# Test that without GOPATH set, go get should fail. + +# Fails because GOROOT=GOPATH +env GOPATH=$WORK/tmp +env GOROOT=$WORK/tmp +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +# Fails because GOROOT=GOPATH after cleaning. +env GOPATH=$WORK/tmp/ +env GOROOT=$WORK/tmp +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +env GOPATH=$WORK/tmp +env GOROOT=$WORK/tmp/ +! go get -d github.com/golang/example/hello +stderr 'warning: GOPATH set to GOROOT' +stderr '\$GOPATH must not be set to \$GOROOT' + +# Make a home directory +mkdir $WORK/home/go + +# Fails because GOROOT=$HOME/go so default GOPATH unset. +[windows] env USERPROFILE=$WORK/home +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOPATH= +env GOROOT=$WORK/home/go +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' + +[windows] env USERPROFILE=$WORK/home/ +[plan9] env home=$WORK/home/ +[!windows] [!plan9] env HOME=$WORK/home/ +env GOPATH= +env GOROOT=$WORK/home/go +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' + +[windows] env USERPROFILE=$WORK/home +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOPATH= +env GOROOT=$WORK/home/go/ +! go get -d github.com/golang/example/hello +stderr '\$GOPATH not set' diff --git a/src/cmd/go/testdata/script/get_insecure.txt b/src/cmd/go/testdata/script/get_insecure.txt new file mode 100644 index 0000000..69930f7 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure.txt @@ -0,0 +1,57 @@ +# TODO(matloob): Split this test into two? It's one of the slowest tests we have. + +[!net] skip +[!exec:git] skip + +env PATH=$WORK/tmp/bin${:}$PATH +go build -o $WORK/tmp/bin/ssh ssh.go + +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try again with GOINSECURE (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com +go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating without GOINSECURE (should fail). +env GOINSECURE='' +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Set up +env GOPATH=$WORK/m/gp +mkdir $WORK/m +cp module_file $WORK/m/go.mod +cd $WORK/m +env GO111MODULE=on +env GOPROXY='' + +# Modules: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Try again with GOINSECURE (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com +env GONOSUMDB=insecure.go-get-issue-15410.appspot.com +go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# Modules: Try updating without GOINSECURE (should fail). +env GOINSECURE='' +env GONOSUMDB='' +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +go list -m ... +stdout 'insecure.go-get-issue' + +-- ssh.go -- +// stub out uses of ssh by go get +package main + +import "os" + +func main() { + os.Exit(1) +} +-- module_file -- +module m diff --git a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt new file mode 100644 index 0000000..7eba42e --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt @@ -0,0 +1,8 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +env GOINSECURE=insecure.go-get-issue-15410.appspot.com +go get -d insecure.go-get-issue-15410.appspot.com/pkg/p diff --git a/src/cmd/go/testdata/script/get_insecure_env.txt b/src/cmd/go/testdata/script/get_insecure_env.txt new file mode 100644 index 0000000..8d88427 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_env.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:git] skip + +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Try go get -d of HTTP-only repo (should fail). +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try again with invalid GOINSECURE (should fail). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/q +! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try with correct GOINSECURE (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com/pkg/p +go get -d insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating without GOINSECURE (should fail). +env GOINSECURE= +! go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating with GOINSECURE glob (should succeed). +env GOINSECURE=*.go-get-*.appspot.com +go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + +# GOPATH: Try updating with GOINSECURE base URL (should succeed). +env GOINSECURE=insecure.go-get-issue-15410.appspot.com +go get -d -u -f insecure.go-get-issue-15410.appspot.com/pkg/p + diff --git a/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt b/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt new file mode 100644 index 0000000..00bf32f --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_no_longer_supported.txt @@ -0,0 +1,13 @@ +# GOPATH: Set up +env GO111MODULE=off + +# GOPATH: Fetch with insecure, should error +! go get -insecure test +stderr 'go: -insecure flag is no longer supported; use GOINSECURE instead' + +# Modules: Set up +env GO111MODULE=on + +# Modules: Fetch with insecure, should error +! go get -insecure test +stderr 'go: -insecure flag is no longer supported; use GOINSECURE instead' diff --git a/src/cmd/go/testdata/script/get_insecure_redirect.txt b/src/cmd/go/testdata/script/get_insecure_redirect.txt new file mode 100644 index 0000000..fb5f269 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_redirect.txt @@ -0,0 +1,13 @@ +# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure (now replaced by GOINSECURE). +# golang.org/issue/34049: 'go get' would panic in case of an insecure redirect in GOPATH mode + +[!net] skip +[!exec:git] skip + +env GO111MODULE=off + +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' + +env GOINSECURE=vcs-test.golang.org/insecure/go/insecure +go get -d vcs-test.golang.org/insecure/go/insecure diff --git a/src/cmd/go/testdata/script/get_insecure_update.txt b/src/cmd/go/testdata/script/get_insecure_update.txt new file mode 100644 index 0000000..e1a1a23 --- /dev/null +++ b/src/cmd/go/testdata/script/get_insecure_update.txt @@ -0,0 +1,14 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Clone the repo via HTTP manually. +exec git clone -q http://github.com/golang/example github.com/golang/example + +# Update without GOINSECURE should fail. +# We need -f to ignore import comments. +! go get -d -u -f github.com/golang/example/hello + +# Update with GOINSECURE should succeed. +env GOINSECURE=github.com/golang/example/hello +go get -d -u -f github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_internal_wildcard.txt b/src/cmd/go/testdata/script/get_internal_wildcard.txt new file mode 100644 index 0000000..ff20d4b --- /dev/null +++ b/src/cmd/go/testdata/script/get_internal_wildcard.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# This used to fail with errors about internal packages +go get github.com/rsc/go-get-issue-11960/... diff --git a/src/cmd/go/testdata/script/get_issue11307.txt b/src/cmd/go/testdata/script/get_issue11307.txt new file mode 100644 index 0000000..9d6b7dd --- /dev/null +++ b/src/cmd/go/testdata/script/get_issue11307.txt @@ -0,0 +1,9 @@ +# go get -u was not working except in checkout directory + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +env GOPATH=$WORK/tmp/gopath +go get github.com/rsc/go-get-issue-11307 +go get -u github.com/rsc/go-get-issue-11307 # was failing diff --git a/src/cmd/go/testdata/script/get_legacy.txt b/src/cmd/go/testdata/script/get_legacy.txt new file mode 100644 index 0000000..938d428 --- /dev/null +++ b/src/cmd/go/testdata/script/get_legacy.txt @@ -0,0 +1,58 @@ +# This test was converted from a test in vendor_test.go (which no longer exists). +# That seems to imply that it's about vendoring semantics, but the test doesn't +# use 'go -mod=vendor' (and none of the fetched repos have vendor folders). +# The test still seems to be useful as a test of direct-mode go get. + +[short] skip +[!exec:git] skip +env GO111MODULE=off + +env GOPATH=$WORK/tmp/d1 +go get vcs-test.golang.org/git/modlegacy1-old.git/p1 +go list -f '{{.Deps}}' vcs-test.golang.org/git/modlegacy1-old.git/p1 +stdout 'new.git/p2' # old/p1 should depend on new/p2 +! stdout new.git/v2/p2 # old/p1 should NOT depend on new/v2/p2 +go build vcs-test.golang.org/git/modlegacy1-old.git/p1 vcs-test.golang.org/git/modlegacy1-new.git/p1 +! stdout . + +env GOPATH=$WORK/tmp/d2 + +rm $GOPATH +go get github.com/rsc/vgotest5 +go get github.com/rsc/vgotest4 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest4 +go get github.com/rsc/vgotest5 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/rsc/vgotest5 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 +go get github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat github.com/rsc/vgotest4 github.com/rsc/vgotest5 + +rm $GOPATH +go get github.com/myitcv/vgo_example_compat github.com/rsc/vgotest5 github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat github.com/rsc/vgotest5 + +rm $GOPATH +go get github.com/rsc/vgotest4 github.com/rsc/vgotest5 github.com/myitcv/vgo_example_compat + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/myitcv/vgo_example_compat github.com/rsc/vgotest4 + +rm $GOPATH +go get github.com/rsc/vgotest5 github.com/rsc/vgotest4 github.com/myitcv/vgo_example_compat diff --git a/src/cmd/go/testdata/script/get_non_pkg.txt b/src/cmd/go/testdata/script/get_non_pkg.txt new file mode 100644 index 0000000..a878530 --- /dev/null +++ b/src/cmd/go/testdata/script/get_non_pkg.txt @@ -0,0 +1,14 @@ +[!net] skip +[!exec:git] skip + +env GOBIN=$WORK/tmp/gobin +env GO111MODULE=off + +! go get -d golang.org/x/tools +stderr 'golang.org/x/tools: no Go files' + +! go get -d -u golang.org/x/tools +stderr 'golang.org/x/tools: no Go files' + +! go get -d golang.org/x/tools +stderr 'golang.org/x/tools: no Go files'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/get_race.txt b/src/cmd/go/testdata/script/get_race.txt new file mode 100644 index 0000000..16a560a --- /dev/null +++ b/src/cmd/go/testdata/script/get_race.txt @@ -0,0 +1,8 @@ +# Tests issue #20502 + +[!net] skip +[!exec:git] skip +[!race] skip +env GO111MODULE=off + +go get -race github.com/rsc/go-get-issue-9224-cmd diff --git a/src/cmd/go/testdata/script/get_test_only.txt b/src/cmd/go/testdata/script/get_test_only.txt new file mode 100644 index 0000000..a3f38dd --- /dev/null +++ b/src/cmd/go/testdata/script/get_test_only.txt @@ -0,0 +1,6 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get golang.org/x/tour/content... +go get -t golang.org/x/tour/content... diff --git a/src/cmd/go/testdata/script/get_tilde.txt b/src/cmd/go/testdata/script/get_tilde.txt new file mode 100644 index 0000000..e520957 --- /dev/null +++ b/src/cmd/go/testdata/script/get_tilde.txt @@ -0,0 +1,24 @@ +env GO111MODULE=off +[short] skip + +# Paths containing windows short names should be rejected before attempting to fetch. +! go get example.com/longna~1.dir/thing +stderr 'trailing tilde and digits' +! go get example.com/longna~1/thing +stderr 'trailing tilde and digits' +! go get example.com/~9999999/thing +stderr 'trailing tilde and digits' + +# A path containing an element that is just a tilde, or a tilde followed by non-digits, +# should attempt to resolve. +! go get example.com/~glenda/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' + +! go get example.com/~glenda2/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' + +! go get example.com/~/notfound +! stderr 'trailing tilde and digits' +stderr 'unrecognized import path' diff --git a/src/cmd/go/testdata/script/get_update.txt b/src/cmd/go/testdata/script/get_update.txt new file mode 100644 index 0000000..9afce6a --- /dev/null +++ b/src/cmd/go/testdata/script/get_update.txt @@ -0,0 +1,25 @@ +# Tests Issue #9224 +# The recursive updating was trying to walk to +# former dependencies, not current ones. + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Rewind +go get github.com/rsc/go-get-issue-9224-cmd +cd $GOPATH/src/github.com/rsc/go-get-issue-9224-lib +exec git reset --hard HEAD~ +cd $GOPATH/src + +# Run get +go get -u 'github.com/rsc/go-get-issue-9224-cmd' + +# (Again with -d -u) Rewind +go get github.com/rsc/go-get-issue-9224-cmd +cd $GOPATH/src/github.com/rsc/go-get-issue-9224-lib +exec git reset --hard HEAD~ +cd $GOPATH/src + +# (Again with -d -u) Run get +go get -d -u 'github.com/rsc/go-get-issue-9224-cmd' diff --git a/src/cmd/go/testdata/script/get_update_all.txt b/src/cmd/go/testdata/script/get_update_all.txt new file mode 100644 index 0000000..2b75849 --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_all.txt @@ -0,0 +1,9 @@ +# Issue 14444: go get -u .../ duplicate loads errors +# Check that go get update -u ... does not try to load duplicates + +[!net] skip + +env GO111MODULE=off + +go get -u -n .../ +! stderr 'duplicate loads of' # make sure old packages are removed from cache diff --git a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt new file mode 100644 index 0000000..b00adea --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt @@ -0,0 +1,14 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +# Clone the repo via HTTPS manually. +exec git clone -q https://github.com/golang/example github.com/golang/example + +# Configure the repo to use a protocol unknown to cmd/go +# that still actually works. +cd github.com/golang/example +exec git remote set-url origin xyz://github.com/golang/example +exec git config --local url.https://github.com/.insteadOf xyz://github.com/ + +go get -d -u -f github.com/golang/example/hello diff --git a/src/cmd/go/testdata/script/get_update_wildcard.txt b/src/cmd/go/testdata/script/get_update_wildcard.txt new file mode 100644 index 0000000..4e66004 --- /dev/null +++ b/src/cmd/go/testdata/script/get_update_wildcard.txt @@ -0,0 +1,16 @@ +# Issue 14450: go get -u .../ tried to import not downloaded package + +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get github.com/tmwh/go-get-issue-14450/a +! go get -u .../ +stderr 'cannot find package.*d-dependency/e' + +# Even though get -u failed, the source for others should be downloaded. +exists github.com/tmwh/go-get-issue-14450/b +exists github.com/tmwh/go-get-issue-14450-b-dependency/c +exists github.com/tmwh/go-get-issue-14450-b-dependency/d + +! exists github.com/tmwh/go-get-issue-14450-c-dependency/e diff --git a/src/cmd/go/testdata/script/get_vcs_error_message.txt b/src/cmd/go/testdata/script/get_vcs_error_message.txt new file mode 100644 index 0000000..8dc84fc --- /dev/null +++ b/src/cmd/go/testdata/script/get_vcs_error_message.txt @@ -0,0 +1,9 @@ +# Test that the Version Control error message includes the correct directory +env GO111MODULE=off +! go get -u foo +stderr gopath(\\\\|/)src(\\\\|/)foo + +-- foo/foo.go -- +package foo +-- math/math.go -- +package math diff --git a/src/cmd/go/testdata/script/get_vendor.txt b/src/cmd/go/testdata/script/get_vendor.txt new file mode 100644 index 0000000..4ebb8a2 --- /dev/null +++ b/src/cmd/go/testdata/script/get_vendor.txt @@ -0,0 +1,95 @@ +[short] skip +env GO111MODULE=off + +cd $GOPATH/src/v +go run m.go +go test +go list -f '{{.Imports}}' +stdout 'v/vendor/vendor.org/p' +go list -f '{{.TestImports}}' +stdout 'v/vendor/vendor.org/p' +go get -d +go get -t -d + +[!net] stop +[!exec:git] stop + +cd $GOPATH/src + +# Update +go get 'github.com/rsc/go-get-issue-11864' +go get -u 'github.com/rsc/go-get-issue-11864' +exists github.com/rsc/go-get-issue-11864/vendor + +# get -u +rm $GOPATH +mkdir $GOPATH/src +go get -u 'github.com/rsc/go-get-issue-11864' +exists github.com/rsc/go-get-issue-11864/vendor + +# get -t -u +rm $GOPATH +mkdir $GOPATH/src +go get -t -u 'github.com/rsc/go-get-issue-11864/...' +exists github.com/rsc/go-get-issue-11864/vendor + +# Submodules +rm $GOPATH +mkdir $GOPATH/src +go get -d 'github.com/rsc/go-get-issue-12612' +go get -u -d 'github.com/rsc/go-get-issue-12612' +exists github.com/rsc/go-get-issue-12612/vendor/golang.org/x/crypto/.git + +# Bad vendor (bad/imp) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/imp2) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp2' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/imp3) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/imp3' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +# Bad vendor (bad/...) +rm $GOPATH +mkdir $GOPATH/src +! go get -t -u 'github.com/rsc/go-get-issue-18219/bad/...' +stderr 'must be imported as' +! exists github.com/rsc/go-get-issue-11864/vendor + +-- v/m.go -- +package main + +import ( + "fmt" + "vendor.org/p" +) + +func main() { + fmt.Println(p.C) +} +-- v/m_test.go -- +package main +import ( + "fmt" + "testing" + "vendor.org/p" +) + +func TestNothing(t *testing.T) { + fmt.Println(p.C) +} +-- v/vendor/vendor.org/p/p.go -- +package p +const C = 1 diff --git a/src/cmd/go/testdata/script/get_with_git_trace.txt b/src/cmd/go/testdata/script/get_with_git_trace.txt new file mode 100644 index 0000000..98854c7 --- /dev/null +++ b/src/cmd/go/testdata/script/get_with_git_trace.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +env GIT_TRACE=1 + +[!net] skip +[!exec:git] skip + +# go get should be success when GIT_TRACE set +go get golang.org/x/text diff --git a/src/cmd/go/testdata/script/go_version.txt b/src/cmd/go/testdata/script/go_version.txt new file mode 100644 index 0000000..1a787e1 --- /dev/null +++ b/src/cmd/go/testdata/script/go_version.txt @@ -0,0 +1,9 @@ +# test that go version doesn't panic on non-go binaries
+# See Issue #49181
+
+[exec:/bin/true] cp /bin/true true
+[exec:C:\windows\system32\help.exe] cp C:\windows\system32\help.exe help.exe
+
+go version -m .
+! stdout .
+! stderr .
diff --git a/src/cmd/go/testdata/script/goflags.txt b/src/cmd/go/testdata/script/goflags.txt new file mode 100644 index 0000000..f4872ff --- /dev/null +++ b/src/cmd/go/testdata/script/goflags.txt @@ -0,0 +1,59 @@ +env GO111MODULE=off + +# GOFLAGS sets flags for commands + +env GOFLAGS='-e -f={{.Dir}} --test.benchtime=1s -count=10' +go list asdfasdfasdf # succeeds because of -e +go list runtime +stdout '[\\/]runtime$' + +env GOFLAGS=-race OLDGOARCH=$GOARCH OLDGOOS=$GOOS GOARCH=386 GOOS=linux +! go list runtime +stderr 'race is not supported on linux/386' + +env GOARCH=$OLDGOARCH GOOS=$OLDGOOS + +# go env succeeds even though -f={{.Dir}} is inappropriate +go env + +# bad flags are diagnosed +env GOFLAGS=-typoflag +! go list runtime +stderr 'unknown flag -typoflag' + +env GOFLAGS=- +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "-"' + +env GOFLAGS=-- +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "--"' + +env GOFLAGS=---oops +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "---oops"' + +env GOFLAGS=-=noname +! go list runtime +stderr '^go: parsing \$GOFLAGS: non-flag "-=noname"' + +env GOFLAGS=-f +! go list runtime +stderr '^go: flag needs an argument: -f \(from (\$GOFLAGS|%GOFLAGS%)\)$' + +env GOFLAGS=-e=asdf +! go list runtime +stderr '^go: invalid boolean value \"asdf\" for flag -e \(from (\$GOFLAGS|%GOFLAGS%)\)' + +# except in go bug (untested) and go env +go env +stdout GOFLAGS + +# Flags listed in GOFLAGS should be safe to duplicate on the command line. +env GOFLAGS=-tags=magic +go list -tags=magic +go test -tags=magic -c -o $devnull +go vet -tags=magic + +-- foo_test.go -- +package foo diff --git a/src/cmd/go/testdata/script/gopath_install.txt b/src/cmd/go/testdata/script/gopath_install.txt new file mode 100644 index 0000000..6c572ea --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_install.txt @@ -0,0 +1,53 @@ +# Regression test for 'go install' locations in GOPATH mode. +env GO111MODULE=off +[short] skip + +# Without $GOBIN set, binaries should be installed into the GOPATH bin directory. +env GOBIN= +rm $GOPATH/bin/go-cmd-test$GOEXE +go install go-cmd-test +exists $GOPATH/bin/go-cmd-test$GOEXE + +# With $GOBIN set, binaries should be installed to $GOBIN. +env GOBIN=$WORK/bin1 +mkdir -p $GOBIN +go install go-cmd-test +exists $GOBIN/go-cmd-test$GOEXE + +# Issue 11065: installing to the current directory should create an executable. +cd go-cmd-test +env GOBIN=$PWD +go install +exists ./go-cmd-test$GOEXE +cd .. + +# Without $GOBIN set, installing a program outside $GOPATH should fail +# (there is nowhere to install it). +env GOPATH= # reset to default ($HOME/go, which does not exist) +env GOBIN= +! go install go-cmd-test/helloworld.go +stderr '^go: no install location for \.go files listed on command line \(GOBIN not set\)$' + +# With $GOBIN set, should install there. +env GOBIN=$WORK/bin1 +go install go-cmd-test/helloworld.go +exists $GOBIN/helloworld$GOEXE + +# We can't assume that we can write to GOROOT, because it may not be writable. +# However, we can check its install location using 'go list'. +# cmd/fix should be installed to GOROOT/pkg, not GOPATH/bin. +env GOPATH=$PWD +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +# GOBIN should not affect toolchain install locations. +env GOBIN=$WORK/bin1 +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/src/cmd/go/testdata/script/gopath_local.txt b/src/cmd/go/testdata/script/gopath_local.txt new file mode 100644 index 0000000..54beaca --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_local.txt @@ -0,0 +1,117 @@ +env GO111MODULE=off # Relative imports only work in GOPATH mode. + +[short] skip + +# Imports should be resolved relative to the source file. +go build testdata/local/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/local/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/local/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/local/easy.go +stderr '^go: no install location for \.go files listed on command line \(GOBIN not set\)$' + +[windows] stop # Windows does not allow the ridiculous directory name we're about to use. + +env BAD_DIR_NAME='#$%:, &()*;<=>?\^{}' + +mkdir -p testdata/$BAD_DIR_NAME/easysub +mkdir -p testdata/$BAD_DIR_NAME/sub/sub + +cp testdata/local/easy.go testdata/$BAD_DIR_NAME/easy.go +cp testdata/local/easysub/easysub.go testdata/$BAD_DIR_NAME/easysub/easysub.go +cp testdata/local/easysub/main.go testdata/$BAD_DIR_NAME/easysub/main.go +cp testdata/local/hard.go testdata/$BAD_DIR_NAME/hard.go +cp testdata/local/sub/sub.go testdata/$BAD_DIR_NAME/sub/sub.go +cp testdata/local/sub/sub/subsub.go testdata/$BAD_DIR_NAME/sub/sub/subsub.go + +# Imports should be resolved relative to the source file. +go build testdata/$BAD_DIR_NAME/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/$BAD_DIR_NAME/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/$BAD_DIR_NAME/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/$BAD_DIR_NAME/easy.go +stderr '^go: no install location for \.go files listed on command line \(GOBIN not set\)$' + +-- testdata/local/easy.go -- +package main + +import "./easysub" + +func main() { + easysub.Hello() +} +-- testdata/local/easysub/easysub.go -- +package easysub + +import "fmt" + +func Hello() { + fmt.Println("easysub.Hello") +} +-- testdata/local/easysub/main.go -- +// +build ignore + +package main + +import "." + +func main() { + easysub.Hello() +} +-- testdata/local/hard.go -- +package main + +import "./sub" + +func main() { + sub.Hello() +} +-- testdata/local/sub/sub.go -- +package sub + +import ( + "fmt" + + subsub "./sub" +) + +func Hello() { + fmt.Println("sub.Hello") + subsub.Hello() +} +-- testdata/local/sub/sub/subsub.go -- +package subsub + +import "fmt" + +func Hello() { + fmt.Println("subsub.Hello") +} diff --git a/src/cmd/go/testdata/script/gopath_moved_repo.txt b/src/cmd/go/testdata/script/gopath_moved_repo.txt new file mode 100644 index 0000000..99d80bf --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_moved_repo.txt @@ -0,0 +1,67 @@ +env GO111MODULE=off + +# Test that 'go get -u' reports packages whose VCS configurations do not +# match their import paths. + +[!net] skip +[short] skip + +# We need to execute a custom Go program to break the config files. +# +# git will ask for a username and password when we run 'go get -d -f -u', +# so we also need to set GIT_ASKPASS. Conveniently, a single binary can +# perform both tasks! + +go build -o replace.exe replace +env GIT_ASKPASS=$PWD/replace.exe + + +# Test that 'go get -u' reports moved git packages. + +[exec:git] go get -d rsc.io/pdf +[exec:git] go get -d -u rsc.io/pdf +[exec:git] exec ./replace.exe pdf rsc.io/pdf/.git/config + +[exec:git] ! go get -d -u rsc.io/pdf +[exec:git] stderr 'is a custom import path for' +[exec:git] ! go get -d -f -u rsc.io/pdf +[exec:git] stderr 'validating server certificate|[nN]ot [fF]ound' + + +# Test that 'go get -u' reports moved Mercurial packages. + +[exec:hg] go get -d vcs-test.golang.org/go/custom-hg-hello +[exec:hg] go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] exec ./replace.exe custom-hg-hello vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc + +[exec:hg] ! go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'is a custom import path for' +[exec:hg] ! go get -d -f -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'validating server certificate|[nN]ot [fF]ound' + + +-- replace/replace.go -- +package main + +import ( + "bytes" + "log" + "os" +) + +func main() { + if len(os.Args) < 3 { + return + } + + base := []byte(os.Args[1]) + path := os.Args[2] + data, err := os.ReadFile(path) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/gopath_paths.txt b/src/cmd/go/testdata/script/gopath_paths.txt new file mode 100644 index 0000000..04265b1 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_paths.txt @@ -0,0 +1,43 @@ +# Regression test for GOPATH validation in GOPATH mode. +env GO111MODULE=off + +env ORIG_GOPATH=$GOPATH + +# The literal path '.' in GOPATH should be rejected. +env GOPATH=. +! go build go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# It should still be rejected if the requested package can be +# found using another entry. +env GOPATH=${:}$ORIG_GOPATH${:}. +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +# GOPATH cannot be a relative subdirectory of the working directory. +env ORIG_GOPATH +stdout 'ORIG_GOPATH='$WORK[/\\]gopath +cd $WORK +env GOPATH=gopath +! go build gopath/src/go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# Blank paths in GOPATH should be rejected as relative (issue 21928). +env GOPATH=' '${:}$ORIG_GOPATH +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +[short] stop + +# Empty paths in GOPATH should be ignored (issue 21928). +env GOPATH=${:}$ORIG_GOPATH +env GOPATH +go install go-cmd-test +exists $ORIG_GOPATH/bin/go-cmd-test$GOEXE + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt new file mode 100644 index 0000000..a0a41a5 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt @@ -0,0 +1,44 @@ +env GO111MODULE=off + +[!gc] skip + +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOPATH[/\\]src[/\\]vendor + +# A package importing 'net/http' should resolve its dependencies +# to the package 'vendor/golang.org/x/net/http2/hpack' within GOROOT. +cd importnethttp +go list -deps -f '{{.ImportPath}} {{.Dir}}' +stdout ^vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOPATH[/\\]src[/\\]vendor + +# In the presence of $GOPATH/src/vendor/golang.org/x/net/http2/hpack, +# a package in GOPATH importing 'golang.org/x/net/http2/hpack' should +# resolve its dependencies in GOPATH/src. +cd ../issue16333 +go build . + +go list -deps -f '{{.ImportPath}} {{.Dir}}' . +stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOROOT[/\\]src[/\\]vendor + +go list -test -deps -f '{{.ImportPath}} {{.Dir}}' . +stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack +! stdout $GOROOT[/\\]src[/\\]vendor + +-- issue16333/issue16333.go -- +package vendoring17 + +import _ "golang.org/x/net/http2/hpack" +-- issue16333/issue16333_test.go -- +package vendoring17 + +import _ "testing" +import _ "golang.org/x/net/http2/hpack" +-- importnethttp/http.go -- +package importnethttp + +import _ "net/http" +-- $GOPATH/src/vendor/golang.org/x/net/http2/hpack/hpack.go -- +package hpack diff --git a/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt new file mode 100644 index 0000000..22e6048 --- /dev/null +++ b/src/cmd/go/testdata/script/gopath_vendor_dup_err.txt @@ -0,0 +1,25 @@ +[!net] skip +env GO111MODULE=off + +# Issue 17119: Test more duplicate load errors. +! go build dupload +! stderr 'duplicate load|internal error' +stderr 'dupload/vendor/p must be imported as p' + +-- dupload/dupload.go -- +package main + +import ( + _ "dupload/p2" + _ "p" +) + +func main() {} +-- dupload/p/p.go -- +package p +-- dupload/p2/p2.go -- +package p2 + +import _ "dupload/vendor/p" +-- dupload/vendor/p/p.go -- +package p diff --git a/src/cmd/go/testdata/script/goroot_executable.txt b/src/cmd/go/testdata/script/goroot_executable.txt new file mode 100644 index 0000000..fdbcde0 --- /dev/null +++ b/src/cmd/go/testdata/script/goroot_executable.txt @@ -0,0 +1,111 @@ +[gccgo] skip + +mkdir $WORK/new/bin + +# In this test, we are specifically checking the logic for deriving +# the value of GOROOT from runtime.GOROOT. +# GOROOT_FINAL changes the default behavior of runtime.GOROOT, +# and will thus cause the test to fail if it is set when our +# new cmd/go is built. +env GOROOT_FINAL= + +go build -o $WORK/new/bin/go$GOEXE cmd/go & +go build -o $WORK/bin/check$GOEXE check.go & +wait + +env TESTGOROOT=$GOROOT +env GOROOT= + +# Relocated Executable +# cp $TESTGOROOT/bin/go$GOEXE $WORK/new/bin/go$GOEXE +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $TESTGOROOT + +# Relocated Tree: +# If the binary is sitting in a bin dir next to ../pkg/tool, that counts as a GOROOT, +# so it should find the new tree. +mkdir $WORK/new/pkg/tool +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $WORK/new + +[!symlink] stop 'The rest of the test cases require symlinks' + +# Symlinked Executable: +# With a symlink into go tree, we should still find the go tree. +mkdir $WORK/other/bin +symlink $WORK/other/bin/go$GOEXE -> $WORK/new/bin/go$GOEXE +exec $WORK/bin/check$GOEXE $WORK/new/bin/go$GOEXE $WORK/new + +rm $WORK/new/pkg + +# Runtime GOROOT: +# Binaries built in the new tree should report the +# new tree when they call runtime.GOROOT. +symlink $WORK/new/src -> $TESTGOROOT/src +symlink $WORK/new/pkg -> $TESTGOROOT/pkg +exec $WORK/new/bin/go$GOEXE run check_runtime_goroot.go $WORK/new + +-- check.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + exe := os.Args[1] + want := os.Args[2] + cmd := exec.Command(exe, "env", "GOROOT") + out, err := cmd.CombinedOutput() + if err != nil { + fmt.Fprintf(os.Stderr, "%s env GOROOT: %v, %s\n", exe, err, out) + os.Exit(1) + } + goroot, err := filepath.EvalSymlinks(strings.TrimSpace(string(out))) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + want, err = filepath.EvalSymlinks(want) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if !strings.EqualFold(goroot, want) { + fmt.Fprintf(os.Stderr, "go env GOROOT:\nhave %s\nwant %s\n", goroot, want) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "go env GOROOT: %s\n", goroot) + +} +-- check_runtime_goroot.go -- +package main + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" +) + +func main() { + goroot, err := filepath.EvalSymlinks(runtime.GOROOT()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + want, err := filepath.EvalSymlinks(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if !strings.EqualFold(goroot, want) { + fmt.Fprintf(os.Stderr, "go env GOROOT:\nhave %s\nwant %s\n", goroot, want) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "go env GOROOT: %s\n", goroot) + +} diff --git a/src/cmd/go/testdata/script/govcs.txt b/src/cmd/go/testdata/script/govcs.txt new file mode 100644 index 0000000..46f1bd0 --- /dev/null +++ b/src/cmd/go/testdata/script/govcs.txt @@ -0,0 +1,174 @@ +env GO111MODULE=on +env proxy=$GOPROXY +env GOPROXY=direct + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^go: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr '^go: github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr '^go: github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list +env GOPROXY=$proxy +go get rsc.io/quote # ok because used proxy +env GOPROXY=direct + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr '^go: rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr '^go: rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr '^go: rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr '^go: rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr '^go: rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$' + +# Repeat in GOPATH mode. Error texts slightly different. + +env GO111MODULE=off + +# GOVCS stops go get +env GOVCS='*:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOPRIVATE='github.com/google' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# public pattern works +env GOPRIVATE='github.com/google' +env GOVCS='public:all,private:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$' + +# private pattern works +env GOPRIVATE='hubgit.com/google' +env GOVCS='private:all,public:none' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# other patterns work (for more patterns, see TestGOVCS) +env GOPRIVATE= +env GOVCS='github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' +env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$' + +# bad patterns are reported (for more bad patterns, see TestGOVCSErrors) +env GOVCS='git' +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$' + +env GOVCS=github.com:hg,github.com:git +! go get github.com/google/go-cmp +stderr '^package github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$' + +# bad GOVCS patterns do not stop commands that do not need to check VCS +go list + +# svn is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.svn/hello +stderr '^package rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$' + +# fossil is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.fossil/hello +stderr '^package rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$' + +# bzr is disallowed by default +env GOPRIVATE= +env GOVCS= +! go get rsc.io/nonexist.bzr/hello +stderr '^package rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$' + +# git is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:git] [!short] go get rsc.io/sampler + +# hg is OK by default +env GOVCS= +env GONOSUMDB='*' +[net] [exec:hg] [!short] go get vcs-test.golang.org/go/custom-hg-hello + +# git can be disallowed +env GOVCS=public:hg +! go get rsc.io/nonexist.git/hello +stderr '^package rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$' + +# hg can be disallowed +env GOVCS=public:git +! go get rsc.io/nonexist.hg/hello +stderr '^package rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$' + +-- go.mod -- +module m + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/script/help.txt b/src/cmd/go/testdata/script/help.txt new file mode 100644 index 0000000..26a0194 --- /dev/null +++ b/src/cmd/go/testdata/script/help.txt @@ -0,0 +1,51 @@ +env GO111MODULE=off + +# go help shows overview. +go help +stdout 'Go is a tool' +stdout 'bug.*start a bug report' + +# go help bug shows usage for bug +go help bug +stdout 'usage: go bug' +stdout 'bug report' + +# go bug help is an error (bug takes no arguments) +! go bug help +stderr 'bug takes no arguments' + +# go help mod shows mod subcommands +go help mod +stdout 'go mod <command>' +stdout tidy + +# go help mod tidy explains tidy +go help mod tidy +stdout 'usage: go mod tidy' + +# go mod help tidy does too +go mod help tidy +stdout 'usage: go mod tidy' + +# go mod --help doesn't print help but at least suggests it. +! go mod --help +stderr 'Run ''go help mod'' for usage.' + +# Earlier versions of Go printed the same as 'go -h' here. +# Also make sure we print the short help line. +! go vet -h +stderr 'usage: go vet .*' +stderr 'Run ''go help vet'' for details.' +stderr 'Run ''go tool vet help'' for a full list of flags and analyzers.' +stderr 'Run ''go tool vet -help'' for an overview.' + +# Earlier versions of Go printed a large document here, instead of these two +# lines. +! go test -h +stderr 'usage: go test' +stderr 'Run ''go help test'' and ''go help testflag'' for details.' + +# go help get shows usage for get +go help get +stdout 'usage: go get' +stdout 'get when using GOPATH' diff --git a/src/cmd/go/testdata/script/import_cycle.txt b/src/cmd/go/testdata/script/import_cycle.txt new file mode 100644 index 0000000..901f43c --- /dev/null +++ b/src/cmd/go/testdata/script/import_cycle.txt @@ -0,0 +1,12 @@ +env GO111MODULE=off + +! go build selfimport +stderr -count=1 'import cycle not allowed' + +# 'go list' shouldn't hang forever. +go list -e -json selfimport + +-- $GOPATH/src/selfimport/selfimport.go -- +package selfimport + +import "selfimport" diff --git a/src/cmd/go/testdata/script/import_ignore.txt b/src/cmd/go/testdata/script/import_ignore.txt new file mode 100644 index 0000000..83a39a0 --- /dev/null +++ b/src/cmd/go/testdata/script/import_ignore.txt @@ -0,0 +1,11 @@ +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +-- go.mod -- +module m.test + +go 1.16 +-- .ignore.go -- +package p +import _ "golang.org/x/mod/modfile"
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/import_main.txt b/src/cmd/go/testdata/script/import_main.txt new file mode 100644 index 0000000..bc2cc4d --- /dev/null +++ b/src/cmd/go/testdata/script/import_main.txt @@ -0,0 +1,114 @@ +env GO111MODULE=off + +# Test that you cannot import a main package. +# See golang.org/issue/4210 and golang.org/issue/17475. + +[short] skip +cd $WORK + +# Importing package main from that package main's test should work. +go build x +go test -c x + +# Importing package main from another package should fail. +! go build p1 +stderr 'import "x" is a program, not an importable package' + +# ... even in that package's test. +go build p2 +! go test -c p2 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package's test is an xtest. +go build p3 +! go test p3 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main +go build p4 +! go test -c p4 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main using an xtest. +go build p5 +! go test -c p5 +stderr 'import "x" is a program, not an importable package' + +-- x/main.go -- +package main + +var X int + +func main() {} +-- x/main_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p1/p.go -- +package p1 + +import xmain "x" + +var _ = xmain.X +-- p2/p.go -- +package p2 +-- p2/p_test.go -- +package p2 + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p3/p.go -- +package p +-- p3/p_test.go -- +package p_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p4/p.go -- +package main + +func main() {} +-- p4/p_test.go -- +package main + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p5/p.go -- +package main +func main() {} +-- p5/p_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/install_cgo_excluded.txt b/src/cmd/go/testdata/script/install_cgo_excluded.txt new file mode 100644 index 0000000..5a2b460 --- /dev/null +++ b/src/cmd/go/testdata/script/install_cgo_excluded.txt @@ -0,0 +1,15 @@ +env CGO_ENABLED=0 + +! go install cgotest +stderr 'build constraints exclude all Go files' + +-- go.mod -- +module cgotest + +go 1.16 +-- m.go -- +package cgotest + +import "C" + +var _ C.int diff --git a/src/cmd/go/testdata/script/install_cleans_build.txt b/src/cmd/go/testdata/script/install_cleans_build.txt new file mode 100644 index 0000000..dc85eb8 --- /dev/null +++ b/src/cmd/go/testdata/script/install_cleans_build.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +[short] skip + +# 'go install' with no arguments should clean up after go build +cd mycmd +go build +exists mycmd$GOEXE +go install +! exists mycmd$GOEXE + +# 'go install mycmd' does not clean up, even in the mycmd directory +go build +exists mycmd$GOEXE +go install mycmd +exists mycmd$GOEXE + +# 'go install mycmd' should not clean up in an unrelated current directory either +cd .. +cp mycmd/mycmd$GOEXE mycmd$GOEXE +go install mycmd +exists mycmd$GOEXE + +-- mycmd/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/install_cmd_gobin.txt b/src/cmd/go/testdata/script/install_cmd_gobin.txt new file mode 100644 index 0000000..38fd66c --- /dev/null +++ b/src/cmd/go/testdata/script/install_cmd_gobin.txt @@ -0,0 +1,10 @@ +# Check that commands in cmd are install to $GOROOT/bin, not $GOBIN. +# Verifies golang.org/issue/32674. +env GOBIN=gobin +mkdir gobin +go list -f '{{.Target}}' cmd/go +stdout $GOROOT[/\\]bin[/\\]go$GOEXE + +# Check that tools are installed to $GOTOOLDIR, not $GOBIN. +go list -f '{{.Target}}' cmd/compile +stdout $GOROOT[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]compile$GOEXE diff --git a/src/cmd/go/testdata/script/install_cross_gobin.txt b/src/cmd/go/testdata/script/install_cross_gobin.txt new file mode 100644 index 0000000..33d48fc --- /dev/null +++ b/src/cmd/go/testdata/script/install_cross_gobin.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +[short] skip # rebuilds std for alternate architecture + +cd mycmd +go build mycmd + +# cross-compile install with implicit GOBIN=$GOPATH/bin can make subdirectory +env GOARCH=386 +[386] env GOARCH=amd64 +env GOOS=linux +go install mycmd +exists $GOPATH/bin/linux_$GOARCH/mycmd + +# cross-compile install with explicit GOBIN cannot make subdirectory +env GOBIN=$WORK/bin +! go install mycmd +! exists $GOBIN/linux_$GOARCH + +# The install directory for a cross-compiled standard command should include GOARCH. +go list -f '{{.Target}}' cmd/pack +stdout ${GOROOT}[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]pack$ + +-- mycmd/x.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt b/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt new file mode 100644 index 0000000..5e88f7b --- /dev/null +++ b/src/cmd/go/testdata/script/install_msan_and_race_require_cgo.txt @@ -0,0 +1,20 @@ +# Tests Issue #21895 + +env CGO_ENABLED=0 + +[race] ! go install -race triv.go +[race] stderr '-race requires cgo' +[race] ! stderr '-msan' + +[msan] ! go install -msan triv.go +[msan] stderr '-msan requires cgo' +[msan] ! stderr '-race' + +[asan] ! go install -asan triv.go +[asan] stderr '-asan requires cgo' +[asan] ! stderr '-msan' + +-- triv.go -- +package main + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/install_rebuild_gopath.txt b/src/cmd/go/testdata/script/install_rebuild_gopath.txt new file mode 100644 index 0000000..14a6c86 --- /dev/null +++ b/src/cmd/go/testdata/script/install_rebuild_gopath.txt @@ -0,0 +1,30 @@ +env GO111MODULE=off + +# GOPATH with p1 in d1, p2 in d2 +env GOPATH=$WORK/d1${:}$WORK/d2 + +# build & install p1 +go install -i p1 +! stale p1 p2 + +# modify p2 - p1 should appear stale +cp $WORK/p2x.go $WORK/d2/src/p2/p2.go +stale p1 p2 + +# build & install p1 again +go install -i p1 +! stale p1 p2 + +-- $WORK/d1/src/p1/p1.go -- +package p1 +import "p2" +func F() { p2.F() } + +-- $WORK/d2/src/p2/p2.go -- +package p2 +func F() {} + +-- $WORK/p2x.go -- +package p2 +func F() {} +func G() {} diff --git a/src/cmd/go/testdata/script/install_rebuild_removed.txt b/src/cmd/go/testdata/script/install_rebuild_removed.txt new file mode 100644 index 0000000..5db3778 --- /dev/null +++ b/src/cmd/go/testdata/script/install_rebuild_removed.txt @@ -0,0 +1,44 @@ +env GO111MODULE=off + +# go command should detect package staleness as source file set changes +go install mypkg +! stale mypkg + +# z.go was not compiled; removing it should NOT make mypkg stale +rm mypkg/z.go +! stale mypkg + +# y.go was compiled; removing it should make mypkg stale +rm mypkg/y.go +stale mypkg + +# go command should detect executable staleness too +go install mycmd +! stale mycmd +rm mycmd/z.go +! stale mycmd +rm mycmd/y.go +stale mycmd + +-- mypkg/x.go -- +package mypkg + +-- mypkg/y.go -- +package mypkg + +-- mypkg/z.go -- +// +build missingtag + +package mypkg + +-- mycmd/x.go -- +package main +func main() {} + +-- mycmd/y.go -- +package main + +-- mycmd/z.go -- +// +build missingtag + +package main diff --git a/src/cmd/go/testdata/script/install_relative_gobin_fail.txt b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt new file mode 100644 index 0000000..aa14524 --- /dev/null +++ b/src/cmd/go/testdata/script/install_relative_gobin_fail.txt @@ -0,0 +1,12 @@ +env GOBIN=. +! go install +stderr 'cannot install, GOBIN must be an absolute path' + +-- go.mod -- +module triv + +go 1.16 +-- triv.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/install_shadow_gopath.txt b/src/cmd/go/testdata/script/install_shadow_gopath.txt new file mode 100644 index 0000000..2039d9e --- /dev/null +++ b/src/cmd/go/testdata/script/install_shadow_gopath.txt @@ -0,0 +1,20 @@ +# Tests Issue #3562 +# go get foo.io (not foo.io/subdir) was not working consistently. + +[!net] skip + +env GO111MODULE=off +env GOPATH=$WORK/gopath1${:}$WORK/gopath2 + +mkdir $WORK/gopath1/src/test +mkdir $WORK/gopath2/src/test +cp main.go $WORK/gopath2/src/test/main.go +cd $WORK/gopath2/src/test + +! go install +stderr 'no install location for.*gopath2.src.test: hidden by .*gopath1.src.test' + +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/issue36000.txt b/src/cmd/go/testdata/script/issue36000.txt new file mode 100644 index 0000000..4173275 --- /dev/null +++ b/src/cmd/go/testdata/script/issue36000.txt @@ -0,0 +1,6 @@ +# Tests golang.org/issue/36000 + +[!cgo] skip + +# go env with CGO flags should not make NUL file +go env CGO_CFLAGS diff --git a/src/cmd/go/testdata/script/ldflag.txt b/src/cmd/go/testdata/script/ldflag.txt new file mode 100644 index 0000000..6ceb33b --- /dev/null +++ b/src/cmd/go/testdata/script/ldflag.txt @@ -0,0 +1,44 @@ +# Issue #42565 + +[!cgo] skip + +# We can't build package bad, which uses #cgo LDFLAGS. +cd bad +! go build +stderr no-such-warning + +# We can build package ok with the same flags in CGO_LDFLAGS. +env CGO_LDFLAGS=-Wno-such-warning -Wno-unknown-warning-option +cd ../ok +go build + +# Build a main program that actually uses LDFLAGS. +cd .. +go build -ldflags=-v + +# Because we passed -v the Go linker should print the external linker +# command which should include the flag we passed in CGO_LDFLAGS. +stderr no-such-warning + +-- go.mod -- +module ldflag + +-- bad/bad.go -- +package bad + +// #cgo LDFLAGS: -Wno-such-warning -Wno-unknown-warning +import "C" + +func F() {} +-- ok/ok.go -- +package ok + +import "C" + +func F() {} +-- main.go -- +package main + +import _ "ldflag/ok" + +func main() {} diff --git a/src/cmd/go/testdata/script/link_external_undef.txt b/src/cmd/go/testdata/script/link_external_undef.txt new file mode 100644 index 0000000..d86b3a3 --- /dev/null +++ b/src/cmd/go/testdata/script/link_external_undef.txt @@ -0,0 +1,48 @@ + +# Test case for issue 47993, in which the linker crashes +# on a bad input instead of issuing an error and exiting. + +# This test requires external linking, so use cgo as a proxy +[!cgo] skip + +! go build -ldflags='-linkmode=external' . +! stderr 'panic' +stderr '^.*unreachable sym in relocation.*' + +-- go.mod -- + +module issue47993 + +go 1.16 + +-- main.go -- + +package main + +type M struct { + b bool +} + +// Note the body-less func def here. This is what causes the problems. +func (m *M) run(fp func()) + +func doit(m *M) { + InAsm() + m.run(func() { + }) +} + +func main() { + m := &M{true} + doit(m) +} + +func InAsm() + +-- main.s -- + +// Add an assembly function so as to leave open the possibility +// that body-less functions in Go might be defined in assembly. + +// Currently we just need an empty file here. + diff --git a/src/cmd/go/testdata/script/link_matching_actionid.txt b/src/cmd/go/testdata/script/link_matching_actionid.txt new file mode 100644 index 0000000..b8d423d --- /dev/null +++ b/src/cmd/go/testdata/script/link_matching_actionid.txt @@ -0,0 +1,38 @@ +# Checks that an identical binary is built with -trimpath from the same +# source files, with GOROOT in two different locations. +# Verifies golang.org/issue/38989 + +[short] skip +[!symlink] skip + +# Symlink the compiler to a local path +env GOROOT=$WORK/goroot1 +symlink $GOROOT -> $TESTGO_GOROOT + +# Set up fresh GOCACHE +env GOCACHE=$WORK/gocache1 +mkdir $GOCACHE + +# Build a simple binary +go build -o binary1 -trimpath -x main.go + +# Now repeat the same process with the compiler at a different local path +env GOROOT=$WORK/goroot2 +symlink $GOROOT -> $TESTGO_GOROOT + +env GOCACHE=$WORK/gocache2 +mkdir $GOCACHE + +go build -o binary2 -trimpath -x main.go + +# Check that the binaries match exactly +go tool buildid binary1 +cp stdout buildid1 +go tool buildid binary2 +cp stdout buildid2 +cmp buildid1 buildid2 + + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt new file mode 100644 index 0000000..8a8cb4a --- /dev/null +++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt @@ -0,0 +1,43 @@ +# Test that we can use the external linker with a host syso file that is +# embedded in a package, that is referenced by a Go assembly function. +# See issue 33139. +[!gc] skip +[!cgo] skip + +# External linking is not supported on linux/ppc64. +# See: https://github.com/golang/go/issues/8912 +[linux] [ppc64] skip + +cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c +go build -ldflags='-linkmode=external' ./cmd/main.go + +-- go.mod -- +module m + +go 1.16 +-- syso/objTest.s -- +#include "textflag.h" + +TEXT ·ObjTest(SB), NOSPLIT, $0 + // We do not actually execute this function in the test above, thus + // there is no stack frame setup here. + // We only care about Go build and/or link errors when referencing + // the objTestImpl symbol in the syso file. + JMP objTestImpl(SB) + +-- syso/pkg.go -- +package syso + +func ObjTest() + +-- syso/src/objTestImpl.c -- +void objTestImpl() { /* Empty */ } + +-- cmd/main.go -- +package main + +import "m/syso" + +func main() { + syso.ObjTest() +} diff --git a/src/cmd/go/testdata/script/linkname.txt b/src/cmd/go/testdata/script/linkname.txt new file mode 100644 index 0000000..1133659 --- /dev/null +++ b/src/cmd/go/testdata/script/linkname.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# check for linker name in error message about linker crash +[!gc] skip +! go build -ldflags=-crash_for_testing x.go +stderr [\\/]tool[\\/].*[\\/]link + +-- x.go -- +package main; func main() {} diff --git a/src/cmd/go/testdata/script/list_all_gobuild.txt b/src/cmd/go/testdata/script/list_all_gobuild.txt new file mode 100644 index 0000000..e0a4739 --- /dev/null +++ b/src/cmd/go/testdata/script/list_all_gobuild.txt @@ -0,0 +1,41 @@ +# go list all should work with GOOS=linux because all packages build on Linux +env GOOS=linux +go list all + +# go list all should work with GOOS=darwin, but it used to fail because +# in the absence of //go:build support, p looked like it needed q +# (p_test.go was not properly excluded), and q was Linux-only. +# +# Also testing with r and s that +build lines keep working. +env GOOS=darwin +go list all + +-- go.mod -- +go 1.17 +module m + +-- p/p.go -- +package p + +-- p/p_test.go -- +//go:build linux + +package p + +import "m/q" + +-- q/q_linux.go -- +package q + +-- r/r.go -- +package r + +-- r/r_test.go -- +// +build linux + +package r + +import "m/s" + +-- s/s_linux.go -- +package s diff --git a/src/cmd/go/testdata/script/list_ambiguous_path.txt b/src/cmd/go/testdata/script/list_ambiguous_path.txt new file mode 100644 index 0000000..82dde45 --- /dev/null +++ b/src/cmd/go/testdata/script/list_ambiguous_path.txt @@ -0,0 +1,38 @@ +# Ensures that we can correctly list package patterns ending in '.go'. +# See golang.org/issue/34653. + +# A single pattern for a package ending in '.go'. +go list ./foo.go +stdout '^test/foo.go$' + +# Multiple patterns for packages including one ending in '.go'. +go list ./bar ./foo.go +stdout '^test/bar$' +stdout '^test/foo.go$' + +# A single pattern for a Go file. +go list ./a.go +stdout '^command-line-arguments$' + +# A single typo-ed pattern for a Go file. This should +# treat the wrong pattern as if it were a package. +! go list ./foo.go/b.go +stderr '^stat .*[/\\]foo\.go[/\\]b\.go: directory not found$' + +# Multiple patterns for Go files with a typo. This should +# treat the wrong pattern as if it were a nonexistent file. +! go list ./foo.go/a.go ./foo.go/b.go +[plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist' +[windows] stderr './foo.go/b.go: The system cannot find the file specified' +[!plan9] [!windows] stderr './foo.go/b.go: no such file or directory' + +-- a.go -- +package main +-- bar/a.go -- +package bar +-- foo.go/a.go -- +package foo.go +-- go.mod -- +module "test" + +go 1.13 diff --git a/src/cmd/go/testdata/script/list_bad_import.txt b/src/cmd/go/testdata/script/list_bad_import.txt new file mode 100644 index 0000000..dbec350 --- /dev/null +++ b/src/cmd/go/testdata/script/list_bad_import.txt @@ -0,0 +1,72 @@ +env GO111MODULE=off +[short] skip + +# This test matches mod_list_bad_import, but in GOPATH mode. +# Please keep them in sync. + +env GO111MODULE=off +cd example.com + +# Without -e, listing an otherwise-valid package with an unsatisfied direct import should fail. +# BUG: Today it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/direct +! stdout ^error +stdout 'incomplete' +stdout 'bad dep: .*example.com[/\\]notfound' + +# Listing with -deps should also fail. +! go list -deps example.com/direct +stderr example.com[/\\]notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct +stdout example.com/notfound + + +# Listing an otherwise-valid package that imports some *other* package with an +# unsatisfied import should also fail. +# BUG: Today, it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/indirect +! stdout ^error +stdout incomplete +stdout 'bad dep: .*example.com[/\\]notfound' + +# Again, -deps should fail. +! go list -deps example.com/indirect +stderr example.com[/\\]notfound + +# But -deps -e should succeed. +go list -e -deps example.com/indirect +stdout example.com/notfound + + +# Listing the missing dependency directly should fail outright... +! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stderr 'no Go files in .*example.com[/\\]notfound' +! stdout error +! stdout incomplete + +# ...but listing with -e should succeed. +go list -e -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stdout error +stdout incomplete + + +# The pattern "all" should match only packages that actually exist, +# ignoring those whose existence is merely implied by imports. +go list -e -f '{{.ImportPath}}' all +stdout example.com/direct +stdout example.com/indirect +! stdout example.com/notfound + + +-- example.com/direct/direct.go -- +package direct +import _ "example.com/notfound" + +-- example.com/indirect/indirect.go -- +package indirect +import _ "example.com/direct" + +-- example.com/notfound/README -- +This directory intentionally left blank. diff --git a/src/cmd/go/testdata/script/list_case_collision.txt b/src/cmd/go/testdata/script/list_case_collision.txt new file mode 100644 index 0000000..181a202 --- /dev/null +++ b/src/cmd/go/testdata/script/list_case_collision.txt @@ -0,0 +1,41 @@ +# Tests golang.org/issue/4773 + +go list -json example/a +stdout 'case-insensitive import collision' + +! go build example/a +stderr 'case-insensitive import collision' + +# List files explicitly on command line, to encounter case-checking +# logic even on case-insensitive filesystems. +cp b/file.go b/FILE.go # no-op on case-insensitive filesystems +! go list b/file.go b/FILE.go +stderr 'case-insensitive file name collision' + +mkdir a/Pkg # no-op on case-insensitive filesystems +cp a/pkg/pkg.go a/Pkg/pkg.go # no-op on case-insensitive filesystems +! go list example/a/pkg example/a/Pkg + +# Test that the path reported with an indirect import is correct. +cp b/file.go b/FILE.go +[case-sensitive] ! go build example/c +[case-sensitive] stderr '^package example/c\n\timports example/b: case-insensitive file name collision: "FILE.go" and "file.go"$' + +-- go.mod -- +module example + +go 1.16 +-- a/a.go -- +package p +import ( + _ "example/a/pkg" + _ "example/a/Pkg" +) +-- a/pkg/pkg.go -- +package pkg +-- b/file.go -- +package b +-- c/c.go -- +package c + +import _ "example/b" diff --git a/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt new file mode 100644 index 0000000..30effb1 --- /dev/null +++ b/src/cmd/go/testdata/script/list_cgo_compiled_importmap.txt @@ -0,0 +1,38 @@ +# Regression test for https://golang.org/issue/46462. +# +# The "runtime/cgo" import found in synthesized .go files (reported in +# the CompiledGoFiles field) should have a corresponding entry in the +# ImportMap field when a runtime/cgo variant (such as a test variant) +# will be used. + +[short] skip # -compiled can be slow (because it compiles things) +[!cgo] skip + +env CGO_ENABLED=1 +env GOFLAGS=-tags=netcgo # Force net to use cgo even on Windows. + + +# "runtime/cgo [runtime.test]" appears in the test dependencies of "runtime", +# because "runtime/cgo" itself depends on "runtime" + +go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .Imports}}{{end}}' runtime + + # Control case: the explicitly-imported package "sync" is a test variant, + # because "sync" depends on "runtime". +stdout '"sync \[runtime\.test\]"' +! stdout '"sync"' + + # Experiment: the implicitly-imported package "runtime/cgo" is also a test variant, + # because "runtime/cgo" also depends on "runtime". +stdout '"runtime/cgo \[runtime\.test\]"' +! stdout '"runtime/cgo"' + + +# Because the import of "runtime/cgo" in the cgo-generated file actually refers +# to "runtime/cgo [runtime.test]", the latter should be listed in the ImportMap. +# BUG(#46462): Today, it is not. + +go list -deps -test -compiled -f '{{if eq .ImportPath "net [runtime.test]"}}{{printf "%q" .ImportMap}}{{end}}' runtime + +stdout '"sync":"sync \[runtime\.test\]"' # control +stdout '"runtime/cgo":"runtime/cgo \[runtime\.test\]"' # experiment diff --git a/src/cmd/go/testdata/script/list_compiled_imports.txt b/src/cmd/go/testdata/script/list_compiled_imports.txt new file mode 100644 index 0000000..7780b07 --- /dev/null +++ b/src/cmd/go/testdata/script/list_compiled_imports.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off + +[!cgo] skip + +# go list should report import "C" +cd x +go list -f '{{.Imports}}' +! stdout runtime/cgo +! stdout unsafe +! stdout syscall +stdout C +stdout unicode +stdout unicode/utf16 + +# go list -compiled should report imports in compiled files as well, +# adding "runtime/cgo", "unsafe", and "syscall" but not dropping "C". +go list -compiled -f '{{.Imports}}' +stdout runtime/cgo +stdout unsafe +stdout syscall +stdout C +stdout unicode +stdout unicode/utf16 + +-- x/x.go -- +package x +import "C" +import "unicode" // does not use unsafe, syscall, runtime/cgo, unicode/utf16 +-- x/x1.go -- +package x +import "unicode/utf16" // does not use unsafe, syscall, runtime/cgo, unicode diff --git a/src/cmd/go/testdata/script/list_constraints.txt b/src/cmd/go/testdata/script/list_constraints.txt new file mode 100644 index 0000000..7115c36 --- /dev/null +++ b/src/cmd/go/testdata/script/list_constraints.txt @@ -0,0 +1,86 @@ +# Check that files and their imports are not included in 'go list' output +# when they are excluded by build constraints. + +# Linux and cgo files should be included when building in that configuration. +env GOOS=linux +env GOARCH=amd64 +env CGO_ENABLED=1 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^cgotag.go empty.go suffix_linux.go tag.go $' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +stdout '^cgoimport.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^C cgoimport cgotag suffix tag $' + +# Disabling cgo should exclude cgo files and their imports. +env CGO_ENABLED=0 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout 'empty.go suffix_linux.go tag.go' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +! stdout . +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^suffix tag $' + +# Changing OS should exclude linux sources. +env GOOS=darwin +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^$' + +# Enabling a tag should include files that require it. +go list -tags=extra -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go extra.go $' +go list -tags=extra -f '{{range .Imports}}{{.}} {{end}}' +stdout '^extra $' + +# Packages that require a tag should not be listed unless the tag is on. +! go list ./tagonly +go list -tags=extra ./tagonly +stdout m/tagonly + +-- go.mod -- +module m + +go 1.13 + +-- empty.go -- +package p + +-- extra.go -- +// +build extra + +package p + +import _ "extra" + +-- suffix_linux.go -- +package p + +import _ "suffix" + +-- tag.go -- +// +build linux + +package p + +import _ "tag" + +-- cgotag.go -- +// +build cgo + +package p + +import _ "cgotag" + +-- cgoimport.go -- +package p + +import "C" + +import _ "cgoimport" + +-- tagonly/tagonly.go -- +// +build extra + +package tagonly diff --git a/src/cmd/go/testdata/script/list_dedup_packages.txt b/src/cmd/go/testdata/script/list_dedup_packages.txt new file mode 100644 index 0000000..30c68dd --- /dev/null +++ b/src/cmd/go/testdata/script/list_dedup_packages.txt @@ -0,0 +1,31 @@ +# Setup +env GO111MODULE=off +mkdir $WORK/tmp/testdata/src/xtestonly +cp f.go $WORK/tmp/testdata/src/xtestonly/f.go +cp f_test.go $WORK/tmp/testdata/src/xtestonly/f_test.go +env GOPATH=$WORK/tmp/testdata +cd $WORK + +# Check output of go list to ensure no duplicates +go list xtestonly ./tmp/testdata/src/xtestonly/... +cmp stdout $WORK/gopath/src/wantstdout + +-- wantstdout -- +xtestonly +-- f.go -- +package xtestonly + +func F() int { return 42 } +-- f_test.go -- +package xtestonly_test + +import ( + "testing" + "xtestonly" +) + +func TestF(t *testing.T) { + if x := xtestonly.F(); x != 42 { + t.Errorf("f.F() = %d, want 42", x) + } +} diff --git a/src/cmd/go/testdata/script/list_err_cycle.txt b/src/cmd/go/testdata/script/list_err_cycle.txt new file mode 100644 index 0000000..44b82a6 --- /dev/null +++ b/src/cmd/go/testdata/script/list_err_cycle.txt @@ -0,0 +1,15 @@ +# Check that we don't get infinite recursion when loading a package with +# an import cycle and another error. Verifies #25830. +! go list +stderr 'found packages a \(a.go\) and b \(b.go\)' + +-- go.mod -- +module errcycle + +go 1.16 +-- a.go -- +package a + +import _ "errcycle" +-- b.go -- +package b
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_err_stack.txt b/src/cmd/go/testdata/script/list_err_stack.txt new file mode 100644 index 0000000..a7be9fd --- /dev/null +++ b/src/cmd/go/testdata/script/list_err_stack.txt @@ -0,0 +1,27 @@ + +# golang.org/issue/40544: regression in error stacks for parse errors + +env GO111MODULE=off +cd sandbox/foo +go list -e -json . +stdout '"sandbox/foo"' +stdout '"sandbox/bar"' +stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"' +stdout '"Err": "expected ''package'', found ackage"' + +env GO111MODULE=on +go list -e -json . +stdout '"sandbox/foo"' +stdout '"sandbox/bar"' +stdout '"Pos": "..(/|\\\\)bar(/|\\\\)bar.go:1:1"' +stdout '"Err": "expected ''package'', found ackage"' + +-- sandbox/go.mod -- +module sandbox + +-- sandbox/foo/foo.go -- +package pkg + +import "sandbox/bar" +-- sandbox/bar/bar.go -- +ackage bar
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_find.txt b/src/cmd/go/testdata/script/list_find.txt new file mode 100644 index 0000000..d450fc9 --- /dev/null +++ b/src/cmd/go/testdata/script/list_find.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +# go list -find should not report imports + +go list -f {{.Incomplete}} x/y/z... # should probably exit non-zero but never has +stdout true +go list -find -f '{{.Incomplete}} {{.Imports}}' x/y/z... +stdout '^false \[\]' + +# go list -find -compiled should use cached sources the second time it's run. +# It might not find the same cached sources as "go build", but the sources +# should be identical. "go build" derives action IDs (which are used as cache +# keys) from dependencies' action IDs. "go list -find" won't know what the +# dependencies are, so it's can't construct the same action IDs. +[short] skip +go list -find -compiled net +go list -find -compiled -x net +! stderr 'cgo' + +-- x/y/z/z.go -- +package z +import "does/not/exist" diff --git a/src/cmd/go/testdata/script/list_find_nodeps.txt b/src/cmd/go/testdata/script/list_find_nodeps.txt new file mode 100644 index 0000000..e08ce78 --- /dev/null +++ b/src/cmd/go/testdata/script/list_find_nodeps.txt @@ -0,0 +1,49 @@ +# Issue #46092 +# go list -find should always return a package with an empty Deps list + +# The linker loads implicit dependencies +go list -find -f {{.Deps}} ./cmd +stdout '\[\]' + +# Cgo translation may add imports of "unsafe", "runtime/cgo" and "syscall" +go list -find -f {{.Deps}} ./cgo +stdout '\[\]' + +# SWIG adds imports of some standard packages +go list -find -f {{.Deps}} ./swig +stdout '\[\]' + +-- go.mod -- +module listfind + +-- cmd/main.go -- +package main + +func main() {} + +-- cgo/pkg.go -- +package cgopkg + +/* +#include <limits.h> +*/ +import "C" + +func F() { + println(C.INT_MAX) +} + +-- cgo/pkg_notcgo.go -- +//go:build !cgo +// +build !cgo + +package cgopkg + +func F() { + println(0) +} + +-- swig/pkg.go -- +package swigpkg + +-- swig/a.swigcxx -- diff --git a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt new file mode 100644 index 0000000..6e48d7b --- /dev/null +++ b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt @@ -0,0 +1,76 @@ +# Return an error if the user tries to list a go source file directly in $GOROOT/src. +# Tests golang.org/issue/36587 + +env GOROOT=$WORK/goroot +env GOPATH=$WORK/gopath + +go env GOROOT +stdout $WORK[/\\]goroot + +# switch to GOROOT/src +cd $GOROOT/src + +# In module mode, 'go list ./...' should not treat .go files in GOROOT/src as an +# importable package, since that directory has no valid import path. +env GO111MODULE=on +go list ... +stdout -count=1 '^.+$' +stdout '^fmt$' +! stdout foo + +go list ./... +stdout -count=1 '^.+$' +stdout '^fmt$' +! stdout foo + +go list std +stdout -count=1 '^.+$' +stdout '^fmt$' + +! go list . +stderr '^GOROOT/src is not an importable package$' + +# In GOPATH mode, 'go list ./...' should synthesize a legacy GOPATH-mode path — +# not a standard-library or empty path — for the errant package. +env GO111MODULE=off +go list ./... +stdout -count=2 '^.+$' # Both 'fmt' and GOROOT/src should be listed. +stdout '^fmt$' +[!windows] stdout ^_$WORK/goroot/src$ +[windows] stdout goroot/src$ # On windows the ":" in the volume name is mangled + +go list ... +! stdout goroot/src + +go list std +! stdout goroot/src + +go list . +[!windows] stdout ^_$WORK/goroot/src$ +[windows] stdout goroot/src$ + +# switch to GOPATH/src +cd $GOPATH/src + +# GO111MODULE=off,GOPATH +env GO111MODULE=off +go list ./... +[!windows] stdout ^_$WORK/gopath/src$ +[windows] stdout gopath/src$ + +go list all +! stdout gopath/src + +-- $WORK/goroot/src/go.mod -- +module std + +go 1.14 +-- $WORK/goroot/src/foo.go -- +package foo +-- $WORK/goroot/src/fmt/fmt.go -- +package fmt +-- $WORK/goroot/src/cmd/README -- +This directory must exist in order for the 'cmd' pattern to have something to +match against. +-- $GOPATH/src/foo.go -- +package foo diff --git a/src/cmd/go/testdata/script/list_gomod_in_gopath.txt b/src/cmd/go/testdata/script/list_gomod_in_gopath.txt new file mode 100644 index 0000000..064f33a --- /dev/null +++ b/src/cmd/go/testdata/script/list_gomod_in_gopath.txt @@ -0,0 +1,23 @@ +# Issue 46119 + +# When a module is inside a GOPATH workspace, Package.Root should be set to +# Module.Dir instead of $GOPATH/src. + +env GOPATH=$WORK/tmp +cd $WORK/tmp/src/test + +go list -f {{.Root}} +stdout ^$PWD$ + +# Were we really inside a GOPATH workspace? +env GO111MODULE=off +go list -f {{.Root}} +stdout ^$WORK/tmp$ + +-- $WORK/tmp/src/test/go.mod -- +module test + +-- $WORK/tmp/src/test/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/list_importmap.txt b/src/cmd/go/testdata/script/list_importmap.txt new file mode 100644 index 0000000..f424b98 --- /dev/null +++ b/src/cmd/go/testdata/script/list_importmap.txt @@ -0,0 +1,27 @@ +env GO111MODULE=off + +# gccgo does not have standard packages. +[gccgo] skip + +# fmt should have no rewritten imports. +# The import from a/b should map c/d to a's vendor directory. +go list -f '{{.ImportPath}}: {{.ImportMap}}' fmt a/b +stdout 'fmt: map\[\]' +stdout 'a/b: map\[c/d:a/vendor/c/d\]' + +# flag [fmt.test] should import fmt [fmt.test] as fmt +# fmt.test should import testing [fmt.test] as testing +# fmt.test should not import a modified os +go list -deps -test -f '{{.ImportPath}} MAP: {{.ImportMap}}{{"\n"}}{{.ImportPath}} IMPORT: {{.Imports}}' fmt +stdout '^flag \[fmt\.test\] MAP: map\[fmt:fmt \[fmt\.test\]\]' +stdout '^fmt\.test MAP: map\[(.* )?testing:testing \[fmt\.test\]' +! stdout '^fmt\.test MAP: map\[(.* )?os:' +stdout '^fmt\.test IMPORT: \[fmt \[fmt\.test\] fmt_test \[fmt\.test\] os reflect testing \[fmt\.test\] testing/internal/testdeps \[fmt\.test\]\]' + + +-- a/b/b.go -- +package b + +import _ "c/d" +-- a/vendor/c/d/d.go -- +package d diff --git a/src/cmd/go/testdata/script/list_json_with_f.txt b/src/cmd/go/testdata/script/list_json_with_f.txt new file mode 100644 index 0000000..2011a6e --- /dev/null +++ b/src/cmd/go/testdata/script/list_json_with_f.txt @@ -0,0 +1,20 @@ +[short] skip + +# list -json should generate output on stdout +go list -json ./... +stdout . +# list -f should generate output on stdout +go list -f '{{.}}' ./... +stdout . + +# test passing first -json then -f +! go list -json -f '{{.}}' ./... +stderr '^go list -f cannot be used with -json$' + +# test passing first -f then -json +! go list -f '{{.}}' -json ./... +stderr '^go list -f cannot be used with -json$' +-- go.mod -- +module m +-- list_test.go -- +package list_test diff --git a/src/cmd/go/testdata/script/list_linkshared.txt b/src/cmd/go/testdata/script/list_linkshared.txt new file mode 100644 index 0000000..baae1e2 --- /dev/null +++ b/src/cmd/go/testdata/script/list_linkshared.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# golang.org/issue/35759: 'go list -linkshared' +# panicked if invoked on a test-only package. + +[!buildmode:shared] skip + +go list -f '{{.ImportPath}}: {{.Target}} {{.Shlib}}' -linkshared . +stdout '^example.com: $' + +-- go.mod -- +module example.com + +go 1.14 +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/list_load_err.txt b/src/cmd/go/testdata/script/list_load_err.txt new file mode 100644 index 0000000..0cfa7fb --- /dev/null +++ b/src/cmd/go/testdata/script/list_load_err.txt @@ -0,0 +1,95 @@ +# go list -e -deps should list imports from any file it can read, even if +# other files in the same package cause go/build.Import to return an error. +# Verfifies golang.org/issue/38568 + +go list -e -deps ./scan +stdout m/want + +go list -e -deps ./multi +stdout m/want + +go list -e -deps ./constraint +stdout m/want + +[cgo] go list -e -test -deps ./cgotest +[cgo] stdout m/want + +[cgo] go list -e -deps ./cgoflag +[cgo] stdout m/want + + +# go list -e should include files with errors in GoFiles, TestGoFiles, and +# other lists, assuming they match constraints. +# Verifies golang.org/issue/39986 +go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./scan +stdout '^good.go,scan.go,$' + +go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./multi +stdout '^a.go,b.go,$' + +go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./constraint +stdout '^good.go,$' +go list -e -f '{{range .IgnoredGoFiles}}{{.}},{{end}}' ./constraint +stdout '^constraint.go,$' + +[cgo] go list -e -f '{{range .XTestGoFiles}}{{.}},{{end}}' ./cgotest +[cgo] stdout '^cgo_test.go,$' + +[cgo] go list -e -f '{{range .GoFiles}}{{.}},{{end}}' ./cgoflag +[cgo] stdout '^cgoflag.go,$' + +-- go.mod -- +module m + +go 1.14 + +-- want/want.go -- +package want + +-- scan/scan.go -- +// scan error +ʕ◔ϖ◔ʔ + +-- scan/good.go -- +package scan + +import _ "m/want" + +-- multi/a.go -- +package a + +-- multi/b.go -- +package b + +import _ "m/want" + +-- constraint/constraint.go -- +// +build !!nope + +package constraint + +-- constraint/good.go -- +package constraint + +import _ "m/want" + +-- cgotest/cgo_test.go -- +package cgo_test + +// cgo is not allowed in tests. +// See golang.org/issue/18647 + +import "C" +import ( + "testing" + _ "m/want" +) + +func Test(t *testing.T) {} + +-- cgoflag/cgoflag.go -- +package cgoflag + +// #cgo ʕ◔ϖ◔ʔ: + +import _ "m/want" diff --git a/src/cmd/go/testdata/script/list_module_when_error.txt b/src/cmd/go/testdata/script/list_module_when_error.txt new file mode 100644 index 0000000..844164c --- /dev/null +++ b/src/cmd/go/testdata/script/list_module_when_error.txt @@ -0,0 +1,19 @@ +# The Module field should be populated even if there is an error loading the package. + +env GO111MODULE=on + +go list -e -f {{.Module}} +stdout '^mod.com$' + +-- go.mod -- +module mod.com + +go 1.16 + +-- blah.go -- +package blah + +import _ "embed" + +//go:embed README.md +var readme string diff --git a/src/cmd/go/testdata/script/list_overlay.txt b/src/cmd/go/testdata/script/list_overlay.txt new file mode 100644 index 0000000..1153975 --- /dev/null +++ b/src/cmd/go/testdata/script/list_overlay.txt @@ -0,0 +1,63 @@ +# Test listing with overlays + +# Overlay in an existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' . +stdout '^\[f.go\]$' + +# Overlays in a non-existing directory +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir +stdout '^\[g.go\]$' + +# Overlays in an existing directory with already existing files +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir2 +stdout '^\[h.go i.go\]$' + +# Overlay that removes a file from a directory +! go list ./dir3 # contains a file without a package statement +go list -overlay overlay.json -f '{{.GoFiles}}' ./dir3 # overlay removes that file + +# Walking through an overlay +go list -overlay overlay.json ./... +cmp stdout want-list.txt + +# TODO(#39958): assembly files, C files, files that require cgo preprocessing + +-- want-list.txt -- +m +m/dir +m/dir2 +m/dir3 +-- go.mod -- +// TODO(#39958): Support and test overlays including go.mod itself (especially if mod=readonly) +module m + +go 1.16 + +-- dir2/h.go -- +package dir2 + +-- dir3/good.go -- +package dir3 +-- dir3/bad.go -- +// no package statement +-- overlay.json -- +{ + "Replace": { + "f.go": "overlay/f_go", + "dir/g.go": "overlay/dir_g_go", + "dir2/i.go": "overlay/dir2_i_go", + "dir3/bad.go": "" + } +} +-- overlay/f_go -- +package m + +func f() { +} +-- overlay/dir_g_go -- +package m + +func g() { +} +-- overlay/dir2_i_go -- +package dir2 diff --git a/src/cmd/go/testdata/script/list_parse_err.txt b/src/cmd/go/testdata/script/list_parse_err.txt new file mode 100644 index 0000000..3c53458 --- /dev/null +++ b/src/cmd/go/testdata/script/list_parse_err.txt @@ -0,0 +1,45 @@ +# 'go list' without -e should fail and print errors on stderr. +! go list ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -f '{{range .Imports}}{{.}} {{end}}' ./p +stderr '^p[/\\]b.go:2:2: expected ''package'', found ''EOF''$' +! go list -test ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' +! go list -test -f '{{range .Imports}}{{.}} {{end}}' ./t +stderr '^can''t load test package: t[/\\]t_test.go:8:1: expected declaration, found ʕ' + +# 'go list -e' should report imports, even if some files have parse errors +# before the import block. +go list -e -f '{{range .Imports}}{{.}} {{end}}' ./p +stdout '^fmt ' + +# 'go list' should report the position of the error if there's only one. +go list -e -f '{{.Error.Pos}} => {{.Error.Err}}' ./p +stdout 'b.go:[0-9:]+ => expected ''package'', found ''EOF''' + +# 'go test' should report the position of the error if there's only one. +go list -e -test -f '{{if .Error}}{{.Error.Pos}} => {{.Error.Err}}{{end}}' ./t +stdout 't_test.go:[0-9:]+ => expected declaration, found ʕ' + +-- go.mod -- +module m + +go 1.13 + +-- p/a.go -- +package a + +import "fmt" + +-- p/b.go -- +// no package statement + +-- t/t_test.go -- +package t + +import "testing" + +func Test(t *testing.T) {} + +// scan error +ʕ◔ϖ◔ʔ diff --git a/src/cmd/go/testdata/script/list_permissions.txt b/src/cmd/go/testdata/script/list_permissions.txt new file mode 100644 index 0000000..f65896c --- /dev/null +++ b/src/cmd/go/testdata/script/list_permissions.txt @@ -0,0 +1,84 @@ +env GO111MODULE=on + +# Establish baseline behavior, before mucking with file permissions. + +go list ./noread/... +stdout '^example.com/noread$' + +go list example.com/noread/... +stdout '^example.com/noread$' + +go list ./empty/... +stderr 'matched no packages' + +[root] stop # Root typically ignores file permissions. + +# Make the directory ./noread unreadable, and verify that 'go list' reports an +# explicit error for a pattern that should match it (rather than treating it as +# equivalent to an empty directory). + +[windows] skip # Does not have Unix-style directory permissions. +[plan9] skip # Might not have Unix-style directory permissions. + +chmod 000 noread + +# Check explicit paths. + +! go list ./noread +! stdout '^example.com/noread$' +! stderr 'matched no packages' + +! go list example.com/noread +! stdout '^example.com/noread$' +! stderr 'matched no packages' + +# Check filesystem-relative patterns. + +! go list ./... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ./...: ' + +! go list ./noread/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ./noread/...: ' + + +# Check module-prefix patterns. + +! go list example.com/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern example.com/...: ' + +! go list example.com/noread/... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern example.com/noread/...: ' + + +[short] stop + +# Check global patterns, which should still +# fail due to errors in the local module. + +! go list all +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern all: ' + +! go list ... +! stdout '^example.com/noread$' +! stderr 'matched no packages' +stderr '^pattern ...: ' + + +-- go.mod -- +module example.com +go 1.15 +-- noread/noread.go -- +// Package noread exists, but will be made unreadable. +package noread +-- empty/README.txt -- +This directory intentionally left empty. diff --git a/src/cmd/go/testdata/script/list_reserved.txt b/src/cmd/go/testdata/script/list_reserved.txt new file mode 100644 index 0000000..b9c5361 --- /dev/null +++ b/src/cmd/go/testdata/script/list_reserved.txt @@ -0,0 +1,7 @@ +# https://golang.org/issue/37641: the paths "example" and "test" are reserved +# for end users, and must never exist in the standard library. + +go list example/... test/... +stderr 'go: warning: "example/..." matched no packages$' +stderr 'go: warning: "test/..." matched no packages$' +! stdout . diff --git a/src/cmd/go/testdata/script/list_shadow.txt b/src/cmd/go/testdata/script/list_shadow.txt new file mode 100644 index 0000000..660508d --- /dev/null +++ b/src/cmd/go/testdata/script/list_shadow.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off +env GOPATH=$WORK/gopath/src/shadow/root1${:}$WORK/gopath/src/shadow/root2 + +# The math in root1 is not "math" because the standard math is. +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root1/src/math +stdout '^\(.*(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)math\) \('$GOROOT'(\\|/)?src(\\|/)math\)$' + +# The foo in root1 is "foo". +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root1/src/foo +stdout '^\(foo\) \(\)$' + +# The foo in root2 is not "foo" because the foo in root1 got there first. +go list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./shadow/root2/src/foo +stdout '^\(.*gopath(\\|/)src(\\|/)shadow(\\|/)root2(\\|/)src(\\|/)foo\) \('$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)foo\)$' + +# The error for go install should mention the conflicting directory. +! go install -n ./shadow/root2/src/foo +stderr 'go: no install location for '$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root2(\\|/)src(\\|/)foo: hidden by '$WORK'(\\|/)?gopath(\\|/)src(\\|/)shadow(\\|/)root1(\\|/)src(\\|/)foo' + +-- shadow/root1/src/foo/foo.go -- +package foo +-- shadow/root1/src/math/math.go -- +package math +-- shadow/root2/src/foo/foo.go -- +package foo
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/list_split_main.txt b/src/cmd/go/testdata/script/list_split_main.txt new file mode 100644 index 0000000..74e7d5d --- /dev/null +++ b/src/cmd/go/testdata/script/list_split_main.txt @@ -0,0 +1,25 @@ +# This test checks that a "main" package with an external test package +# is recompiled only once. +# Verifies golang.org/issue/34321. + +env GO111MODULE=off + +go list -e -test -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' pkg +cmp stdout want + +-- $GOPATH/src/pkg/pkg.go -- +package main + +func main() {} + +-- $GOPATH/src/pkg/pkg_test.go -- +package main + +import "testing" + +func Test(t *testing.T) {} + +-- want -- +pkg +pkg [pkg.test] +pkg.test diff --git a/src/cmd/go/testdata/script/list_std.txt b/src/cmd/go/testdata/script/list_std.txt new file mode 100644 index 0000000..6ab1bd1 --- /dev/null +++ b/src/cmd/go/testdata/script/list_std.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[!gc] skip +[short] skip + +# Listing GOROOT should only find standard packages. +cd $GOROOT/src +go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' ./... +! stdout . + +# Standard packages should include cmd, but not cmd/vendor. +go list ./... +stdout cmd/compile +! stdout vendor/golang.org +! stdout cmd/vendor + +# In GOPATH mode, packages vendored into GOROOT should be reported as standard. +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd +stdout golang.org/x/net/http2/hpack +stdout cmd/vendor/golang\.org/x/arch/x86/x86asm + +# However, vendored packages should not match wildcard patterns beginning with cmd. +go list cmd/... +stdout cmd/compile +! stdout cmd/vendor diff --git a/src/cmd/go/testdata/script/list_std_vendor.txt b/src/cmd/go/testdata/script/list_std_vendor.txt new file mode 100644 index 0000000..8f27cc1 --- /dev/null +++ b/src/cmd/go/testdata/script/list_std_vendor.txt @@ -0,0 +1,32 @@ +# https://golang.org/issue/44725: packages in std should have the same +# dependencies regardless of whether they are listed from within or outside +# GOROOT/src. + +# Control case: net, viewed from outside the 'std' module, +# should depend on vendor/golang.org/… instead of golang.org/…. + +go list -deps net +stdout '^vendor/golang.org/x/net' +! stdout '^golang.org/x/net' +cp stdout $WORK/net-deps.txt + + +# It should still report the same package dependencies when viewed from +# within GOROOT/src. + +cd $GOROOT/src + +go list -deps net +stdout '^vendor/golang.org/x/net' +! stdout '^golang.org/x/net' +cmp stdout $WORK/net-deps.txt + + +# However, 'go mod' and 'go get' subcommands should report the original module +# dependencies, not the vendored packages. + +[!net] stop + +env GOPROXY= +go mod why -m golang.org/x/net +stdout '^# golang.org/x/net\nnet\ngolang.org/x/net' diff --git a/src/cmd/go/testdata/script/list_swigcxx.txt b/src/cmd/go/testdata/script/list_swigcxx.txt new file mode 100644 index 0000000..d4227a8 --- /dev/null +++ b/src/cmd/go/testdata/script/list_swigcxx.txt @@ -0,0 +1,29 @@ +# go list should not report SWIG-generated C++ files in CompiledGoFiles. + +[!exec:swig] skip +[!exec:g++] skip +[!cgo] skip + +# CompiledGoFiles should contain 4 files: +# a.go +# a.swigcxx.go +# _cgo_gotypes.go +# a.cgo1.go +# +# These names we see here, other than a.go, will be from the build cache, +# so we just count them. + +go list -f '{{.CompiledGoFiles}}' -compiled=true example/swig + +stdout a\.go +stdout -count=3 $GOCACHE + +-- go.mod -- +module example + +go 1.16 + +-- swig/a.go -- +package swig + +-- swig/a.swigcxx -- diff --git a/src/cmd/go/testdata/script/list_symlink.txt b/src/cmd/go/testdata/script/list_symlink.txt new file mode 100644 index 0000000..f74ca86 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink.txt @@ -0,0 +1,12 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/src +symlink $WORK/tmp/src/dir1 -> $WORK/tmp +cp p.go $WORK/tmp/src/dir1/p.go +env GOPATH=$WORK/tmp +go list -f '{{.Root}}' dir1 +stdout '^'$WORK/tmp'$' + +-- p.go -- +package p diff --git a/src/cmd/go/testdata/script/list_symlink_internal.txt b/src/cmd/go/testdata/script/list_symlink_internal.txt new file mode 100644 index 0000000..f756a56 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_internal.txt @@ -0,0 +1,27 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/dir1/internal/v +cp p.go $WORK/tmp/gopath/src/dir1/p.go +cp v.go $WORK/tmp/gopath/src/dir1/internal/v/v.go +symlink $WORK/tmp/symdir1 -> $WORK/tmp/gopath/src/dir1 +env GOPATH=$WORK/tmp/gopath +cd $WORK/tmp/symdir1 +go list -f '{{.Root}}' . +stdout '^'$WORK/tmp/gopath'$' + +# All of these should succeed, not die in internal-handling code. +go run p.go & +go build & +go install & + +wait + +-- p.go -- +package main + +import _ `dir1/internal/v` + +func main() {} +-- v.go -- +package v diff --git a/src/cmd/go/testdata/script/list_symlink_issue35941.txt b/src/cmd/go/testdata/script/list_symlink_issue35941.txt new file mode 100644 index 0000000..eb12bde --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_issue35941.txt @@ -0,0 +1,18 @@ +[!symlink] skip +env GO111MODULE=off + +# Issue 35941: suppress symlink warnings when running 'go list all'. +symlink goproj/css -> $GOPATH/src/css + +go list all +! stderr 'warning: ignoring symlink' + +# Show symlink warnings when patterns contain '...'. +go list goproj/... +stderr 'warning: ignoring symlink' + +-- goproj/a.go -- +package a + +-- css/index.css -- +body {} diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt new file mode 100644 index 0000000..8e63a5a --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue14054.txt @@ -0,0 +1,28 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/dir1/vendor/v +cp p.go $WORK/tmp/gopath/src/dir1/p.go +cp v.go $WORK/tmp/gopath/src/dir1/vendor/v/v.go +symlink $WORK/tmp/symdir1 -> $WORK/tmp/gopath/src/dir1 +env GOPATH=$WORK/tmp/gopath +cd $WORK/tmp/symdir1 + +go list -f '{{.Root}}' . +stdout '^'$WORK/tmp/gopath'$' + +# All of these should succeed, not die in vendor-handling code. +go run p.go & +go build & +go install & + +wait + +-- p.go -- +package main + +import _ `v` + +func main () {} +-- v.go -- +package v diff --git a/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt new file mode 100644 index 0000000..19f2138 --- /dev/null +++ b/src/cmd/go/testdata/script/list_symlink_vendor_issue15201.txt @@ -0,0 +1,21 @@ +[!symlink] skip +env GO111MODULE=off + +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x +symlink $WORK/tmp/gopath/src/x/y/_vendor/src/x/y -> ../../.. +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x/y/w +cp w.go $WORK/tmp/gopath/src/x/y/w/w.go +symlink $WORK/tmp/gopath/src/x/y/w/vendor -> ../_vendor/src +mkdir $WORK/tmp/gopath/src/x/y/_vendor/src/x/y/z +cp z.go $WORK/tmp/gopath/src/x/y/z/z.go + +env GOPATH=$WORK/tmp/gopath/src/x/y/_vendor${:}$WORK/tmp/gopath +cd $WORK/tmp/gopath/src +go list ./... + +-- w.go -- +package w + +import "x/y/z" +-- z.go -- +package z diff --git a/src/cmd/go/testdata/script/list_test_e.txt b/src/cmd/go/testdata/script/list_test_e.txt new file mode 100644 index 0000000..263892b --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_e.txt @@ -0,0 +1,11 @@ +env GO111MODULE=off + +# issue 25980: crash in go list -e -test +go list -e -test -deps -f '{{.Error}}' p +stdout '^p[/\\]d_test.go:2:8: cannot find package "d" in any of:' + +-- p/d.go -- +package d +-- p/d_test.go -- +package d_test +import _ "d" diff --git a/src/cmd/go/testdata/script/list_test_err.txt b/src/cmd/go/testdata/script/list_test_err.txt new file mode 100644 index 0000000..25dbb96 --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_err.txt @@ -0,0 +1,143 @@ +env GO111MODULE=off + +# issue 28491: errors in test source files should not prevent +# "go list -test" from returning useful information. + +# go list prints information for package, internal test, +# external test, but not testmain package when there is a +# syntax error in test sources. +! go list -test -deps syntaxerr +stdout pkgdep +stdout testdep_a +stdout testdep_b +stdout ^syntaxerr$ +stdout '^syntaxerr \[syntaxerr.test\]' +stdout '^syntaxerr_test \[syntaxerr.test\]' +! stdout '^syntaxerr\.test' +stderr 'expected declaration' + +# go list -e prints information for all test packages. +# The syntax error is shown in the package error field. +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' syntaxerr +stdout 'pkgdep <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_b <nil>' +stdout 'syntaxerr <nil>' +stdout 'syntaxerr \[syntaxerr.test\] <nil>' +stdout 'syntaxerr_test \[syntaxerr.test\] <nil>' +stdout 'syntaxerr\.test "[^"]*expected declaration' +! stderr 'expected declaration' + +[short] stop + +# go list prints partial information with test naming error +! go list -test -deps nameerr +stdout pkgdep +stdout testdep_a +stdout testdep_b +stderr 'wrong signature for TestBad' + +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' nameerr +stdout 'pkgdep <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_b <nil>' +stdout 'nameerr\.test "[^"]*wrong signature for TestBad' +! stderr 'wrong signature for TestBad' + +# go list prints a useful error for generic test functions +! go list -test -deps genericerr +stderr 'wrong signature for TestGeneric, test functions cannot have type parameters' + +# go list prints partial information with error if test has cyclic import +! go list -test -deps cycleerr +stdout cycleerr +stderr 'import cycle not allowed in test' + +go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' cycleerr +stdout 'cycleerr <nil>' +stdout 'testdep_a <nil>' +stdout 'testdep_cycle <nil>' +stdout 'cycleerr \[cycleerr.test\] "[^"]*import cycle not allowed in test' +! stderr 'import cycle not allowed in test' + +-- syntaxerr/syntaxerr.go -- +package syntaxerr + +import _ "pkgdep" + +-- syntaxerr/syntaxerr_ie_test.go -- +package syntaxerr + +!!!syntax error + +-- syntaxerr/syntaxerr_xe_test.go -- +package syntaxerr_test + +!!!syntax error + +-- syntaxerr/syntaxerr_i_test.go -- +package syntaxerr + +import _ "testdep_a" + +-- syntaxerr/syntaxerr_x_test.go -- +package syntaxerr + +import _ "testdep_b" + +-- nameerr/nameerr.go -- +package nameerr + +import _ "pkgdep" + +-- nameerr/nameerr_i_test.go -- +package nameerr + +import ( + _ "testdep_a" + "testing" +) + +func TestBad(t *testing.B) {} + +-- nameerr/nameerr_x_test.go -- +package nameerr_test + +import ( + _ "testdep_b" + "testing" +) + +func TestBad(t *testing.B) {} + +-- genericerr/genericerr.go -- +package genericerr + +-- genericerr/genericerr_test.go -- +package genericerr + +import "testing" + +func TestGeneric[T any](t *testing.T) {} + +-- cycleerr/cycleerr_test.go -- +package cycleerr + +import ( + _ "testdep_a" + _ "testdep_cycle" +) + +-- pkgdep/pkgdep.go -- +package pkgdep + +-- testdep_a/testdep_a.go -- +package testdep_a + +-- testdep_b/testdep_b.go -- +package testdep_b + +-- testdep_cycle/testdep_cycle.go -- +package testdep_cycle + +import _ "cycleerr" diff --git a/src/cmd/go/testdata/script/list_test_imports.txt b/src/cmd/go/testdata/script/list_test_imports.txt new file mode 100644 index 0000000..0342eba --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_imports.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off + +# issue 26880: list with tests has wrong variant in imports +go list -test -f '{{.ImportPath}}:{{with .Imports}} {{join . ", "}}{{end}}' a b +cmp stdout imports.txt + +-- a/a.go -- +package a; import _ "b" +-- b/b.go -- +package b +-- b/b_test.go -- +package b +-- b/b_x_test.go -- +package b_test; import _ "a" + +-- imports.txt -- +a: b +b: +b.test: b [b.test], b_test [b.test], os, reflect, testing, testing/internal/testdeps +b [b.test]: +b_test [b.test]: a [b.test] diff --git a/src/cmd/go/testdata/script/list_test_non_go_files.txt b/src/cmd/go/testdata/script/list_test_non_go_files.txt new file mode 100644 index 0000000..6b2b633 --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_non_go_files.txt @@ -0,0 +1,13 @@ +env GO111MODULE=off + +# issue 29899: handling files with non-Go extension +go list -e -test -json -- c.c x.go +stdout '"Err": "named files must be .go files: c.c"' + +! go list -test -json -- c.c x.go +stderr '^named files must be \.go files: c\.c$' + +-- x.go -- +package main +-- c.c -- +package c diff --git a/src/cmd/go/testdata/script/list_test_simple.txt b/src/cmd/go/testdata/script/list_test_simple.txt new file mode 100644 index 0000000..954897c --- /dev/null +++ b/src/cmd/go/testdata/script/list_test_simple.txt @@ -0,0 +1,67 @@ +[short] skip + +# Test +go test -list=Test +stdout TestSimple + +# Benchmark +go test -list=Benchmark +stdout BenchmarkSimple + +# Examples +go test -list=Example +stdout ExampleSimple +stdout ExampleWithEmptyOutput + +-- go.mod -- +module m + +go 1.16 +-- bench_test.go -- +package testlist + +import ( + "fmt" + "testing" +) + +func BenchmarkSimplefunc(b *testing.B) { + b.StopTimer() + b.StartTimer() + for i := 0; i < b.N; i++ { + _ = fmt.Sprint("Test for bench") + } +} +-- example_test.go -- +package testlist + +import ( + "fmt" +) + +func ExampleSimple() { + fmt.Println("Test with Output.") + + // Output: Test with Output. +} + +func ExampleWithEmptyOutput() { + fmt.Println("") + + // Output: +} + +func ExampleNoOutput() { + _ = fmt.Sprint("Test with no output") +} +-- test_test.go -- +package testlist + +import ( + "fmt" + "testing" +) + +func TestSimple(t *testing.T) { + _ = fmt.Sprint("Test simple") +} diff --git a/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt new file mode 100644 index 0000000..02b1088 --- /dev/null +++ b/src/cmd/go/testdata/script/list_wildcard_skip_nonmatching.txt @@ -0,0 +1,17 @@ +# Test that wildcards don't look in useless directories. + +# First make sure that badpkg fails the list of '...'. +! go list ./... +stderr badpkg + +# Check that the list of './goodpkg...' succeeds. That implies badpkg was skipped. +go list ./goodpkg... + +-- go.mod -- +module m + +go 1.16 +-- goodpkg/x.go -- +package goodpkg +-- badpkg/x.go -- +pkg badpkg diff --git a/src/cmd/go/testdata/script/load_test_pkg_err.txt b/src/cmd/go/testdata/script/load_test_pkg_err.txt new file mode 100644 index 0000000..d088ee4 --- /dev/null +++ b/src/cmd/go/testdata/script/load_test_pkg_err.txt @@ -0,0 +1,30 @@ +# Tests issue 37971. Check that tests are still loaded even when the package has an error. + +go list -e -test d +cmp stdout want_stdout + +go list -e -test -deps d +stdout golang.org/fake/d + +-- want_stdout -- +d +d.test +d_test [d.test] +-- go.mod -- +module d + +go 1.16 +-- d.go -- +package d + +import "net/http" + +const d = http.MethodGet +func Get() string { return d; } +-- d2.go -- +-- d_test.go -- +package d_test + +import "testing" +import "golang.org/fake/d" +func TestD(t *testing.T) { d.Get(); } diff --git a/src/cmd/go/testdata/script/mod_all.txt b/src/cmd/go/testdata/script/mod_all.txt new file mode 100644 index 0000000..b71a920 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_all.txt @@ -0,0 +1,531 @@ +# This test illustrates the relationship between the 'all' pattern and +# the dependencies of the main module. + +# The package import graph used in this test looks like: +# +# main --------- a --------- b +# | | +# | a_test ---- c +# | | +# | c_test ---- d +# | +# main_test ---- t --------- u +# | +# t_test ---- w +# | +# w_test ---- x +# +# main/testonly_test ---- q --------- r +# | +# q_test ---- s +# +# And the module dependency graph looks like: +# +# main --- a.1 ---- b.1 +# \ \ \ +# \ \ c.1 -- d.1 +# \ \ +# \ t.1 ---- u.1 +# \ \ +# \ w.1 -- x.1 +# \ +# q.1 ---- r.1 +# \ +# s.1 + +env PKGFMT='{{if .Module}}{{.ImportPath}}{{end}}' +env MODFMT='{{.Path}}' + + +# 'go list -deps' lists packages and tests in the main module, +# along with their transitive dependencies. + +go list -f $PKGFMT -deps ./... +stdout -count=4 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly' + + +# 'go list -deps -test' lists transitive imports of tests and non-tests in the +# main module. + +go list -f $PKGFMT -deps -test ./... +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + + +# 'go list all' lists the fixpoint of iterating 'go list -deps -test' starting +# with the packages in the main module, then reducing to only the non-test +# variants of those packages. + +go list -f $PKGFMT all +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' + + +# 'go list -test all' is equivalent to 'go list -test $(go list all)' +# and both should include tests for every package in 'all'. + +go list -test -f $PKGFMT example.com/a example.com/b example.com/c example.com/d example.com/main example.com/main/testonly example.com/q example.com/r example.com/s example.com/t example.com/u example.com/w example.com/x +cp stdout list-test-explicit.txt + +go list -test -f $PKGFMT all +cmp stdout list-test-explicit.txt +stdout -count=36 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/c.test$' +stdout '^example.com/c_test \[example.com/c.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/s.test$' +stdout '^example.com/s_test \[example.com/s.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' +stdout '^example.com/w.test$' +stdout '^example.com/w_test \[example.com/w.test\]$' + + +# 'go list -m all' covers the packages in 'go list -test -deps all'. + +go list -m -f $MODFMT all +stdout -count=12 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/x$' + + +# 'go mod vendor' copies in only the packages transitively imported by the main +# module, and omits their tests. As a result, the 'all' and '...' patterns +# report fewer packages when using '-mod=vendor'. + +go mod vendor + +go list -f $PKGFMT -mod=vendor all +stdout -count=8 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + +go list -test -f $PKGFMT -mod=vendor all +stdout -count=13 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' + +rm vendor + +# Convert all modules to go 1.17 to enable lazy loading. +go mod edit -go=1.17 a/go.mod +go mod edit -go=1.17 b/go.mod +go mod edit -go=1.17 c/go.mod +go mod edit -go=1.17 d/go.mod +go mod edit -go=1.17 q/go.mod +go mod edit -go=1.17 r/go.mod +go mod edit -go=1.17 s/go.mod +go mod edit -go=1.17 t/go.mod +go mod edit -go=1.17 u/go.mod +go mod edit -go=1.17 w/go.mod +go mod edit -go=1.17 x/go.mod +go mod edit -go=1.17 +cmp go.mod go.mod.beforetidy +go mod tidy +cmp go.mod go.mod.aftertidy + +# With lazy loading, 'go list all' with neither -mod=vendor nor -test should +# match -mod=vendor without -test in 1.15. + +go list -f $PKGFMT all +stdout -count=8 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' + +# 'go list -test all' should expand that to include the test variants of the +# packages in 'all', but not the dependencies of outside tests. + +go list -test -f $PKGFMT all +stdout -count=25 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + +# 'go list -test -deps all' should include the dependencies of those tests, +# but not the tests of the dependencies of outside tests. + +go list -test -deps -f $PKGFMT all +stdout -count=28 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +stdout '^example.com/main$' +stdout '^example.com/main/testonly$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +stdout '^example.com/a.test$' +stdout '^example.com/a_test \[example.com/a.test\]$' +stdout '^example.com/b.test$' +stdout '^example.com/b_test \[example.com/b.test\]$' +stdout '^example.com/main.test$' +stdout '^example.com/main \[example.com/main.test\]$' +stdout '^example.com/main_test \[example.com/main.test\]$' +stdout '^example.com/main/testonly.test$' +stdout '^example.com/main/testonly_test \[example.com/main/testonly.test\]$' +stdout '^example.com/q.test$' +stdout '^example.com/q_test \[example.com/q.test\]$' +stdout '^example.com/r.test$' +stdout '^example.com/r_test \[example.com/r.test\]$' +stdout '^example.com/t.test$' +stdout '^example.com/t_test \[example.com/t.test\]$' +stdout '^example.com/u.test$' +stdout '^example.com/u_test \[example.com/u.test\]$' + +# 'go list -m all' should cover all of the modules providing packages in +# 'go list -test -deps all', but should exclude modules d and x, +# which are not relevant to the main module and are outside of the +# lazy-loading horizon. + +go list -m -f $MODFMT all +stdout -count=10 '^.' +stdout '^example.com/a$' +stdout '^example.com/b$' +stdout '^example.com/c$' +! stdout '^example.com/d$' +stdout '^example.com/main$' +stdout '^example.com/q$' +stdout '^example.com/r$' +stdout '^example.com/s$' +stdout '^example.com/t$' +stdout '^example.com/u$' +stdout '^example.com/w$' +! stdout '^example.com/x$' + +-- go.mod -- +module example.com/main + +// Note: this go.mod file initially specifies go 1.15, +// but includes some redundant roots so that it +// also already obeys the 1.17 lazy loading invariants. +go 1.15 + +require ( + example.com/a v0.1.0 + example.com/b v0.1.0 // indirect + example.com/q v0.1.0 + example.com/r v0.1.0 // indirect + example.com/t v0.1.0 + example.com/u v0.1.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c + example.com/d v0.1.0 => ./d + example.com/q v0.1.0 => ./q + example.com/r v0.1.0 => ./r + example.com/s v0.1.0 => ./s + example.com/t v0.1.0 => ./t + example.com/u v0.1.0 => ./u + example.com/w v0.1.0 => ./w + example.com/x v0.1.0 => ./x +) +-- main.go -- +package main + +import _ "example.com/a" + +func main() {} +-- main_test.go -- +package main_test + +import _ "example.com/t" +-- testonly/testonly_test.go -- +package testonly_test + +import _ "example.com/q" +-- a/go.mod -- +module example.com/a + +go 1.15 + +require ( + example.com/b v0.1.0 + example.com/c v0.1.0 +) +-- a/a.go -- +package a + +import _ "example.com/b" +-- a/a_test.go -- +package a_test + +import _ "example.com/c" +-- b/go.mod -- +module example.com/b + +go 1.15 +-- b/b.go -- +package b +-- b/b_test.go -- +package b_test +-- c/go.mod -- +module example.com/c + +go 1.15 + +require example.com/d v0.1.0 +-- c/c.go -- +package c +-- c/c_test.go -- +package c_test + +import _ "example.com/d" +-- d/go.mod -- +module example.com/d + +go 1.15 +-- d/d.go -- +package d +-- q/go.mod -- +module example.com/q + +go 1.15 + +require ( + example.com/r v0.1.0 + example.com/s v0.1.0 +) +-- q/q.go -- +package q +import _ "example.com/r" +-- q/q_test.go -- +package q_test +import _ "example.com/s" +-- r/go.mod -- +module example.com/r + +go 1.15 +-- r/r.go -- +package r +-- r/r_test.go -- +package r_test +-- s/go.mod -- +module example.com/s + +go 1.15 +-- s/s.go -- +package s +-- s/s_test.go -- +package s_test +-- t/go.mod -- +module example.com/t + +go 1.15 + +require ( + example.com/u v0.1.0 + example.com/w v0.1.0 +) +-- t/t.go -- +package t + +import _ "example.com/u" +-- t/t_test.go -- +package t_test + +import _ "example.com/w" +-- u/go.mod -- +module example.com/u + +go 1.15 +-- u/u.go -- +package u +-- u/u_test.go -- +package u_test +-- w/go.mod -- +module example.com/w + +go 1.15 + +require example.com/x v0.1.0 +-- w/w.go -- +package w +-- w/w_test.go -- +package w_test + +import _ "example.com/x" +-- x/go.mod -- +module example.com/x + +go 1.15 +-- x/x.go -- +package x +-- go.mod.beforetidy -- +module example.com/main + +// Note: this go.mod file initially specifies go 1.15, +// but includes some redundant roots so that it +// also already obeys the 1.17 lazy loading invariants. +go 1.17 + +require ( + example.com/a v0.1.0 + example.com/b v0.1.0 // indirect + example.com/q v0.1.0 + example.com/r v0.1.0 // indirect + example.com/t v0.1.0 + example.com/u v0.1.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c + example.com/d v0.1.0 => ./d + example.com/q v0.1.0 => ./q + example.com/r v0.1.0 => ./r + example.com/s v0.1.0 => ./s + example.com/t v0.1.0 => ./t + example.com/u v0.1.0 => ./u + example.com/w v0.1.0 => ./w + example.com/x v0.1.0 => ./x +) +-- go.mod.aftertidy -- +module example.com/main + +// Note: this go.mod file initially specifies go 1.15, +// but includes some redundant roots so that it +// also already obeys the 1.17 lazy loading invariants. +go 1.17 + +require ( + example.com/a v0.1.0 + example.com/q v0.1.0 + example.com/t v0.1.0 +) + +require ( + example.com/b v0.1.0 // indirect + example.com/r v0.1.0 // indirect + example.com/u v0.1.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c + example.com/d v0.1.0 => ./d + example.com/q v0.1.0 => ./q + example.com/r v0.1.0 => ./r + example.com/s v0.1.0 => ./s + example.com/t v0.1.0 => ./t + example.com/u v0.1.0 => ./u + example.com/w v0.1.0 => ./w + example.com/x v0.1.0 => ./x +) diff --git a/src/cmd/go/testdata/script/mod_alt_goroot.txt b/src/cmd/go/testdata/script/mod_alt_goroot.txt new file mode 100644 index 0000000..32f94c5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_alt_goroot.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +# If the working directory is a different GOROOT, then the 'std' module should be +# treated as an ordinary module (with an ordinary module prefix). +# It should not override packages in GOROOT, but should not fail the command. +# See golang.org/issue/30756. +go list -e -deps -f '{{.ImportPath}} {{.Dir}}' ./bytes +stdout ^std/bytes.*$PWD[/\\]bytes +stdout '^bytes/modified' + +-- go.mod -- +module std + +go 1.12 +-- bytes/bytes.go -- +package bytes + +import _"bytes/modified" +-- bytes/modified/modified.go -- +package modified diff --git a/src/cmd/go/testdata/script/mod_ambiguous_import.txt b/src/cmd/go/testdata/script/mod_ambiguous_import.txt new file mode 100644 index 0000000..feaf5d2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_ambiguous_import.txt @@ -0,0 +1,48 @@ +env GO111MODULE=on + +cd $WORK + +# An import provided by two different modules should be flagged as an error. +! go build ./importx +stderr '^importx[/\\]importx.go:2:8: ambiguous import: found package example.com/a/x in multiple modules:\n\texample.com/a v0.1.0 \('$WORK'[/\\]a[/\\]x\)\n\texample.com/a/x v0.1.0 \('$WORK'[/\\]ax\)$' + +# However, it should not be an error if that import is unused. +go build ./importy + +# An import provided by both the main module and the vendor directory +# should be flagged as an error only when -mod=vendor is set. +mkdir vendor/example.com/m/importy +cp $WORK/importy/importy.go vendor/example.com/m/importy/importy.go +go build example.com/m/importy +! go build -mod=vendor example.com/m/importy +stderr '^ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$' + +-- $WORK/go.mod -- +module example.com/m +go 1.13 +require ( + example.com/a v0.1.0 + example.com/a/x v0.1.0 +) +replace ( + example.com/a v0.1.0 => ./a + example.com/a/x v0.1.0 => ./ax +) +-- $WORK/importx/importx.go -- +package importx +import _ "example.com/a/x" +-- $WORK/importy/importy.go -- +package importy +import _ "example.com/a/y" +-- $WORK/a/go.mod -- +module example.com/a +go 1.14 +-- $WORK/a/x/x.go -- +package x +-- $WORK/a/y/y.go -- +package y +-- $WORK/ax/go.mod -- +module example.com/a/x +go 1.14 +-- $WORK/ax/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_auth.txt b/src/cmd/go/testdata/script/mod_auth.txt new file mode 100644 index 0000000..d8ea586 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_auth.txt @@ -0,0 +1,35 @@ +[!net] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOVCS='*:off' + +# Without credentials, downloading a module from a path that requires HTTPS +# basic auth should fail. +env NETRC=$WORK/empty +! go mod tidy +stderr '^\tserver response: ACCESS DENIED, buddy$' +stderr '^\tserver response: File\? What file\?$' + +# With credentials from a netrc file, it should succeed. +env NETRC=$WORK/netrc +go mod tidy +go list all +stdout vcs-test.golang.org/auth/or401 +stdout vcs-test.golang.org/auth/or404 + +-- go.mod -- +module private.example.com +-- main.go -- +package useprivate + +import ( + _ "vcs-test.golang.org/auth/or401" + _ "vcs-test.golang.org/auth/or404" +) +-- $WORK/empty -- +-- $WORK/netrc -- +machine vcs-test.golang.org + login aladdin + password opensesame diff --git a/src/cmd/go/testdata/script/mod_bad_domain.txt b/src/cmd/go/testdata/script/mod_bad_domain.txt new file mode 100644 index 0000000..afd6e51 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_bad_domain.txt @@ -0,0 +1,47 @@ +env GO111MODULE=on + +# explicit get should report errors about bad names +! go get appengine +stderr '^go: malformed module path "appengine": missing dot in first path element$' +! go get x/y.z +stderr 'malformed module path "x/y.z": missing dot in first path element' + + +# 'go list -m' should report errors about module names, never GOROOT. +! go list -m -versions appengine +stderr 'malformed module path "appengine": missing dot in first path element' +! go list -m -versions x/y.z +stderr 'malformed module path "x/y.z": missing dot in first path element' + + +# build should report all unsatisfied imports, +# but should be more definitive about non-module import paths +! go build ./useappengine +stderr '^useappengine[/\\]x.go:2:8: cannot find package$' +! go build ./usenonexistent +stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; to add it:\n\tgo get nonexistent.rsc.io$' + + +# 'get -d' should be similarly definitive + +go get ./useappengine # TODO(#41315): This should fail. + # stderr '^useappengine[/\\]x.go:2:8: cannot find package$' + +! go get ./usenonexistent +stderr '^x/usenonexistent imports\n\tnonexistent.rsc.io: cannot find module providing package nonexistent.rsc.io$' + + +# go mod vendor and go mod tidy should ignore appengine imports. +rm usenonexistent/x.go +go mod tidy +go mod vendor + +-- go.mod -- +module x + +-- useappengine/x.go -- +package useappengine +import _ "appengine" // package does not exist +-- usenonexistent/x.go -- +package usenonexistent +import _ "nonexistent.rsc.io" // domain does not exist diff --git a/src/cmd/go/testdata/script/mod_bad_filenames.txt b/src/cmd/go/testdata/script/mod_bad_filenames.txt new file mode 100644 index 0000000..eb556f4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_bad_filenames.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +! go get rsc.io/badfile1 rsc.io/badfile2 rsc.io/badfile3 rsc.io/badfile4 rsc.io/badfile5 +! stderr 'unzip.*badfile1' +stderr 'unzip.*badfile2[\\/]@v[\\/]v1.0.0.zip:.*malformed file path "☺.go": invalid char ''☺''' +stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile3@v1.0.0[\\/]x\?y.go: malformed file path "x\?y.go": invalid char ''\?''' +stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile4@v1.0.0[\\/]x[\\/]y.go: case-insensitive file name collision: "x/Y.go" and "x/y.go"' +stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile5@v1.0.0[\\/]x[\\/]Y[\\/]zz[\\/]ww.go: case-insensitive file name collision: "x/y" and "x/Y"' + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_build_info_err.txt b/src/cmd/go/testdata/script/mod_build_info_err.txt new file mode 100644 index 0000000..5c3c309 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_info_err.txt @@ -0,0 +1,33 @@ +# This test verifies that line numbers are included in module import errors. +# Verifies golang.org/issue/34393. + +go list -e -mod=mod -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main +stdout '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#26909): This should include an import stack. +# (Today it includes only a file and line.) +! go build ./main +stderr '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#41688): This should include a file and line, and report the reason for the error.. +# (Today it includes only an import stack.) +! go get ./main +stderr '^m/main imports\n\tm/bad imports\n\t🐧.example.com/string: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + + +-- go.mod -- +module m + +go 1.13 + +-- main/main.go -- +package main + +import _ "m/bad" + +func main() {} + +-- bad/bad.go -- +package bad + +import _ "🐧.example.com/string" diff --git a/src/cmd/go/testdata/script/mod_build_tags.txt b/src/cmd/go/testdata/script/mod_build_tags.txt new file mode 100644 index 0000000..ae1d605 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_tags.txt @@ -0,0 +1,33 @@ +# Test that build tags are used. +# golang.org/issue/24053. + +env GO111MODULE=on + +cd x +! go list -f {{.GoFiles}} +stderr 'build constraints exclude all Go files' + +go list -f {{.GoFiles}} -tags tag1 +stdout '\[x.go\]' + +go list -f {{.GoFiles}} -tags tag2 +stdout '\[y\.go\]' + +go list -f {{.GoFiles}} -tags 'tag1 tag2' +stdout '\[x\.go y\.go\]' + +go list -f {{.GoFiles}} -tags tag1,tag2 # commas allowed as of Go 1.13 +stdout '\[x\.go y\.go\]' + +-- x/go.mod -- +module x + +-- x/x.go -- +// +build tag1 + +package y + +-- x/y.go -- +// +build tag2 + +package y diff --git a/src/cmd/go/testdata/script/mod_build_trimpath_issue48557.txt b/src/cmd/go/testdata/script/mod_build_trimpath_issue48557.txt new file mode 100644 index 0000000..859eafc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_trimpath_issue48557.txt @@ -0,0 +1,52 @@ +# Regression test for issue #48557. +# Since builds in module mode do not support relative imports at all, the build +# ID for (and other contents of) a binary built with -trimpath in module mode +# should not depend on its working directory, even if the binary is specified as +# a list of relative source files. + +[short] skip # links and runs binaries + +env GOFLAGS=-trimpath +env GOCACHE=$WORK/gocache + + +# When we build a binary in module mode with -trimpath, the -D flag (for the +# "local import prefix") should not be passed to it. + +cd $WORK/tmp/foo +go build -x -o a.exe main.go +stderr ${/}compile$GOEXE.*' -nolocalimports' +! stderr ${/}compile$GOEXE.*' -D[ =]' + +go tool buildid a.exe +cp stdout ../foo-buildid.txt +go version a.exe +cp stdout ../foo-version.txt +cd .. + + +# On the second build — in a different directory but with -trimpath — the +# compiler should not be invoked, since the cache key should be identical. +# Only the linker and buildid tool should be needed. + +mkdir bar +cp foo/main.go bar/main.go +cd bar +go build -x -o a.exe main.go +! stderr ${/}compile$GOEXE + +go tool buildid a.exe +cp stdout ../bar-buildid.txt +go version a.exe +cp stdout ../bar-version.txt +cd .. + +cmp bar-buildid.txt foo-buildid.txt +cmp bar-version.txt foo-version.txt +cmp bar/a.exe foo/a.exe + + +-- $WORK/tmp/foo/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_build_versioned.txt b/src/cmd/go/testdata/script/mod_build_versioned.txt new file mode 100644 index 0000000..f550418 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_build_versioned.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on +[short] skip + +go get rsc.io/fortune/v2 + +# The default executable name shouldn't be v2$GOEXE +go build rsc.io/fortune/v2 +! exists v2$GOEXE +exists fortune$GOEXE + +# The default test binary name shouldn't be v2.test$GOEXE +go test -c rsc.io/fortune/v2 +! exists v2.test$GOEXE +exists fortune.test$GOEXE + +-- go.mod -- +module scratch diff --git a/src/cmd/go/testdata/script/mod_cache_dir.txt b/src/cmd/go/testdata/script/mod_cache_dir.txt new file mode 100644 index 0000000..4045928 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_cache_dir.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +# Go should reject relative paths in GOMODCACHE environment. + +env GOMODCACHE="~/test" +! go install example.com/tools/cmd/hello@latest +stderr 'must be absolute path' + +env GOMODCACHE="./test" +! go install example.com/tools/cmd/hello@latest +stderr 'must be absolute path' diff --git a/src/cmd/go/testdata/script/mod_cache_rw.txt b/src/cmd/go/testdata/script/mod_cache_rw.txt new file mode 100644 index 0000000..0775541 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_cache_rw.txt @@ -0,0 +1,49 @@ +# Regression test for golang.org/issue/31481. + +env GO111MODULE=on + +# golang.org/issue/31481: an explicit flag should make directories in the module +# cache writable in order to work around the historical inability of 'rm -rf' to +# forcibly remove files in unwritable directories. +go get -modcacherw rsc.io/quote@v1.5.2 +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + +# After adding an extraneous file, 'go mod verify' should fail. +! go mod verify + +# However, files within those directories should still be read-only to avoid +# accidental mutations. +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# If all 'go' commands ran with the flag, the system's 'rm' binary +# should be able to remove the module cache if the '-rf' flags are set. +[!windows] [exec:rm] exec rm -rf $GOPATH/pkg/mod +[!windows] [!exec:rm] go clean -modcache +[windows] [exec:cmd.exe] exec cmd.exe /c rmdir /s /q $GOPATH\pkg\mod +[windows] [!exec:cmd.exe] go clean -modcache +! exists $GOPATH/pkg/mod + +# The directories in the module cache should by default be unwritable, +# so that tests and tools will not accidentally add extraneous files to them. +# Windows does not respect FILE_ATTRIBUTE_READONLY on directories, according +# to MSDN, so there we disable testing whether the directory itself is +# unwritable. +go get rsc.io/quote@latest +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +[!windows] [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + + +# Repeat part of the test with 'go mod download' instead of 'go get' to verify +# -modcacherw is supported on 'go mod' subcommands. +go clean -modcache +go mod download -modcacherw rsc.io/quote +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! go mod verify +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + + +-- $WORK/extraneous.txt -- +module oops +-- go.mod -- +module golang.org/issue/31481 diff --git a/src/cmd/go/testdata/script/mod_case.txt b/src/cmd/go/testdata/script/mod_case.txt new file mode 100644 index 0000000..d3fb11d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_case.txt @@ -0,0 +1,25 @@ +env GO111MODULE=on + +go get +go list -m all +stdout '^rsc.io/quote v1.5.2' +stdout '^rsc.io/QUOTE v1.5.2' + +go list -f 'DIR {{.Dir}} DEPS {{.Deps}}' rsc.io/QUOTE/QUOTE +stdout 'DEPS.*rsc.io/quote' +stdout 'DIR.*!q!u!o!t!e' + +go get rsc.io/QUOTE@v1.5.3-PRE +go list -m all +stdout '^rsc.io/QUOTE v1.5.3-PRE' + +go list -f '{{.Dir}}' rsc.io/QUOTE/QUOTE +stdout '!q!u!o!t!e@v1.5.3-!p!r!e' + +-- go.mod -- +module x + +-- use.go -- +package use + +import _ "rsc.io/QUOTE/QUOTE" diff --git a/src/cmd/go/testdata/script/mod_case_cgo.txt b/src/cmd/go/testdata/script/mod_case_cgo.txt new file mode 100644 index 0000000..7c768a0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_case_cgo.txt @@ -0,0 +1,11 @@ +[!cgo] skip + +env GO111MODULE=on + +go get rsc.io/CGO +[short] stop + +go build rsc.io/CGO + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_clean_cache.txt b/src/cmd/go/testdata/script/mod_clean_cache.txt new file mode 100644 index 0000000..01fbc38 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_clean_cache.txt @@ -0,0 +1,58 @@ +env GO111MODULE=on + +# 'mod download' should download the module to the cache. +go mod download rsc.io/quote@v1.5.0 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# '-n' should print commands but not actually execute them. +go clean -modcache -n +stdout '^rm -rf .*pkg.mod$' +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# 'go clean -modcache' should actually delete the files. +go clean -modcache +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip + +# 'go clean -r -modcache' should clean only the dependencies that are within the +# main module. +# BUG(golang.org/issue/28680): Today, it cleans across module boundaries. +cd r +exists ./test.out +exists ../replaced/test.out +go clean -r -modcache +! exists ./test.out +! exists ../replaced/test.out # BUG: should still exist + +# 'go clean -modcache' should not download anything before cleaning. +go mod edit -require rsc.io/quote@v1.99999999.0-not-a-real-version +go clean -modcache +! stderr 'finding rsc.io' +go mod edit -droprequire rsc.io/quote + +-- go.mod -- +module m +-- m.go -- +package m + +-- r/go.mod -- +module example.com/r +require example.com/r/replaced v0.0.0 +replace example.com/r/replaced => ../replaced +-- r/r.go -- +package r +import _ "example.com/r/replaced" +-- r/test.out -- +DELETE ME + +-- replaced/go.mod -- +module example.com/r/replaced +-- replaced/replaced.go -- +package replaced +-- replaced/test.out -- +DO NOT DELETE diff --git a/src/cmd/go/testdata/script/mod_concurrent.txt b/src/cmd/go/testdata/script/mod_concurrent.txt new file mode 100644 index 0000000..e2224d6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_concurrent.txt @@ -0,0 +1,32 @@ +env GO111MODULE=on + +# Concurrent builds should succeed, even if they need to download modules. +go get ./x ./y +go build ./x & +go build ./y +wait + +# Concurrent builds should update go.sum to the union of the hashes for the +# modules they read. +cmp go.sum go.sum.want + +-- go.mod -- +module golang.org/issue/26794 + +require ( + golang.org/x/text v0.3.0 + rsc.io/sampler v1.0.0 +) +-- x/x.go -- +package x + +import _ "golang.org/x/text/language" +-- y/y.go -- +package y + +import _ "rsc.io/sampler" +-- go.sum.want -- +golang.org/x/text v0.3.0 h1:ivTorhoiROmZ1mcs15mO2czVF0uy0tnezXpBVNzgrmA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/sampler v1.0.0 h1:SRJnjyQ07sAtq6G4RcfJEmz8JxqLyj3PoGXG2VhbDWo= +rsc.io/sampler v1.0.0/go.mod h1:cqxpM3ZVz9VtirqxZPmrWzkQ+UkiNiGtkrN+B+i8kx8= diff --git a/src/cmd/go/testdata/script/mod_convert.txt b/src/cmd/go/testdata/script/mod_convert.txt new file mode 100644 index 0000000..f60fe87 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert.txt @@ -0,0 +1,66 @@ +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY= +env GOSUMDB= + +go mod download github.com/docker/distribution@v0.0.0-20150410205453-85de3967aa93 +mkdir x/Godeps +cp $GOPATH/pkg/mod/github.com/docker/distribution@v0.0.0-20150410205453-85de3967aa93/Godeps/Godeps.json x/Godeps +cd x +go mod init github.com/docker/distribution +cmpenv go.mod go.mod.want + +go mod download github.com/fishy/gcsbucket@v0.0.0-20180217031846-618d60fe84e0 +cp $GOPATH/pkg/mod/github.com/fishy/gcsbucket@v0.0.0-20180217031846-618d60fe84e0/Gopkg.lock ../y +cd ../y +go mod init github.com/fishy/gcsbucket +cmpenv go.mod go.mod.want + +-- x/go.mod.want -- +module github.com/docker/distribution + +go $goversion + +require ( + github.com/AdRoll/goamz v0.0.0-20150130162828-d3664b76d905 + github.com/MSOpenTech/azure-sdk-for-go v0.0.0-20150323223030-d90753bcad2e + github.com/Sirupsen/logrus v0.7.3 + github.com/bugsnag/bugsnag-go v1.0.3-0.20141110184014-b1d153021fcd + github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b + github.com/bugsnag/panicwrap v0.0.0-20141110184334-e5f9854865b9 + github.com/codegangsta/cli v1.4.2-0.20150131031259-6086d7927ec3 + github.com/docker/docker v1.4.2-0.20150204013315-165ea5c158cf + github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 + github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 + github.com/gorilla/context v0.0.0-20140604161150-14f550f51af5 + github.com/gorilla/handlers v0.0.0-20140825150757-0e84b7d810c1 + github.com/gorilla/mux v0.0.0-20140926153814-e444e69cbd2e + github.com/jlhawn/go-crypto v0.0.0-20150401213827-cd738dde20f0 + github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 + github.com/yvasiyarov/gorelic v0.0.7-0.20141212073537-a9bba5b9ab50 + github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f + golang.org/x/net v0.0.0-20150202051010-1dfe7915deaf + gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789 + gopkg.in/yaml.v2 v2.0.0-20150116202057-bef53efd0c76 +) +-- y/go.mod.want -- +module github.com/fishy/gcsbucket + +go $goversion + +require ( + cloud.google.com/go v0.18.0 + github.com/fishy/fsdb v0.0.0-20180217030800-5527ded01371 + github.com/golang/protobuf v1.0.0 + github.com/googleapis/gax-go v2.0.0+incompatible + golang.org/x/net v0.0.0-20180216171745-136a25c244d3 + golang.org/x/oauth2 v0.0.0-20180207181906-543e37812f10 + golang.org/x/text v0.3.1-0.20180208041248-4e4a3210bb54 + google.golang.org/api v0.0.0-20180217000815-c7a403bb5fe1 + google.golang.org/appengine v1.0.0 + google.golang.org/genproto v0.0.0-20180206005123-2b5a72b8730b + google.golang.org/grpc v1.10.0 +) diff --git a/src/cmd/go/testdata/script/mod_convert_dep.txt b/src/cmd/go/testdata/script/mod_convert_dep.txt new file mode 100644 index 0000000..875a836 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_dep.txt @@ -0,0 +1,30 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found Gopkg.lock in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +# In Plan 9, directories are automatically created in /n. +# For example, /n/Gopkg.lock always exists, but it's a directory. +# Test that we ignore directories when trying to find alternate config files. +cd $WORK/gopkgdir/x +! go list . +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! stderr 'Gopkg.lock' + +-- $WORK/test/Gopkg.lock -- +-- $WORK/test/x/x.go -- +package x // import "m/x" +-- $WORK/gopkgdir/Gopkg.lock/README.txt -- +../Gopkg.lock is a directory, not a file. +-- $WORK/gopkgdir/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_git.txt b/src/cmd/go/testdata/script/mod_convert_git.txt new file mode 100644 index 0000000..6ff1eb5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_git.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found .git/config in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +# We should not suggest creating a go.mod file in $GOROOT, even though there may be a .git/config there. +cd $GOROOT +! go list . +! stderr 'go mod init' + +# We should also not suggest creating a go.mod file in $GOROOT if its own +# .git/config has been stripped away and we find one in a parent directory. +# (https://golang.org/issue/34191) +env GOROOT=$WORK/parent/goroot +cd $GOROOT +! go list . +! stderr 'go mod init' + +cd $GOROOT/doc +! go list . +! stderr 'go mod init' + +-- $WORK/test/.git/config -- +-- $WORK/test/x/x.go -- +package x // import "m/x" +-- $WORK/parent/.git/config -- +-- $WORK/parent/goroot/README -- +This directory isn't really a GOROOT, but let's pretend that it is. +-- $WORK/parent/goroot/doc/README -- +This is a subdirectory of our fake GOROOT. diff --git a/src/cmd/go/testdata/script/mod_convert_glide.txt b/src/cmd/go/testdata/script/mod_convert_glide.txt new file mode 100644 index 0000000..9f1fff5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_glide.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found glide.lock in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/glide.lock -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_glockfile.txt b/src/cmd/go/testdata/script/mod_convert_glockfile.txt new file mode 100644 index 0000000..6aa0794 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_glockfile.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found GLOCKFILE in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/GLOCKFILE -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_godeps.txt b/src/cmd/go/testdata/script/mod_convert_godeps.txt new file mode 100644 index 0000000..da7b6c1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_godeps.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found Godeps/Godeps.json in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/Godeps/Godeps.json -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_tsv.txt b/src/cmd/go/testdata/script/mod_convert_tsv.txt new file mode 100644 index 0000000..6015ac8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_tsv.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found dependencies.tsv in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/dependencies.tsv -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt new file mode 100644 index 0000000..283e2d9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt @@ -0,0 +1,29 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +[!net] skip +[!exec:git] skip + +# secure fetch should report insecure warning +cd $WORK/test +go mod init +stderr 'redirected .* to insecure URL' + +# insecure fetch should not +env GOINSECURE=*.golang.org +rm go.mod +go mod init +! stderr 'redirected .* to insecure URL' + +# insecure fetch invalid path should report insecure warning +env GOINSECURE=foo.golang.org +rm go.mod +go mod init +stderr 'redirected .* to insecure URL' + +-- $WORK/test/dependencies.tsv -- +vcs-test.golang.org/insecure/go/insecure git 6fecd21f7c0c 2019-09-04T18:39:48Z + +-- $WORK/test/x.go -- +package x // import "m" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt b/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt new file mode 100644 index 0000000..57ec419 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_conf.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor.conf in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/vendor.conf -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_json.txt b/src/cmd/go/testdata/script/mod_convert_vendor_json.txt new file mode 100644 index 0000000..df6db36 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_json.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor/vendor.json in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m +stdout '^m$' + +-- $WORK/test/vendor/vendor.json -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt b/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt new file mode 100644 index 0000000..8b6a141 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor/manifest in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m +stdout '^m$' + +-- $WORK/test/vendor/manifest -- +{} +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt b/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt new file mode 100644 index 0000000..4ed140a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_convert_vendor_yml.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# We should not create a go.mod file unless the user ran 'go mod init' explicitly. +# However, we should suggest 'go mod init' if we can find an alternate config file. +cd $WORK/test/x +! go list . +stderr 'found vendor.yml in .*[/\\]test' +stderr '\s*cd \.\. && go mod init' + +# The command we suggested should succeed. +cd .. +go mod init +go list -m all +stdout '^m$' + +-- $WORK/test/vendor.yml -- +-- $WORK/test/x/x.go -- +package x // import "m/x" diff --git a/src/cmd/go/testdata/script/mod_deprecate_message.txt b/src/cmd/go/testdata/script/mod_deprecate_message.txt new file mode 100644 index 0000000..8e2771d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_deprecate_message.txt @@ -0,0 +1,73 @@ +# When there is a short single-line message, 'go get' should print it all. +go get short +stderr '^go: module short is deprecated: short$' +go list -m -u -f '{{.Deprecated}}' short +stdout '^short$' + +# When there is a multi-line message, 'go get' should print the first line. +go get multiline +stderr '^go: module multiline is deprecated: first line$' +! stderr 'second line' +go list -m -u -f '{{.Deprecated}}' multiline +stdout '^first line\nsecond line.$' + +# When there is a long message, 'go get' should print a placeholder. +go get long +stderr '^go: module long is deprecated: \(message omitted: too long\)$' +go list -m -u -f '{{.Deprecated}}' long +stdout '^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$' + +# When a message contains unprintable chracters, 'go get' should say that +# without printing the message. +go get unprintable +stderr '^go: module unprintable is deprecated: \(message omitted: contains non-printable characters\)$' +go list -m -u -f '{{.Deprecated}}' unprintable +stdout '^message contains ASCII BEL\x07$' + +-- go.mod -- +module use + +go 1.16 + +require ( + short v0.0.0 + multiline v0.0.0 + long v0.0.0 + unprintable v0.0.0 +) + +replace ( + short v0.0.0 => ./short + multiline v0.0.0 => ./multiline + long v0.0.0 => ./long + unprintable v0.0.0 => ./unprintable +) +-- short/go.mod -- +// Deprecated: short +module short + +go 1.16 +-- short/short.go -- +package short +-- multiline/go.mod -- +// Deprecated: first line +// second line. +module multiline + +go 1.16 +-- multiline/multiline.go -- +package multiline +-- long/go.mod -- +// Deprecated: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +module long + +go 1.16 +-- long/long.go -- +package long +-- unprintable/go.mod -- +// Deprecated: message contains ASCII BEL +module unprintable + +go 1.16 +-- unprintable/unprintable.go -- +package unprintable diff --git a/src/cmd/go/testdata/script/mod_dir.txt b/src/cmd/go/testdata/script/mod_dir.txt new file mode 100644 index 0000000..05548f6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_dir.txt @@ -0,0 +1,20 @@ +# The directory named go.mod should be ignored + +env GO111MODULE=on + +cd $WORK/sub + +go list . +stdout 'x/sub' + +mkdir go.mod +exists go.mod + +go list . +stdout 'x/sub' + +-- $WORK/go.mod -- +module x + +-- $WORK/sub/x.go -- +package x
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_doc.txt b/src/cmd/go/testdata/script/mod_doc.txt new file mode 100644 index 0000000..595ad67 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_doc.txt @@ -0,0 +1,89 @@ +# go doc should find module documentation + +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# Check when module x is inside GOPATH/src. +go doc y +stdout 'Package y is.*alphabet' +stdout 'import "x/y"' +go doc x/y +stdout 'Package y is.*alphabet' +! go doc quote.Hello +stderr 'doc: symbol quote is not a type' # because quote is not in local cache +go list rsc.io/quote # now it is +go doc quote.Hello +stdout 'Hello returns a greeting' +go doc quote +stdout 'Package quote collects pithy sayings.' + +# Double-check when module x is outside GOPATH/src. +env GOPATH=$WORK/emptygopath +go doc x/y +stdout 'Package y is.*alphabet' +go doc y +stdout 'Package y is.*alphabet' + +# Triple-check when module x is outside GOPATH/src, +# but other packages with same import paths are in GOPATH/src. +# Since go doc is running in module mode here, packages in active module +# should be preferred over packages in GOPATH. See golang.org/issue/28992. +env GOPATH=$WORK/gopath2 +go doc x/y +! stdout 'Package y is.*GOPATH' +stdout 'Package y is.*alphabet' +go doc rsc.io/quote +! stdout 'Package quote is located in a GOPATH workspace.' +stdout 'Package quote collects pithy sayings.' + +# Check that a sensible error message is printed when a package is not found. +env GOPROXY=off +! go doc example.com/hello +stderr '^doc: cannot find module providing package example.com/hello: module lookup disabled by GOPROXY=off$' + +# When in a module with a vendor directory, doc should use the vendored copies +# of the packages. 'std' and 'cmd' are convenient examples of such modules. +# +# When in those modules, the "// import" comment should refer to the same import +# path used in source code, not to the absolute path relative to GOROOT. + +cd $GOROOT/src +env GOFLAGS= +go doc cryptobyte +stdout '// import "golang.org/x/crypto/cryptobyte"' + +cd $GOROOT/src/cmd/go +go doc modfile +stdout '// import "golang.org/x/mod/modfile"' + +# When outside of the 'std' module, its vendored packages +# remain accessible using the 'vendor/' prefix, but report +# the correct "// import" comment as used within std. +cd $GOPATH +go doc vendor/golang.org/x/crypto/cryptobyte +stdout '// import "vendor/golang.org/x/crypto/cryptobyte"' + +go doc cmd/vendor/golang.org/x/mod/modfile +stdout '// import "cmd/vendor/golang.org/x/mod/modfile"' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- y/y.go -- +// Package y is the next to last package of the alphabet. +package y + +-- x.go -- +package x + +-- $WORK/gopath2/src/x/y/y.go -- +// Package y is located in a GOPATH workspace. +package y +-- $WORK/gopath2/src/rsc.io/quote/quote.go -- +// Package quote is located in a GOPATH workspace. +package quote + +// Hello is located in a GOPATH workspace. +func Hello() string { return "" } diff --git a/src/cmd/go/testdata/script/mod_domain_root.txt b/src/cmd/go/testdata/script/mod_domain_root.txt new file mode 100644 index 0000000..c13029d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_domain_root.txt @@ -0,0 +1,12 @@ +# Module paths that are domain roots should resolve. +# (example.com not example.com/something) + +env GO111MODULE=on +go get + +-- go.mod -- +module x + +-- x.go -- +package x +import _ "example.com" diff --git a/src/cmd/go/testdata/script/mod_dot.txt b/src/cmd/go/testdata/script/mod_dot.txt new file mode 100644 index 0000000..cb60e98 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_dot.txt @@ -0,0 +1,131 @@ +env GO111MODULE=on + +# golang.org/issue/32917 and golang.org/issue/28459: 'go build' and 'go test' +# in an empty directory should refer to the path '.' and should not attempt +# to resolve an external module. +cd dir +! go get +stderr '^go: no package to get in current directory$' +! go get . +stderr '^go: .: no package to get in current directory$' +! go get ./subdir +stderr '^go: \.[/\\]subdir \('$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir\) is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src[/\\]dir$' +! go list +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' + +cd subdir +! go list +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' +cd .. + +# golang.org/issue/30590: if a package is found in the filesystem +# but is not in the main module, the error message should not say +# "cannot find module providing package", and we shouldn't try +# to find a module providing the package. +! go list ./othermodule +! stderr 'cannot find module providing package' +stderr '^main module \(example\.com\) does not contain package example.com/othermodule$' + +# golang.org/issue/27122: 'go build' of a nonexistent directory should produce +# a helpful "no Go files" error message, not a generic "unknown import path". +! go list ./subdir +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir$' + +# golang.org/issue/29280: 'go list -e' for a nonexistent directory should +# report a nonexistent package with an error. +go list -e -json ./subdir +stdout '"Incomplete": true' + +# golang.org/issue/28155: 'go list ./testdata' should not synthesize underscores. +go list ./testdata +stdout '^example.com/testdata' + +# golang.org/issue/32921: vendor directories should only be accepted as directories +# if the directory would actually be used to load the package. +! go list ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list ./vendor/pkg +stderr '^without -mod=vendor, directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]pkg has no package path$' + +! go list -mod=vendor ./vendor/nonexist +stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]nonexist$' + +! go list -mod=vendor ./vendor/unlisted +stderr '^directory '$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]vendor[/\\]unlisted is not a package listed in vendor/modules.txt$' + +go list -mod=vendor ./vendor/pkg +stdout '^pkg$' + +# Packages within GOROOT should resolve as in any other module, +# except that -mod=vendor is implied by default. +cd $GOROOT/src +! go list . +stderr '^no Go files in '$GOROOT'[/\\]src$' + +! go list ./builtin +stderr '^"builtin" is a pseudo-package, not an importable package$' + +! go list ./debug +! stderr 'cannot find module providing package' +stderr '^no Go files in '$GOROOT'[/\\]src[/\\]debug$' + +! go list ./golang.org/x/tools/cmd/goimports +! stderr 'cannot find module providing package' +stderr '^stat '$GOROOT'[/\\]src[/\\]golang.org[/\\]x[/\\]tools[/\\]cmd[/\\]goimports: directory not found' + +go list ./vendor/golang.org/x/net/http2/hpack +stdout '^golang.org/x/net/http2/hpack$' + +# golang.org/issue/30756: packages in other GOROOTs should not get the special +# prefixless treatment of GOROOT itself. +cd $WORK/othergoroot/src +! go list . +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src$' + +go list ./builtin +stdout '^std/builtin$' # Only the "std" in actual $GOROOT is special, and only its "builtin" is special. + +! go list ./bytes +! stderr 'cannot find module providing package' +stderr '^no Go files in '$WORK'[/\\]othergoroot[/\\]src[/\\]bytes$' + +! go list ./vendor/golang.org/x/net/http2/hpack +stderr '^without -mod=vendor, directory '$WORK'[/\\]othergoroot[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack has no package path$' + +-- dir/go.mod -- +module example.com +go 1.13 +-- dir/subdir/README -- +There are no Go source files in this directory. +-- dir/othermodule/go.mod -- +module example.com/othermodule +go 1.13 +-- dir/othermodule/om.go -- +package othermodule +-- dir/testdata/td.go -- +package testdata +-- dir/vendor/modules.txt -- +# pkg v0.0.0 +pkg +-- dir/vendor/nonexist/README -- +There are no Go source files here either. +-- dir/vendor/pkg/pkg.go -- +package pkg +-- dir/vendor/unlisted/unlisted.go -- +package unlisted +-- emptyroot/go.mod -- +module example.com/emptyroot +-- emptyroot/pkg/pkg.go -- +package pkg +-- $WORK/othergoroot/src/go.mod -- +module std +go 1.13 +-- $WORK/othergoroot/src/builtin/builtin.go -- +package builtin +-- $WORK/othergoroot/src/bytes/README -- +There are no Go source files in this directory. +-- $WORK/othergoroot/src/vendor/golang.org/x/net/http2/hpack -- +package hpack diff --git a/src/cmd/go/testdata/script/mod_download.txt b/src/cmd/go/testdata/script/mod_download.txt new file mode 100644 index 0000000..154e683 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download.txt @@ -0,0 +1,214 @@ +env GO111MODULE=on + +# download with version should print nothing. +# It should not load retractions from the .mod file from the latest version. +go mod download rsc.io/quote@v1.5.0 +! stdout . +! stderr . +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod + +# download of an invalid path should report the error +[short] skip +! go mod download this.domain.is.invalid/somemodule@v1.0.0 +stderr 'this.domain.is.invalid' +! go mod download -json this.domain.is.invalid/somemodule@v1.0.0 +stdout '"Error": ".*this.domain.is.invalid.*"' + +# download -json with version should print JSON +go mod download -json 'rsc.io/quote@<=v1.5.0' +stdout '^\t"Path": "rsc.io/quote"' +stdout '^\t"Version": "v1.5.0"' +stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.info"' +stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.mod"' +stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.0.zip"' +stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of testdata/mod version, not real version! +stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="' +! stdout '"Error"' + +# download queries above should not have added to go.mod. +go list -m all +! stdout rsc.io + +# download query should have downloaded go.mod for the highest release version +# in order to find retractions when resolving the query '@<=v1.5.0'. +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# add to go.mod so we can test non-query downloads +go mod edit -require rsc.io/quote@v1.5.3-pre1 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + +# module loading will page in the info and mod files +go list -m -mod=mod all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + +# download will fetch and unpack the zip file +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 + +# download repopulates deleted files and directories independently. +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 +go mod download +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 + +# download reports the locations of downloaded files +go mod download -json +stdout '^\t"Path": "rsc.io/quote"' +stdout '^\t"Version": "v1.5.3-pre1"' +stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.info"' +stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.mod"' +stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.zip"' +stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.3-pre1"' + +# download will follow replacements +go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.2 +go mod download +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# download will not follow replacements for explicit module queries +go mod download -json rsc.io/quote@v1.5.1 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip + +# download reports errors encountered when locating modules +! go mod download bad/path +stderr '^go: module bad/path: not a known dependency$' +! go mod download bad/path@latest +stderr '^go: bad/path@latest: malformed module path "bad/path": missing dot in first path element$' +! go mod download rsc.io/quote@v1.999.999 +stderr '^go: rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' +! go mod download -json bad/path +stdout '^\t"Error": "module bad/path: not a known dependency"' + +# download main module produces a warning or error +go mod download m +stderr '^go: skipping download of m that resolves to the main module\n' +! go mod download m@latest +stderr '^go: m@latest: malformed module path "m": missing dot in first path element$' + +# download without arguments updates go.mod and go.sum after loading the +# build list, but does not save sums for downloaded zips. +cd update +cp go.mod.orig go.mod +! exists go.sum +go mod download +cmp go.mod.update go.mod +cmp go.sum.update go.sum +cp go.mod.orig go.mod +rm go.sum + +# download with arguments (even "all") does update go.mod and go.sum. +go mod download rsc.io/sampler +cmp go.mod.update go.mod +grep '^rsc.io/sampler v1.3.0 ' go.sum +cp go.mod.orig go.mod +rm go.sum + +go mod download all +cmp go.mod.update go.mod +grep '^rsc.io/sampler v1.3.0 ' go.sum + +# https://golang.org/issue/44435: At go 1.17 or higher, 'go mod download' +# (without arguments) should only download the modules explicitly required in +# the go.mod file, not (presumed-irrelevant) transitive dependencies. +# +# (If the go.mod file is inconsistent, the version downloaded should be the +# selected version from the broader graph, but the go.mod file will also be +# updated to list the correct versions. If at some point we change 'go mod +# download' to stop updating for consistency, then it should fail if the +# requirements are inconsistent.) + +rm go.sum +cp go.mod.orig go.mod +go mod edit -go=1.17 +cp go.mod.update go.mod.go117 +go mod edit -go=1.17 go.mod.go117 + +go clean -modcache +go mod download +cmp go.mod go.mod.go117 + +go list -e -m all +stdout '^rsc.io/quote v1.5.2$' +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +stdout '^rsc.io/sampler v1.3.0$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/sampler/@v/v1.2.1.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/sampler/@v/v1.3.0.zip +stdout '^golang\.org/x/text v0.0.0-20170915032832-14c0d48ead0c$' +! exists $GOPATH/pkg/mod/cache/download/golang.org/x/text/@v/v0.0.0-20170915032832-14c0d48ead0c.zip +cmp go.mod go.mod.go117 + +# However, 'go mod download all' continues to download the selected version +# of every module reported by 'go list -m all'. + +cp go.mod.orig go.mod +go mod edit -go=1.17 +go clean -modcache +go mod download all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/sampler/@v/v1.2.1.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/sampler/@v/v1.3.0.zip +exists $GOPATH/pkg/mod/cache/download/golang.org/x/text/@v/v0.0.0-20170915032832-14c0d48ead0c.zip +cmp go.mod go.mod.go117 + +cd .. + +# allow go mod download without go.mod +env GO111MODULE=auto +rm go.mod +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip +go mod download rsc.io/quote@v1.2.1 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip + +# download -x with version should print +# the underlying commands such as contacting GOPROXY. +go mod download -x rsc.io/quote@v1.0.0 +! stdout . +stderr 'get '$GOPROXY + +-- go.mod -- +module m + +-- update/go.mod.orig -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.2.1 // older version than in build list +) +-- update/go.mod.update -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // older version than in build list +) +-- update/go.sum.update -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt new file mode 100644 index 0000000..231babd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt @@ -0,0 +1,110 @@ +# This test simulates a process watching for changes and reading files in +# module cache as a module is extracted. +# +# Before Go 1.16, we extracted each module zip to a temporary directory with +# a random name, then renamed that into place with os.Rename. On Windows, +# this failed with ERROR_ACCESS_DENIED when another process (usually an +# anti-virus scanner) opened files in the temporary directory. This test +# simulates that behavior, verifying golang.org/issue/36568. +# +# Since 1.16, we extract to the final directory, but we create a .partial file +# so that if we crash, other processes know the directory is incomplete. + +[!windows] skip +[short] skip + +go run downloader.go + +-- go.mod -- +module example.com/m + +go 1.14 + +-- downloader.go -- +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" +) + +func main() { + if err := run(); err != nil { + log.Fatal(err) + } +} + +// run repeatedly downloads a module while opening files in the module cache +// in a background goroutine. +// +// run uses a different temporary module cache in each iteration so that we +// don't need to clean the cache or synchronize closing files after each +// iteration. +func run() (err error) { + tmpDir, err := os.MkdirTemp("", "") + if err != nil { + return err + } + defer func() { + if rmErr := os.RemoveAll(tmpDir); err == nil && rmErr != nil { + err = rmErr + } + }() + for i := 0; i < 10; i++ { + gopath := filepath.Join(tmpDir, fmt.Sprintf("gopath%d", i)) + var err error + done := make(chan struct{}) + go func() { + err = download(gopath) + close(done) + }() + readCache(gopath, done) + if err != nil { + return err + } + } + return nil +} + +// download downloads a module into the given cache using 'go mod download'. +func download(gopath string) error { + cmd := exec.Command("go", "mod", "download", "-modcacherw", "rsc.io/quote@v1.5.2") + cmd.Stderr = os.Stderr + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + return cmd.Run() +} + +// readCache repeatedly globs for go.mod files in the given cache, then opens +// those files for reading. When the done chan is closed, readCache closes +// files and returns. +func readCache(gopath string, done <-chan struct{}) { + files := make(map[string]*os.File) + defer func() { + for _, f := range files { + f.Close() + } + }() + + pattern := filepath.Join(gopath, "pkg/mod/rsc.io/quote@v1.5.2*/go.mod") + for { + select { + case <-done: + return + default: + } + + names, _ := filepath.Glob(pattern) + for _, name := range names { + if files[name] != nil { + continue + } + f, _ := os.Open(name) + if f != nil { + files[name] = f + } + } + } +} diff --git a/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt b/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt new file mode 100644 index 0000000..3b19acc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt @@ -0,0 +1,28 @@ +env GO111MODULE=on + +[!net] skip +[!exec:git] skip + +env GOPROXY=direct +env HOME=$WORK/home/gopher + + +go env GOPROXY +stdout 'direct' + +exec git config --get log.decorate +stdout 'full' + +# Test that Git log with user's global config '~/gitconfig' has log.decorate=full +# go mod download has an error 'v1.x.y is not a tag' +# with go1.16.14: +# `go1.16.14 list -m vcs-test.golang.org/git/gitrepo1.git@v1.2.3` +# will output with error: +# go list -m: vcs-test.golang.org/git/gitrepo1.git@v1.2.3: invalid version: unknown revision v1.2.3 +# See golang/go#51312. +go list -m vcs-test.golang.org/git/gitrepo1.git@v1.2.3 +stdout 'vcs-test.golang.org/git/gitrepo1.git v1.2.3' + +-- $WORK/home/gopher/.gitconfig -- +[log] + decorate = full
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_download_hash.txt b/src/cmd/go/testdata/script/mod_download_hash.txt new file mode 100644 index 0000000..5a42c4b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_hash.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on + +# Testing mod download with non semantic versions; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off + +go mod download rsc.io/quote@a91498bed0a73d4bb9c1fb2597925f7883bc40a7 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.zip + +go mod download rsc.io/quote@master +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-0.20180709162918-a91498bed0a7.zip + + +-- go.mod -- +module m + +-- m.go -- +package m diff --git a/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt new file mode 100644 index 0000000..46eb666 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt @@ -0,0 +1,32 @@ +# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure (now replaced by GOINSECURE). + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go mod download vcs-test.golang.org/insecure/go/insecure@latest +stderr 'redirected .* to insecure URL' + +# insecure host +env GOINSECURE=vcs-test.golang.org +go clean -modcache +go mod download vcs-test.golang.org/insecure/go/insecure@latest + +# insecure glob host +env GOINSECURE=*.golang.org +go clean -modcache +go mod download vcs-test.golang.org/insecure/go/insecure@latest + +# insecure multiple host +env GOINSECURE=somewhere-else.com,*.golang.org +go clean -modcache +go mod download vcs-test.golang.org/insecure/go/insecure@latest + +# different insecure host does not fetch +env GOINSECURE=somewhere-else.com +go clean -modcache +! go mod download vcs-test.golang.org/insecure/go/insecure@latest +stderr 'redirected .* to insecure URL' diff --git a/src/cmd/go/testdata/script/mod_download_json.txt b/src/cmd/go/testdata/script/mod_download_json.txt new file mode 100644 index 0000000..9555adf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_json.txt @@ -0,0 +1,9 @@ +env GO111MODULE=on +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong + +# download -json with version should print JSON on sumdb failure +! go mod download -json 'rsc.io/quote@<=v1.5.0' +stdout '"Error": ".*verifying (module|go.mod)' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_download_partial.txt b/src/cmd/go/testdata/script/mod_download_partial.txt new file mode 100644 index 0000000..617b1fd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_partial.txt @@ -0,0 +1,69 @@ +# Download modules and populate go.sum. +go get -modcacherw +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# 'go mod verify' should fail if we delete a file. +go mod verify +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +! go mod verify + +# Create a .partial file to simulate an failure extracting the zip file. +cp empty $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial + +# 'go mod verify' should not fail, since the module hasn't been completely +# ingested into the cache. +go mod verify + +# 'go list' should not load packages from the directory. +# NOTE: the message "directory $dir outside main module or its selected dependencies" +# is reported for directories not in the main module, active modules in the +# module cache, or local replacements. In this case, the directory is in the +# right place, but it's incomplete, so 'go list' acts as if it's not an +# active module. +! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stderr 'outside main module or its selected dependencies' + +# 'go list -m' should not print the directory. +go list -m -f '{{.Dir}}' rsc.io/quote +! stdout . + +# 'go mod download' should re-extract the module and remove the .partial file. +go mod download -modcacherw rsc.io/quote +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# 'go list' should succeed. +go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote$' + +# 'go list -m' should print the directory. +go list -m -f '{{.Dir}}' rsc.io/quote +stdout 'pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2' + +# go mod verify should fail if we delete a file. +go mod verify +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +! go mod verify + +# 'go mod download' should not leave behind a directory or a .partial file +# if there is an error extracting the zip file. +rm $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +cp empty $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +! go mod download +stderr 'not a valid zip file' +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.partial + +-- go.mod -- +module m + +go 1.14 + +require rsc.io/quote v1.5.2 + +-- use.go -- +package use + +import _ "rsc.io/quote" + +-- empty -- diff --git a/src/cmd/go/testdata/script/mod_download_private_vcs.txt b/src/cmd/go/testdata/script/mod_download_private_vcs.txt new file mode 100644 index 0000000..e126793 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_private_vcs.txt @@ -0,0 +1,43 @@ +env GO111MODULE=on + +# Testing stderr for git ls-remote; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct + +! go mod download github.com/golang/nonexist@latest +stderr 'Confirm the import path was entered correctly.' +stderr 'If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.' +! stdout . + +# Fetching a nonexistent commit should return an "unknown revision" +# error message. +! go mod download github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b +stderr '^go: github.com/golang/term@86186f3aba07ed0212cfb944f3398997d2d07c6b: invalid version: unknown revision 86186f3aba07ed0212cfb944f3398997d2d07c6b$' +! stdout . + +! go mod download github.com/golang/nonexist@master +stderr '^Confirm the import path was entered correctly.$' +stderr '^If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.$' +! stderr 'unknown revision' +! stdout . + +[!linux] stop # Needs XDG_CONFIG_HOME. +[!exec:false] stop + +# Test that Git clone errors will be shown to the user instead of a generic +# "unknown revision" error. To do this we want to force git ls-remote to return +# an error we don't already have special handling for. See golang/go#42751. +# +# Set XDG_CONFIG_HOME to tell Git where to look for the git config file listed +# below, which turns on ssh. +env XDG_CONFIG_HOME=$TMPDIR +env GIT_SSH_COMMAND=false +! go install github.com/golang/nonexist@master +stderr 'fatal: Could not read from remote repository.' +! stderr 'unknown revision' +! stdout . + +-- $TMPDIR/git/config -- +[url "git@github.com:"] + insteadOf = https://github.com/ diff --git a/src/cmd/go/testdata/script/mod_download_replace_file.txt b/src/cmd/go/testdata/script/mod_download_replace_file.txt new file mode 100644 index 0000000..f6ab4fe --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_replace_file.txt @@ -0,0 +1,16 @@ +# This test checks that 'go mod download' produces no output for +# the main module (when specified implicitly) and for a module replaced +# with a file path. +# Verifies golang.org/issue/35505. +go mod download -json all +cmp stdout no-output + +-- go.mod -- +module example.com/a + +require example.com/b v1.0.0 + +replace example.com/b => ./local/b +-- local/b/go.mod -- +module example.com/b +-- no-output -- diff --git a/src/cmd/go/testdata/script/mod_download_svn.txt b/src/cmd/go/testdata/script/mod_download_svn.txt new file mode 100644 index 0000000..79e00dc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_svn.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:svn] skip + +# 'go mod download' will fall back to svn+ssh once svn fails over protocols like https. +# If vcs-test.golang.org isn't in the user's known_hosts file, this will result +# in an ssh prompt, which will stop 'go test' entirely +# +# Unfortunately, there isn't a way to globally disable host checking for ssh, +# without modifying the real system's or user's configs. Changing $HOME won't +# affect ssh either, as it ignores the environment variable entirely. +# +# However, a useful trick is pointing SVN_SSH to a program that doesn't exist, +# resulting in svn skipping ssh entirely. Alternatives like +# SVN_SSH="ssh -o StrictHostKeyChecking=no" didn't avoid the prompt. +env SVN_SSH="svn_do_not_use_ssh" + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Attempting to get a module zip using svn should succeed. +go mod download vcs-test.golang.org/svn/hello.svn@000000000001 +exists $GOPATH/pkg/mod/cache/download/vcs-test.golang.org/svn/hello.svn/@v/v0.0.0-20170922011245-000000000001.zip + +# Attempting to get a nonexistent module using svn should fail with a +# reasonable message instead of a panic. +! go mod download vcs-test.golang.org/svn/nonexistent.svn@latest +! stderr panic +stderr 'go: module vcs-test.golang.org/svn/nonexistent.svn: no matching versions for query "latest"$' diff --git a/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt b/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt new file mode 100644 index 0000000..a6b5a59 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on +env GOPROXYBASE=$GOPROXY +env GOPROXY=$GOPROXYBASE/redirect/11 +env GOSUMDB=off + +! go mod download rsc.io/quote@v1.2.0 +stderr 'stopped after 10 redirects' + +env GOPROXY=$GOPROXYBASE/redirect/9 +go mod download rsc.io/quote@v1.2.0 diff --git a/src/cmd/go/testdata/script/mod_e.txt b/src/cmd/go/testdata/script/mod_e.txt new file mode 100644 index 0000000..3cffaf6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_e.txt @@ -0,0 +1,96 @@ +cp go.mod go.mod.orig + + +# If a dependency cannot be resolved, 'go mod tidy' fails with an error message +# explaining the problem and does not update the go.mod file. +# TODO(bcmills): Ideally, with less redundancy than these error messages! + +! go mod tidy + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: cannot find module providing package example.net/directnotfound: module example.net/directnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m imports\n\texample.net/indirectnotfound: cannot find module providing package example.net/indirectnotfound: module example.net/indirectnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: cannot find module providing package example.net/directtestnotfound: module example.net/directtestnotfound: reading http://.*: 404 Not Found$' + +stderr '^example.com/untidy imports\n\texample.net/m tested by\n\texample.net/m.test imports\n\texample.net/indirecttestnotfound: cannot find module providing package example.net/indirecttestnotfound: module example.net/indirecttestnotfound: reading http://.*: 404 Not Found$' + +cmp go.mod.orig go.mod + + +# If a dependency cannot be resolved, 'go mod vendor' fails with an error message +# explaining the problem, does not update the go.mod file, and does not create +# the vendor directory. + +! go mod vendor + +stderr '^example.com/untidy imports\n\texample.net/directnotfound: no required module provides package example.net/directnotfound; to add it:\n\tgo get example.net/directnotfound$' + +stderr '^example.com/untidy imports\n\texample.net/m: module example.net/m provides package example.net/m and is replaced but not required; to add it:\n\tgo get example.net/m@v0.1.0$' + +stderr '^example.com/untidy tested by\n\texample.com/untidy.test imports\n\texample.net/directtestnotfound: no required module provides package example.net/directtestnotfound; to add it:\n\tgo get example.net/directtestnotfound$' + +! stderr 'indirecttestnotfound' # Vendor prunes test dependencies. + +cmp go.mod.orig go.mod +! exists vendor + + +# 'go mod tidy' still logs the errors, but succeeds and updates go.mod. + +go mod tidy -e +stderr -count=4 'cannot find module providing package' +cmp go.mod.final go.mod + + +# 'go mod vendor -e' still logs the errors, but creates a vendor directory +# and exits with status 0. +# 'go mod vendor -e' does not update go.mod and will not vendor packages that +# would require changing go.mod, for example, by adding a requirement. +cp go.mod.orig go.mod +go mod vendor -e +stderr -count=2 'no required module provides package' +stderr '^example.com/untidy imports\n\texample.net/m: module example.net/m provides package example.net/m and is replaced but not required; to add it:\n\tgo get example.net/m@v0.1.0$' +exists vendor/modules.txt +! exists vendor/example.net + +go mod edit -require example.net/m@v0.1.0 +go mod vendor -e +stderr -count=3 'no required module provides package' +exists vendor/modules.txt +exists vendor/example.net/m/m.go + +-- go.mod -- +module example.com/untidy +go 1.16 +replace example.net/m v0.1.0 => ./m +-- go.mod.final -- +module example.com/untidy + +go 1.16 + +replace example.net/m v0.1.0 => ./m + +require example.net/m v0.1.0 +-- untidy.go -- +package untidy + +import ( + _ "example.net/m" + _ "example.net/directnotfound" +) +-- untidy_test.go -- +package untidy_test + +import _ "example.net/directtestnotfound" +-- m/go.mod -- +module example.net/m +go 1.16 +-- m/m.go -- +package m + +import _ "example.net/indirectnotfound" +-- m/m_test.go -- +package m_test + +import _ "example.net/indirecttestnotfound" diff --git a/src/cmd/go/testdata/script/mod_edit.txt b/src/cmd/go/testdata/script/mod_edit.txt new file mode 100644 index 0000000..ebc032a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_edit.txt @@ -0,0 +1,321 @@ +env GO111MODULE=on + +# Test that go mod edits and related mod flags work. +# Also test that they can use a dummy name that isn't resolvable. golang.org/issue/24100 + +# go mod init +! go mod init +stderr 'cannot determine module path' +! exists go.mod + +go mod init x.x/y/z +stderr 'creating new go.mod: module x.x/y/z' +cmpenv go.mod $WORK/go.mod.init + +! go mod init +cmpenv go.mod $WORK/go.mod.init + +# go mod edits +go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -exclude=x.1@v2.0.0+incompatible -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0 +cmpenv go.mod $WORK/go.mod.edit1 +go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropexclude=x.1@v2.0.0+incompatible -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0] +cmpenv go.mod $WORK/go.mod.edit2 + +# -exclude and -retract reject invalid versions. +! go mod edit -exclude=example.com/m@bad +stderr '^go: -exclude=example.com/m@bad: version "bad" invalid: must be of the form v1.2.3$' +! go mod edit -retract=bad +stderr '^go: -retract=bad: version "bad" invalid: must be of the form v1.2.3$' + +! go mod edit -exclude=example.com/m@v2.0.0 +stderr '^go: -exclude=example.com/m@v2\.0\.0: version "v2\.0\.0" invalid: should be v2\.0\.0\+incompatible \(or module example\.com/m/v2\)$' + +! go mod edit -exclude=example.com/m/v2@v1.0.0 +stderr '^go: -exclude=example.com/m/v2@v1\.0\.0: version "v1\.0\.0" invalid: should be v2, not v1$' + +! go mod edit -exclude=gopkg.in/example.v1@v2.0.0 +stderr '^go: -exclude=gopkg\.in/example\.v1@v2\.0\.0: version "v2\.0\.0" invalid: should be v1, not v2$' + +cmpenv go.mod $WORK/go.mod.edit2 + +# go mod edit -json +go mod edit -json +cmpenv stdout $WORK/go.mod.json + +# go mod edit -json (retractions with rationales) +go mod edit -json $WORK/go.mod.retractrationale +cmp stdout $WORK/go.mod.retractrationale.json + +# go mod edit -json (deprecation) +go mod edit -json $WORK/go.mod.deprecation +cmp stdout $WORK/go.mod.deprecation.json + +# go mod edit -json (empty mod file) +go mod edit -json $WORK/go.mod.empty +cmp stdout $WORK/go.mod.empty.json + +# go mod edit -replace +go mod edit -replace=x.1@v1.3.0=y.1/v2@v2.3.5 -replace=x.1@v1.4.0=y.1/v2@v2.3.5 +cmpenv go.mod $WORK/go.mod.edit3 +go mod edit -replace=x.1=y.1/v2@v2.3.6 +cmpenv go.mod $WORK/go.mod.edit4 +go mod edit -dropreplace=x.1 +cmpenv go.mod $WORK/go.mod.edit5 + +# go mod edit -fmt +cp $WORK/go.mod.badfmt go.mod +go mod edit -fmt -print # -print should avoid writing file +cmpenv stdout $WORK/go.mod.goodfmt +cmp go.mod $WORK/go.mod.badfmt +go mod edit -fmt # without -print, should write file (and nothing to stdout) +! stdout . +cmpenv go.mod $WORK/go.mod.goodfmt + +# go mod edit -module +cd $WORK/m +go mod init a.a/b/c +go mod edit -module x.x/y/z +cmpenv go.mod go.mod.edit + +# golang.org/issue/30513: don't require go-gettable module paths. +cd $WORK/local +go mod init foo +go mod edit -module local-only -require=other-local@v1.0.0 -replace other-local@v1.0.0=./other +cmpenv go.mod go.mod.edit + +-- x.go -- +package x + +-- w/w.go -- +package w + +-- $WORK/go.mod.init -- +module x.x/y/z + +go $goversion +-- $WORK/go.mod.edit1 -- +module x.x/y/z + +go $goversion + +require x.1 v1.0.0 + +exclude ( + x.1 v1.2.0 + x.1 v1.2.1 + x.1 v2.0.0+incompatible +) + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +) + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] + [v1.1.0, v1.2.0] + v1.0.0 +) +-- $WORK/go.mod.edit2 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace x.1 v1.4.0 => ../z + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.json -- +{ + "Module": { + "Path": "x.x/y/z" + }, + "Go": "$goversion", + "Require": [ + { + "Path": "x.3", + "Version": "v1.99.0" + } + ], + "Exclude": [ + { + "Path": "x.1", + "Version": "v1.2.0" + } + ], + "Replace": [ + { + "Old": { + "Path": "x.1", + "Version": "v1.4.0" + }, + "New": { + "Path": "../z" + } + } + ], + "Retract": [ + { + "Low": "v1.6.0", + "High": "v1.6.0" + }, + { + "Low": "v1.3.0", + "High": "v1.4.0" + } + ] +} +-- $WORK/go.mod.edit3 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace ( + x.1 v1.3.0 => y.1/v2 v2.3.5 + x.1 v1.4.0 => y.1/v2 v2.3.5 +) + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.edit4 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/go.mod.edit5 -- +module x.x/y/z + +go $goversion + +exclude x.1 v1.2.0 + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + +require x.3 v1.99.0 +-- $WORK/local/go.mod.edit -- +module local-only + +go $goversion + +require other-local v1.0.0 + +replace other-local v1.0.0 => ./other +-- $WORK/go.mod.badfmt -- +module x.x/y/z + +go 1.10 + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +require x.3 v1.99.0 + +retract [ "v1.8.1" , "v1.8.2" ] +-- $WORK/go.mod.goodfmt -- +module x.x/y/z + +go 1.10 + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +require x.3 v1.99.0 + +retract [v1.8.1, v1.8.2] +-- $WORK/m/go.mod.edit -- +module x.x/y/z + +go $goversion +-- $WORK/go.mod.retractrationale -- +module x.x/y/z + +go 1.15 + +// a +retract v1.0.0 + +// b +retract ( + v1.0.1 + v1.0.2 // c +) +-- $WORK/go.mod.retractrationale.json -- +{ + "Module": { + "Path": "x.x/y/z" + }, + "Go": "1.15", + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": [ + { + "Low": "v1.0.0", + "High": "v1.0.0", + "Rationale": "a" + }, + { + "Low": "v1.0.1", + "High": "v1.0.1", + "Rationale": "b" + }, + { + "Low": "v1.0.2", + "High": "v1.0.2", + "Rationale": "c" + } + ] +} +-- $WORK/go.mod.deprecation -- +// Deprecated: and the new one is not ready yet +module m +-- $WORK/go.mod.deprecation.json -- +{ + "Module": { + "Path": "m", + "Deprecated": "and the new one is not ready yet" + }, + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": null +} +-- $WORK/go.mod.empty -- +-- $WORK/go.mod.empty.json -- +{ + "Module": { + "Path": "" + }, + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": null +} diff --git a/src/cmd/go/testdata/script/mod_edit_go.txt b/src/cmd/go/testdata/script/mod_edit_go.txt new file mode 100644 index 0000000..7e9740f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_edit_go.txt @@ -0,0 +1,23 @@ +# Test support for go mod -edit to set language version. + +env GO111MODULE=on +! go build +stderr ' type aliases requires' +go mod edit -go=1.9 +grep 'go 1.9' go.mod +go build + +# Reverting the version should force a rebuild and error instead of using +# the cached 1.9 build. (https://golang.org/issue/37804) +go mod edit -go=1.8 +! go build +stderr 'type aliases requires' + + +-- go.mod -- +module m +go 1.8 + +-- alias.go -- +package alias +type T = int diff --git a/src/cmd/go/testdata/script/mod_edit_no_modcache.txt b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt new file mode 100644 index 0000000..ced15bb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_edit_no_modcache.txt @@ -0,0 +1,15 @@ +# 'go mod edit' opportunistically locks the side-lock file in the module cache, +# for compatibility with older versions of the 'go' command. +# It does not otherwise depend on the module cache, so it should not +# fail if the module cache directory cannot be created. + +[root] skip + +mkdir $WORK/readonly +chmod 0555 $WORK/readonly +env GOPATH=$WORK/readonly/nonexist + +go mod edit -go=1.17 + +-- go.mod -- +module example.com/m diff --git a/src/cmd/go/testdata/script/mod_empty_err.txt b/src/cmd/go/testdata/script/mod_empty_err.txt new file mode 100644 index 0000000..c4359bc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_empty_err.txt @@ -0,0 +1,36 @@ +# This test checks error messages for non-existent packages in module mode. +# Veries golang.org/issue/35414 +env GO111MODULE=on +cd $WORK + +go list -e -f {{.Error}} . +stdout 'no Go files in \$WORK' + +go list -e -f {{.Error}} ./empty +stdout 'no Go files in \$WORK[/\\]empty' + +go list -e -f {{.Error}} ./exclude +stdout 'build constraints exclude all Go files in \$WORK[/\\]exclude' + +go list -e -f {{.Error}} ./missing +stdout 'stat '$WORK'[/\\]missing: directory not found' + +# use 'go build -n' because 'go list' reports no error. +! go build -n ./testonly +stderr 'example.com/m/testonly: no non-test Go files in \$WORK[/\\]testonly' + +-- $WORK/go.mod -- +module example.com/m + +go 1.14 + +-- $WORK/empty/empty.txt -- +-- $WORK/exclude/exclude.go -- +// +build exclude + +package exclude +-- $WORK/testonly/testonly_test.go -- +package testonly_test +-- $WORK/excluded-stdout -- +package ./excluded: cannot find package "." in: + $WORK/excluded diff --git a/src/cmd/go/testdata/script/mod_enabled.txt b/src/cmd/go/testdata/script/mod_enabled.txt new file mode 100644 index 0000000..39f1ece --- /dev/null +++ b/src/cmd/go/testdata/script/mod_enabled.txt @@ -0,0 +1,93 @@ +# GO111MODULE=auto should trigger any time a go.mod exists in a parent directory. +env GO111MODULE=auto + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod +go list -m -f {{.GoMod}} +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y/z/w +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +! stdout . + +cd $GOPATH/foo +go env GOMOD +stdout foo[/\\]go.mod +go list -m -f {{.GoMod}} +stdout foo[/\\]go.mod + +cd $GOPATH/foo/bar/baz +go env GOMOD +stdout foo[/\\]go.mod + +# GO111MODULE unset should be equivalent to on. +env GO111MODULE= + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +stdout 'NUL|/dev/null' + +# GO111MODULE=on should trigger everywhere +env GO111MODULE=on + +cd $GOPATH/src/x/y/z +go env GOMOD +stdout z[/\\]go.mod + +cd $GOPATH/src/x/y/z/w +go env GOMOD +stdout z[/\\]go.mod + +cd $GOPATH/src/x/y +go env GOMOD +stdout 'NUL|/dev/null' +go list -m +stdout '^command-line-arguments$' + +cd $GOPATH/foo +go env GOMOD +stdout foo[/\\]go.mod + +cd $GOPATH/foo/bar/baz +go env GOMOD +stdout foo[/\\]go.mod + +# GO111MODULE=off should trigger nowhere +env GO111MODULE=off + +cd $GOPATH/src/x/y/z +go env GOMOD +! stdout .+ + +cd $GOPATH/foo +go env GOMOD +! stdout .+ + +cd $GOPATH/foo/bar/baz +go env GOMOD +! stdout .+ + +# GO111MODULE=auto should ignore and warn about /tmp/go.mod +env GO111MODULE=auto +cp $GOPATH/src/x/y/z/go.mod $WORK/tmp/go.mod +mkdir $WORK/tmp/mydir +cd $WORK/tmp/mydir +go env GOMOD +! stdout .+ +stderr '^go: warning: ignoring go.mod in system temp root ' + +-- $GOPATH/src/x/y/z/go.mod -- +module x/y/z +-- $GOPATH/src/x/y/z/w/w.txt -- +-- $GOPATH/foo/go.mod -- +module example.com/mod +-- $GOPATH/foo/bar/baz/quux.txt -- diff --git a/src/cmd/go/testdata/script/mod_file_proxy.txt b/src/cmd/go/testdata/script/mod_file_proxy.txt new file mode 100644 index 0000000..38d9fd2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_file_proxy.txt @@ -0,0 +1,36 @@ +[short] skip + +# Allow (cached) downloads for -mod=readonly. +env GO111MODULE=on +env GOPATH=$WORK/gopath1 +cd $WORK/x +go mod edit -fmt +go list -mod=readonly +env GOPROXY=file:///nonexist +go list +grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list + +# Use download cache as file:/// proxy. +env GOPATH=$WORK/gopath2 +[windows] env GOPROXY=file:///C:/nonexist +[!windows] env GOPROXY=file:///nonexist +! go list +[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download +[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download +go list +grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list + +-- $WORK/x/go.mod -- +module x +go 1.13 +require rsc.io/quote v1.5.1 +-- $WORK/x/x.go -- +package x +import _ "rsc.io/quote" +-- $WORK/x/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.1 h1:ZE3OgnVGrhXtFkGw90HwW992ZRqcdli/33DLqEYsoxA= +rsc.io/quote v1.5.1/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_find.txt b/src/cmd/go/testdata/script/mod_find.txt new file mode 100644 index 0000000..1e01973 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_find.txt @@ -0,0 +1,104 @@ +env GO111MODULE=on + +# Derive module path from import comment. +cd $WORK/x +exists x.go +go mod init +stderr 'module x' + +# Import comment works even with CRLF line endings. +rm go.mod +addcrlf x.go +go mod init +stderr 'module x' + +# Derive module path from location inside GOPATH. +# 'go mod init' should succeed if modules are not explicitly disabled. +cd $GOPATH/src/example.com/x/y +go mod init +stderr 'module example.com/x/y$' +rm go.mod + +# go mod init rejects a zero-length go.mod file +cp $devnull go.mod # can't use touch to create it because Windows +! go mod init +stderr 'go.mod already exists' + +# Module path from Godeps/Godeps.json overrides GOPATH. +cd $GOPATH/src/example.com/x/y/z +go mod init +stderr 'unexpected.com/z' +rm go.mod + +# Empty directory outside GOPATH fails. +mkdir $WORK/empty +cd $WORK/empty +! go mod init +stderr 'cannot determine module path for source directory' +rm go.mod + +# Empty directory inside GOPATH/src uses location inside GOPATH. +mkdir $GOPATH/src/empty +cd $GOPATH/src/empty +go mod init +stderr 'empty' +rm go.mod + +# In Plan 9, directories are automatically created in /n. +# For example, /n/go.mod always exist, but it's a directory. +# Test that we ignore directories when trying to find go.mod. +cd $WORK/gomoddir +! go list . +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +[!symlink] stop + +# gplink1/src/empty where gopathlink -> GOPATH +symlink $WORK/gopathlink -> gopath +cd $WORK/gopathlink/src/empty +go mod init +rm go.mod + +# GOPATH/src/link where link -> out of GOPATH +symlink $GOPATH/src/link -> $WORK/empty +cd $WORK/empty +! go mod init +cd $GOPATH/src/link +go mod init +stderr link +rm go.mod + +# GOPATH/src/empty where GOPATH itself is a symlink +env GOPATH=$WORK/gopathlink +cd $GOPATH/src/empty +go mod init +rm go.mod +cd $WORK/gopath/src/empty +go mod init +rm go.mod + +# GOPATH/src/link where GOPATH and link are both symlinks +cd $GOPATH/src/link +go mod init +stderr link +rm go.mod + +# Too hard: doesn't match unevaluated nor completely evaluated. (Only partially evaluated.) +# Whether this works depends on which OS we are running on. +# cd $WORK/gopath/src/link +# ! go mod init + +-- $WORK/x/x.go -- +package x // import "x" + +-- $GOPATH/src/example.com/x/y/y.go -- +package y +-- $GOPATH/src/example.com/x/y/z/z.go -- +package z +-- $GOPATH/src/example.com/x/y/z/Godeps/Godeps.json -- +{"ImportPath": "unexpected.com/z"} + +-- $WORK/gomoddir/go.mod/README.txt -- +../go.mod is a directory, not a file. +-- $WORK/gomoddir/p.go -- +package p diff --git a/src/cmd/go/testdata/script/mod_fs_patterns.txt b/src/cmd/go/testdata/script/mod_fs_patterns.txt new file mode 100644 index 0000000..276d04e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_fs_patterns.txt @@ -0,0 +1,97 @@ +env GO111MODULE=on + +# File system pattern searches should skip sub-modules and vendor directories. +cd x + +# all packages +go list all +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# path pattern +go list m/... +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# directory pattern +go list ./... +stdout ^m$ +stdout ^m/vendor$ +! stdout vendor/ +stdout ^m/y$ +! stdout ^m/y/z + +# non-existent directory should not prompt lookups +! go build -mod=readonly example.com/nonexist +stderr 'import lookup disabled' + +! go build -mod=readonly ./nonexist +! stderr 'import lookup disabled' +stderr '^stat '$GOPATH'[/\\]src[/\\]x[/\\]nonexist: directory not found' + +! go build -mod=readonly ./go.mod +! stderr 'import lookup disabled' +stderr 'main module \(m\) does not contain package m/go.mod' + + +# File system paths and patterns should allow the '@' character. +cd ../@at +go list $PWD +stdout '^at$' +go list $PWD/... +stdout '^at$' + +# The '@' character is not allowed in directory paths that are part of +# a package path. +cd ../badat/bad@ +! go list . +stderr 'directory . outside main module or its selected dependencies' +! go list $PWD +stderr 'directory . outside main module or its selected dependencies' +! go list $PWD/... +stderr 'directory . outside main module or its selected dependencies' + +-- x/go.mod -- +module m + +-- x/x.go -- +package x + +-- x/vendor/v/v.go -- +package v +import _ "golang.org/x/crypto" + +-- x/vendor/v.go -- +package main + +-- x/y/y.go -- +package y + +-- x/y/z/go.mod -- +syntax error! + +-- x/y/z/z.go -- +package z + +-- x/y/z/w/w.go -- +package w + +-- @at/go.mod -- +module at + +go 1.14 +-- @at/at.go -- +package at + +-- badat/go.mod -- +module badat + +go 1.14 +-- badat/bad@/bad.go -- +package bad diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt new file mode 100644 index 0000000..9214993 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_arg.txt @@ -0,0 +1,107 @@ +go mod tidy +cp go.mod go.mod.orig + +# If there is no sensible *package* meaning for 'm/p', it should refer +# to *module* m/p. + +go get m/p # @latest +go list -m all +stdout '^m/p v0.3.0 ' +! stdout '^m ' + +cp go.mod.orig go.mod + +go get m/p@v0.1.0 +go list -m all +stdout '^m/p v0.1.0 ' +! stdout '^m ' + +# When feasible, the argument 'm/p' in 'go get m/p' refers to *package* m/p, +# which is in module m. +# +# (It only refers to *module* m/p if there is no such package at the +# requested version.) + +go get m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' # unchanged from the previous case + +# Repeating the above with module m/p already in the module graph does not +# change its meaning. + +go get m/p@v0.2.0 +go list -m all +stdout '^m v0.2.0 ' +stdout '^m/p v0.1.0 ' + +-- go.mod -- +module example.com + +go 1.16 + +replace ( + m v0.1.0 => ./m01 + m v0.2.0 => ./m02 + m v0.3.0 => ./m03 + m/p v0.1.0 => ./mp01 + m/p v0.2.0 => ./mp02 + m/p v0.3.0 => ./mp03 +) +-- m01/go.mod -- +module m + +go 1.16 +-- m01/README.txt -- +Module m at v0.1.0 does not yet contain package p. + +-- m02/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m02/p/p.go -- +// Package p is present in module m, but not module m/p. +package p + +-- m03/go.mod -- +module m + +go 1.16 + +require m/p v0.1.0 +-- m03/README.txt -- +Module m at v0.3.0 no longer contains package p. + +-- mv2/go.mod -- +module m/v2 + +go 1.16 +-- mv2/README.txt -- +This module is m/v2. It doesn't actually need to exist, +but it explains how module m could plausibly exist +and still contain package p at 'latest' even when module +m/p also exists. + +-- mp01/go.mod -- +module m/p + +go 1.16 +-- mp01/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp02/go.mod -- +module m/p + +go 1.16 +-- mp02/README.txt -- +This module is m/p. +Package m/p does not exist in this module. +-- mp03/go.mod -- +module m/p + +go 1.16 +-- mp03/README.txt -- +This module is m/p. +Package m/p does not exist in this module. diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt new file mode 100644 index 0000000..0af78bd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_import.txt @@ -0,0 +1,60 @@ +go list -m all +stdout '^example.net/m v0.1.0 ' +! stdout '^example.net/m/p ' +cp go.mod go.mod.orig + +# Upgrading example.net/m/p without also upgrading example.net/m +# causes the import of package example.net/m/p to be ambiguous. +# +# TODO(#27899): Should we automatically upgrade example.net/m to v0.2.0 +# to resolve the conflict? +! go get example.net/m/p@v1.0.0 +stderr '^example.net/m/p: ambiguous import: found package example.net/m/p in multiple modules:\n\texample.net/m v0.1.0 \(.*[/\\]m1[/\\]p\)\n\texample.net/m/p v1.0.0 \(.*[/\\]p0\)\n\z' +cmp go.mod go.mod.orig + +# Upgrading both modules simultaneously resolves the ambiguous upgrade. +# Note that this command line mixes a module path (example.net/m) +# and a package path (example.net/m/p) in the same command. +go get example.net/m@v0.2.0 example.net/m/p@v1.0.0 + +go list -m all +stdout '^example.net/m v0.2.0 ' +stdout '^example.net/m/p v1.0.0 ' + +-- go.mod -- +module example.net/importer + +go 1.16 + +require ( + example.net/m v0.1.0 +) + +replace ( + example.net/m v0.1.0 => ./m1 + example.net/m v0.2.0 => ./m2 + example.net/m/p v1.0.0 => ./p0 +) +-- importer.go -- +package importer +import _ "example.net/m/p" +-- m1/go.mod -- +module example.net/m + +go 1.16 +-- m1/p/p.go -- +package p +-- m2/go.mod -- +module example.net/m + +go 1.16 +-- m2/README.txt -- +Package p has been moved to module …/m/p. +Module …/m/p does not require any version of module …/m. + +-- p0/go.mod -- +module example.net/m/p + +go 1.16 +-- p0/p.go -- +package p diff --git a/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt new file mode 100644 index 0000000..1641196 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_ambiguous_pkg.txt @@ -0,0 +1,87 @@ +# Both example.net/ambiguous v0.1.0 and example.net/ambiguous/pkg v0.1.0 exist. +# 'go mod tidy' would arbitrarily choose the one with the longer path, +# but 'go mod tidy' also arbitrarily chooses the latest version. + +cp go.mod go.mod.orig + + +# From a clean slate, 'go get' currently does the same thing as 'go mod tidy': +# it resolves the package from the module with the longest matching prefix. + +go get example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# From an initial state that already depends on the shorter path, +# the same 'go get' command should (somewhat arbitrarily) keep the +# existing path, since it is a valid interpretation of the command. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous v0.1.0$' +! stdout '^example.net/ambiguous/nested ' + + +# The user should be able to make the command unambiguous by explicitly +# upgrading the conflicting module... + +go get example.net/ambiguous@v0.2.0 example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +stdout '^example.net/ambiguous v0.2.0$' + + +# ...or by explicitly NOT adding the conflicting module. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get example.net/ambiguous/nested/pkg@v0.1.0 example.net/ambiguous/nested@none +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +# The user should also be able to fix it by *downgrading* the conflicting module +# away. + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get example.net/ambiguous@none example.net/ambiguous/nested/pkg@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +# In contrast, if we do the same thing tacking a wildcard pattern ('/...') on +# the end of the package path, we get different behaviors depending on the +# initial state, and no error. (This seems to contradict the “same meaning +# regardless of the initial state” point above, but maybe that's ok?) + +cp go.mod.orig go.mod + +go get example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +stdout '^example.net/ambiguous/nested v0.1.0$' +! stdout '^example.net/ambiguous ' + + +cp go.mod.orig go.mod +go mod edit -require=example.net/ambiguous@v0.1.0 + +go get example.net/ambiguous/nested/pkg/...@v0.1.0 +go list -m all +! stdout '^example.net/ambiguous/nested ' +stdout '^example.net/ambiguous v0.1.0$' + + +-- go.mod -- +module test + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_get_changes.txt b/src/cmd/go/testdata/script/mod_get_changes.txt new file mode 100644 index 0000000..12a112b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_changes.txt @@ -0,0 +1,70 @@ +# When adding a requirement, 'go get' prints a message for the requirement +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go list -m all +! stdout golang.org/x/text +go get rsc.io/quote@v1.5.2 +stderr '^go: added rsc.io/quote v1.5.2$' +stderr '^go: upgraded rsc.io/sampler v1.0.0 => v1.3.0$' +! stderr '^go get.*golang.org/x/text' +go list -m all +stdout golang.org/x/text +cmp go.mod go.mod.upgrade + +# When removing a requirement, 'go get' prints a message for the requiremnent +# and for changed explicit dependencies. 'go get' does not print messages +# for changed indirect dependencies. +go get rsc.io/sampler@none +stderr '^go: downgraded rsc.io/quote v1.5.2 => v1.3.0$' +stderr '^go: removed rsc.io/sampler v1.3.0$' +! stderr '^go get.*golang.org/x/text' +cmp go.mod go.mod.downgrade + +# When removing or downgrading a requirement, 'go get' also prints a message +# for explicit dependencies removed as a consequence. +cp go.mod.usequote go.mod +go get rsc.io/quote@v1.5.1 +stderr '^go: downgraded rsc.io/quote v1.5.2 => v1.5.1$' +stderr '^go: removed usequote v0.0.0$' + +-- go.mod -- +module m + +go 1.16 + +require rsc.io/sampler v1.0.0 +-- go.sum -- +rsc.io/sampler v1.0.0 h1:SRJnjyQ07sAtq6G4RcfJEmz8JxqLyj3PoGXG2VhbDWo= +rsc.io/sampler v1.0.0/go.mod h1:cqxpM3ZVz9VtirqxZPmrWzkQ+UkiNiGtkrN+B+i8kx8= +-- go.mod.upgrade -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 +) +-- go.mod.downgrade -- +module m + +go 1.16 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/quote v1.3.0 // indirect +) +-- go.mod.usequote -- +module m + +go 1.16 + +require usequote v0.0.0 + +replace usequote => ./usequote +-- usequote/go.mod -- +module usequote + +go 1.16 + +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_get_commit.txt b/src/cmd/go/testdata/script/mod_get_commit.txt new file mode 100644 index 0000000..f60eaab --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_commit.txt @@ -0,0 +1,52 @@ +env GO111MODULE=on +[short] skip + +# @commit should resolve + +# golang.org/x/text/language@commit should resolve. +# Because of -d, the compiler should not run. +go get -x golang.org/x/text/language@14c0d48 +! stderr 'compile|cp|gccgo .*language\.a$' + +# go get should skip build with no Go files in root +go get golang.org/x/text@14c0d48 + +# dropping -d, we should see a build. +[short] skip + +env GOCACHE=$WORK/gocache # Looking for compile commands, so need a clean cache. + +go build -x golang.org/x/text/language +stderr 'compile|cp|gccgo .*language\.a$' + +# BUG: after the build, the package should not be stale, as 'go install' would +# not do anything further. +go list -f '{{.Stale}}' golang.org/x/text/language +stdout ^true + +# install after build should not run the compiler again. +go install -x golang.org/x/text/language +! stderr 'compile|cp|gccgo .*language\.a$' + +# we should see an error for unknown packages. +! go get -x golang.org/x/text/foo@14c0d48 +stderr '^go: module golang.org/x/text@14c0d48 found \(v0.3.0\), but does not contain package golang.org/x/text/foo$' + +# get pseudo-version should record that version +go get rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 +grep 'rsc.io/quote v0.0.0-20180214005840-23179ee8a569' go.mod + +# but as commit should record as v1.5.1 +go get rsc.io/quote@23179ee8 +grep 'rsc.io/quote v1.5.1' go.mod + +# go mod edit -require does not interpret commits +go mod edit -require rsc.io/quote@23179ee +grep 'rsc.io/quote 23179ee' go.mod + +# but other commands fix them +go list -m -mod=mod all +grep 'rsc.io/quote v1.5.1' go.mod + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_get_deprecate_install.txt b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt new file mode 100644 index 0000000..03258f5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_deprecate_install.txt @@ -0,0 +1,42 @@ +[short] skip + +env GO111MODULE=on + +# 'go get' outside a module prints an error. +! go get example.com/cmd/a +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' + +cp go.mod.orig go.mod + +# 'go get' inside a module with a non-main package does not print a message. +# This will stop building in the future, but it's the command we want to use. +go get rsc.io/quote +! stderr deprecated +! stderr 'no longer installs' +cp go.mod.orig go.mod + +# 'go get' inside a module with an executable does not print a message. +# In 1.16 and 1.17, 'go get' did print a message in this case suggesting the +# use of -d. In 1.18, -d is a no-op, and we'd like to begin discouraging +# its use. +go get example.com/cmd/a +! stderr deprecated +! stderr 'no longer installs' +cp go.mod.orig go.mod + +# 'go get' should not print a warning for a main package inside the main module. +# The intent is most likely to update the dependencies of that package. +# 'go install' would be used otherwise. +go get m +! stderr . +cp go.mod.orig go.mod + +-- go.mod.orig -- +module m + +go 1.17 +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_get_deprecated.txt b/src/cmd/go/testdata/script/mod_get_deprecated.txt new file mode 100644 index 0000000..ec7bcfd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_deprecated.txt @@ -0,0 +1,66 @@ +# 'go get pkg' should not show a deprecation message for an unrelated module. +go get ./use/nothing +! stderr 'module.*is deprecated' + +# 'go get pkg' should show a deprecation message for the module providing pkg. +go get example.com/deprecated/a +stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$' +go get example.com/deprecated/a@v1.0.0 +stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$' + +# 'go get pkg' should show a deprecation message for a module providing +# packages directly imported by pkg. +go get ./use/a +stderr '^go: module example.com/deprecated/a is deprecated: in example.com/deprecated/a@v1.9.0$' + +# 'go get pkg' may show a deprecation message for an indirectly required module +# if it provides a package named on the command line. +go get ./use/b +! stderr 'module.*is deprecated' +go get local/use +! stderr 'module.*is deprecated' +go get example.com/deprecated/b +stderr '^go: module example.com/deprecated/b is deprecated: in example.com/deprecated/b@v1.9.0$' + +# 'go get pkg' does not show a deprecation message for a module providing a +# directly imported package if the module is no longer deprecated in its +# latest version, even if the module is deprecated in its current version. +go get ./use/undeprecated +! stderr 'module.*is deprecated' + +-- go.mod -- +module m + +go 1.17 + +require ( + example.com/deprecated/a v1.0.0 + example.com/undeprecated v1.0.0 + local v0.0.0 +) + +replace local v0.0.0 => ./local +-- use/nothing/nothing.go -- +package nothing +-- use/a/a.go -- +package a + +import _ "example.com/deprecated/a" +-- use/b/b.go -- +package b + +import _ "local/use" +-- use/undeprecated/undeprecated.go -- +package undeprecated + +import _ "example.com/undeprecated" +-- local/go.mod -- +module local + +go 1.17 + +require example.com/deprecated/b v1.0.0 +-- local/use/use.go -- +package use + +import _ "example.com/deprecated/b" diff --git a/src/cmd/go/testdata/script/mod_get_direct.txt b/src/cmd/go/testdata/script/mod_get_direct.txt new file mode 100644 index 0000000..856e05b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_direct.txt @@ -0,0 +1,20 @@ +# Regression test for golang.org/issue/34092: with an empty module cache, +# 'GOPROXY=direct go get golang.org/x/tools/gopls@master' did not correctly +# resolve the pseudo-version for its dependency on golang.org/x/tools. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +go list -m cloud.google.com/go@main +! stdout 'v0.0.0-' + +-- go.mod -- +module example.com + +go 1.14 +-- go.sum -- diff --git a/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt b/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt new file mode 100644 index 0000000..0f5ba99 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downadd_indirect.txt @@ -0,0 +1,81 @@ +# This test illustrates a case where downgrading one module may upgrade another. +# Compare to the downcross2 test case in cmd/go/internal/mvs/mvs_test.go. + +# The initial package import graph used in this test looks like: +# +# a ---- b ---- d +# +# The module dependency graph originally looks like: +# +# a ---- b.2 ---- d.2 +# +# b.1 ---- c.1 +# +# If we downgrade module d to version 1, we must downgrade b as well. +# If that downgrade selects b version 1, we will add a new dependency on module c. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go get example.com/d@v0.1.0 +go list -m all +stdout '^example.com/b v0.1.0 ' +stdout '^example.com/c v0.1.0 ' +stdout '^example.com/d v0.1.0 ' + +-- go.mod -- +module example.com/a + +go 1.15 + +require example.com/b v0.2.0 + +replace ( + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/c v0.1.0 => ./c + example.com/d v0.1.0 => ./d + example.com/d v0.2.0 => ./d +) +-- a.go -- +package a + +import _ "example.com/b" + +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b + +import _ "example.com/c" + +-- b2/go.mod -- +module example.com/b + +go 1.15 + +require example.com/d v0.2.0 +-- b2/b.go -- +package b + +import _ "example.com/d" + +-- c/go.mod -- +module example.com/c + +go 1.15 + +-- c/c.go -- +package c + +-- d/go.mod -- +module example.com/d + +go 1.15 +-- d/d.go -- +package d diff --git a/src/cmd/go/testdata/script/mod_get_downgrade.txt b/src/cmd/go/testdata/script/mod_get_downgrade.txt new file mode 100644 index 0000000..2eed56d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downgrade.txt @@ -0,0 +1,56 @@ +env GO111MODULE=on +[short] skip + +# downgrade sampler should downgrade quote +cp go.mod.orig go.mod +go get rsc.io/sampler@v1.0.0 +go list -m all +stdout 'rsc.io/quote v1.4.0' +stdout 'rsc.io/sampler v1.0.0' + +# downgrade sampler away should downgrade quote further +go get rsc.io/sampler@none +go list -m all +stdout 'rsc.io/quote v1.3.0' + +# downgrade should report inconsistencies and not change go.mod +go get rsc.io/quote@v1.5.1 +go list -m all +stdout 'rsc.io/quote v1.5.1' +stdout 'rsc.io/sampler v1.3.0' + +! go get rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none +! stderr add|remove|upgrad|downgrad +stderr '^go: rsc.io/quote@v1.5.2 requires rsc.io/sampler@v1.3.0, not rsc.io/sampler@v1.0.0$' + +go list -m all +stdout 'rsc.io/quote v1.5.1' +stdout 'rsc.io/sampler v1.3.0' + +# go get -u args should limit upgrades +cp go.mod.empty go.mod +go get -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 +go list -m all +stdout 'rsc.io/quote v1.4.0' +stdout 'rsc.io/sampler v1.0.0' +! stdout golang.org/x/text + +# downgrading away quote should also downgrade away latemigrate/v2, +# since there are no older versions. v2.0.0 is incompatible. +cp go.mod.orig go.mod +go list -m -versions example.com/latemigrate/v2 +stdout v2.0.0 # proxy may serve incompatible versions +go get rsc.io/quote@none +go list -m all +! stdout 'example.com/latemigrate/v2' + +-- go.mod.orig -- +module x +require ( + rsc.io/quote v1.5.1 + example.com/latemigrate/v2 v2.0.1 +) +-- go.mod.empty -- +module x +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt new file mode 100644 index 0000000..582593b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downgrade_missing.txt @@ -0,0 +1,43 @@ +cp go.mod go.mod.orig + +# getting a specific version of a module along with a pattern +# not yet present in that module should report the version mismatch +# rather than a "matched no packages" warning. + +! go get example.net/pkgadded@v1.1.0 example.net/pkgadded/subpkg/... +stderr '^go: example.net/pkgadded@v1.1.0 conflicts with example.net/pkgadded/subpkg/...@upgrade \(v1.2.0\)$' +! stderr 'matched no packages' +cmp go.mod.orig go.mod + + +# A wildcard pattern should match the pattern with that path. + +go get example.net/pkgadded/...@v1.0.0 +go list -m all +stdout '^example.net/pkgadded v1.0.0' +cp go.mod.orig go.mod + + +# If we need to resolve a transitive dependency of a package, +# and another argument constrains away the version that provides that +# package, then 'go get' should fail with a useful error message. + +! go get example.net/pkgadded@v1.0.0 . +stderr '^example.com/m imports\n\texample.net/pkgadded/subpkg: cannot find module providing package example.net/pkgadded/subpkg$' +! stderr 'example.net/pkgadded v1\.2\.0' +cmp go.mod.orig go.mod + +go get example.net/pkgadded@v1.0.0 +! go list -deps -mod=readonly . +stderr '^m.go:3:8: cannot find module providing package example\.net/pkgadded/subpkg: ' + +-- go.mod -- +module example.com/m + +go 1.16 + +require example.net/pkgadded v1.2.0 +-- m.go -- +package m + +import _ "example.net/pkgadded/subpkg" diff --git a/src/cmd/go/testdata/script/mod_get_downup_artifact.txt b/src/cmd/go/testdata/script/mod_get_downup_artifact.txt new file mode 100644 index 0000000..111a54f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downup_artifact.txt @@ -0,0 +1,159 @@ +# This test illustrates a case where an upgrade–downgrade–upgrade cycle can +# result in upgrades of otherwise-irrelevant dependencies. +# +# This case has no corresponding test in the mvs package, because it is an +# artifact that results from the composition of *multiple* MVS operations. + +# The initial package import graph used in the test looks like: +# +# m ---- a +# | | +# +----- b +# | | +# +----- c +# | +# +----- d +# +# b version 2 adds its own import of package d. +# +# The module dependency graph initially looks like: +# +# m ---- a.1 +# | | +# +----- b.1 +# | | +# +----- c.1 +# | +# +----- d.1 +# +# b.2 ---- c.2 +# | +# +------ d.2 +# | +# +------ e.1 +# +# If we upgrade module b to version 2, we will upgrade c and d and add a new +# dependency on e. If b version 2 is disallowed because of any of those +# dependencies, the other dependencies should not be upgraded as a side-effect. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.1.0 ' +stdout '^example.com/c v0.1.0 ' +stdout '^example.com/d v0.1.0 ' +! stdout '^example.com/e ' + +# b is imported by a, so the -u flag would normally upgrade it to v0.2.0. +# However, that would conflict with the explicit c@v0.1.0 constraint, +# so b must remain at v0.1.0. +# +# If we're not careful, we might temporarily add b@v0.2.0 and pull in its +# upgrades of module d and addition of module e, which are not relevant to +# b@v0.1.0 and should not be added to the main module's dependencies. + +go get -u example.com/a@latest example.com/c@v0.1.0 + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.1.0 ' +stdout '^example.com/c v0.1.0 ' +stdout '^example.com/d v0.1.0 ' +! stdout '^example.com/e ' + +-- go.mod -- +module example.com/m + +go 1.16 + +require ( + example.com/a v0.1.0 + example.com/b v0.1.0 + example.com/c v0.1.0 + example.com/d v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a1 + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/c v0.1.0 => ./c + example.com/c v0.2.0 => ./c + example.com/d v0.1.0 => ./d + example.com/d v0.2.0 => ./d + example.com/e v0.1.0 => ./e +) +-- m.go -- +package m + +import ( + _ "example.com/a" + _ "example.com/b" + _ "example.com/c" + _ "example.com/d" +) + +-- a1/go.mod -- +module example.com/a + +go 1.16 + +require example.com/b v0.1.0 +-- a1/a.go -- +package a + +import _ "example.com/b" + +-- b1/go.mod -- +module example.com/b + +go 1.16 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b + +import _ "example.com/c" + +-- b2/go.mod -- +module example.com/b + +go 1.16 + +require ( + example.com/c v0.2.0 + example.com/d v0.2.0 + example.com/e v0.1.0 +) +-- b2/b.go -- +package b + +import ( + "example.com/c" + "example.com/d" + "example.com/e" +) + +-- c/go.mod -- +module example.com/c + +go 1.16 +-- c/c.go -- +package c + +-- d/go.mod -- +module example.com/d + +go 1.16 +-- d/d.go -- +package d + +-- e/go.mod -- +module example.com/e + +go 1.16 +-- e/e.go -- +package e diff --git a/src/cmd/go/testdata/script/mod_get_downup_indirect.txt b/src/cmd/go/testdata/script/mod_get_downup_indirect.txt new file mode 100644 index 0000000..3a46a77 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downup_indirect.txt @@ -0,0 +1,101 @@ +# This test illustrates a case where downgrading one module may upgrade another. +# Compare to the downcross1 test case in cmd/go/internal/mvs/mvs_test.go. + +# The package import graph used in this test looks like: +# +# a ---- b +# \ \ +# \ \ +# ----- c ---- d +# +# The module dependency graph originally looks like: +# +# a ---- b.2 +# \ \ +# \ \ +# ----- c.1 ---- d.2 +# +# b.1 ---- c.2 +# +# If we downgrade module d to version 1, we must downgrade b as well. +# If that downgrade selects b version 1, we will upgrade module c to version 2. +# So 'go get d@1' should instead downgrade both b and c to "none". + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go get example.com/d@v0.1.0 +go list -m all +! stdout '^example.com/b ' +! stdout '^example.com/c ' +stdout '^example.com/d v0.1.0 ' + +-- go.mod -- +module example.com/a + +go 1.15 + +require ( + example.com/b v0.2.0 + example.com/c v0.1.0 +) + +replace ( + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 + example.com/d v0.1.0 => ./d + example.com/d v0.2.0 => ./d +) +-- a.go -- +package a + +import ( + _ "example.com/b" + _ "example.com/c" +) + +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.2.0 +-- b1/b.go -- +package b + +import _ "example.com/c" + +-- b2/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b2/b.go -- +package b + +import _ "example.com/c" + +-- c1/go.mod -- +module example.com/c + +go 1.15 + +require example.com/d v0.2.0 +-- c1/c.go -- +package c + +-- c2/go.mod -- +module example.com/c + +go 1.15 +-- c2/c.go -- +package c + +-- d/go.mod -- +module example.com/d + +go 1.15 diff --git a/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt b/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt new file mode 100644 index 0000000..b678a17 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_downup_pseudo_artifact.txt @@ -0,0 +1,129 @@ +# This test illustrates a case where an upgrade–downgrade–upgrade cycle could +# add extraneous dependencies due to another module depending on an +# otherwise-unlisted version (such as a pseudo-version). +# +# This case corresponds to the "downhiddenartifact" test in the mvs package. + +# The initial package import graph used in the test looks like: +# +# a --- b +# \ \ +# \ \ +# c --- d +# +# The module dependency graph initially looks like: +# +# a --- b.3 +# \ \ +# \ \ +# c.2 --- d.2 +# +# c.1 --- b.2 (pseudo) +# +# b.1 --- e.1 + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +# When we downgrade d.2 to d.1, no dependency on e should be added +# because nothing else in the module or import graph requires it. +go get example.net/d@v0.1.0 + +go list -m all +stdout '^example.net/b v0.2.1-0.20210219000000-000000000000 ' +stdout '^example.net/c v0.1.0 ' +stdout '^example.net/d v0.1.0 ' +! stdout '^example.net/e ' + +-- go.mod -- +module example.net/a + +go 1.16 + +require ( + example.net/b v0.3.0 + example.net/c v0.2.0 +) + +replace ( + example.net/b v0.1.0 => ./b1 + example.net/b v0.2.1-0.20210219000000-000000000000 => ./b2 + example.net/b v0.3.0 => ./b3 + example.net/c v0.1.0 => ./c1 + example.net/c v0.2.0 => ./c2 + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d + example.net/e v0.1.0 => ./e +) +-- a.go -- +package a + +import ( + _ "example.net/b" + _ "example.net/c" +) + +-- b1/go.mod -- +module example.net/b + +go 1.16 + +require example.net/e v0.1.0 +-- b1/b.go -- +package b + +import _ "example.net/e" + +-- b2/go.mod -- +module example.net/b + +go 1.16 +-- b2/b.go -- +package b + +-- b3/go.mod -- +module example.net/b + +go 1.16 + +require example.net/d v0.2.0 +-- b3/b.go -- +package b + +import _ "example.net/d" +-- c1/go.mod -- +module example.net/c + +go 1.16 + +require example.net/b v0.2.1-0.20210219000000-000000000000 +-- c1/c.go -- +package c + +import _ "example.net/b" + +-- c2/go.mod -- +module example.net/c + +go 1.16 + +require example.net/d v0.2.0 +-- c2/c.go -- +package c + +import _ "example.net/d" + +-- d/go.mod -- +module example.net/d + +go 1.16 +-- d/d.go -- +package d + +-- e/go.mod -- +module example.net/e + +go 1.16 +-- e/e.go -- +package e diff --git a/src/cmd/go/testdata/script/mod_get_errors.txt b/src/cmd/go/testdata/script/mod_get_errors.txt new file mode 100644 index 0000000..7cb03ce --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_errors.txt @@ -0,0 +1,57 @@ +cp go.mod go.mod.orig + + +# 'go get' should fail, without updating go.mod, if the transitive dependencies +# of the requested package (by default, the package in the current directory) +# cannot be resolved. + +! go get +stderr '^example.com/m imports\n\texample.com/badimport imports\n\texample.net/oops: cannot find module providing package example.net/oops$' +cmp go.mod.orig go.mod + +cd importsyntax + + +# A syntax error in a dependency prevents the compiler from needing that +# dependency's imports, so 'go get' should not report an error when those +# imports cannot be resolved: it has all of the dependencies that the compiler +# needs, and the user did not request to run the compiler. + +go get +cmp ../go.mod.syntax-d ../go.mod + + +-- go.mod -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport +-- go.mod.syntax-d -- +module example.com/m + +go 1.16 + +replace example.com/badimport v0.1.0 => ./badimport + +require example.com/badimport v0.1.0 +-- m.go -- +package m + +import _ "example.com/badimport" +-- importsyntax/importsyntax.go -- +package importsyntax + +import _ "example.com/badimport/syntaxerror" +-- badimport/go.mod -- +module example.com/badimport + +go 1.16 +-- badimport/badimport.go -- +package badimport + +import "example.net/oops" +-- badimport/syntaxerror/syntaxerror.go -- +pack-age syntaxerror // sic + +import "example.net/oops" diff --git a/src/cmd/go/testdata/script/mod_get_extra.txt b/src/cmd/go/testdata/script/mod_get_extra.txt new file mode 100644 index 0000000..083e036 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_extra.txt @@ -0,0 +1,69 @@ +cp go.mod go.mod.orig + +# The -u flag should not (even temporarily) upgrade modules whose versions are +# determined by explicit queries to any version other than the explicit one. +# Otherwise, 'go get -u' could introduce spurious dependencies. + +go get -u example.net/a@v0.1.0 example.net/b@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +! stdout '^example.net/c ' + + +# TODO(bcmills): This property does not yet hold for modules added for +# missing packages when the newly-added module matches a wildcard. + +cp go.mod.orig go.mod + +go get -u example.net/a@v0.1.0 example.net/b/...@v0.1.0 +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' +stdout '^example.net/c ' # BUG, but a minor and rare one + + +-- go.mod -- +module example + +go 1.15 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/b v0.1.0 => ./b1 + example.net/b v0.2.0 => ./b2 + example.net/c v0.1.0 => ./c1 + example.net/c v0.2.0 => ./c1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 + +// example.net/a needs a dependency on example.net/b, but lacks a requirement +// on it (perhaps due to a missed file in a VCS commit). +-- a1/a.go -- +package a +import _ "example.net/b" + +-- b1/go.mod -- +module example.net/b + +go 1.15 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.15 + +require example.net/c v0.1.0 +-- b2/b.go -- +package b + +-- c1/go.mod -- +module example.net/c + +go 1.15 diff --git a/src/cmd/go/testdata/script/mod_get_fallback.txt b/src/cmd/go/testdata/script/mod_get_fallback.txt new file mode 100644 index 0000000..3572233 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_fallback.txt @@ -0,0 +1,15 @@ +env GO111MODULE=on + +[!net] skip + +env GOPROXY=https://proxy.golang.org,direct +env GOSUMDB=off + +go get -x -v golang.org/x/tools/cmd/goimports +stderr '# get https://proxy.golang.org/golang.org/x/tools/@v/list' +! stderr '# get https://golang.org' + +-- go.mod -- +module m + +go 1.18 diff --git a/src/cmd/go/testdata/script/mod_get_fossil.txt b/src/cmd/go/testdata/script/mod_get_fossil.txt new file mode 100644 index 0000000..c2d42f0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_fossil.txt @@ -0,0 +1,28 @@ +[!net] skip +[!exec:fossil] skip + +# Regression test for 'go get' to ensure repositories +# provided by fossil v2.12 and up are able to be fetched +# and parsed correctly. +# Verifies golang.org/issue/42323. + + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get' for the fossil repo will fail if fossil +# is unable to determine your fossil user. Easiest +# way to set it for use by 'go get' is specifying +# a any non-empty $USER; the value doesn't otherwise matter. +env USER=fossiluser +env FOSSIL_HOME=$WORK/home + +# Attempt to get the latest version of a fossil repo. +go get vcs-test.golang.org/fossil/hello.fossil +! stderr 'unexpected response from fossil info' +grep 'vcs-test.golang.org/fossil/hello.fossil' go.mod + +-- go.mod -- +module x +-- $WORK/home/.fossil -- diff --git a/src/cmd/go/testdata/script/mod_get_go_file.txt b/src/cmd/go/testdata/script/mod_get_go_file.txt new file mode 100644 index 0000000..c81e491 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_go_file.txt @@ -0,0 +1,73 @@ +# Tests Issue #38478 +# Tests that go get in GOMOD mode returns a specific error if the argument +# ends with '.go', has no version, and either has no slash or refers to an +# existing file. + +env GO111MODULE=on + +# argument doesn't have .go suffix and has no version +! go get test +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix and has version +! go get test.go@v1.0.0 +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a file and exists +! go get test.go +stderr 'go: test.go: arguments must be package or module paths' + +# argument has .go suffix, doesn't exist and has no slashes +! go get test_missing.go +stderr 'arguments must be package or module paths' + +# argument has .go suffix, is a file and exists in sub-directory +! go get test/test.go +stderr 'go: test/test.go exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, doesn't exist and has slashes +! go get test/test_missing.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' + +# argument has .go suffix, is a symlink and exists +[symlink] symlink test_sym.go -> test.go +[symlink] ! go get test_sym.go +[symlink] stderr 'go: test_sym.go: arguments must be package or module paths' +[symlink] rm test_sym.go + +# argument has .go suffix, is a symlink and exists in sub-directory +[symlink] symlink test/test_sym.go -> test.go +[symlink] ! go get test/test_sym.go +[symlink] stderr 'go: test/test_sym.go exists as a file, but ''go get'' requires package arguments' +[symlink] rm test_sym.go + +# argument has .go suffix, is a directory and exists +mkdir test_dir.go +! go get test_dir.go +stderr 'go: test_dir.go: arguments must be package or module paths' +rm test_dir.go + +# argument has .go suffix, is a directory and exists in sub-directory +mkdir test/test_dir.go +! go get test/test_dir.go +! stderr 'arguments must be package or module paths' +! stderr 'exists as a file, but ''go get'' requires package arguments' +rm test/test_dir.go + + +-- go.mod -- +module m + +go 1.18 + +-- test.go -- +package main +func main() {println("test")} + + +-- test/test.go -- +package main +func main() {println("test")} diff --git a/src/cmd/go/testdata/script/mod_get_hash.txt b/src/cmd/go/testdata/script/mod_get_hash.txt new file mode 100644 index 0000000..3bb3ee7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_hash.txt @@ -0,0 +1,19 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +[!net] skip +[!exec:git] skip + +# fetch commit hash reachable from refs/heads/* and refs/tags/* is OK +go list -m golang.org/x/time@8be79e1e0910c292df4e79c241bb7e8f7e725959 # on master branch + +# fetch other commit hash, even with a non-standard ref, is not OK +! go list -m golang.org/x/time@334d83c35137ac2b376c1dc3e4c7733791855a3a # refs/changes/24/41624/3 +stderr 'unknown revision' +! go list -m golang.org/x/time@v0.0.0-20170424233410-334d83c35137 +stderr 'unknown revision' +! go list -m golang.org/x/time@334d83c35137 +stderr 'unknown revision' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_get_incompatible.txt b/src/cmd/go/testdata/script/mod_get_incompatible.txt new file mode 100644 index 0000000..5a7d706 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_incompatible.txt @@ -0,0 +1,26 @@ +env GO111MODULE=on + +go get x +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +cp go.mod2 go.mod +go get rsc.io/breaker@7307b30 +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +go get rsc.io/breaker@v2.0.0 +go list -m all +stdout 'rsc.io/breaker v2.0.0\+incompatible' + +-- go.mod -- +module x + +-- go.mod2 -- +module x +require rsc.io/breaker v1.0.0 + +-- x.go -- +package x +import "rsc.io/breaker" +var _ = breaker.XX diff --git a/src/cmd/go/testdata/script/mod_get_indirect.txt b/src/cmd/go/testdata/script/mod_get_indirect.txt new file mode 100644 index 0000000..fa7edf2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_indirect.txt @@ -0,0 +1,59 @@ +env GO111MODULE=on +[short] skip + +# get -u should not upgrade anything, since the package +# in the current directory doesn't import anything. +go get -u +go list -m all +stdout 'quote v1.5.1$' +grep 'rsc.io/quote v1.5.1$' go.mod + +# get -u should find quote v1.5.2 once there is a use. +cp $WORK/tmp/usequote.go x.go +go get -u +go list -m all +stdout 'quote v1.5.2$' +grep 'rsc.io/quote v1.5.2$' go.mod + +# it should also update x/text later than requested by v1.5.2 +go list -m -f '{{.Path}} {{.Version}}{{if .Indirect}} // indirect{{end}}' all +stdout '^golang.org/x/text [v0-9a-f\.-]+ // indirect' +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# importing an empty module root as a package does not remove indirect tag. +cp $WORK/tmp/usetext.go x.go +go list -e +grep 'golang.org/x/text v0.3.0 // indirect$' go.mod + +# indirect tag should be removed upon seeing direct import. +cp $WORK/tmp/uselang.go x.go +go get +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod + +# indirect tag should be added by go mod tidy +cp $WORK/tmp/usequote.go x.go +go mod tidy +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# requirement should be dropped entirely if not needed +cp $WORK/tmp/uselang.go x.go +go mod tidy +! grep rsc.io/quote go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod + +-- go.mod -- +module x +require rsc.io/quote v1.5.1 +-- x.go -- +package x +-- $WORK/tmp/usetext.go -- +package x +import _ "golang.org/x/text" +-- $WORK/tmp/uselang.go -- +package x +import _ "golang.org/x/text/language" +-- $WORK/tmp/usequote.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_issue37438.txt b/src/cmd/go/testdata/script/mod_get_issue37438.txt new file mode 100644 index 0000000..9392e73 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_issue37438.txt @@ -0,0 +1,37 @@ +# Regression test for https://golang.org/issue/37438. +# +# If a path exists at the requested version, but does not exist at the +# version of the module that is already required and does not exist at +# the version that would be selected by 'go mod tidy', then +# 'go get foo@requested' should resolve the requested version, +# not error out on the (unrelated) latest one. + +go get example.net/a/p@v0.2.0 + +-- go.mod -- +module example + +go 1.15 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/a v0.2.0 => ./a2 + example.net/a v0.3.0 => ./a1 +) + +-- a1/go.mod -- +module example.net/a + +go 1.15 +-- a1/README -- +package example.net/a/p does not exist at this version. + +-- a2/go.mod -- +module example.net/a + +go 1.15 +-- a2/p/p.go -- +// Package p exists only at v0.2.0. +package p diff --git a/src/cmd/go/testdata/script/mod_get_issue47979.txt b/src/cmd/go/testdata/script/mod_get_issue47979.txt new file mode 100644 index 0000000..848ee3a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_issue47979.txt @@ -0,0 +1,117 @@ +# Regression test for https://golang.org/issue/47979: +# +# An argument to 'go get' that results in an upgrade to a different existing +# root should be allowed, and should not panic the 'go' command. + +cp go.mod go.mod.orig + + +# Transitive upgrades from upgraded roots should not prevent +# 'go get -u' from performing upgrades. + +cp go.mod.orig go.mod +go get -u . +cmp go.mod go.mod.want + + +# 'go get' of a specific version should allow upgrades of +# every dependency (transitively) required by that version, +# including dependencies that are pulled into the module +# graph by upgrading other root requirements +# (in this case, example.net/indirect). + +cp go.mod.orig go.mod +go get example.net/a@v0.2.0 +cmp go.mod go.mod.want + + +-- go.mod -- +module golang.org/issue47979 + +go 1.17 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/a v0.2.0 => ./a2 + example.net/indirect v0.1.0 => ./indirect1 + example.net/indirect v0.2.0 => ./indirect2 + example.net/other v0.1.0 => ./other + example.net/other v0.2.0 => ./other +) + +require ( + example.net/a v0.1.0 + example.net/other v0.1.0 +) + +require example.net/indirect v0.1.0 // indirect +-- go.mod.want -- +module golang.org/issue47979 + +go 1.17 + +replace ( + example.net/a v0.1.0 => ./a1 + example.net/a v0.2.0 => ./a2 + example.net/indirect v0.1.0 => ./indirect1 + example.net/indirect v0.2.0 => ./indirect2 + example.net/other v0.1.0 => ./other + example.net/other v0.2.0 => ./other +) + +require ( + example.net/a v0.2.0 + example.net/other v0.2.0 +) + +require example.net/indirect v0.2.0 // indirect +-- issue.go -- +package issue + +import _ "example.net/a" +-- useother/useother.go -- +package useother + +import _ "example.net/other" +-- a1/go.mod -- +module example.net/a + +go 1.17 + +require example.net/indirect v0.1.0 +-- a1/a.go -- +package a +-- a2/go.mod -- +module example.net/a + +go 1.17 + +require example.net/indirect v0.2.0 +-- a2/a.go -- +package a + +import "example.net/indirect" +-- indirect1/go.mod -- +module example.net/indirect + +go 1.17 + +require example.net/other v0.1.0 +-- indirect1/indirect.go -- +package indirect +-- indirect2/go.mod -- +module example.net/indirect + +go 1.17 + +require example.net/other v0.2.0 +-- indirect2/indirect.go -- +package indirect + +import "example.net/other" +-- other/go.mod -- +module example.net/other + +go 1.17 +-- other/other.go -- +package other diff --git a/src/cmd/go/testdata/script/mod_get_issue48511.txt b/src/cmd/go/testdata/script/mod_get_issue48511.txt new file mode 100644 index 0000000..0ba486d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_issue48511.txt @@ -0,0 +1,68 @@ +# Regression test for https://golang.org/issue/48511: +# requirement minimization was accidentally replacing previous +# versions of the main module, causing dependencies to be +# spuriously dropping during requirement minimization and +# leading to an infinite loop. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +go get -u=patch ./... +cmp go.mod go.mod.want + +-- go.mod -- +module example.net/m + +go 1.16 + +replace ( + example.net/a v0.1.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.1.1 => ./b + example.net/m v0.1.0 => ./m1 +) + +require example.net/a v0.1.0 +-- go.mod.want -- +module example.net/m + +go 1.16 + +replace ( + example.net/a v0.1.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.1.1 => ./b + example.net/m v0.1.0 => ./m1 +) + +require ( + example.net/a v0.1.0 + example.net/b v0.1.1 // indirect +) +-- m.go -- +package m + +import "example.net/a" +-- m1/go.mod -- +module example.net/m + +go 1.16 + +require example.net/b v0.1.0 +-- a/go.mod -- +module example.net/a + +go 1.16 + +require example.net/m v0.1.0 +-- a/a.go -- +package a + +import "example.net/b" +-- b/go.mod -- +module example.net/b + +go 1.16 +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt new file mode 100644 index 0000000..00da0c3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_latest_pseudo.txt @@ -0,0 +1,10 @@ +# Check that we can build a module with no tagged versions by querying +# "@latest" through a proxy. +# Verifies golang.org/issue/32636 + +env GO111MODULE=on + +go mod init m +go get example.com/notags +go list -m all +stdout '^example.com/notags v0.0.0-20190507143103-cc8cbe209b64$' diff --git a/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt new file mode 100644 index 0000000..1cef9d1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_lazy_indirect.txt @@ -0,0 +1,44 @@ +# https://golang.org/issue/45979: after 'go get' on a package, +# that package should be importable without error. + + +# We start out with an unresolved dependency. +# 'go list' suggests that we run 'go get' on that dependency. + +! go list -deps . +stderr '^m.go:3:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc.io/quote$' + + +# When we run the suggested 'go get' command, the new dependency can be used +# immediately. +# +# 'go get' marks the new dependency as 'indirect', because it doesn't scan +# enough source code to know whether it is direct, and it is easier and less +# invasive to remove an incorrect indirect mark (e.g. using 'go get') than to +# add one that is missing ('go mod tidy' or 'go mod vendor'). + +go get rsc.io/quote +grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod +! grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod + +go list -deps . +! stderr . +[!short] go build . +[!short] ! stderr . + + +# 'go get .' (or 'go mod tidy') removes the indirect mark. + +go get . +grep 'rsc.io/quote v\d+\.\d+\.\d+$' go.mod +! grep 'rsc.io/quote v\d+\.\d+\.\d+ // indirect$' go.mod + + +-- go.mod -- +module example.com/m + +go 1.17 +-- m.go -- +package m + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_lazy_upgrade_lazy.txt b/src/cmd/go/testdata/script/mod_get_lazy_upgrade_lazy.txt new file mode 100644 index 0000000..3dae383 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_lazy_upgrade_lazy.txt @@ -0,0 +1,68 @@ +# Check that 'go get -u' will upgrade a dependency (direct or indirect) +# when the main module and the dependency are both lazy. +# Verifies #47768. + +# Check that go.mod is tidy, and an upgrade is available. +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +go list -m -u example.com/lazyupgrade +stdout '^example.com/lazyupgrade v0.1.0 \[v0.1.1\] => ./lazyupgrade@v0.1.0$' + +# 'go get -u' on a package that directly imports the dependency should upgrade. +go get -u ./usedirect +go list -m example.com/lazyupgrade +stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$' +cp go.mod.orig go.mod + +# 'go get -u' on a package that indirectly imports the dependency should upgrade. +go get -u ./useindirect +go list -m example.com/lazyupgrade +stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$' + +-- go.mod -- +module use + +go 1.17 + +require ( + direct v0.0.0 + example.com/lazyupgrade v0.1.0 +) + +replace ( + direct => ./direct + example.com/lazyupgrade v0.1.0 => ./lazyupgrade@v0.1.0 + example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1 +) +-- usedirect/usedirect.go -- +package use + +import _ "example.com/lazyupgrade" +-- useindirect/useindirect.go -- +package use + +import _ "direct" +-- direct/go.mod -- +module direct + +go 1.17 + +require example.com/lazyupgrade v0.1.0 +-- direct/direct.go -- +package direct + +import _ "example.com/lazyupgrade" +-- lazyupgrade@v0.1.0/go.mod -- +module example.com/lazyupgrade + +go 1.17 +-- lazyupgrade@v0.1.0/lazyupgrade.go -- +package lazyupgrade +-- lazyupgrade@v0.1.1/go.mod -- +module example.com/lazyupgrade + +go 1.17 +-- lazyupgrade@v0.1.1/lazyupgrade.go -- +package lazyupgrade diff --git a/src/cmd/go/testdata/script/mod_get_local.txt b/src/cmd/go/testdata/script/mod_get_local.txt new file mode 100644 index 0000000..4c81d16 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_local.txt @@ -0,0 +1,62 @@ +# Test 'go get' with a local module with a name that is not valid for network lookup. +[short] skip + +env GO111MODULE=on +go mod edit -fmt +cp go.mod go.mod.orig + +# 'go get -u' within the main module should work, even if it has a local-only name. +cp go.mod.orig go.mod +go get -u ./... +grep 'rsc.io/quote.*v1.5.2' go.mod +grep 'golang.org/x/text.*v0.3.0' go.mod +cp go.mod go.mod.implicitmod + +# 'go get -u local/...' should be equivalent to 'go get -u ./...' +# (assuming no nested modules) +cp go.mod.orig go.mod +go get -u local/... +cmp go.mod go.mod.implicitmod + +# For the main module, @patch should be a no-op. +cp go.mod.orig go.mod +go get -u local/...@patch +cmp go.mod go.mod.implicitmod + +# 'go get -u' in the empty root of the main module should fail. +# 'go get -u .' should also fail. +cp go.mod.orig go.mod +! go get -u +! go get -u . + +# 'go get -u .' within a package in the main module updates the dependencies +# of that package. +cp go.mod.orig go.mod +cd uselang +go get -u . +cd .. +grep 'rsc.io/quote.*v1.3.0' go.mod +grep 'golang.org/x/text.*v0.3.0' go.mod +cp go.mod go.mod.dotpkg + +# 'go get -u' with an explicit package in the main module updates the +# dependencies of that package. +cp go.mod.orig go.mod +go get -u local/uselang +cmp go.mod go.mod.dotpkg + +-- go.mod -- +module local + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c + rsc.io/quote v1.3.0 +) + +-- uselang/uselang.go -- +package uselang +import _ "golang.org/x/text/language" + +-- usequote/usequote.go -- +package usequote +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_main.txt b/src/cmd/go/testdata/script/mod_get_main.txt new file mode 100644 index 0000000..cddd5f7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_main.txt @@ -0,0 +1,51 @@ +env GO111MODULE=on +cp go.mod.orig go.mod + +# relative and absolute paths must be within the main module. +! go get .. +stderr '^go: \.\. \('$WORK'[/\\]gopath\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get $WORK +stderr '^go: '$WORK' is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get ../... +stderr '^go: \.\./\.\.\. \('$WORK'[/\\]gopath([/\\]...)?\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' +! go get $WORK/... +stderr '^go: '$WORK'[/\\]\.\.\. is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' + +# @patch and @latest within the main module refer to the current version. +# The main module won't be upgraded, but missing dependencies will be added. +go get rsc.io/x +grep 'rsc.io/quote v1.5.2' go.mod +go get rsc.io/x@upgrade +grep 'rsc.io/quote v1.5.2' go.mod +cp go.mod.orig go.mod +go get rsc.io/x@patch +grep 'rsc.io/quote v1.5.2' go.mod +cp go.mod.orig go.mod + + +# Upgrading a package pattern not contained in the main module should not +# attempt to upgrade the main module. +go get rsc.io/quote/...@v1.5.1 +grep 'rsc.io/quote v1.5.1' go.mod + + +# The main module cannot be updated to a specific version. +! go get rsc.io@v0.1.0 +stderr '^go: can''t request version "v0.1.0" of the main module \(rsc.io\)$' + +# A package in the main module can't be upgraded either. +! go get rsc.io/x@v0.1.0 +stderr '^go: package rsc.io/x is in the main module, so can''t request version v0.1.0$' + +# Nor can a pattern matching packages in the main module. +! go get rsc.io/x/...@latest +stderr '^go: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$' + +-- go.mod.orig -- +module rsc.io + +go 1.13 +-- x/x.go -- +package x + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_major.txt b/src/cmd/go/testdata/script/mod_get_major.txt new file mode 100644 index 0000000..2db1318 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_major.txt @@ -0,0 +1,23 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# golang.org/issue/34383: if a module path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to a module. + +go get vcs-test.golang.org/git/v3pkg.git/v3@v3.0.0 + +go list -m vcs-test.golang.org/git/v3pkg.git/v3 +stdout '^vcs-test.golang.org/git/v3pkg.git/v3 v3.0.0$' + +go get vcs-test.golang.org/git/empty-v2-without-v1.git/v2@v2.0.0 + +go list -m vcs-test.golang.org/git/empty-v2-without-v1.git/v2 +stdout '^vcs-test.golang.org/git/empty-v2-without-v1.git/v2 v2.0.0$' + +-- go.mod -- +module example.com +go 1.13 diff --git a/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt new file mode 100644 index 0000000..5934251 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_missing_ziphash.txt @@ -0,0 +1,55 @@ +# Test that if the module cache contains an extracted source directory but not +# a ziphash, 'go build' complains about a missing sum, and 'go get' adds +# the sum. Verifies #44749. + +# With a tidy go.sum, go build succeeds. This also populates the module cache. +cp go.sum.tidy go.sum +go build -n use +env GOPROXY=off +env GOSUMDB=off + +# Control case: if we delete the hash for rsc.io/quote v1.5.2, +# 'go build' reports an error. 'go get' adds the sum. +cp go.sum.bug go.sum +! go build -n use +stderr '^use.go:3:8: missing go.sum entry for module providing package rsc.io/quote \(imported by use\); to add:\n\tgo get use$' +go get use +cmp go.sum go.sum.tidy +go build -n use + +# If we delete the hash *and* the ziphash file, we should see the same behavior. +cp go.sum.bug go.sum +rm $WORK/gopath/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.ziphash +! go build -n use +stderr '^use.go:3:8: missing go.sum entry for module providing package rsc.io/quote \(imported by use\); to add:\n\tgo get use$' +go get use +cmp go.sum go.sum.tidy +go build -n use + +-- go.mod -- +module use + +go 1.16 + +require rsc.io/quote v1.5.2 +-- go.sum.tidy -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= +-- go.sum.bug -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_moved.txt b/src/cmd/go/testdata/script/mod_get_moved.txt new file mode 100644 index 0000000..ba79c82 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_moved.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on +[short] skip + +# A 'go get' that worked at a previous version should continue to work at that version, +# even if the package was subsequently moved into a submodule. +go mod init example.com/foo +go get example.com/split/subpkg@v1.0.0 +go list -m all +stdout 'example.com/split v1.0.0' + +# A 'go get' that simultaneously upgrades away conflicting package defitions is not ambiguous. +go get example.com/split/subpkg@v1.1.0 + +# A 'go get' without an upgrade should find the package. +rm go.mod +go mod init example.com/foo +go get example.com/split/subpkg +go list -m all +stdout 'example.com/split/subpkg v1.1.0' + + +# A 'go get' that worked at a previous version should continue to work at that version, +# even if the package was subsequently moved into a parent module. +rm go.mod +go mod init example.com/foo +go get example.com/join/subpkg@v1.0.0 +go list -m all +stdout 'example.com/join/subpkg v1.0.0' + +# A 'go get' that simultaneously upgrades away conflicting package definitions is not ambiguous. +# (A wildcard pattern applies to both packages and modules, +# because we define wildcard matching to apply after version resolution.) +go get example.com/join/subpkg/...@v1.1.0 + +# A 'go get' without an upgrade should find the package. +rm go.mod +go mod init example.com/foo +go get example.com/join/subpkg@v1.1.0 +go list -m all +stdout 'example.com/join v1.1.0' diff --git a/src/cmd/go/testdata/script/mod_get_newcycle.txt b/src/cmd/go/testdata/script/mod_get_newcycle.txt new file mode 100644 index 0000000..18dc650 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_newcycle.txt @@ -0,0 +1,14 @@ +env GO111MODULE=on + +# Download modules to avoid stderr chatter +go mod download example.com@v1.0.0 +go mod download example.com/newcycle/a@v1.0.0 +go mod download example.com/newcycle/a@v1.0.1 +go mod download example.com/newcycle/b@v1.0.0 + +go mod init m +! go get example.com/newcycle/a@v1.0.0 +cmp stderr stderr-expected + +-- stderr-expected -- +go: example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1, not example.com/newcycle/a@v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_get_none.txt b/src/cmd/go/testdata/script/mod_get_none.txt new file mode 100644 index 0000000..5aec209 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_none.txt @@ -0,0 +1,12 @@ +env GO111MODULE=on + +go mod init example.com/foo + +# 'go get bar@none' should be a no-op if module bar is not active. +go get example.com/bar@none +go list -m all +! stdout example.com/bar + +go get example.com/bar@none +go list -m all +! stdout example.com/bar diff --git a/src/cmd/go/testdata/script/mod_get_nopkgs.txt b/src/cmd/go/testdata/script/mod_get_nopkgs.txt new file mode 100644 index 0000000..14176a7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_nopkgs.txt @@ -0,0 +1,40 @@ +cd subdir + +# 'go get' on empty patterns that are necessarily local to the module +# should warn that the patterns are empty, exactly once. + +go get ./... +stderr -count=1 'matched no packages' + +go get ./... +stderr -count=1 'matched no packages' + +# 'go get' on patterns that could conceivably match nested modules +# should report a module resolution error. + +go get example.net/emptysubdir/... # control case + +! go get example.net/emptysubdir/subdir/... +! stderr 'matched no packages' +stderr '^go: example\.net/emptysubdir/subdir/\.\.\.: module example\.net/emptysubdir/subdir: reading http://.*: 404 Not Found\n\tserver response: 404 page not found\n\z' + +# It doesn't make sense to 'go get' a path in the standard library, +# since the standard library necessarily can't have unresolved imports. +# +# TODO(#30241): Maybe that won't always be the case? +# +# For that case, we emit a "malformed module path" error message, +# which isn't ideal either. + +! go get builtin/... # in GOROOT/src, but contains no packages +stderr '^go: builtin/...: malformed module path "builtin": missing dot in first path element$' + +-- go.mod -- +module example.net/emptysubdir + +go 1.16 +-- emptysubdir.go -- +// Package emptysubdir has a subdirectory containing no packages. +package emptysubdir +-- subdir/README.txt -- +This module intentionally does not contain any p diff --git a/src/cmd/go/testdata/script/mod_get_patch.txt b/src/cmd/go/testdata/script/mod_get_patch.txt new file mode 100644 index 0000000..35cc276 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patch.txt @@ -0,0 +1,130 @@ +# This test examines the behavior of 'go get …@patch' +# See also mod_upgrade_patch.txt (focused on "-u=patch" specifically) +# and mod_get_patchmod.txt (focused on module/package ambiguities). + +cp go.mod go.mod.orig + +# example.net/b@patch refers to the patch for the version of b that was selected +# at the start of 'go get', not the version after applying other changes. + +! go get example.net/a@v0.2.0 example.net/b@patch +stderr '^go: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch changes the default version for other arguments to '@patch', +# but they continue to be resolved against the originally-selected version, +# not the updated one. +# +# TODO(#42360): Reconsider the change in defaults. + +! go get -u=patch example.net/a@v0.2.0 example.net/b +stderr '^go: example.net/a@v0.2.0 requires example.net/b@v0.2.0, not example.net/b@patch \(v0.1.1\)$' +cmp go.mod go.mod.orig + + +# -u=patch refers to the patches for the selected versions of dependencies *after* +# applying other version changes, not the versions that were selected at the start. +# However, it should not patch versions determined by explicit arguments. + +go get -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.2.1 ' + + +# "-u=patch all" should be equivalent to "all@patch", and should fail if the +# patched versions result in a higher-than-patch upgrade. + +cp go.mod.orig go.mod +! go get -u=patch all +stderr '^go: example.net/a@v0.1.1 \(matching all@patch\) requires example.net/b@v0.2.0, not example.net/b@v0.1.1 \(matching all@patch\)$' +cmp go.mod go.mod.orig + + +# On the other hand, "-u=patch ./..." should patch-upgrade dependencies until +# they reach a fixed point, even if that results in higher-than-patch upgrades. + +go get -u=patch ./... +go list -m all +stdout '^example.net/a v0.1.1 ' +stdout '^example.net/b v0.2.1 ' + + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a21 + example.net/b v0.1.0 => ./b + example.net/b v0.1.1 => ./b + example.net/b v0.2.0 => ./b + example.net/b v0.2.1 => ./b + example.net/b v0.3.0 => ./b + example.net/b v0.3.1 => ./b +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a10/a.go -- +package a + +import _ "example.net/b" + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // upgraded +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 +-- a20/a.go -- +package a + +import _ "example.net/b" + +-- a21/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.2.0 // not upgraded +-- a21/a.go -- +package a + +import _ "example.net/b" + +-- b/go.mod -- +module example.net/b + +go 1.16 +-- b/b.go -- +package b diff --git a/src/cmd/go/testdata/script/mod_get_patchbound.txt b/src/cmd/go/testdata/script/mod_get_patchbound.txt new file mode 100644 index 0000000..e4d3c49 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchbound.txt @@ -0,0 +1,84 @@ +# -u=patch will patch dependencies as far as possible, but not so far that they +# conflict with other command-line arguments. + +go list -m all +stdout '^example.net/a v0.1.0 ' +stdout '^example.net/b v0.1.0 ' + +go get -u=patch example.net/a@v0.2.0 +go list -m all +stdout '^example.net/a v0.2.0 ' +stdout '^example.net/b v0.1.1 ' # not v0.1.2, which requires …/a v0.3.0. + +-- go.mod -- +module example + +go 1.16 + +require ( + example.net/a v0.1.0 + example.net/b v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/a v0.3.0 => ./a + example.net/b v0.1.0 => ./b10 + example.net/b v0.1.1 => ./b11 + example.net/b v0.1.2 => ./b12 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a/a.go -- +package a + +import _ "example.net/b" + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.1.0 +-- b10/b.go -- +package b +-- b10/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b11/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b11/b.go -- +package b +-- b11/b_test.go -- +package b_test + +import _ "example.net/a" + +-- b12/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.3.0 +-- b12/b.go -- +package b +-- b12/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchcycle.txt b/src/cmd/go/testdata/script/mod_get_patchcycle.txt new file mode 100644 index 0000000..6600109 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchcycle.txt @@ -0,0 +1,64 @@ +# If a patch of a module requires a higher version of itself, +# it should be reported as its own conflict. +# +# This case is weird and unlikely to occur often at all, but it should not +# spuriously succeed. +# (It used to print v0.1.1 but then silently upgrade to v0.2.0.) + +! go get example.net/a@patch +stderr '^go: example.net/a@patch \(v0.1.1\) requires example.net/a@v0.2.0, not example.net/a@patch \(v0.1.1\)$' # TODO: A mention of b v0.1.0 would be nice. + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/b v0.1.0 => ./b10 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a + +import _ "example.net/b" + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + + +-- b10/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b10/b.go -- +package b + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_get_patchmod.txt b/src/cmd/go/testdata/script/mod_get_patchmod.txt new file mode 100644 index 0000000..2827731 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patchmod.txt @@ -0,0 +1,82 @@ +# example.net/pkgremoved@v0.1.0 refers to a package. +go get example.net/pkgremoved@v0.1.0 + +go list example.net/pkgremoved +stdout '^example.net/pkgremoved' + +cp go.mod go.mod.orig + + +# When we resolve a new dependency on example.net/other, +# it will change the meaning of the path "example.net/pkgremoved" +# from a package (at v0.1.0) to only a module (at v0.2.0). +# +# If we simultaneously 'get' that module at the query "patch", the module should +# be constrained to the latest patch of its originally-selected version (v0.1.0), +# not upgraded to the latest patch of the new transitive dependency. + +! go get example.net/pkgremoved@patch example.net/other@v0.1.0 +stderr '^go: example.net/other@v0.1.0 requires example.net/pkgremoved@v0.2.0, not example.net/pkgremoved@patch \(v0.1.1\)$' +cmp go.mod.orig go.mod + + +# However, we should be able to patch from a package to a module and vice-versa. + +# Package to module ... + +go get example.net/pkgremoved@v0.3.0 +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + +go get example.net/pkgremoved@patch +! go list example.net/pkgremoved + +# ... and module to package. + +go get example.net/pkgremoved@v0.4.0 +! go list example.net/pkgremoved + +go get example.net/pkgremoved@patch +go list example.net/pkgremoved +stdout 'example.net/pkgremoved' + + +-- go.mod -- +module example + +go 1.16 + +replace ( + example.net/other v0.1.0 => ./other + + example.net/pkgremoved v0.1.0 => ./prpkg + example.net/pkgremoved v0.1.1 => ./prpkg + + example.net/pkgremoved v0.2.0 => ./prmod + example.net/pkgremoved v0.2.1 => ./prmod + + example.net/pkgremoved v0.3.0 => ./prpkg + example.net/pkgremoved v0.3.1 => ./prmod + + example.net/pkgremoved v0.4.0 => ./prmod + example.net/pkgremoved v0.4.1 => ./prpkg +) +-- other/go.mod -- +module example.net/other + +go 1.16 + +require example.net/pkgremoved v0.2.0 +-- other/other.go -- +package other +-- prpkg/go.mod -- +module example.net/pkgremoved + +go 1.16 +-- prpkg/pkgremoved.go -- +package pkgremoved +-- prmod/go.mod -- +module example.net/pkgremoved +-- prmod/README.txt -- +Package pkgremoved was removed in v0.2.0 and v0.3.1, +and added in v0.1.0 and v0.4.1. diff --git a/src/cmd/go/testdata/script/mod_get_patterns.txt b/src/cmd/go/testdata/script/mod_get_patterns.txt new file mode 100644 index 0000000..891353f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_patterns.txt @@ -0,0 +1,42 @@ +env GO111MODULE=on +[short] skip + +# If a pattern doesn't match any packages provided by modules +# in the build list, we assume the pattern matches a single module +# whose path is a prefix of the part of the pattern before "...". +cp go.mod.orig go.mod +go get rsc.io/quote/... +grep 'require rsc.io/quote' go.mod + +cp go.mod.orig go.mod +! go get rsc.io/quote/x... +stderr 'go: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' +! grep 'require rsc.io/quote' go.mod + +! go get rsc.io/quote/x/... +stderr 'go: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' +! grep 'require rsc.io/quote' go.mod + +# If a pattern matches no packages within a module, the module should not +# be upgraded, even if the module path is a prefix of the pattern. +cp go.mod.orig go.mod +go mod edit -require example.com/nest@v1.0.0 +go get example.com/nest/sub/y... +grep 'example.com/nest/sub v1.0.0' go.mod +grep 'example.com/nest v1.0.0' go.mod + +# However, if the pattern matches the module path itself, the module +# should be upgraded even if it contains no matching packages. +go get example.com/n...t +grep 'example.com/nest v1.1.0' go.mod +grep 'example.com/nest/sub v1.0.0' go.mod + +-- go.mod.orig -- +module m + +go 1.13 + +-- use/use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_pkgtags.txt b/src/cmd/go/testdata/script/mod_get_pkgtags.txt new file mode 100644 index 0000000..7ad3c3c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pkgtags.txt @@ -0,0 +1,130 @@ +# https://golang.org/issue/44106 +# 'go get' should fetch the transitive dependencies of packages regardless of +# tags, but shouldn't error out if the package is missing tag-guarded +# dependencies. + +# Control case: just adding the top-level module to the go.mod file does not +# fetch its dependencies. + +go mod edit -require example.net/tools@v0.1.0 +! go list -deps example.net/cmd/tool +stderr '^module example\.net/cmd provides package example\.net/cmd/tool and is replaced but not required; to add it:\n\tgo get example\.net/cmd@v0\.1\.0$' +go mod edit -droprequire example.net/tools + + +# 'go get' makes a best effort to fetch those dependencies, but shouldn't +# error out if dependencies of tag-guarded files are missing. + +go get example.net/tools@v0.1.0 +! stderr 'no Go source files' + +! go list example.net/tools +stderr '^package example.net/tools: build constraints exclude all Go files in .*[/\\]tools$' + +go list -tags=tools -e -deps example.net/tools +stdout '^example.net/cmd/tool$' +stdout '^example.net/missing$' + +go list -deps example.net/cmd/tool + +! go list example.net/missing +stderr '^no required module provides package example.net/missing; to add it:\n\tgo get example.net/missing$' + + +# https://golang.org/issue/33526: 'go get' without '-d' should succeed +# for a module whose root is a constrained-out package. +# +# Ideally it should silently succeed, but today it logs the "no Go source files" +# error and succeeds anyway. + +go get example.net/tools@v0.1.0 +! stderr . + +! go build example.net/tools +stderr '^package example.net/tools: build constraints exclude all Go files in .*[/\\]tools$' + + +# https://golang.org/issue/29268 +# 'go get' should fetch modules whose roots contain test-only packages, but +# without the -t flag shouldn't error out if the test has missing dependencies. + +go get example.net/testonly@v0.1.0 + +# With the -t flag, the test dependencies must resolve successfully. +! go get -t example.net/testonly@v0.1.0 +stderr '^example.net/testonly tested by\n\texample.net/testonly\.test imports\n\texample.net/missing: cannot find module providing package example.net/missing$' + + +# 'go get' should succeed for a module path that does not contain a package, +# but fail for a non-package subdirectory of a module. + +! go get example.net/missing/subdir@v0.1.0 +stderr '^go: module example.net/missing@v0.1.0 found \(replaced by ./missing\), but does not contain package example.net/missing/subdir$' + +go get example.net/missing@v0.1.0 + + +# Getting the subdirectory should continue to fail even if the corresponding +# module is already present in the build list. + +! go get example.net/missing/subdir@v0.1.0 +stderr '^go: module example.net/missing@v0.1.0 found \(replaced by ./missing\), but does not contain package example.net/missing/subdir$' + + +-- go.mod -- +module example.net/m + +go 1.15 + +replace ( + example.net/tools v0.1.0 => ./tools + example.net/cmd v0.1.0 => ./cmd + example.net/testonly v0.1.0 => ./testonly + example.net/missing v0.1.0 => ./missing +) + +-- tools/go.mod -- +module example.net/tools + +go 1.15 + +// Requirements intentionally omitted. + +-- tools/tools.go -- +// +build tools + +package tools + +import ( + _ "example.net/cmd/tool" + _ "example.net/missing" +) + +-- cmd/go.mod -- +module example.net/cmd + +go 1.16 +-- cmd/tool/tool.go -- +package main + +func main() {} + +-- testonly/go.mod -- +module example.net/testonly + +go 1.15 +-- testonly/testonly_test.go -- +package testonly_test + +import _ "example.net/missing" + +func Test(t *testing.T) {} + +-- missing/go.mod -- +module example.net/missing + +go 1.15 +-- missing/README.txt -- +There are no Go source files here. +-- missing/subdir/README.txt -- +There are no Go source files here either. diff --git a/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt b/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt new file mode 100644 index 0000000..06e2fc6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_prefer_incompatible.txt @@ -0,0 +1,29 @@ +# Verifies golang.org/issue/37574. + +# If we are already using an +incompatible version, we shouldn't look up +# a lower compatible version when upgrading. +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod +grep '^example.com/incompatiblewithsub v2\.0\.0\+incompatible' go.sum +! grep '^example.com/incompatiblewithsub v1.0.0' go.sum + +go get example.com/incompatiblewithsub/sub +cmp go.mod.orig go.mod +! grep '^example.com/incompatiblewithsub v1.0.0' go.sum + +# TODO(golang.org/issue/31580): the 'go get' command above should not change +# go.sum. However, as part of the query above, we download example.com@v1.0.0, +# an unrelated module, since it's a possible prefix. The sum for that module +# should not be written to go.sum. + +-- go.mod -- +module m + +go 1.15 + +require example.com/incompatiblewithsub v2.0.0+incompatible +-- use.go -- +package use + +import _ "example.com/incompatiblewithsub/sub" diff --git a/src/cmd/go/testdata/script/mod_get_promote_implicit.txt b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt new file mode 100644 index 0000000..03f6810 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_promote_implicit.txt @@ -0,0 +1,92 @@ +cp go.mod.orig go.mod + +# If we list a package in an implicit dependency imported from the main module, +# we should get an error because the dependency should have an explicit +# requirement. +go list -m indirect-with-pkg +stdout '^indirect-with-pkg v1.0.0 => ./indirect-with-pkg$' +! go list ./use-indirect +stderr '^package m/use-indirect imports indirect-with-pkg from implicitly required module; to add missing requirements, run:\n\tgo get indirect-with-pkg@v1.0.0$' + +# We can promote the implicit requirement by getting the importing package. +# NOTE: the hint recommends getting the imported package (tested below) since +# it's more obvious and doesn't require -d. However, that adds an '// indirect' +# comment on the requirement. +go get m/use-indirect +cmp go.mod go.mod.use +cp go.mod.orig go.mod + +# We can also promote implicit requirements using 'go get' on them, or their +# packages. This gives us "// indirect" requirements, since 'go get' doesn't +# know they're needed by the main module. See #43131 for the rationale. +# The hint above recommends this because it's more obvious usage and doesn't +# require the -d flag. +go get indirect-with-pkg indirect-without-pkg +cmp go.mod go.mod.indirect + +-- go.mod.orig -- +module m + +go 1.16 + +require direct v1.0.0 + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- go.mod.use -- +module m + +go 1.16 + +require ( + direct v1.0.0 + indirect-with-pkg v1.0.0 +) + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- go.mod.indirect -- +module m + +go 1.16 + +require ( + direct v1.0.0 + indirect-with-pkg v1.0.0 // indirect + indirect-without-pkg v1.0.0 // indirect +) + +replace ( + direct v1.0.0 => ./direct + indirect-with-pkg v1.0.0 => ./indirect-with-pkg + indirect-without-pkg v1.0.0 => ./indirect-without-pkg +) +-- use-indirect/use-indirect.go -- +package use + +import _ "indirect-with-pkg" +-- direct/go.mod -- +module direct + +go 1.16 + +require ( + indirect-with-pkg v1.0.0 + indirect-without-pkg v1.0.0 +) +-- indirect-with-pkg/go.mod -- +module indirect-with-pkg + +go 1.16 +-- indirect-with-pkg/p.go -- +package p +-- indirect-without-pkg/go.mod -- +module indirect-without-pkg + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_get_pseudo.txt b/src/cmd/go/testdata/script/mod_get_pseudo.txt new file mode 100644 index 0000000..b964ae4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo.txt @@ -0,0 +1,82 @@ +env GO111MODULE=on + +# Testing git->module converter's generation of +incompatible tags; turn off proxy. +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off + +# We can resolve the @master branch without unshallowing the local repository +# (even with older gits), so try that before we do anything else. +# (This replicates https://golang.org/issue/26713 with git 2.7.4.) +go get github.com/rsc/legacytest@master +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.\d{14}-7303f7796364\+incompatible$' + +# get should include incompatible tags in "latest" calculation. +go mod edit -droprequire github.com/rsc/legacytest +go get github.com/rsc/legacytest@latest +go list +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.1-0.pseudo+incompatible +go get ...test@7303f77 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.\d{14}-7303f7796364\+incompatible$' + +# v2.0.0+incompatible by tag+incompatible +go get ...test@v2.0.0+incompatible +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.0+incompatible by tag +go get ...test@v2.0.0 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v2.0.0+incompatible by hash (back on master) +go get ...test@d7ae1e4 +go list -m all +stdout '^github.com/rsc/legacytest v2\.0\.0\+incompatible$' + +# v1.2.1-0.pseudo +go get ...test@d2d4c3e +go list -m all +stdout '^github.com/rsc/legacytest v1\.2\.1-0\.\d{14}-d2d4c3ea6623$' + +# v1.2.0 +go get ...test@9f6f860 +go list -m all +stdout '^github.com/rsc/legacytest v1\.2\.0$' + +# v1.1.0-pre.0.pseudo +go get ...test@fb3c628 +go list -m all +stdout '^github.com/rsc/legacytest v1\.1\.0-pre\.0\.\d{14}-fb3c628075e3$' + +# v1.1.0-pre (no longer on master) +go get ...test@731e3b1 +go list -m all +stdout '^github.com/rsc/legacytest v1\.1\.0-pre$' + +# v1.0.1-0.pseudo +go get ...test@fa4f5d6 +go list -m all +stdout '^github.com/rsc/legacytest v1\.0\.1-0\.\d{14}-fa4f5d6a71c6$' + +# v1.0.0 +go get ...test@7fff7f3 +go list -m all +stdout '^github.com/rsc/legacytest v1\.0\.0$' + +# v0.0.0-pseudo +go get ...test@52853eb +go list -m all +stdout '^github.com/rsc/legacytest v0\.0\.0-\d{14}-52853eb7b552$' + +-- go.mod -- +module x +-- x.go -- +package x +import "github.com/rsc/legacytest" diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt new file mode 100644 index 0000000..d085f4f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt @@ -0,0 +1,67 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Testing that a pseudo-version is based on the semantically-latest +# tag that appears in any commit that is a (transitive) parent of the commit +# supplied to 'go get', regardless of branches + +[!net] skip +[!exec:git] skip + +# For this test repository: +# tag v0.2.1 is most recent tag on master itself +# tag v0.2.2 is on branch2, which was then merged to master +# master is a merge commit with both tags as parents +# +# The pseudo-version hence sorts immediately after v0.2.2 rather +# than v0.2.1, even though the v0.2.2 tag is not on master. + +go get vcs-test.golang.org/git/tagtests.git@master +go list -m all +stdout '^vcs-test.golang.org/git/tagtests.git v0.2.3-0\.' + +-- go.mod -- +module x + +go 1.12 +-- x.go -- +package x + +import _ "vcs-test.golang.org/git/tagtests.git" +-- gen_testtags.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail +cd "$(dirname "$0")" +rm -rf tagtests +mkdir tagtests +cd tagtests + +git init +echo module vcs-test.golang.org/git/tagtests.git >go.mod +echo package tagtests >tagtests.go +git add go.mod tagtests.go +git commit -m 'create module tagtests' + +git branch b + +echo v0.2.1 >v0.2.1 +git add v0.2.1 +git commit -m v0.2.1 +git tag v0.2.1 + +git checkout b +echo v0.2.2 >v0.2.2 +git add v0.2.2 +git commit -m v0.2.2 +git tag v0.2.2 + +git checkout master +git merge b -m merge + +zip -r ../tagtests.zip . +gsutil cp ../tagtests.zip gs://vcs-test/git/tagtests.zip diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt new file mode 100644 index 0000000..8e6cd90 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt @@ -0,0 +1,64 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Testing that a pseudo-version is based on the semantically-latest +# prefixed tag in any commit that is a parent of the commit supplied +# to 'go get', when using a repo with go.mod in a sub directory. + +[!net] skip +[!exec:git] skip + +# For this test repository go.mod resides in sub/ (only): +# master is not tagged +# tag v0.2.0 is most recent tag before master +# tag sub/v0.0.10 is most recent tag before v0.2.0 +# +# The pseudo-version is based on sub/v0.0.10, since v0.2.0 doesn't +# contain the prefix. +go get vcs-test.golang.org/git/prefixtagtests.git/sub +go list -m all +stdout '^vcs-test.golang.org/git/prefixtagtests.git/sub v0.0.10$' + +go get -u vcs-test.golang.org/git/prefixtagtests.git/sub@master +go list -m all +stdout '^vcs-test.golang.org/git/prefixtagtests.git/sub v0.0.11-0\.' + +-- go.mod -- +module x + +go 1.12 +-- x.go -- +package x + +import _ "vcs-test.golang.org/prefixtagtests.git/sub" +-- gen_prefixtagtests.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail +cd "$(dirname "$0")" +rm -rf prefixtagtests +mkdir prefixtagtests +cd prefixtagtests + +git init +mkdir sub +echo module vcs-test.golang.org/git/prefixtagtests.git/sub >sub/go.mod +echo package sub >sub/sub.go +git add sub +git commit -m 'create module sub' +for i in v0.1.0 sub/v0.0.9 sub/v0.0.10 v0.2.0; do + echo $i >status + git add status + git commit -m $i + git tag $i +done +echo 'after last tag' >status +git add status +git commit -m 'after last tag' + +zip -r ../prefixtagtests.zip . +gsutil cp ../prefixtagtests.zip gs://vcs-test/git/prefixtagtests.zip diff --git a/src/cmd/go/testdata/script/mod_get_replaced.txt b/src/cmd/go/testdata/script/mod_get_replaced.txt new file mode 100644 index 0000000..b1fc8b8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_replaced.txt @@ -0,0 +1,111 @@ +cp go.mod go.mod.orig + +env oldGOPROXY=$GOPROXY + +# If a wildcard replacement exists for an otherwise-nonexistent module, +# 'go get' should resolve it to the minimum valid pseudo-version. + +go mod edit -replace=example.com/x=./x +go get example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# The same should work with GOPROXY=off. + +env GOPROXY=off +cp go.mod.orig go.mod + +go mod edit -replace=example.com/x=./x +go get example.com/x + +go list -m example.com/x +stdout '^example.com/x v0.0.0-00010101000000-000000000000 ' + +# If specific-version replacements exist, the highest matching version should be used. +go mod edit -replace=example.com/x@v0.1.0=./x +go mod edit -replace=example.com/x@v0.2.0=./x + +go get example.com/x +go list -m example.com/x +stdout '^example.com/x v0.2.0 ' + +go get example.com/x@<v0.2.0 +go list -m example.com/x +stdout '^example.com/x v0.1.0 ' + + +# Replacements should also be listed as known versions, and 'go get' should sort +# them in with ordinary versions. + +env GOPROXY=$oldGOPROXY + +cp go.mod.orig go.mod +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.4.0' + +go get rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.0' + +go mod edit -replace rsc.io/quote@v1.3.1=rsc.io/quote@v1.4.0 + +go list -versions -m rsc.io/quote +stdout 'v1.3.0 v1.3.1 v1.4.0' + +go get rsc.io/quote@v1.3 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.3.1 ' + +go get rsc.io/quote@>v1.3.1 +go list -m rsc.io/quote +stdout '^rsc.io/quote v1.4.0' + + +# Replacements should allow 'go get' to work even with dotless module paths. + +cp go.mod.orig go.mod + +! go list example +stderr '^package example is not in GOROOT \(.*\)$' +! go get example +stderr '^go: malformed module path "example": missing dot in first path element$' + +go mod edit -replace example@v0.1.0=./example + +! go list example +stderr '^module example provides package example and is replaced but not required; to add it:\n\tgo get example@v0.1.0$' + +go get example +go list -m example +stdout '^example v0.1.0 ' + + +-- go.mod -- +module example.com + +go 1.16 +-- x/go.mod -- +module example.com/x + +go 1.16 +-- x/x.go -- +package x +-- example/go.mod -- +module example +go 1.16 +-- example/example.go -- +package example diff --git a/src/cmd/go/testdata/script/mod_get_retract.txt b/src/cmd/go/testdata/script/mod_get_retract.txt new file mode 100644 index 0000000..9757989 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_retract.txt @@ -0,0 +1,59 @@ +# 'go get pkg' should not upgrade to a retracted version. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.1.0 +go get example.com/retract/self/prev +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' + +# 'go get pkg' should not downgrade from a retracted version when no higher +# version is available. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get example.com/retract/self/prev +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' +stderr '^go: to switch to the latest unretracted version, run:\n\tgo get example.com/retract/self/prev@latest\n$' +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.9.0$' + +# 'go get pkg@latest' should downgrade from a retracted version. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get example.com/retract/self/prev@latest +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' + +# 'go get pkg@version' should update to a specific version, even if that +# version is retracted. +cp go.mod.orig go.mod +go get example.com/retract@v1.0.0-bad +stderr '^go: warning: example.com/retract@v1.0.0-bad: retracted by module author: bad$' +go list -m example.com/retract +stdout '^example.com/retract v1.0.0-bad$' + +# 'go get -u' should not downgrade from a retracted version when no higher +# version is available. +cp go.mod.orig go.mod +go mod edit -require example.com/retract/self/prev@v1.9.0 +go get -u ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.9.0$' + +# 'go get' should warn if a module needed to build named packages is retracted. +# 'go get' should not warn about unrelated modules. +go get ./empty +! stderr retracted +go get ./use +stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$' + +-- go.mod.orig -- +module example.com/use + +go 1.15 + +-- use/use.go -- +package use + +import _ "example.com/retract/self/prev" +-- empty/empty.go -- +package empty diff --git a/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt new file mode 100644 index 0000000..4b4f5da --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_retract_ambiguous.txt @@ -0,0 +1,10 @@ +! go get example.com/retract/ambiguous/other +stderr 'ambiguous import: found package example.com/retract/ambiguous/nested in multiple modules:' +stderr '^go: warning: example.com/retract/ambiguous/nested@v1.9.0-bad: retracted by module author: nested modules are bad$' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/ambiguous/nested v1.9.0-bad diff --git a/src/cmd/go/testdata/script/mod_get_split.txt b/src/cmd/go/testdata/script/mod_get_split.txt new file mode 100644 index 0000000..0fb22c8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_split.txt @@ -0,0 +1,157 @@ +cp go.mod go.mod.orig + + +# 'go get' on a package already provided by the build list should update +# the module already in the build list, not fail with an ambiguous import error. + +go get example.net/split/nested@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + +# We should get the same behavior if we use a pattern that matches only that package. + +cp go.mod.orig go.mod + +go get example.net/split/nested/...@patch +go list -m all +stdout '^example.net/split v0.2.1 ' +! stdout '^example.net/split/nested' + + +# If we request a version for which the package only exists in one particular module, +# we should add that one particular module but not resolve import ambiguities. +# +# In particular, if the module that previously provided the package has a +# matching version, but does not itself match the pattern and contains no +# matching packages, we should not change its version. (We should *not* downgrade +# module example.net/split to v0.1.0, despite the fact that +# example.net/split v0.2.0 currently provides the package with the requested path.) +# +# TODO(#27899): Maybe we should resolve the ambiguities by upgrading. + +cp go.mod.orig go.mod + +! go get example.net/split/nested@v0.1.0 +stderr '^example.net/split/nested: ambiguous import: found package example.net/split/nested in multiple modules:\n\texample.net/split v0.2.0 \(.*split.2[/\\]nested\)\n\texample.net/split/nested v0.1.0 \(.*nested.1\)$' + +# A wildcard that matches packages in some module at its selected version +# but not at the requested version should fail. +# +# We can't set the module to the selected version, because that version doesn't +# even match the query: if we ran the same query twice, we wouldn't consider the +# module to match the wildcard during the second call, so why should we consider +# it to match during the first one? ('go get' should be idempotent, and if we +# did that then it would not be.) +# +# But we also can't leave it where it is: the user requested that we set everything +# matching the pattern to the given version, and right now we have packages +# that match the pattern but *not* the version. +# +# That only leaves two options: we can set the module to an arbitrary version +# (perhaps 'latest' or 'none'), or we can report an error and the let the user +# disambiguate. We would rather not choose arbitrarily, so we do the latter. +# +# TODO(#27899): Should we instead upgrade or downgrade to an arbirary version? + +! go get example.net/split/nested/...@v0.1.0 +stderr '^go: example.net/split/nested/\.\.\.@v0.1.0 matches packages in example.net/split@v0.2.0 but not example.net/split@v0.1.0: specify a different version for module example.net/split$' + +cmp go.mod go.mod.orig + + +# If another argument resolves the ambiguity, we should be ok again. + +go get example.net/split@none example.net/split/nested@v0.1.0 +go list -m all +! stdout '^example.net/split ' +stdout '^example.net/split/nested v0.1.0 ' + +cp go.mod.orig go.mod + +go get example.net/split@v0.3.0 example.net/split/nested@v0.1.0 +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.1.0 ' + + +# If a pattern applies to modules and to packages, we should set all matching +# modules to the version indicated by the pattern, and also resolve packages +# to match the pattern if possible. + +cp go.mod.orig go.mod +go get example.net/split/nested@v0.0.0 + +go get example.net/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' +stdout '^example.net/split/nested v0.1.0 ' + +go get example.net/... +go list -m all +stdout '^example.net/split v0.3.0 ' +stdout '^example.net/split/nested v0.2.0 ' + + +# @none applies to all matching module paths, +# regardless of whether they contain any packages. + +go get example.net/...@none +go list -m all +! stdout '^example.net' + +# Starting from no dependencies, a wildcard can resolve to an empty module with +# the same prefix even if it contains no packages. + +go get example.net/...@none +go get example.net/split/...@v0.1.0 +go list -m all +stdout '^example.net/split v0.1.0 ' + + +-- go.mod -- +module m + +go 1.16 + +require example.net/split v0.2.0 + +replace ( + example.net/split v0.1.0 => ./split.1 + example.net/split v0.2.0 => ./split.2 + example.net/split v0.2.1 => ./split.2 + example.net/split v0.3.0 => ./split.3 + example.net/split/nested v0.0.0 => ./nested.0 + example.net/split/nested v0.1.0 => ./nested.1 + example.net/split/nested v0.2.0 => ./nested.2 +) +-- split.1/go.mod -- +module example.net/split + +go 1.16 +-- split.2/go.mod -- +module example.net/split + +go 1.16 +-- split.2/nested/nested.go -- +package nested +-- split.3/go.mod -- +module example.net/split + +go 1.16 +-- nested.0/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.1/nested.go -- +package nested +-- nested.2/go.mod -- +module example.net/split/nested + +go 1.16 +-- nested.2/nested.go -- +package nested diff --git a/src/cmd/go/testdata/script/mod_get_sum_noroot.txt b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt new file mode 100644 index 0000000..0d9a840 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_sum_noroot.txt @@ -0,0 +1,11 @@ +# When 'go get' is invoked on a module without a package in the root directory, +# it should add sums for the module's go.mod file and its content to go.sum. +# Verifies golang.org/issue/41103. +go mod init m +go get rsc.io/QUOTE +grep '^rsc.io/QUOTE v1.5.2/go.mod ' go.sum +grep '^rsc.io/QUOTE v1.5.2 ' go.sum + +# Double-check rsc.io/QUOTE does not have a root package. +! go list -mod=readonly rsc.io/QUOTE +stderr '^cannot find module providing package rsc.io/QUOTE: import lookup disabled by -mod=readonly$' diff --git a/src/cmd/go/testdata/script/mod_get_tags.txt b/src/cmd/go/testdata/script/mod_get_tags.txt new file mode 100644 index 0000000..e4fb6c4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_tags.txt @@ -0,0 +1,34 @@ +env GO111MODULE=on + +# get should add modules needed to build packages, even if those +# dependencies are in sources excluded by build tags. +# All build tags are considered true except "ignore". +go mod init m +go get . +go list -m all +stdout 'example.com/version v1.1.0' +stdout 'rsc.io/quote v1.5.2' + +-- empty.go -- +package m + +-- excluded.go -- +// +build windows,mips + +package m + +import _ "example.com/version" + +-- tools.go -- +// +build tools + +package tools + +import _ "rsc.io/quote" + +-- ignore.go -- +// +build ignore + +package ignore + +import _ "example.com/doesnotexist" diff --git a/src/cmd/go/testdata/script/mod_get_test.txt b/src/cmd/go/testdata/script/mod_get_test.txt new file mode 100644 index 0000000..0fa7cd9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_test.txt @@ -0,0 +1,58 @@ +env GO111MODULE=on + +# By default, 'go get' should ignore tests +cp go.mod.empty go.mod +go get m/a +! grep rsc.io/quote go.mod + +# 'go get -t' should consider test dependencies of the named package. +cp go.mod.empty go.mod +go get -t m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t' should not consider test dependencies of imported packages, +# including packages imported from tests. +cp go.mod.empty go.mod +go get -t m/b +! grep rsc.io/quote go.mod + +# 'go get -t -u' should update test dependencies of the named package. +cp go.mod.empty go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -t -u m/a +grep 'rsc.io/quote v1.5.2$' go.mod + +# 'go get -t -u' should not add or update test dependencies +# of imported packages, including packages imported from tests. +cp go.mod.empty go.mod +go get -t -u m/b +! grep rsc.io/quote go.mod +go mod edit -require=rsc.io/quote@v1.5.1 +go get -t -u m/b +grep 'rsc.io/quote v1.5.1$' go.mod + +# 'go get all' should consider test dependencies with or without -t. +cp go.mod.empty go.mod +go get all +grep 'rsc.io/quote v1.5.2$' go.mod + +-- go.mod.empty -- +module m + +-- a/a.go -- +package a + +-- a/a_test.go -- +package a_test + +import _ "rsc.io/quote" + +-- b/b.go -- +package b + +import _ "m/a" + +-- b/b_test.go -- +package b_test + +import _ "m/a" diff --git a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt new file mode 100644 index 0000000..7b46900 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -0,0 +1,30 @@ +# go list should succeed to load a package ending with ".go" if the path does +# not correspond to an existing local file. Listing a pattern ending with +# ".go/" should try to list a package regardless of whether a file exists at the +# path without the suffixed "/" or not. +go list example.com/dotgo.go +stdout ^example.com/dotgo.go$ +go list example.com/dotgo.go/ +stdout ^example.com/dotgo.go$ + +# go get should succeed in either case, with or without a version. +# Arguments are interpreted as packages or package patterns with versions, +# not source files. +go get example.com/dotgo.go +go get example.com/dotgo.go/ +go get example.com/dotgo.go@v1.0.0 +go get example.com/dotgo.go/@v1.0.0 + +-- go.mod -- +module m + +go 1.13 + +require example.com/dotgo.go v1.0.0 +-- go.sum -- +example.com/dotgo.go v1.0.0 h1:XKJfs0V8x2PvY2tX8bJBCEbCDLnt15ma2onwhVpew/I= +example.com/dotgo.go v1.0.0/go.mod h1:Qi6z/X3AC5vHiuMt6HF2ICx3KhIBGrMdrA7YoPDKqR0= +-- use.go -- +package use + +import _ "example.com/dotgo.go" diff --git a/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt b/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt new file mode 100644 index 0000000..a5651e9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_update_unrelated_sum.txt @@ -0,0 +1,120 @@ +# Check that 'go get' adds sums for updated modules if we had sums before, +# even if we didn't load packages from them. +# Verifies #44129. + +env fmt='{{.ImportPath}}: {{if .Error}}{{.Error.Err}}{{else}}ok{{end}}' + +# Control case: before upgrading, we have the sums we need. +# go list -deps -e -f $fmt . +# stdout '^rsc.io/quote: ok$' +# ! stdout rsc.io/sampler # not imported by quote in this version +cp go.mod.orig go.mod +cp go.sum.orig go.sum +go mod tidy +cmp go.mod.orig go.mod +cmp go.sum.orig go.sum + + +# Upgrade a module. This also upgrades rsc.io/quote, and though we didn't load +# a package from it, we had the sum for its old version, so we need the +# sum for the new version, too. +go get example.com/upgrade@v0.0.2 +grep '^rsc.io/quote v1.5.2 ' go.sum + +# The upgrade still breaks the build because the new version of quote imports +# rsc.io/sampler, and we don't have its zip sum. +go list -deps -e -f $fmt +stdout 'rsc.io/quote: ok' +stdout 'rsc.io/sampler: missing go.sum entry for module providing package rsc.io/sampler' +cp go.mod.orig go.mod +cp go.sum.orig go.sum + + +# Replace the old version with a directory before upgrading. +# We didn't need a sum for it before (even though we had one), so we won't +# fetch a new sum. +go mod edit -replace rsc.io/quote@v1.0.0=./dummy +go get example.com/upgrade@v0.0.2 +! grep '^rsc.io/quote v1.5.2 ' go.sum +cp go.mod.orig go.mod +cp go.sum.orig go.sum + + +# Replace the new version with a directory before upgrading. +# We can't get a sum for a directory. +go mod edit -replace rsc.io/quote@v1.5.2=./dummy +go get example.com/upgrade@v0.0.2 +! grep '^rsc.io/quote v1.5.2 ' go.sum +cp go.mod.orig go.mod +cp go.sum.orig go.sum + + +# Replace the new version with a different version. +# We should get a sum for that version. +go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1 +go get example.com/upgrade@v0.0.2 +! grep '^rsc.io/quote v1.5.2 ' go.sum +grep '^rsc.io/quote v1.5.1 ' go.sum +cp go.mod.orig go.mod +cp go.sum.orig go.sum + + +# Delete the new version's zip (but not mod) from the cache and go offline. +# 'go get' should fail when fetching the zip. +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +env GOPROXY=off +! go get example.com/upgrade@v0.0.2 +stderr '^go: upgraded rsc.io/quote v1.0.0 => v1.5.2: error finding sum for rsc.io/quote@v1.5.2: module lookup disabled by GOPROXY=off$' + +-- go.mod.orig -- +module m + +go 1.16 + +require ( + example.com/upgrade v0.0.1 + rsc.io/quote v1.0.0 +) + +replace ( + example.com/upgrade v0.0.1 => ./upgrade1 + example.com/upgrade v0.0.2 => ./upgrade2 +) +-- go.sum.orig -- +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= +-- go.sum.want -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- use.go -- +package use + +import ( + _ "example.com/upgrade" + _ "rsc.io/quote" +) +-- upgrade1/go.mod -- +module example.com/upgrade + +go 1.16 +-- upgrade1/upgrade.go -- +package upgrade +-- upgrade2/go.mod -- +module example.com/upgrade + +go 1.16 + +require rsc.io/quote v1.5.2 // indirect +-- upgrade2/upgrade.go -- +package upgrade +-- dummy/go.mod -- +module rsc.io/quote + +go 1.16 +-- dummy/quote.go -- +package quote + diff --git a/src/cmd/go/testdata/script/mod_get_upgrade.txt b/src/cmd/go/testdata/script/mod_get_upgrade.txt new file mode 100644 index 0000000..51d5990 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_upgrade.txt @@ -0,0 +1,46 @@ +env GO111MODULE=on + +go get rsc.io/quote@v1.5.1 +go list -m all +stdout 'rsc.io/quote v1.5.1' +grep 'rsc.io/quote v1.5.1$' go.mod + +# get -u should update dependencies of the package in the current directory +go get -u +grep 'rsc.io/quote v1.5.2$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# get -u rsc.io/sampler should update only sampler's dependencies +cp go.mod-v1.5.1 go.mod +go get -u rsc.io/sampler +grep 'rsc.io/quote v1.5.1$' go.mod +grep 'golang.org/x/text [v0-9a-f\.-]+ // indirect' go.mod + +# move to a pseudo-version after any tags +go get rsc.io/quote@dd9747d +grep 'rsc.io/quote v0.0.0-20180628003336-dd9747d19b04' go.mod + +# get -u should not jump off newer pseudo-version to earlier tag +go get -u +grep 'rsc.io/quote v0.0.0-20180628003336-dd9747d19b04' go.mod + +# move to earlier pseudo-version +go get rsc.io/quote@e7a685a342 +grep 'rsc.io/quote v0.0.0-20180214005133-e7a685a342c0' go.mod + +# get -u should jump off earlier pseudo-version to newer tag +go get -u +grep 'rsc.io/quote v1.5.2' go.mod + +-- go.mod -- +module x +require rsc.io/quote v1.1.0 + +-- go.mod-v1.5.1 -- +module x +require rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt b/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt new file mode 100644 index 0000000..deff935 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_upgrade_pseudo.txt @@ -0,0 +1,70 @@ +env GO111MODULE=on + +# For this test module there are three versions: +# * v0.1.1-0.20190429073117-b5426c86b553 +# * v0.1.0 +# * v0.0.0-20190430073000-30950c05d534 +# Only v0.1.0 is tagged. +# +# The v0.1.1 pseudo-version is semantically higher than the latest tag. +# The v0.0.0 pseudo-version is chronologically newer. + +# Start at v0.1.1-0.20190429073117-b5426c86b553 +go get example.com/pseudoupgrade@b5426c8 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get -u' should not downgrade to the (lower) tagged version. +go get -u +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade@upgrade' should not downgrade. +go get example.com/pseudoupgrade@upgrade +go list -m all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade' should not downgrade. +# This is equivalent to 'get example.com/pseudoupgrade@upgrade'. +go get example.com/pseudoupgrade +go list -m all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +# @latest should not consider the current version. +go get example.com/pseudoupgrade@latest +go list -m all +stdout '^example.com/pseudoupgrade v0.1.0$' + +# We should observe the same behavior with the newer pseudo-version. +go get example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534 + +# 'get -u' should not downgrade to the chronologically older tagged version. +go get -u +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade@upgrade should not downgrade. +go get example.com/pseudoupgrade@upgrade +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade' should not downgrade. +go get example.com/pseudoupgrade +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +# 'get example.com/pseudoupgrade@latest' should downgrade. +go get example.com/pseudoupgrade@latest +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.0$' + +-- go.mod -- +module x + +go 1.12 + +-- main.go -- +package x + +import _ "example.com/pseudoupgrade" diff --git a/src/cmd/go/testdata/script/mod_get_wild.txt b/src/cmd/go/testdata/script/mod_get_wild.txt new file mode 100644 index 0000000..06f9973 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_get_wild.txt @@ -0,0 +1,95 @@ +# This test covers a crazy edge-case involving wildcards and multiple passes of +# patch-upgrades, but if we get it right we probably get many other edge-cases +# right too. + +go list -m all +stdout '^example.net/a v0.1.0 ' +! stdout '^example.net/b ' + + +# Requesting pattern example.../b by itself fails: there is no such module +# already in the build list, and the wildcard in the first element prevents us +# from attempting to resolve a new module whose path is a prefix of the pattern. + +! go get -u=patch example.../b@upgrade +stderr '^go: no modules to query for example\.\.\./b@upgrade because first path element contains a wildcard$' + + +# Patching . causes a patch to example.net/a, which introduces a new match +# for example.net/b/..., which is itself patched and causes another upgrade to +# example.net/a, which is then patched again. + +go get -u=patch . example.../b@upgrade +go list -m all +stdout '^example.net/a v0.2.1 ' # upgraded by dependency of b and -u=patch +stdout '^example.net/b v0.2.0 ' # introduced by patch of a and upgraded by wildcard + + +-- go.mod -- +module example + +go 1.16 + +require example.net/a v0.1.0 + +replace ( + example.net/a v0.1.0 => ./a10 + example.net/a v0.1.1 => ./a11 + example.net/a v0.2.0 => ./a20 + example.net/a v0.2.1 => ./a20 + example.net/b v0.1.0 => ./b1 + example.net/b v0.1.1 => ./b1 + example.net/b v0.2.0 => ./b2 +) +-- example.go -- +package example + +import _ "example.net/a" + +-- a10/go.mod -- +module example.net/a + +go 1.16 +-- a10/a.go -- +package a + +-- a11/go.mod -- +module example.net/a + +go 1.16 + +require example.net/b v0.1.0 +-- a11/a.go -- +package a +-- a11/unimported/unimported.go -- +package unimported + +import _ "example.net/b" + + +-- a20/go.mod -- +module example.net/a + +go 1.16 +-- a20/a.go -- +package a + +-- b1/go.mod -- +module example.net/b + +go 1.16 +-- b1/b.go -- +package b + +-- b2/go.mod -- +module example.net/b + +go 1.16 + +require example.net/a v0.2.0 +-- b2/b.go -- +package b +-- b2/b_test.go -- +package b_test + +import _ "example.net/a" diff --git a/src/cmd/go/testdata/script/mod_getmode_vendor.txt b/src/cmd/go/testdata/script/mod_getmode_vendor.txt new file mode 100644 index 0000000..aaf526b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_getmode_vendor.txt @@ -0,0 +1,31 @@ +env GO111MODULE=on + +go get rsc.io/quote@v1.5.1 +go mod vendor +env GOPATH=$WORK/empty +env GOPROXY=file:///nonexist + +go list -mod=vendor +go list -mod=vendor -f '{{with .Module}}{{.Path}} {{.Version}}{{end}} {{.Dir}}' all +stdout '^rsc.io/quote v1.5.1 .*vendor[\\/]rsc.io[\\/]quote$' +stdout '^golang.org/x/text v0.0.0.* .*vendor[\\/]golang.org[\\/]x[\\/]text[\\/]language$' + +! go list -mod=vendor -m rsc.io/quote@latest +stderr 'go: rsc.io/quote@latest: cannot query module due to -mod=vendor' +! go get -mod=vendor -u +stderr 'flag provided but not defined: -mod' + +# Since we don't have a complete module graph, 'go list -m' queries +# that require the complete graph should fail with a useful error. +! go list -mod=vendor -m all +stderr 'go: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' +! go list -mod=vendor -m ... +stderr 'go: can''t match module patterns using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +-- go.mod -- +module x + +go 1.16 +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_getx.txt b/src/cmd/go/testdata/script/mod_getx.txt new file mode 100644 index 0000000..b3d06c1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_getx.txt @@ -0,0 +1,19 @@ +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get -x' should log URLs with an HTTP or HTTPS scheme. +# A bug had caused us to log schemeless URLs instead. +go get -x golang.org/x/text@v0.1.0 +stderr '^# get https://golang.org/x/text\?go-get=1$' +stderr '^# get https://golang.org/x/text\?go-get=1: 200 OK \([0-9.]+s\)$' +! stderr '^# get //.*' + +-- go.mod -- +module m + +go 1.18 diff --git a/src/cmd/go/testdata/script/mod_git_export_subst.txt b/src/cmd/go/testdata/script/mod_git_export_subst.txt new file mode 100644 index 0000000..a28b4f2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_git_export_subst.txt @@ -0,0 +1,21 @@ +env GO111MODULE=on +env GOPROXY=direct + +# Testing that git export-subst is disabled +[!net] skip +[!exec:git] skip +go build + +-- x.go -- +package x + +import _ "github.com/jasonkeene/export-subst" + +-- go.mod -- +module x + +require github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626 + +-- go.sum -- +github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626 h1:AUkXi/xFnm7lH2pgtvVkGb7buRn1ywFHw+xDpZ29Rz0= +github.com/jasonkeene/export-subst v0.0.0-20180927204031-5845945ec626/go.mod h1:DwJXqVtrgrQkv3Giuf2Jh4YyubVe7y41S1eOIaysTJw= diff --git a/src/cmd/go/testdata/script/mod_go_version.txt b/src/cmd/go/testdata/script/mod_go_version.txt new file mode 100644 index 0000000..97d9975 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_go_version.txt @@ -0,0 +1,110 @@ +# Test support for declaring needed Go version in module. + +env GO111MODULE=on + +go list +go build +go build sub.1 +go build subver.1 +! stderr 'module requires' +! go build badsub.1 +stderr '^note: module requires Go 1.11111$' + +go build versioned.1 +go mod edit -require versioned.1@v1.1.0 +! go build versioned.1 +stderr '^note: module requires Go 1.99999$' + +[short] stop + +# The message should be printed even if the compiler emits no output. +go build -o $WORK/nooutput.exe nooutput.go +! go build -toolexec=$WORK/nooutput.exe versioned.1 +stderr '^# versioned.1\nnote: module requires Go 1.99999$' + +-- go.mod -- +module m +go 1.999 +require ( + sub.1 v1.0.0 + subver.1 v1.0.0 + badsub.1 v1.0.0 + versioned.1 v1.0.0 +) +replace ( + sub.1 => ./sub + subver.1 => ./subver + badsub.1 => ./badsub + versioned.1 v1.0.0 => ./versioned1 + versioned.1 v1.1.0 => ./versioned2 +) + +-- x.go -- +package x + +-- sub/go.mod -- +module m +go 1.11 + +-- sub/x.go -- +package x + +-- subver/go.mod -- +module m +go 1.11111 + +-- subver/x.go -- +package x + +-- badsub/go.mod -- +module m +go 1.11111 + +-- badsub/x.go -- +package x +invalid syntax + +-- versioned1/go.mod -- +module versioned +go 1.0 + +-- versioned1/x.go -- +package x + +-- versioned2/go.mod -- +module versioned +go 1.99999 + +-- versioned2/x.go -- +package x +invalid syntax + +-- nooutput.go -- +// +build ignore + +package main + +import ( + "bytes" + "os" + "os/exec" + "strings" +) + +func main() { + stderr := new(bytes.Buffer) + stdout := new(bytes.Buffer) + + cmd := exec.Command(os.Args[1], os.Args[2:]...) + cmd.Stderr = stderr + cmd.Stdout = stdout + + err := cmd.Run() + if strings.HasPrefix(os.Args[2], "-V") { + os.Stderr.Write(stderr.Bytes()) + os.Stdout.Write(stdout.Bytes()) + } + if err != nil { + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/mod_go_version_missing.txt b/src/cmd/go/testdata/script/mod_go_version_missing.txt new file mode 100644 index 0000000..2159a1e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_go_version_missing.txt @@ -0,0 +1,122 @@ +cp go.mod go.mod.orig + +# For modules whose go.mod file does not include a 'go' directive, +# we assume the language and dependency semantics of Go 1.16, +# but do not trigger “automatic vendoring” mode (-mod=vendor), +# which was added in Go 1.14 and was not triggered +# under the same conditions in Go 1.16 (which would instead +# default to -mod=readonly when no 'go' directive is present). + +# For Go 1.16 modules, 'all' should prune out dependencies of tests, +# even if the 'go' directive is missing. + +go list -mod=readonly all +stdout '^example.com/dep$' +! stdout '^example.com/testdep$' +cp stdout list-1.txt +cmp go.mod go.mod.orig + +# We should only default to -mod=vendor if the 'go' directive is explicit in the +# go.mod file. Otherwise, we don't actually know whether the module was written +# against Go 1.11 or 1.16. We would have to update the go.mod file to clarify, +# and as of Go 1.16 we don't update the go.mod file by default. +# +# If we set -mod=vendor explicitly, we shouldn't apply the Go 1.14 +# consistency check, because — again — we don't know whether we're in a 1.11 +# module or a bad-script-edited 1.16 module. + +! go list -mod=vendor all +! stderr '^go: inconsistent vendoring' +stderr 'cannot find package "vendor/example.com/badedit" in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$' + +# When we set -mod=mod, the go version should be updated immediately, +# to the current version, converting the requirements from eager to lazy. +# +# Since we don't know which requirements are actually relevant to the main +# module, all requirements are added as roots, making the requirements untidy. + +go list -mod=mod all +! stdout '^example.com/testdep$' +cmp stdout list-1.txt +cmpenv go.mod go.mod.untidy + +go mod tidy +cmpenv go.mod go.mod.tidy + +# On the other hand, if we jump straight to 'go mod tidy', +# the requirements remain tidy from the start. + +cp go.mod.orig go.mod +go mod tidy +cmpenv go.mod go.mod.tidy + + +# The updated version should have been written back to go.mod, so now the 'go' +# directive is explicit. -mod=vendor should trigger by default, and the stronger +# Go 1.14 consistency check should apply. +! go list all +stderr '^go: inconsistent vendoring' +! stderr badedit + + +-- go.mod -- +module example.com/m + +require example.com/dep v0.1.0 + +replace ( + example.com/dep v0.1.0 => ./dep + example.com/testdep v0.1.0 => ./testdep +) +-- go.mod.untidy -- +module example.com/m + +go $goversion + +require example.com/dep v0.1.0 + +require example.com/testdep v0.1.0 // indirect + +replace ( + example.com/dep v0.1.0 => ./dep + example.com/testdep v0.1.0 => ./testdep +) +-- go.mod.tidy -- +module example.com/m + +go $goversion + +require example.com/dep v0.1.0 + +replace ( + example.com/dep v0.1.0 => ./dep + example.com/testdep v0.1.0 => ./testdep +) +-- vendor/example.com/dep/dep.go -- +package dep +import _ "example.com/badedit" +-- vendor/modules.txt -- +HAHAHA this is broken. + +-- m.go -- +package m + +import _ "example.com/dep" + +const x = 1_000 + +-- dep/go.mod -- +module example.com/dep + +require example.com/testdep v0.1.0 +-- dep/dep.go -- +package dep +-- dep/dep_test.go -- +package dep_test + +import _ "example.com/testdep" + +-- testdep/go.mod -- +module example.com/testdep +-- testdep/testdep.go -- +package testdep diff --git a/src/cmd/go/testdata/script/mod_go_version_mixed.txt b/src/cmd/go/testdata/script/mod_go_version_mixed.txt new file mode 100644 index 0000000..d6216ae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_go_version_mixed.txt @@ -0,0 +1,43 @@ +# Test that dependencies can use Go language features newer than the +# Go version specified by the main module. + +env GO111MODULE=on + +go build + +-- go.mod -- +module m +go 1.12 +require ( + sub.1 v1.0.0 +) +replace ( + sub.1 => ./sub +) + +-- x.go -- +package x + +import "sub.1" + +func F() { sub.F(0, 0) } + +var A sub.Alias +var D sub.Defined + +-- sub/go.mod -- +module m +go 1.14 + +-- sub/sub.go -- +package sub + +// signed shift counts added in Go 1.13 +func F(l, r int) int { return l << r } + +type m1 interface { M() } +type m2 interface { M() } + +// overlapping interfaces added in Go 1.14 +type Alias = interface { m1; m2; M() } +type Defined interface { m1; m2; M() } diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt new file mode 100644 index 0000000..c13ae84 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt @@ -0,0 +1,133 @@ +[short] skip + +# go/build's Import should find modules by invoking the go command + +go build -o $WORK ./testimport ./testfindonly + +# GO111MODULE=off +env GO111MODULE=off +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . + +# GO111MODULE=auto in GOPATH/src +env GO111MODULE=auto +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . + +# GO111MODULE=auto outside GOPATH/src +cd $GOPATH/other +env GO111MODULE=auto +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stderr 'no required module provides package gobuild.example.com/x/y/z/w; to add it:\n\tgo get gobuild.example.com/x/y/z/w' + +cd z +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +# GO111MODULE=on outside GOPATH/src +env GO111MODULE= +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go +env GO111MODULE=on +exec $WORK/testimport$GOEXE other/x/y/z/w . +stdout w2.go + +# GO111MODULE=on in GOPATH/src +cd $GOPATH/src +env GO111MODULE= +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stdout w1.go +env GO111MODULE=on +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . +stdout w1.go +cd w +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .. +stdout w1.go + +# go/build's Import in FindOnly mode should find directories by invoking the go command +# +# Calling build.Import in build.FindOnly mode on an import path of a Go package +# that produces errors when loading (e.g., due to build constraints not matching +# the current build context) should return the package directory and nil error. + +# Issue 31603: Import with non-empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=<nil>$' + +# Issue 37153: Import with empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i '' +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=<nil>$' + +-- go.mod -- +module gobuild.example.com/x/y/z + +-- z.go -- +package z + +-- w/w1.go -- +package w + +-- i/i.go -- +// +build i + +package i + +-- testimport/x.go -- +package main + +import ( + "fmt" + "go/build" + "log" + "os" + "path/filepath" + "strings" +) + +func main() { + // build.Import should support relative and absolute source dir paths. + path := os.Args[1] + srcDir := os.Args[2] + p1, err := build.Import(path, srcDir, 0) + if err != nil { + log.Fatal(err) + } + absSrcDir, err := filepath.Abs(srcDir) + if err != nil { + log.Fatal(err) + } + p2, err := build.Import(path, absSrcDir, 0) + if err != nil { + log.Fatal(err) + } + if p1.Dir != p2.Dir { + log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir) + } + + fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " ")) +} + +-- testfindonly/x.go -- +package main + +import ( + "fmt" + "go/build" + "os" +) + +func main() { + p, err := build.Import(os.Args[1], os.Args[2], build.FindOnly) + fmt.Printf("dir=%s err=%v\n", p.Dir, err) +} + +-- $GOPATH/other/go.mod -- +module other/x/y + +-- $GOPATH/other/z/w/w2.go -- +package w diff --git a/src/cmd/go/testdata/script/mod_gofmt_invalid.txt b/src/cmd/go/testdata/script/mod_gofmt_invalid.txt new file mode 100644 index 0000000..21edc7d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gofmt_invalid.txt @@ -0,0 +1,13 @@ +# Test for a crash in go fmt on invalid input when using modules. +# Issue 26792. + +env GO111MODULE=on +! go fmt x.go +! stderr panic + +-- go.mod -- +module x + +-- x.go -- +// Missing package declaration. +var V int diff --git a/src/cmd/go/testdata/script/mod_gomodcache.txt b/src/cmd/go/testdata/script/mod_gomodcache.txt new file mode 100644 index 0000000..bafa587 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gomodcache.txt @@ -0,0 +1,74 @@ +# Test GOMODCACHE +env GO111MODULE=on + +# Explicitly set GOMODCACHE +env GOMODCACHE=$WORK/modcache +go env GOMODCACHE +stdout $WORK[/\\]modcache +go get rsc.io/quote@v1.0.0 +exists $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info +grep '{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"}' $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info + +# Ensure GOMODCACHE doesn't affect location of sumdb, but $GOMODCACHE/cache/download/sumdb is still written +exists $GOPATH/pkg/sumdb +! exists $WORK/modcache/sumdb +exists $WORK/modcache/cache/download/sumdb + +# Test that the default GOMODCACHE is $GOPATH[0]/pkg/mod +env GOMODCACHE= +go env GOMODCACHE +stdout $GOPATH[/\\]pkg[/\\]mod +go get rsc.io/quote@v1.0.0 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.0.0.info +grep '{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"}' $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.0.0.info + +# If neither GOMODCACHE or GOPATH are set, GOPATH defaults to the user's $HOME/go, so GOMODCACHE becomes $HOME/go/pkg/mod +[windows] env USERPROFILE=$WORK/home # Ensure USERPROFILE is a valid path (rather than /no-home/ so we don't run into the logic that "uninfers" GOPATH in cmd/go/main.go +[plan9] env home=$WORK/home +[!windows] [!plan9] env HOME=$WORK/home +env GOMODCACHE= +env GOPATH= +go env GOMODCACHE +stdout $HOME[/\\]go[/\\]pkg[/\\]mod + +# If GOMODCACHE isn't set and GOPATH starts with the path list separator, +# GOMODCACHE is empty and any command that needs it errors out. +env GOMODCACHE= +env GOPATH=${:}$WORK/this/is/ignored + +go env GOMODCACHE +stdout '^$' +! stdout . +! stderr . + +! go mod download rsc.io/quote@v1.0.0 +stderr '^go: module cache not found: neither GOMODCACHE nor GOPATH is set$' + +# If GOMODCACHE isn't set and GOPATH has multiple elements only the first is used. +env GOMODCACHE= +env GOPATH=$WORK/first/path${:}$WORK/this/is/ignored +go env GOMODCACHE +stdout $WORK[/\\]first[/\\]path[/\\]pkg[/\\]mod + +env GOMODCACHE=$WORK/modcache +go mod download rsc.io/quote@v1.0.0 +exists $WORK/modcache/cache/download/rsc.io/quote/@v/v1.0.0.info + +# Test error when cannot create GOMODCACHE directory +env GOMODCACHE=$WORK/modcachefile +! go install example.com/cmd/a@v1.0.0 +stderr 'go: could not create module cache' + +# Test that the following work even with GO111MODULE=off +env GO111MODULE=off + +# Cleaning modcache +exists $WORK/modcache +env GOMODCACHE=$WORK/modcache +go clean -modcache +! exists $WORK/modcache + +-- go.mod -- +module m + +-- $WORK/modcachefile -- diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt new file mode 100644 index 0000000..d42d668 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt @@ -0,0 +1,54 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPRIVATE GOPROXY GONOPROXY GOSUMDB GONOSUMDB +env dbname=localhost.localdev/sumdb + +# disagree with sumdb fails +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong +! go get rsc.io/quote +stderr 'SECURITY ERROR' + +# GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text +env GONOSUMDB='*/quote,*/*mple*,golang.org/x' +go get rsc.io/quote +rm go.sum +env GOPRIVATE='*/quote,*/*mple*,golang.org/x' +env GONOPROXY=none # that is, proxy all despite GOPRIVATE +go get rsc.io/quote + +# Download .info files needed for 'go list -m all' later. +# TODO(#42723): either 'go list -m' should not read these files, +# or 'go get' and 'go mod tidy' should download them. +go list -m all +stdout '^golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c$' + +# When GOPROXY is not empty but contains no entries, an error should be reported. +env GOPROXY=',' +! go get golang.org/x/text +stderr '^go: golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$' + +# When GOPROXY=off, fetching modules not matched by GONOPROXY fails. +env GONOPROXY=*/fortune +env GOPROXY=off +! go get golang.org/x/text +stderr '^go: golang.org/x/text: module lookup disabled by GOPROXY=off$' + +# GONOPROXY bypasses proxy +[!net] skip +[!exec:git] skip +env GOPRIVATE=none +env GONOPROXY='*/fortune' +! go get rsc.io/fortune # does not exist in real world, only on test proxy +stderr 'git ls-remote' + +env GOSUMDB= +env GONOPROXY= +env GOPRIVATE='*/x' +go get golang.org/x/text +go list -m all +! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt new file mode 100644 index 0000000..beba3e7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on + +cp go.mod.empty go.mod +go get gopkg.in/dummy.v2-unstable + +cp x.go.txt x.go +cp go.mod.empty go.mod +go list + +[!net] skip +[!exec:git] skip + +env GOPROXY=direct +env GOSUMDB=off +go get gopkg.in/macaroon-bakery.v2-unstable/bakery +go list -m all +stdout 'gopkg.in/macaroon-bakery.v2-unstable v2.0.0-[0-9]+-[0-9a-f]+$' + +-- go.mod.empty -- +module m + +-- x.go.txt -- +package x +import _ "gopkg.in/dummy.v2-unstable" diff --git a/src/cmd/go/testdata/script/mod_goroot_errors.txt b/src/cmd/go/testdata/script/mod_goroot_errors.txt new file mode 100644 index 0000000..9d7a94d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_goroot_errors.txt @@ -0,0 +1,53 @@ +env GO111MODULE=on + +# Regression test for https://golang.org/issue/34769. +# Missing standard-library imports should refer to GOROOT rather than +# complaining about a malformed module path. +# This is especially important when GOROOT is set incorrectly, +# since such an error will occur for every package in std. + +# Building a nonexistent std package directly should fail usefully. + +! go build -mod=readonly nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building a nonexistent std package indirectly should also fail usefully. + +! go build -mod=readonly ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building an *actual* std package should fail if GOROOT is set to something bogus. + +[!short] go build ./importjson # Prove that it works when GOROOT is valid. + +env GOROOT=$WORK/not-a-valid-goroot +! go build ./importjson +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr 'importjson[/\\]x.go:2:8: package encoding/json is not in GOROOT \('$WORK'[/\\]not-a-valid-goroot[/\\]src[/\\]encoding[/\\]json\)$' + +-- go.mod -- +module example.com +go 1.14 +-- importnonexist/x.go -- +package importnonexist +import _ "nonexist" +-- importjson/x.go -- +package importjson +import _ "encoding/json" +-- $WORK/not-a-valid-goroot/README -- +This directory is not a valid GOROOT. diff --git a/src/cmd/go/testdata/script/mod_graph.txt b/src/cmd/go/testdata/script/mod_graph.txt new file mode 100644 index 0000000..07968f5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_graph.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on + +go mod graph +stdout '^m rsc.io/quote@v1.5.2$' +stdout '^rsc.io/quote@v1.5.2 rsc.io/sampler@v1.3.0$' +! stdout '^m rsc.io/sampler@v1.3.0$' + +-- go.mod -- +module m +require rsc.io/quote v1.5.2 diff --git a/src/cmd/go/testdata/script/mod_graph_version.txt b/src/cmd/go/testdata/script/mod_graph_version.txt new file mode 100644 index 0000000..f9a73f4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_graph_version.txt @@ -0,0 +1,101 @@ +# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant) +# requirement on a retracted higher version of a dependency. +# However, when Go 1.16 reads the same requirements from the go.mod file, +# it does not prune out that requirement, and selects the retracted version. +# +# The Go 1.16 module graph looks like: +# +# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible +# | | +# + -------+------------- incompatible v1.0.0 +# +# The Go 1.17 module graph is the same except that the dependencies of +# requireincompatible are pruned out (because the module that requires +# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to +# the main module). + +cp go.mod go.mod.orig + +go mod graph +cp stdout graph-1.17.txt +stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$' +stdout '^example\.net/lazy@v0\.1\.0 example\.com/retract/incompatible@v1\.0\.0$' +! stdout 'example\.com/retract/incompatible@v2\.0\.0\+incompatible' + +go mod graph -go=1.17 +cmp stdout graph-1.17.txt + +cmp go.mod go.mod.orig + + +# Setting -go=1.16 should report the graph as viewed by Go 1.16, +# but should not edit the go.mod file. + +go mod graph -go=1.16 +cp stdout graph-1.16.txt +stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$' +stdout '^example\.net/lazy@v0\.1\.0 example.com/retract/incompatible@v1\.0\.0$' +stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$' + +cmp go.mod go.mod.orig + + +# If we actually update the go.mod file to the requested go version, +# we should get the same selected versions, but the roots of the graph +# may be updated. +# +# TODO(#45551): The roots should not be updated. + +go mod edit -go=1.16 +go mod graph +! stdout '^example\.com/m example\.com/retract/incompatible@v1\.0\.0$' +stdout '^example\.net/lazy@v0.1.0 example.com/retract/incompatible@v1\.0\.0$' +stdout '^example.net/requireincompatible@v0.1.0 example.com/retract/incompatible@v2\.0\.0\+incompatible$' + # TODO(#45551): cmp stdout graph-1.16.txt + + +# Unsupported go versions should be rejected, since we don't know +# what versions they would report. +! go mod graph -go=1.99999999999 +stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\]\nRun ''go help mod graph'' for details.$' + + +-- go.mod -- +// Module m indirectly imports a package from +// example.com/retract/incompatible. Its selected version of +// that module is lower under Go 1.17 semantics than under Go 1.16. +module example.com/m + +go 1.17 + +replace ( + example.net/lazy v0.1.0 => ./lazy + example.net/requireincompatible v0.1.0 => ./requireincompatible +) + +require ( + example.com/retract/incompatible v1.0.0 // indirect + example.net/lazy v0.1.0 +) +-- lazy/go.mod -- +// Module lazy requires example.com/retract/incompatible v1.0.0. +// +// When viewed from the outside it also has a transitive dependency +// on v2.0.0+incompatible, but in lazy mode that transitive dependency +// is pruned out. +module example.net/lazy + +go 1.17 + +exclude example.com/retract/incompatible v2.0.0+incompatible + +require ( + example.com/retract/incompatible v1.0.0 + example.net/requireincompatible v0.1.0 +) +-- requireincompatible/go.mod -- +module example.net/requireincompatible + +go 1.15 + +require example.com/retract/incompatible v2.0.0+incompatible diff --git a/src/cmd/go/testdata/script/mod_help.txt b/src/cmd/go/testdata/script/mod_help.txt new file mode 100644 index 0000000..b5cd30c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_help.txt @@ -0,0 +1,6 @@ +env GO111MODULE=on + +# go help get shows usage for get +go help get +stdout 'usage: go get' +stdout 'get using modules to manage source'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_import.txt b/src/cmd/go/testdata/script/mod_import.txt new file mode 100644 index 0000000..07714e9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +# latest rsc.io/quote should be v1.5.2 not v1.5.3-pre1 +go get +go list -m all +stdout 'rsc.io/quote v1.5.2' + +# but v1.5.3-pre1 should be a known version +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' + +-- go.mod -- +module x + +-- x.go -- +package x +import _ "rsc.io/quote" + diff --git a/src/cmd/go/testdata/script/mod_import_cycle.txt b/src/cmd/go/testdata/script/mod_import_cycle.txt new file mode 100644 index 0000000..7be0749 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_cycle.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on + +# 'go list all' should fail with a reasonable error message +! go list all +stderr '^package m\n\timports m/a\n\timports m/b\n\timports m/a: import cycle not allowed' + +# 'go list -e' should not print to stderr, but should mark all three +# packages (m, m/a, and m/b) as Incomplete. +go list -e -json all +! stderr . +stdout -count=3 '"Incomplete": true,' + +-- go.mod -- +module m + +require ( + m/a v0.0.0 + m/b v0.0.0 +) + +replace ( + m/a => ./a + m/b => ./b +) +-- m.go -- +package m +import ( + _ "m/a" + _ "m/b" +) +-- a/go.mod -- +module m/a +-- a/a.go -- +package a +import _ "m/b" +-- b/go.mod -- +module m/b +-- b/b.go -- +package b +import _ "m/a" diff --git a/src/cmd/go/testdata/script/mod_import_issue41113.txt b/src/cmd/go/testdata/script/mod_import_issue41113.txt new file mode 100644 index 0000000..fed2510 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue41113.txt @@ -0,0 +1,28 @@ +# Regression test for https://golang.org/issue/41113. +# +# When resolving a missing import path, the inability to add the package from +# one module path should not interfere with adding a nested path. + +# Initially, our module depends on split-incompatible v2.1.0-pre+incompatible, +# from which an imported package has been removed (and relocated to the nested +# split-incompatible/subpkg module). modload.QueryPattern will suggest +# split-incompatible v2.0.0+incompatible, which we cannot use (because it would +# be an implicit downgrade), and split-incompatible/subpkg v0.1.0, which we +# *should* use. + +go mod tidy + +go list -m all +stdout '^example.com/split-incompatible/subpkg v0\.1\.0$' +! stdout '^example.com/split-incompatible .*' + +-- go.mod -- +module golang.org/issue/41113 + +go 1.16 + +require example.com/split-incompatible v2.1.0-pre+incompatible +-- x.go -- +package issue41113 + +import _ "example.com/split-incompatible/subpkg" diff --git a/src/cmd/go/testdata/script/mod_import_issue42891.txt b/src/cmd/go/testdata/script/mod_import_issue42891.txt new file mode 100644 index 0000000..a78cab2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_issue42891.txt @@ -0,0 +1,14 @@ +# If an import declaration is an absolute path, most commands should report +# an error instead of going into an infinite loop. +# Verifies golang.org/issue/42891. +go list . +stdout '^m$' + +-- go.mod -- +module m + +go 1.16 +-- m.go -- +package m + +import "/" diff --git a/src/cmd/go/testdata/script/mod_import_meta.txt b/src/cmd/go/testdata/script/mod_import_meta.txt new file mode 100644 index 0000000..0e469d0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_meta.txt @@ -0,0 +1,45 @@ +# The loader should not attempt to resolve imports of the "all", "std", and "cmd" meta-packages. + +! go list -deps ./importall +! stderr 'internal error' +stderr '^importall[/\\]x.go:3:8: "all" is not an importable package; see ''go help packages''$' + +! go list -deps ./importcmd +! stderr 'internal error' +stderr '^importcmd[/\\]x.go:3:8: "cmd" is not an importable package; see ''go help packages''$' + +! go list -deps ./importstd +! stderr 'internal error' +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +# Not even if such a path is theoretically provided by a (necessarily replaced) module. + +go mod edit -replace std@v0.1.0=./modstd +go mod edit -require std@v0.1.0 + +! go list -deps ./importstd +stderr '^importstd[/\\]x.go:3:8: "std" is not an importable package; see ''go help packages''$' + + +-- go.mod -- +module example.com +go 1.16 +-- importall/x.go -- +package importall + +import _ "all" +-- importcmd/x.go -- +package importcmd + +import _ "cmd" +-- importstd/x.go -- +package importstd + +import _ "std" +-- modstd/go.mod -- +module std +go 1.16 +-- modstd/std.go -- +// Package std is an incredibly confusingly-named package. +package std diff --git a/src/cmd/go/testdata/script/mod_import_mod.txt b/src/cmd/go/testdata/script/mod_import_mod.txt new file mode 100644 index 0000000..b035e3d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_mod.txt @@ -0,0 +1,7 @@ +# Test that GOPATH/pkg/mod is excluded +env GO111MODULE=off +! go list mod/foo +stderr 'disallowed import path' + +-- mod/foo/foo.go -- +package foo diff --git a/src/cmd/go/testdata/script/mod_import_v1suffix.txt b/src/cmd/go/testdata/script/mod_import_v1suffix.txt new file mode 100644 index 0000000..75b3374 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_import_v1suffix.txt @@ -0,0 +1,11 @@ +env GO111MODULE=on + +! go get example.com/invalidpath/v1 +! go install . + +-- go.mod -- +module example.com +-- main.go -- +package main +import _ "example.com/invalidpath/v1" +func main() {} diff --git a/src/cmd/go/testdata/script/mod_in_testdata_dir.txt b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt new file mode 100644 index 0000000..866f784 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_in_testdata_dir.txt @@ -0,0 +1,45 @@ +# Regression test for golang.org/issue/28481: +# 'mod tidy' removed dependencies if the module root was +# within a directory named 'testdata' or '_foo'. + +env GO111MODULE=on + +# A module should be allowed in a directory named testdata. +cd $WORK/testdata +go mod init testdata.tld/foo + +# Getting a package within that module should resolve its dependencies. +go get +grep 'rsc.io/quote' go.mod + +# Tidying the module should preserve those dependencies. +go mod tidy +grep 'rsc.io/quote' go.mod + +[short] stop + +# Vendoring the module's dependencies should work too. +go mod vendor +exists vendor/rsc.io/quote + +# The same should work in directories with names starting with underscores. +cd $WORK/_ignored +go mod init testdata.tld/foo + +go get +grep 'rsc.io/quote' go.mod + +go mod tidy +grep 'rsc.io/quote' go.mod + +go mod vendor +exists vendor/rsc.io/quote + +-- $WORK/testdata/main.go -- +package foo + +import _ "rsc.io/quote" +-- $WORK/_ignored/main.go -- +package foo + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_indirect.txt b/src/cmd/go/testdata/script/mod_indirect.txt new file mode 100644 index 0000000..6ea1cae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect.txt @@ -0,0 +1,81 @@ +env GO111MODULE=on + +# golang.org/issue/31248: required modules imposed by dependency versions +# older than the selected version must still be taken into account. + +env GOFLAGS=-mod=readonly + +# Indirect dependencies required via older-than-selected versions must exist in +# the module graph, but do not need to be listed explicitly in the go.mod file +# (since they are implied). +go mod graph +stdout i@v0.1.0 + +# The modules must also appear in the build list, not just the graph. +go list -m all +stdout '^i v0.1.0' + +# The packages provided by those dependencies must resolve. +go list all +stdout '^i$' + +-- go.mod -- +module main + +go 1.13 + +require ( + a v0.0.0 + b v0.0.0 + c v0.0.0 +) + +// Apply replacements so that the test can be self-contained. +// (It's easier to see all of the modules here than to go +// rooting around in testdata/mod.) +replace ( + a => ./a + b => ./b + c => ./c + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 + i => ./i +) +-- main.go -- +package main + +import ( + _ "a" + _ "b" + _ "c" +) + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require x v0.1.0 +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.2.0 +-- b/b.go -- +package b +-- c/go.mod -- +module c +go 1.13 +-- c/c.go -- +package c +import _ "i" +-- x1/go.mod -- +module x +go1.13 +require i v0.1.0 +-- x2/go.mod -- +module x +go1.13 +-- i/go.mod -- +-- i/i.go -- +package i diff --git a/src/cmd/go/testdata/script/mod_indirect_main.txt b/src/cmd/go/testdata/script/mod_indirect_main.txt new file mode 100644 index 0000000..eeb93f1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect_main.txt @@ -0,0 +1,65 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/29773: 'go list -m' was not following +# dependencies through older versions of the main module. + +go list -f '{{with .Module}}{{.Path}}{{with .Version}} {{.}}{{end}}{{end}}' all +cmp stdout pkgmods.txt + +go list -m all +cmp stdout mods.txt + +go mod graph +cmp stdout graph.txt + +-- go.mod -- +module golang.org/issue/root + +go 1.12 + +replace ( + golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 + golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 + golang.org/issue/root v0.1.0 => ./root-v0.1.0 +) + +require golang.org/issue/mirror v0.1.0 + +-- root.go -- +package root + +import _ "golang.org/issue/mirror" + +-- mirror-v0.1.0/go.mod -- +module golang.org/issue/mirror + +require golang.org/issue/root v0.1.0 + +-- mirror-v0.1.0/mirror.go -- +package mirror + +import _ "golang.org/issue/pkg" + +-- pkg-v0.1.0/go.mod -- +module golang.org/issue/pkg + +-- pkg-v0.1.0/pkg.go -- +package pkg + +-- root-v0.1.0/go.mod -- +module golang.org/issue/root + +require golang.org/issue/pkg v0.1.0 + +-- pkgmods.txt -- +golang.org/issue/mirror v0.1.0 +golang.org/issue/pkg v0.1.0 +golang.org/issue/root +-- mods.txt -- +golang.org/issue/root +golang.org/issue/mirror v0.1.0 => ./mirror-v0.1.0 +golang.org/issue/pkg v0.1.0 => ./pkg-v0.1.0 +-- graph.txt -- +golang.org/issue/root golang.org/issue/mirror@v0.1.0 +golang.org/issue/mirror@v0.1.0 golang.org/issue/root@v0.1.0 +golang.org/issue/root@v0.1.0 golang.org/issue/pkg@v0.1.0 diff --git a/src/cmd/go/testdata/script/mod_indirect_nospace.txt b/src/cmd/go/testdata/script/mod_indirect_nospace.txt new file mode 100644 index 0000000..f4fb6a8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect_nospace.txt @@ -0,0 +1,32 @@ +# https://golang.org/issue/45932: "indirect" comments missing spaces +# should not be corrupted when the comment is removed. + +go mod tidy +cmp go.mod go.mod.direct + +-- go.mod -- +module example.net/m + +go 1.16 + +require example.net/x v0.1.0 //indirect + +replace example.net/x v0.1.0 => ./x +-- go.mod.direct -- +module example.net/m + +go 1.16 + +require example.net/x v0.1.0 + +replace example.net/x v0.1.0 => ./x +-- m.go -- +package m +import _ "example.net/x" + +-- x/go.mod -- +module example.net/x + +go 1.16 +-- x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_indirect_tidy.txt b/src/cmd/go/testdata/script/mod_indirect_tidy.txt new file mode 100644 index 0000000..a12b35c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_indirect_tidy.txt @@ -0,0 +1,60 @@ +env GO111MODULE=on + +# golang.org/issue/31248: loading the build list must not add explicit entries +# for indirect dependencies already implied by older-than-selected versions +# already in the build list. + +cp go.mod.orig go.mod +go mod tidy +cmp go.mod go.mod.orig + +cp go.mod.orig go.mod +go list -m all +cmp go.mod go.mod.orig + +-- go.mod.orig -- +module main + +go 1.13 + +require a v0.0.0 + +replace ( + a v0.0.0 => ./a + b v0.0.0 => ./b + i v0.0.0 => ./i + x v0.1.0 => ./x1 + x v0.2.0 => ./x2 +) +-- main.go -- +package main + +import _ "a" + +func main() {} +-- a/go.mod -- +module a +go 1.13 +require ( + x v0.2.0 + b v0.0.0 +) +-- a/a.go -- +package a +-- b/go.mod -- +module b +go 1.13 +require x v0.1.0 +-- x1/go.mod -- +module x +go 1.13 +require ( + b v0.0.0 + i v0.0.0 +) +-- x2/go.mod -- +module x +go 1.13 +-- i/go.mod -- +module i +go 1.13 diff --git a/src/cmd/go/testdata/script/mod_init_dep.txt b/src/cmd/go/testdata/script/mod_init_dep.txt new file mode 100644 index 0000000..76b4867 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_dep.txt @@ -0,0 +1,40 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod + +# go mod init should populate go.mod from Gopkg.lock +go mod init x +stderr 'copying requirements from Gopkg.lock' +go list -m all +stdout 'rsc.io/sampler v1.0.0' + +# test dep replacement +cd y +go mod init +cmpenv go.mod go.mod.replace + +-- x.go -- +package x + +-- Gopkg.lock -- +[[projects]] + name = "rsc.io/sampler" + version = "v1.0.0" + +-- y/Gopkg.lock -- +[[projects]] + name = "z" + revision = "v1.0.0" + source = "rsc.io/quote" + +-- y/y.go -- +package y // import "y" +import _ "z" + +-- y/go.mod.replace -- +module y + +go $goversion + +replace z v1.0.0 => rsc.io/quote v1.0.0 + +require rsc.io/quote v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_init_empty.txt b/src/cmd/go/testdata/script/mod_init_empty.txt new file mode 100644 index 0000000..1c3888c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_empty.txt @@ -0,0 +1,18 @@ +env GO111MODULE=on + +env GOPATH=$devnull + +go list -m +stdout '^example.com$' + +go list +stdout '^example.com$' + +-- go.mod -- +module example.com + +go 1.13 +-- main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_init_glide.txt b/src/cmd/go/testdata/script/mod_init_glide.txt new file mode 100644 index 0000000..373810c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_glide.txt @@ -0,0 +1,35 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB= + +# Regression test for golang.org/issue/32161: +# 'go mod init' did not locate tags when resolving a commit to a pseudo-version. +go mod init x +cmpenv go.mod go.mod.out + +-- main.go -- +package main + +import ( + _ "github.com/rsc/legacytest" +) + +func main() {} + +-- glide.lock -- +imports: +- name: github.com/rsc/legacytest + version: fb3c628075e32f7f3c248a3abbdafd69ad6e21e1 + +-- glide.yaml -- +package: x + +-- go.mod.out -- +module x + +go $goversion + +require github.com/rsc/legacytest v1.1.0-pre.0.20180717164849-fb3c628075e3 diff --git a/src/cmd/go/testdata/script/mod_init_invalid_major.txt b/src/cmd/go/testdata/script/mod_init_invalid_major.txt new file mode 100644 index 0000000..ae93e70 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_invalid_major.txt @@ -0,0 +1,82 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod + +! go mod init example.com/user/repo/v0 +stderr '(?s)^go: invalid module path "example.com/user/repo/v0": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v02 +stderr '(?s)^go: invalid module path "example.com/user/repo/v02": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v023 +stderr '(?s)^go: invalid module path "example.com/user/repo/v023": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v23$' + +! go mod init example.com/user/repo/v1 +stderr '(?s)^go: invalid module path "example.com/user/repo/v1": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v2.0 +stderr '(?s)^go: invalid module path "example.com/user/repo/v2.0": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v2.1.4 +stderr '(?s)^go: invalid module path "example.com/user/repo/v2.1.4": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v3.5 +stderr '(?s)^go: invalid module path "example.com/user/repo/v3.5": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v3$' + +! go mod init example.com/user/repo/v4.1.4 +stderr '(?s)^go: invalid module path "example.com/user/repo/v4.1.4": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v4$' + +! go mod init example.com/user/repo/v.2.3 +stderr '(?s)^go: invalid module path "example.com/user/repo/v.2.3": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v2$' + +! go mod init example.com/user/repo/v.5.3 +stderr '(?s)^go: invalid module path "example.com/user/repo/v.5.3": major version suffixes must be in the form of /vN and are only allowed for v2 or later(.*)go mod init example.com/user/repo/v5$' + +! go mod init gopkg.in/pkg +stderr '(?s)^go: invalid module path "gopkg.in/pkg": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/pkg.v1$' + +! go mod init gopkg.in/user/pkg +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg/v0 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v0": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg/v1 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg/v2 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg/v2": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v2$' + +! go mod init gopkg.in/user/pkg.v +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg.v0.1 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v0.1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg.v.1 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v.1": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg.v01 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v01": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v1$' + +! go mod init gopkg.in/user/pkg.v.2.3 +stderr '(?s)^go: invalid module path "gopkg.in/user/pkg.v.2.3": module paths beginning with gopkg.in/ must always have a major version suffix in the form of .vN(.*)go mod init gopkg.in/user/pkg.v2$' + +# module paths with a trailing dot are rejected as invalid import paths +! go mod init example.com/user/repo/v2. +stderr '(?s)^go: malformed module path "example.com/user/repo/v2.": trailing dot in path element$' + +! go mod init example.com/user/repo/v2.. +stderr '(?s)^go: malformed module path "example.com/user/repo/v2..": trailing dot in path element$' + +! go mod init gopkg.in/user/pkg.v.2. +stderr '(?s)^go: malformed module path "gopkg.in/user/pkg.v.2.": trailing dot in path element$' + +! go mod init gopkg.in/user/pkg.v.2.. +stderr '(?s)^go: malformed module path "gopkg.in/user/pkg.v.2..": trailing dot in path element$' + +# module paths with spaces are also rejected +! go mod init 'foo bar' +stderr '(?s)^go: malformed module path "foo bar": invalid char '' ''$' + +! go mod init 'foo bar baz' +stderr '(?s)^go: malformed module path "foo bar baz": invalid char '' ''$' diff --git a/src/cmd/go/testdata/script/mod_init_path.txt b/src/cmd/go/testdata/script/mod_init_path.txt new file mode 100644 index 0000000..e5fd4dd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_path.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +! go mod init . +stderr '^go: malformed module path ".": is a local import path$' + +cd x +go mod init example.com/x + +cd ../y +go mod init m + +-- x/main.go -- +package main + +func main() {} + +-- y/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_init_tidy.txt b/src/cmd/go/testdata/script/mod_init_tidy.txt new file mode 100644 index 0000000..4a52590 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_init_tidy.txt @@ -0,0 +1,30 @@ +# 'go mod init' should not recommend 'go mod tidy' in an empty directory +# (one that contains no non-hidden .go files or subdirectories). +cd empty +go mod init m +! stderr tidy +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a .go file. +cd pkginroot +go mod init m +stderr '^go: to add module requirements and sums:\n\tgo mod tidy$' +cd .. + +# 'go mod init' should recommend 'go mod tidy' if the directory has a +# subdirectory. We don't walk the tree to see if it has .go files. +cd subdir +go mod init m +stderr '^go: to add module requirements and sums:\n\tgo mod tidy$' +cd .. + +-- empty/empty.txt -- +Not a .go file. Still counts as an empty project. +-- empty/.hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- empty/_hidden/empty.go -- +File in hidden directory. Still as an empty project. +-- pkginroot/hello.go -- +package vendorimport +-- subdir/sub/empty.txt -- +Subdirectory doesn't need to contain a package. diff --git a/src/cmd/go/testdata/script/mod_install_hint.txt b/src/cmd/go/testdata/script/mod_install_hint.txt new file mode 100644 index 0000000..ab02840 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_hint.txt @@ -0,0 +1,5 @@ +# Module is replaced but not required. No hint appears as no module is suggested.
+go mod init m
+go mod edit -replace=github.com/notrequired@v0.5.0=github.com/doesnotexist@v0.5.0
+! go install github.com/notrequired
+! stderr 'to add it:'
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_install_pkg_version.txt b/src/cmd/go/testdata/script/mod_install_pkg_version.txt new file mode 100644 index 0000000..14153b8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_pkg_version.txt @@ -0,0 +1,203 @@ +# 'go install pkg@version' works outside a module. +env GO111MODULE=auto +go install example.com/cmd/a@v1.0.0 +exists $GOPATH/bin/a$GOEXE +rm $GOPATH/bin + + +# 'go install pkg@version' reports an error if modules are disabled. +env GO111MODULE=off +! go install example.com/cmd/a@v1.0.0 +stderr '^go: modules disabled by GO111MODULE=off; see ''go help modules''$' +env GO111MODULE=auto + + +# 'go install pkg@version' ignores go.mod in current directory. +cd m +cp go.mod go.mod.orig +! go list -m all +stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$' +go install example.com/cmd/a@latest +cmp go.mod go.mod.orig +exists $GOPATH/bin/a$GOEXE +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' # "latest", not from go.mod +rm $GOPATH/bin/a +cd .. + + +# 'go install -modfile=x.mod pkg@version' reports an error, but only if +# -modfile is specified explicitly on the command line. +cd m +env GOFLAGS=-modfile=go.mod +go install example.com/cmd/a@latest # same as above +env GOFLAGS= +! go install -modfile=go.mod example.com/cmd/a@latest +stderr '^go: -modfile cannot be used with commands that ignore the current module$' +cd .. + + +# Every test case requires linking, so we only cover the most important cases +# when -short is set. +[short] stop + + +# 'go install pkg@version' works on a module that doesn't have a go.mod file +# and with a module whose go.mod file has missing requirements. +# With a proxy, the two cases are indistinguishable. +go install rsc.io/fortune@v1.0.0 +stderr '^go: found rsc.io/quote in rsc.io/quote v1.5.2$' +exists $GOPATH/bin/fortune$GOEXE +! exists $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0/go.mod # no go.mod file +go version -m $GOPATH/bin/fortune$GOEXE +stdout '^\tdep\trsc.io/quote\tv1.5.2\t' # latest version of fortune's dependency +rm $GOPATH/bin + + +# 'go install dir@version' works like a normal 'go install' command if +# dir is a relative or absolute path. +env GO111MODULE=on +go mod download rsc.io/fortune@v1.0.0 +! go install $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go install ../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +mkdir tmp +cd tmp +go mod init tmp +go mod edit -require=rsc.io/fortune@v1.0.0 +! go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$' +! go install -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$' +go get rsc.io/fortune@v1.0.0 +go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +exists $GOPATH/bin/fortune$GOEXE +cd .. +rm tmp +rm $GOPATH/bin +env GO111MODULE=auto + +# 'go install pkg@version' reports errors for meta packages, std packages, +# and directories. +! go install std@v1.0.0 +stderr '^go: std@v1.0.0: argument must be a package path, not a meta-package$' +! go install fmt@v1.0.0 +stderr '^go: fmt@v1.0.0: argument must not be a package in the standard library$' +! go install example.com//cmd/a@v1.0.0 +stderr '^go: example.com//cmd/a@v1.0.0: argument must be a clean package path$' +! go install example.com/cmd/a@v1.0.0 ./x@v1.0.0 +stderr '^go: ./x@v1.0.0: argument must be a package path, not a relative path$' +! go install example.com/cmd/a@v1.0.0 $GOPATH/src/x@v1.0.0 +stderr '^go: '$WORK'[/\\]gopath/src/x@v1.0.0: argument must be a package path, not an absolute path$' +! go install example.com/cmd/a@v1.0.0 cmd/...@v1.0.0 +stderr '^package cmd/go not provided by module example.com/cmd@v1.0.0$' + +# 'go install pkg@version' should accept multiple arguments but report an error +# if the version suffixes are different, even if they refer to the same version. +go install example.com/cmd/a@v1.0.0 example.com/cmd/b@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +env GO111MODULE=on +go list -m example.com/cmd@latest +stdout '^example.com/cmd v1.0.0$' +env GO111MODULE=auto + +! go install example.com/cmd/a@v1.0.0 example.com/cmd/b@latest +stderr '^go: example.com/cmd/b@latest: all arguments must have the same version \(@v1.0.0\)$' + + +# 'go install pkg@version' should report an error if the arguments are in +# different modules. +! go install example.com/cmd/a@v1.0.0 rsc.io/fortune@v1.0.0 +stderr '^package rsc.io/fortune provided by module rsc.io/fortune@v1.0.0\n\tAll packages must be provided by the same module \(example.com/cmd@v1.0.0\).$' + + +# 'go install pkg@version' should report an error if an argument is not +# a main package. +! go install example.com/cmd/a@v1.0.0 example.com/cmd/err@v1.0.0 +stderr '^package example.com/cmd/err is not a main package$' + +# Wildcards should match only main packages. This module has a non-main package +# with an error, so we'll know if that gets built. +mkdir tmp +cd tmp +go mod init m +go get example.com/cmd@v1.0.0 +! go build example.com/cmd/... +stderr 'err[/\\]err.go:3:9: undefined: DoesNotCompile$' +cd .. + +go install example.com/cmd/...@v1.0.0 +exists $GOPATH/bin/a$GOEXE +exists $GOPATH/bin/b$GOEXE +rm $GOPATH/bin + +# If a wildcard matches no packages, we should see a warning. +! go install example.com/cmd/nomatch...@v1.0.0 +stderr '^go: example.com/cmd/nomatch\.\.\.@v1.0.0: module example.com/cmd@v1.0.0 found, but does not contain packages matching example.com/cmd/nomatch\.\.\.$' +go install example.com/cmd/a@v1.0.0 example.com/cmd/nomatch...@v1.0.0 +stderr '^go: warning: "example.com/cmd/nomatch\.\.\." matched no packages$' + +# If a wildcard matches only non-main packges, we should see a different warning. +go install example.com/cmd/err...@v1.0.0 +stderr '^go: warning: "example.com/cmd/err\.\.\." matched only non-main packages$' + + +# 'go install pkg@version' should report errors if the module contains +# replace or exclude directives. +go mod download example.com/cmd@v1.0.0-replace +! go install example.com/cmd/a@v1.0.0-replace +cmp stderr replace-err + +go mod download example.com/cmd@v1.0.0-exclude +! go install example.com/cmd/a@v1.0.0-exclude +cmp stderr exclude-err + +# 'go install pkg@version' should report an error if the module requires a +# higher version of itself. +! go install example.com/cmd/a@v1.0.0-newerself +stderr '^go: example.com/cmd/a@v1.0.0-newerself: version constraints conflict:\n\texample.com/cmd@v1.0.0-newerself requires example.com/cmd@v1.0.0, but example.com/cmd@v1.0.0-newerself is requested$' + + +# 'go install pkg@version' will only match a retracted version if it's +# explicitly requested. +env GO111MODULE=on +go list -m -versions example.com/cmd +! stdout v1.9.0 +go list -m -versions -retracted example.com/cmd +stdout v1.9.0 +go install example.com/cmd/a@latest +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.0.0\t' +go install example.com/cmd/a@v1.9.0 +go version -m $GOPATH/bin/a$GOEXE +stdout '^\tmod\texample.com/cmd\tv1.9.0\t' +env GO111MODULE= + +# 'go install pkg@version' succeeds when -mod=readonly is set explicitly. +# Verifies #43278. +go install -mod=readonly example.com/cmd/a@v1.0.0 + +-- m/go.mod -- +module m + +go 1.16 + +require example.com/cmd v1.1.0-doesnotexist +-- x/x.go -- +package main + +func main() {} +-- replace-err -- +go: example.com/cmd/a@v1.0.0-replace (in example.com/cmd@v1.0.0-replace): + The go.mod file for the module providing named packages contains one or + more replace directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. +-- exclude-err -- +go: example.com/cmd/a@v1.0.0-exclude (in example.com/cmd@v1.0.0-exclude): + The go.mod file for the module providing named packages contains one or + more exclude directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. diff --git a/src/cmd/go/testdata/script/mod_install_versioned.txt b/src/cmd/go/testdata/script/mod_install_versioned.txt new file mode 100644 index 0000000..627a9a8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_install_versioned.txt @@ -0,0 +1,14 @@ +env GO111MODULE=on + +go get rsc.io/fortune +go list -f '{{.Target}}' rsc.io/fortune +! stdout fortune@v1 +stdout 'fortune(\.exe)?$' + +go get rsc.io/fortune/v2 +go list -f '{{.Target}}' rsc.io/fortune/v2 +! stdout v2 +stdout 'fortune(\.exe)?$' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_internal.txt b/src/cmd/go/testdata/script/mod_internal.txt new file mode 100644 index 0000000..787b21f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_internal.txt @@ -0,0 +1,96 @@ +env GO111MODULE=on +[short] skip + +# golang.org/x/internal should be importable from other golang.org/x modules. +go mod edit -module=golang.org/x/anything +go get . + +# ...and their tests... +go test +stdout PASS + +# ...but that should not leak into other modules. +go get ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +# Internal packages in the standard library should not leak into modules. +go get ./fromstd +! go build ./fromstd +stderr 'use of internal package internal/testenv not allowed' + +# Dependencies should be able to use their own internal modules... +go mod edit -module=golang.org/notx +go get ./throughdep + +# ... but other modules should not, even if they have transitive dependencies. +go get . +! go build . +stderr 'use of internal package golang.org/x/.* not allowed' + +# And transitive dependencies still should not leak. +go get ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +# Replacing an internal module should keep it internal to the same paths. +go mod edit -module=golang.org/notx +go mod edit -replace golang.org/x/internal=./replace/golang.org/notx/internal +go get ./throughdep + +go get ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +go mod edit -replace golang.org/x/internal=./vendor/golang.org/x/internal +go get ./throughdep + +go get ./baddep +! go build ./baddep +stderr golang.org[/\\]notx[/\\]useinternal +stderr 'use of internal package golang.org/x/.* not allowed' + +-- go.mod -- +module TBD +go 1.12 +-- useinternal.go -- +package useinternal +import _ "golang.org/x/internal/subtle" + +-- useinternal_test.go -- +package useinternal_test +import ( + "testing" + _ "golang.org/x/internal/subtle" +) + +func Test(*testing.T) {} + +-- throughdep/useinternal.go -- +package throughdep +import _ "golang.org/x/useinternal" + +-- baddep/useinternal.go -- +package baddep +import _ "golang.org/notx/useinternal" + +-- fromstd/useinternal.go -- +package fromstd +import _ "internal/testenv" + +-- replace/golang.org/notx/internal/go.mod -- +module golang.org/x/internal + +-- replace/golang.org/notx/internal/subtle/subtle.go -- +package subtle +// Ha ha! Nothing here! + +-- vendor/golang.org/x/internal/go.mod -- +module golang.org/x/internal + +-- vendor/golang.org/x/internal/subtle/subtle.go -- +package subtle +// Ha ha! Nothing here! diff --git a/src/cmd/go/testdata/script/mod_invalid_path.txt b/src/cmd/go/testdata/script/mod_invalid_path.txt new file mode 100644 index 0000000..667b76e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_path.txt @@ -0,0 +1,61 @@ +# Test that mod files with invalid or missing paths produce an error. + +# Test that go list fails on a go.mod with no module declaration. +cd $WORK/gopath/src/mod +! go list . +stderr '^go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod$' + +# Test that go mod init in GOPATH doesn't add a module declaration +# with a path that can't possibly be a module path, because +# it isn't even a valid import path. +# The single quote and backtick are the only characters which are not allowed +# but are a valid Windows file name. +cd $WORK/'gopath/src/m''d' +! go mod init +stderr 'cannot determine module path' + +# Test that a go.mod file is rejected when its module declaration has a path that can't +# possibly be a module path, because it isn't even a valid import path +cd $WORK/gopath/src/badname +! go list . +stderr 'malformed module path' + +# Test that an import path containing an element with a leading dot is valid, +# but such a module path is not. +# Verifies #43985. +cd $WORK/gopath/src/dotname +go list ./.dot +stdout '^example.com/dotname/.dot$' +go list ./use +stdout '^example.com/dotname/use$' +! go list -m example.com/dotname/.dot@latest +stderr '^go: example.com/dotname/.dot@latest: malformed module path "example.com/dotname/.dot": leading dot in path element$' +go get example.com/dotname/.dot +go get example.com/dotname/use +go mod tidy + +-- mod/go.mod -- + +-- mod/foo.go -- +package foo + +-- m'd/foo.go -- +package mad + +-- badname/go.mod -- + +module .\. + +-- badname/foo.go -- +package badname + +-- dotname/go.mod -- +module example.com/dotname + +go 1.16 +-- dotname/.dot/dot.go -- +package dot +-- dotname/use/use.go -- +package use + +import _ "example.com/dotname/.dot" diff --git a/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt b/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt new file mode 100644 index 0000000..484c208 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_path_dotname.txt @@ -0,0 +1,46 @@ +# Test that an import path containing an element with a leading dot +# in another module is valid. + +# 'go get' works with no version query. +cp go.mod.empty go.mod +go get example.com/dotname/.dot +go list -m example.com/dotname +stdout '^example.com/dotname v1.0.0$' + +# 'go get' works with a version query. +cp go.mod.empty go.mod +go get example.com/dotname/.dot@latest +go list -m example.com/dotname +stdout '^example.com/dotname v1.0.0$' + +# 'go get' works on an importing package. +cp go.mod.empty go.mod +go get . +go list -m example.com/dotname +stdout '^example.com/dotname v1.0.0$' + +# 'go list' works on the dotted package. +go list example.com/dotname/.dot +stdout '^example.com/dotname/.dot$' + +# 'go list' works on an importing package. +go list . +stdout '^m$' + +# 'go mod tidy' works. +cp go.mod.empty go.mod +go mod tidy +go list -m example.com/dotname +stdout '^example.com/dotname v1.0.0$' + +-- go.mod.empty -- +module m + +go 1.16 +-- go.sum -- +example.com/dotname v1.0.0 h1:Q0JMAn464CnwFVCshs1n4+f5EFiW/eRhnx/fTWjw2Ag= +example.com/dotname v1.0.0/go.mod h1:7K4VLT7QylRI8H7yZwUkeDH2s19wQnyfp/3oBlItWJ0= +-- use.go -- +package use + +import _ "example.com/dotname/.dot" diff --git a/src/cmd/go/testdata/script/mod_invalid_path_plus.txt b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt new file mode 100644 index 0000000..dd59eb1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_path_plus.txt @@ -0,0 +1,36 @@ +# https://golang.org/issue/44776 +# The '+' character should be disallowed in module paths, but allowed in package +# paths within valid modules. + +# 'go list' accepts package paths with pluses. +cp go.mod.orig go.mod +go get example.net/cmd +go list example.net/cmd/x++ + +# 'go list -m' rejects module paths with pluses. +! go list -versions -m 'example.net/bad++' +stderr '^go: malformed module path "example.net/bad\+\+": invalid char ''\+''$' + +# 'go get' accepts package paths with pluses. +cp go.mod.orig go.mod +go get example.net/cmd/x++ +go list -m example.net/cmd +stdout '^example.net/cmd v0.0.0-00010101000000-000000000000 => ./cmd$' + +-- go.mod.orig -- +module example.com/m + +go 1.16 + +replace ( + example.net/cmd => ./cmd +) + +-- cmd/go.mod -- +module example.net/cmd + +go 1.16 +-- cmd/x++/main.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt new file mode 100644 index 0000000..8385b08 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_invalid_version.txt @@ -0,0 +1,251 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOFLAGS=-mod=mod + +# Regression test for golang.org/issue/27173: if the user (or go.mod file) +# requests a pseudo-version that does not match both the module path and commit +# metadata, reject it with a helpful error message. +# +# TODO(bcmills): Replace the github.com/pierrec/lz4 examples with something +# equivalent on vcs-test.golang.org. + +# An incomplete commit hash is not a valid semantic version, +# but can appear in the main go.mod file anyway and should be resolved. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' +grep 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' go.mod + +# A module path below the repo root that does not contain a go.mod file is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c: invalid version: missing golang.org/x/text/unicode/go.mod at revision 14c0d48ead0c' + +# However, arguments to 'go get' can name packages above the root. +cp go.mod.orig go.mod +go get golang.org/x/text/unicode@v0.0.0-20170915032832-14c0d48ead0c +go list -m golang.org/x/text/... +stdout 'golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' +! stdout 'golang.org/x/text/unicode' + +# A major version that does not match the module path is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ..[/\\]go.mod: '$WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' +cd .. +! go list -m golang.org/x/text +stderr $WORK'[/\\]gopath[/\\]src[/\\]go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' + +# A pseudo-version with fewer than 12 digits of SHA-1 prefix is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0 +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(expected 14c0d48ead0c\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0: invalid pseudo-version: revision is shorter than canonical \(expected 14c0d48ead0c\)' + +# A pseudo-version with more than 12 digits of SHA-1 prefix is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(expected 14c0d48ead0c\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0cd47e3104ada247d91be04afc7a5a: invalid pseudo-version: revision is longer than canonical \(expected 14c0d48ead0c\)' + +# A pseudo-version that does not match the commit timestamp is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' + +# A 'replace' directive in the main module can replace an invalid timestamp +# with a valid one. +go mod edit -replace golang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c=golang.org/x/text@14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20190915032832-14c0d48ead0c: invalid pseudo-version: does not match version-control timestamp \(expected 20170915032832\)' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.1.1-0.20190915032832-14c0d48ead0c => golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' + +# A pseudo-version that is not derived from a tag is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v1.999.999-0.20170915032832-14c0d48ead0c: invalid pseudo-version: preceding tag \(v1.999.998\) not found' + +# A v1.0.0- pseudo-version that is not derived from a tag is invalid: +# v1.0.0- implies no tag, but the correct no-tag prefix for a module path +# without a major-version suffix is v0.0.0-. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v1.0.0-20170915032832-14c0d48ead0c: invalid pseudo-version: major version without preceding tag must be v0, not v1' + +# A pseudo-version vX.Y.Z+1 cannot have Z+1 == 0, since that would +# imply a base tag with a negative patch field. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' + +# A 'replace' directive in the main module can replace an +# invalid pseudo-version base with a valid one. +go mod edit -replace golang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.0.0-0.20170915032832-14c0d48ead0c: invalid pseudo-version: version before v0.0.0 would have negative patch number' +cd .. +go list -m golang.org/x/text +stdout 'golang.org/x/text v0.0.0-0.20170915032832-14c0d48ead0c => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' + +# A 'replace' directive can replace an invalid 'latest' version, and +# should suppress errors for that version in 'go get -u' +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v1.999999.0 +go mod edit -replace golang.org/x/text@v1.999999.0=golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +cd outside +! go get golang.org/x/text@upgrade +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v1.999999.0: reading golang.org/x/text/go.mod at revision v1.999999.0: unknown revision v1.999999.0' +cd .. +go get golang.org/x/text@upgrade +go list -m golang.org/x/text +stdout 'golang.org/x/text v1.999999.0 => golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c' + +# A pseudo-version derived from a non-ancestor tag is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.2.1-0.20170915032832-14c0d48ead0c: invalid pseudo-version: revision 14c0d48ead0c is not a descendent of preceding tag \(v0.2.0\)' + +# A pseudo-version derived from a canonical tag on the same revision is invalid. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.2.1-0.20171213102548-c4d099d611ac: invalid pseudo-version: tag \(v0.2.0\) found on revision c4d099d611ac is already canonical, so should not be replaced with a pseudo-version derived from that tag' + +# A +incompatible suffix is not allowed on a version that is actually compatible. +cp go.mod.orig go.mod +go mod edit -require golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c+incompatible +cd outside +! go list -m golang.org/x/text +stderr 'go: example.com@v0.0.0 requires\n\tgolang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible' +cd .. +! go list -m golang.org/x/text +stderr 'golang.org/x/text@v0.1.1-0.20170915032832-14c0d48ead0c\+incompatible: invalid version: \+incompatible suffix not allowed: major version v0 is compatible' + +# The pseudo-version for a commit after a tag with a non-matching major version +# should instead be based on the last matching tag. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@473cd7ce01a1 +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1' +cd outside +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1' +cd .. + +# A +incompatible pseudo-version for a module that has an explicit go.mod file is invalid. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible +cd outside +! go list -m github.com/pierrec/lz4 +stderr '^go: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$' +cd .. +! go list -m github.com/pierrec/lz4 +stderr '^go: github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$' + +# A +incompatible pseudo-version is valid for a revision of the module +# that lacks a go.mod file. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.4-0.20180826165652-dbe9298ce099+incompatible +cd outside +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.4-0.20180826165652-dbe9298ce099\+incompatible' +cd .. +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.4-0.20180826165652-dbe9298ce099\+incompatible' + +# 'go get' for a mismatched major version without a go.mod file should resolve +# to the equivalent +incompatible version, not a pseudo-version with a different +# major version. +cp go.mod.orig go.mod +go get github.com/pierrec/lz4@v2.0.5 +go list -m github.com/pierrec/lz4 +stdout 'github.com/pierrec/lz4 v2.0.5\+incompatible' + +# 'go get' for a mismatched major version with a go.mod file should error out, +# not resolve to a pseudo-version with a different major version. +cp go.mod.orig go.mod +! go get github.com/pierrec/lz4@v2.0.8 +stderr 'go: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$' + +# An invalid +incompatible suffix for a canonical version should error out, +# not resolve to a pseudo-version. +# +# TODO(bcmills): The "outside" view for this failure mode is missing its import stack. +# Figure out why and fix it. +cp go.mod.orig go.mod +go mod edit -require github.com/pierrec/lz4@v2.0.8+incompatible +cd outside +! go list -m github.com/pierrec/lz4 +stderr '^go: github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$' +cd .. +! go list -m github.com/pierrec/lz4 +stderr '^go: github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$' + +-- go.mod.orig -- +module example.com + +go 1.13 +-- outside/go.mod -- +module example.com/outside + +go 1.13 + +require example.com v0.0.0 +replace example.com v0.0.0 => ./.. diff --git a/src/cmd/go/testdata/script/mod_issue35317.txt b/src/cmd/go/testdata/script/mod_issue35317.txt new file mode 100644 index 0000000..92416a5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_issue35317.txt @@ -0,0 +1,8 @@ +# Regression test for golang.org/issue/35317: +# 'go get' with multiple module-only arguments was racy. + +env GO111MODULE=on +[short] skip + +go mod init example.com +go get golang.org/x/text@v0.3.0 golang.org/x/internal@v0.1.0 golang.org/x/exp@none diff --git a/src/cmd/go/testdata/script/mod_lazy_consistency.txt b/src/cmd/go/testdata/script/mod_lazy_consistency.txt new file mode 100644 index 0000000..1bf3e31 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_consistency.txt @@ -0,0 +1,95 @@ +# If the root requirements in a lazy module are inconsistent +# (for example, due to a bad hand-edit or git merge), +# they can go unnoticed as long as the module with the violated +# requirement is not used. +# When we load a package from that module, we should spot-check its +# requirements and either emit an error or update the go.mod file. + +cp go.mod go.mod.orig + + +# If we load package x from x.1, we only check the requirements of x, +# which are fine: loading succeeds. + +go list -deps ./usex +stdout '^example.net/x$' +cmp go.mod go.mod.orig + + +# However, if we load needx2, we should load the requirements of needx2. +# Those requirements indicate x.2, not x.1, so the module graph is +# inconsistent and needs to be fixed. + +! go list -deps ./useneedx2 +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$' + +! go list -deps example.net/needx2 +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$' + + +# The command printed in the error message should fix the problem. + +go mod tidy +go list -deps ./useneedx2 +stdout '^example.net/m/useneedx2$' +stdout '^example.net/needx2$' +stdout '^example.net/x$' + +go list -m all +stdout '^example.net/needx2 v0\.1\.0 ' +stdout '^example.net/x v0\.2\.0 ' + + +-- go.mod -- +module example.net/m + +go 1.17 + +require ( + example.net/needx2 v0.1.0 + example.net/x v0.1.0 +) + +replace ( + example.net/needx2 v0.1.0 => ./needx2.1 + example.net/x v0.1.0 => ./x.1 + example.net/x v0.2.0 => ./x.2 +) +-- useneedx2/useneedx2.go -- +package useneedx2 + +import _ "example.net/needx2" +-- usex/usex.go -- +package usex + +import _ "example.net/x" + +-- x.1/go.mod -- +module example.com/x + +go 1.17 +-- x.1/x.go -- +package x + +-- x.2/go.mod -- +module example.com/x + +go 1.17 +-- x.2/x.go -- +package x + +const AddedInV2 = true + +-- needx2.1/go.mod -- +module example.com/x + +go 1.17 + +require example.net/x v0.2.0 +-- needx2.1/needx2.go -- +// Package needx2 needs x v0.2.0 or higher. +package needx2 + +import "example.net/x" + +var _ = x.AddedInV2 diff --git a/src/cmd/go/testdata/script/mod_lazy_downgrade.txt b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt new file mode 100644 index 0000000..eb69d2e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_downgrade.txt @@ -0,0 +1,183 @@ +# This test illustrates the interaction between lazy loading and downgrading in +# 'go get'. + +# The package import graph used in this test looks like: +# +# lazy ---- a +# | +# a_test ---- b +# b_test ---- c +# +# The module dependency graph initially looks like: +# +# lazy ---- a.1 ---- b.1 ---- c.1 +# \ / +# b.3 ---- c.2 b.2 +# +# (Note that lazy loading will prune out the dependency from b.1 on c.1.) + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +# Downgrading c should also downgrade the b that requires it. + +go get example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +# Removing c entirely should also remove the a and b that require it. + +go get example.com/c@none +go list -m all +! stdout '^example.com/a ' +! stdout '^example.com/b ' +! stdout '^example.com/c ' + + +# With lazy loading, downgrading c should work the same way, but dependencies +# outside of the deepening scan should not affect the downgrade. + +cp go.mod.orig go.mod +go mod edit -go=1.17 + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +go get example.com/c@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.2.0 ' +stdout '^example.com/c v0.1.0 ' + +# At this point, b.2 is still an explicit root, so its dependency on c +# is still tracked, and it will still be downgraded away if we remove c. +# ('go get' never makes a root into a non-root. Only 'go mod tidy' does that.) + +go get example.com/c@none +go list -m all +! stdout '^example.com/a ' +! stdout '^example.com/b ' +! stdout '^example.com/c ' + + +# This time, we drop the explicit 'b' root by downgrading it to v0.1.0 +# (the version required by a.1) and running 'go mod tidy'. +# It is still selected at v0.1.0 (as a dependency of a), +# but its dependency on c is now pruned from the module graph, so it doesn't +# result in any downgrades to b or a if we run 'go get c@none'. + +cp go.mod.orig go.mod +go mod edit -go=1.17 + +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.3.0 ' +stdout '^example.com/c v0.2.0 ' + +go get example.com/c@v0.1.0 example.com/b@v0.1.0 +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.1.0 ' +stdout '^example.com/c v0.1.0 ' + +go mod tidy +go list -m all +stdout '^example.com/a v0.1.0 ' +stdout '^example.com/b v0.1.0 ' +! stdout '^example.com/c ' + +go get example.com/c@none +go list -m all +stdout '^example.com/a v0.1.0' +stdout '^example.com/b v0.1.0' +! stdout '^example.com/c ' + + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require ( + example.com/a v0.1.0 + example.com/b v0.3.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/b v0.3.0 => ./b3 + example.com/c v0.1.0 => ./c + example.com/c v0.2.0 => ./c +) +-- lazy.go -- +package lazy + +import _ "example.com/a" + +-- a/go.mod -- +module example.com/a + +go 1.17 + +require example.com/b v0.1.0 +-- a/a.go -- +package a +-- a/a_test.go -- +package a_test + +import _ "example.com/b" + +-- b1/go.mod -- +module example.com/b + +go 1.17 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b_test +import _ "example.com/c" + +-- b2/go.mod -- +module example.com/b + +go 1.17 + +require example.com/c v0.1.0 +-- b2/b.go -- +package b +-- b2/b_test.go -- +package b_test +import _ "example.com/c" + +-- b3/go.mod -- +module example.com/b + +go 1.17 + +require example.com/c v0.2.0 +-- b3/b.go -- +package b +-- b3/b_test.go -- +package b_test +import _ "example.com/c" + +-- c/go.mod -- +module example.com/c + +go 1.17 +-- c/c.go -- +package c diff --git a/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt new file mode 100644 index 0000000..60d4187 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_import_allmod.txt @@ -0,0 +1,191 @@ +# This test demonstrates dependency resolution when the main module imports a +# new package from a previously-test-only dependency. +# +# When lazy loading is active, the loader will not load dependencies of any +# module whose packages are *only* imported by tests outside the main module. If +# the main module is changed to import a package from such a module, the +# dependencies of that module will need to be reloaded. + +# The import graph used in this test looks like: +# +# m ---- a +# \ | +# \ a_test ---- b/x +# \ +# --------------b/y (new) ---- c +# +# Where b/x and b/y are disjoint packages, but both contained in module b. +# +# The module dependency graph initially looks like: +# +# m ---- a.1 ---- b.1 ---- c.1 +# +# This configuration is similar to that used in mod_lazy_new_import, +# but the new import is from what is initially a test-only dependency. + +# Control case: in Go 1.14, the original go.mod is tidy, +# and the dependency on c is eagerly loaded. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +# After adding a new import of b/y, +# the import of c from b/y should resolve to the version required by b. + +cp m.go m.go.orig +cp m.go.new m.go +go mod tidy +cmp go.mod.new go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +# With lazy loading, the go.mod requirements are the same, +# but the dependency on c is initially pruned out. + +cp m.go.orig m.go +cp go.mod.orig go.mod +go mod edit -go=1.17 +go mod edit -go=1.17 go.mod.new + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod.orig go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +! stdout '^c ' + +# After adding a new direct import of b/y, +# the existing version of b should be promoted to a root, +# bringing the version of c required by b into the build list. + +cp m.go.new m.go +go mod tidy +cmp go.mod.lazy go.mod + +go list -m all +stdout '^a v0.1.0 ' +stdout '^b v0.1.0 ' +stdout '^c v0.1.0 ' + +-- m.go -- +package main + +import ( + "fmt" + + _ "a" // a_test imports b/x. +) + +func main() { +} +-- m.go.new -- +package main + +import ( + "fmt" + + _ "a" // a_test imports b/x. + "b/y" // This is a new import, not yet reflected in the go.mod file. +) + +func main() { + fmt.Println(b.CVersion()) +} +-- go.mod -- +module m + +go 1.14 + +require a v0.1.0 + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) +-- go.mod.new -- +module m + +go 1.14 + +require ( + a v0.1.0 + b v0.1.0 +) + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) +-- go.mod.lazy -- +module m + +go 1.17 + +require ( + a v0.1.0 + b v0.1.0 +) + +require c v0.1.0 // indirect + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) +-- a1/go.mod -- +module a + +go 1.17 + +require b v0.1.0 +-- a1/a.go -- +package a +-- a1/a_test.go -- +package a_test + +import _ "b/x" +-- b1/go.mod -- +module b + +go 1.17 + +require c v0.1.0 +-- b1/x/x.go -- +package x +-- b1/y/y.go -- +package y + +import "c" + +func CVersion() string { + return c.Version +} +-- c1/go.mod -- +module c + +go 1.17 +-- c1/c.go -- +package c + +const Version = "v0.1.0" +-- c2/go.mod -- +This file should be unused. +-- c2/c.go -- +This file should be unused. diff --git a/src/cmd/go/testdata/script/mod_lazy_new_import.txt b/src/cmd/go/testdata/script/mod_lazy_new_import.txt new file mode 100644 index 0000000..520d845 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_new_import.txt @@ -0,0 +1,155 @@ +# This test illustrates the use of a deepening scan to resolve transitive +# imports of imports of new packages from within existing dependencies. + +# The package import graph used in this test looks like: +# +# lazy ---- a/x ---- b +# \ +# ---- a/y (new) ---- c +# +# Where a/x and a/y are disjoint packages, but both contained in module a. +# +# The module dependency graph initially looks like: +# +# lazy ---- a.1 ---- b.1 +# \ +# c.1 + + +cp go.mod go.mod.old +cp lazy.go lazy.go.old +go mod tidy +cmp go.mod go.mod.old + +# Before adding a new import, the go.mod file should +# enumerate modules for all packages already imported. +go list all +cmp go.mod go.mod.old + +# When we add a new import of a package in an existing dependency, +# and that dependency is already tidy, its transitive dependencies +# should already be present. +cp lazy.go.new lazy.go +go list all +go list -m all +stdout '^example.com/c v0.1.0' # not v0.2.0 as would be resolved by 'latest' +cmp go.mod go.mod.old + +# Now, we repeat the test with a lazy main module. +cp lazy.go.old lazy.go +cp go.mod.117 go.mod + +# Before adding a new import, the go.mod file should +# enumerate modules for all packages already imported. +go list all +cmp go.mod go.mod.117 + +# When a new import is found, we should perform a deepening scan of the existing +# dependencies and add a requirement on the version required by those +# dependencies — not re-resolve 'latest'. +cp lazy.go.new lazy.go + +! go list all +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$' + +go mod tidy +go list all +go list -m all +stdout '^example.com/c v0.1.0' # not v0.2.0 as would be resolved by 'latest' + +cmp go.mod go.mod.new + + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require example.com/a v0.1.0 + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- go.mod.117 -- +module example.com/lazy + +go 1.17 + +require example.com/a v0.1.0 + +require example.com/b v0.1.0 // indirect + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- go.mod.new -- +module example.com/lazy + +go 1.17 + +require example.com/a v0.1.0 + +require ( + example.com/b v0.1.0 // indirect + example.com/c v0.1.0 // indirect +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- lazy.go -- +package lazy + +import ( + _ "example.com/a/x" +) +-- lazy.go.new -- +package lazy + +import ( + _ "example.com/a/x" + _ "example.com/a/y" +) +-- a/go.mod -- +module example.com/a + +go 1.15 + +require ( + example.com/b v0.1.0 + example.com/c v0.1.0 +) +-- a/x/x.go -- +package x +import _ "example.com/b" +-- a/y/y.go -- +package y +import _ "example.com/c" +-- b/go.mod -- +module example.com/b + +go 1.15 +-- b/b.go -- +package b +-- c1/go.mod -- +module example.com/c + +go 1.15 +-- c1/c.go -- +package c +-- c2/go.mod -- +module example.com/c + +go 1.15 +-- c2/c.go -- +package c +This file should not be used, so this syntax error should be ignored. diff --git a/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt new file mode 100644 index 0000000..7d07eb6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_test_horizon.txt @@ -0,0 +1,131 @@ +# This file demonstrates the effect of lazy loading on the selected +# versions of test dependencies. + +# The package import graph used in this test looks like: +# +# m ---- a +# \ | +# \ a_test ---- b +# \ | +# x b_test +# | \ +# x_test -------------- c +# +# And the module dependency graph looks like: +# +# m -- a.1 -- b.1 -- c.2 +# \ +# x.1 ------------ c.1 + +# Control case: in Go 1.15, the version of c imported by 'go test x' is the +# version required by module b, even though b_test is not relevant to the main +# module. (The main module imports a, and a_test imports b, but all of the +# packages and tests in the main module can be built without b.) + +go list -m c +stdout '^c v0.2.0 ' + +[!short] go test -v x +[!short] stdout ' c v0.2.0$' + +# With lazy loading, the go.mod requirements are the same, +# but the irrelevant dependency on c v0.2.0 should be pruned out, +# leaving only the relevant dependency on c v0.1.0. + +go mod edit -go=1.17 +go list -m c +stdout '^c v0.1.0' + +[!short] go test -v x +[!short] stdout ' c v0.1.0$' + +-- m.go -- +package m + +import ( + _ "a" + _ "x" +) +-- go.mod -- +module m + +go 1.15 + +require ( + a v0.1.0 + x v0.1.0 +) + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 + x v0.1.0 => ./x1 +) +-- a1/go.mod -- +module a + +go 1.17 + +require b v0.1.0 +-- a1/a.go -- +package a +-- a1/a_test.go -- +package a_test + +import _ "b" +-- b1/go.mod -- +module b + +go 1.17 + +require c v0.2.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b_test + +import ( + "c" + "testing" +) + +func TestCVersion(t *testing.T) { + t.Log(c.Version) +} +-- c1/go.mod -- +module c + +go 1.17 +-- c1/c.go -- +package c + +const Version = "v0.1.0" +-- c2/go.mod -- +module c + +go 1.17 +-- c2/c.go -- +package c + +const Version = "v0.2.0" +-- x1/go.mod -- +module x + +go 1.17 + +require c v0.1.0 +-- x1/x.go -- +package x +-- x1/x_test.go -- +package x_test + +import ( + "c" + "testing" +) + +func TestCVersion(t *testing.T) { + t.Log("c", c.Version) +} diff --git a/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt new file mode 100644 index 0000000..68a5b6d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_lazy_test_of_test_dep.txt @@ -0,0 +1,224 @@ +# This file demonstrates the effect of lazy loading on the reproducibility of +# tests (and tests of test dependencies) outside the main module. +# +# It is similar to the cases in mod_all.txt and mod_lazy_test_horizon.txt, but +# focuses on the effect of "go test" on specific packages instead of the "all" +# pattern. + +# The package import graph used in this test looks like: +# +# lazy ---- a +# | +# a_test ---- b +# | +# b_test ---- c +# +# And the non-lazy module dependency graph looks like: +# +# lazy ---- a.1 ---- b.1 ---- c.1 + +cp go.mod go.mod.old +go mod tidy +cmp go.mod go.mod.old + + +# In Go 1.15 mode, 'go list -m all' includes modules needed by the +# transitive closure of tests of dependencies of tests of dependencies of …. + +go list -m all +stdout '^example.com/b v0.1.0 ' +stdout '^example.com/c v0.1.0 ' +cmp go.mod go.mod.old + +# 'go test' (or equivalent) of any such dependency, no matter how remote, does +# not update the go.mod file. + +go list -test -deps example.com/a +stdout example.com/b +! stdout example.com/c + +[!short] go test -c -o $devnull example.com/a +[!short] cmp go.mod go.mod.old + +go list -test -deps example.com/b +stdout example.com/c + +[!short] go test -c -o $devnull example.com/b +[!short] cmp go.mod go.mod.old + +go mod edit -go=1.17 a/go.mod +go mod edit -go=1.17 b1/go.mod +go mod edit -go=1.17 b2/go.mod +go mod edit -go=1.17 c1/go.mod +go mod edit -go=1.17 c2/go.mod +go mod edit -go=1.17 + + +# After changing to 'go 1.17` uniformly, 'go list -m all' should prune out +# example.com/c, because it is not imported by any package (or test of a package) +# transitively imported by the main module. +# +# example.com/a is imported, +# and example.com/b is needed in order to run 'go test example.com/a', +# but example.com/c is not needed because we don't expect the user to need to run +# 'go test example.com/b'. + +# If we skip directly to adding a new import of c, the dependency is too far +# away for a deepening scan to find, which is fine because the package whose +# test imported it wasn't even it "all". It should resolve from the latest +# version of its module. + +# However, if we reach c by running successive tests starting from the main +# module, we should end up with exactly the version required by b, with an update +# to the go.mod file as soon as we test a test dependency that is not itself in +# "all". + +cp go.mod go.mod.117 +go mod tidy +cmp go.mod go.mod.117 + +go list -m all +stdout '^example.com/b v0.1.0 ' +! stdout '^example.com/c ' + +# 'go test' of a package (transitively) imported by the main module +# should work without changes to the go.mod file. + +go list -test -deps example.com/a +stdout example.com/b +! stdout example.com/c + +[!short] go test -c -o $devnull example.com/a + +# However, 'go test' of a package that is itself a dependency should require an +# update to the go.mod file. +! go list -test -deps example.com/b + + # TODO(#36460): The hint here is wrong. We should suggest + # 'go get -t example.com/b@v0.1.0' instead of 'go mod tidy'. +stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$' + +[!short] ! go test -c -o $devnull example.com/b +[!short] stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$' + +go get -t example.com/b@v0.1.0 +go list -test -deps example.com/b +stdout example.com/c + +[!short] go test -c -o $devnull example.com/b + +# The update should bring the version required by b, not the latest version of c. + +go list -m example.com/c +stdout '^example.com/c v0.1.0 ' + +cmp go.mod go.mod.b + + +# We should reach the same state if we arrive at it via `go test -mod=mod`. + +cp go.mod.117 go.mod + +[short] go list -mod=mod -test -deps example.com/a +[!short] go test -mod=mod -c -o $devnull example.com/a + +[short] go list -mod=mod -test -deps example.com/b +[!short] go test -mod=mod -c -o $devnull example.com/b + +cmp go.mod go.mod.b + + + +-- go.mod -- +module example.com/lazy + +go 1.15 + +require example.com/a v0.1.0 + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- go.mod.b -- +module example.com/lazy + +go 1.17 + +require example.com/a v0.1.0 + +require example.com/b v0.1.0 // indirect + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0 => ./b2 + example.com/c v0.1.0 => ./c1 + example.com/c v0.2.0 => ./c2 +) +-- lazy.go -- +package lazy + +import ( + _ "example.com/a" +) +-- a/go.mod -- +module example.com/a + +go 1.15 + +require example.com/b v0.1.0 +-- a/a.go -- +package a +-- a/a_test.go -- +package a + +import ( + "testing" + + _ "example.com/b" +) + +func TestUsingB(t *testing.T) { + // … +} +-- b1/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b1/b.go -- +package b +-- b1/b_test.go -- +package b + +import _ "example.com/c" +-- b2/go.mod -- +module example.com/b + +go 1.15 + +require example.com/c v0.1.0 +-- b2/b.go -- +package b +This file should not be used, so this syntax error should be ignored. +-- b2/b_test.go -- +package b +This file should not be used, so this syntax error should be ignored. +-- c1/go.mod -- +module example.com/c + +go 1.15 +-- c1/c.go -- +package c +-- c2/go.mod -- +module example.com/c + +go 1.15 +-- c2/c.go -- +package c +This file should not be used, so this syntax error should be ignored. diff --git a/src/cmd/go/testdata/script/mod_list.txt b/src/cmd/go/testdata/script/mod_list.txt new file mode 100644 index 0000000..06316cc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list.txt @@ -0,0 +1,62 @@ +env GO111MODULE=on +[short] skip + +# list {{.Dir}} shows main module and go.mod but not not-yet-downloaded dependency dir. +go list -mod=mod -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all +stdout '^x true .*[\\/]src[\\/]go.mod .*[\\/]src$' +stdout '^rsc.io/quote false .*[\\/]v1.5.2.mod $' + +# list {{.Dir}} shows dependency after download (and go list without -m downloads it) +go list -mod=mod -f '{{.Dir}}' rsc.io/quote +stdout '.*mod[\\/]rsc.io[\\/]quote@v1.5.2$' + +# downloaded dependencies are read-only +exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +exists -readonly $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/buggy + +# go clean -modcache can delete read-only dependencies +go clean -modcache +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 + +# list {{.Dir}} shows replaced directories +cp go.mod2 go.mod +go list -mod=mod -f {{.Dir}} rsc.io/quote +go list -m -f '{{.Path}} {{.Version}} {{.Dir}}{{with .Replace}} {{.GoMod}} => {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' all +stdout 'mod[\\/]rsc.io[\\/]quote@v1.5.1' +stdout 'v1.3.0.*mod[\\/]rsc.io[\\/]sampler@v1.3.1 .*[\\/]v1.3.1.mod => v1.3.1.*sampler@v1.3.1 .*[\\/]v1.3.1.mod' + +# list std should work +go list std +stdout ^math/big + +# rsc.io/quote/buggy should be listable as a package, +# even though it is only a test. +go list -mod=mod rsc.io/quote/buggy + +# rsc.io/quote/buggy should not be listable as a module +go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy +stdout '^module nonexist: not a known dependency$' +stdout '^module rsc.io/quote/buggy: not a known dependency$' + +! go list -m nonexist rsc.io/quote/buggy +stderr '^go: module nonexist: not a known dependency' +stderr '^go: module rsc.io/quote/buggy: not a known dependency' + +# Module loader does not interfere with list -e (golang.org/issue/24149). +go list -e -f '{{.Error.Err}}' database +stdout 'no Go files in ' +! go list database +stderr 'no Go files in ' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- go.mod2 -- +module x +require rsc.io/quote v1.5.1 +replace rsc.io/sampler v1.3.0 => rsc.io/sampler v1.3.1 + +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_bad_import.txt b/src/cmd/go/testdata/script/mod_list_bad_import.txt new file mode 100644 index 0000000..b128408 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_bad_import.txt @@ -0,0 +1,75 @@ +# This test matches list_bad_import, but in module mode. +# Please keep them in sync. + +env GO111MODULE=on +cd example.com + +# Without -e, listing an otherwise-valid package with an unsatisfied direct import should fail. +# BUG: Today it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/direct +! stdout ^error +stdout 'incomplete' +stdout 'bad dep: .*example.com/notfound' + +# Listing with -deps should also fail. +! go list -deps example.com/direct +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct +stdout example.com/notfound + + +# Listing an otherwise-valid package that imports some *other* package with an +# unsatisfied import should also fail. +# BUG: Today, it succeeds. +go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}} {{range .DepsErrors}}bad dep: {{.Err}}{{end}}' example.com/indirect +! stdout ^error +stdout incomplete +stdout 'bad dep: .*example.com/notfound' + +# Again, -deps should fail. +! go list -deps example.com/indirect +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/indirect +stdout example.com/notfound + + +# Listing the missing dependency directly should fail outright... +! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stderr 'no required module provides package example.com/notfound; to add it:\n\tgo get example.com/notfound' +! stdout error +! stdout incomplete + +# ...but listing with -e should succeed. +go list -e -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound +stdout error +stdout incomplete + + +# The pattern "all" should match only packages that actually exist, +# ignoring those whose existence is merely implied by imports. +go list -e -f '{{.ImportPath}} {{.Error}}' all +stdout example.com/direct +stdout example.com/indirect +# TODO: go list creates a dummy package with the import-not-found +# but really the Error belongs on example.com/direct, and this package +# should not be printed. +# ! stdout example.com/notfound + + +-- example.com/go.mod -- +module example.com + +-- example.com/direct/direct.go -- +package direct +import _ "example.com/notfound" + +-- example.com/indirect/indirect.go -- +package indirect +import _ "example.com/direct" + +-- example.com/notfound/README -- +This directory intentionally left blank. diff --git a/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt b/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt new file mode 100644 index 0000000..fd99ae8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt @@ -0,0 +1,35 @@ +# The command-line-arguments package does not belong to a module... +cd a +go list -f '{{.Module}}' ../b/b.go +stdout '^<nil>$' + +# ... even if the arguments are sources from that module +go list -f '{{.Module}}' a.go +stdout '^<nil>$' + +[short] skip + +# check that the version of command-line-arguments doesn't include a module +go build -o a.exe a.go +go version -m a.exe +stdout '^\tpath\tcommand-line-arguments$' +stdout '^\tdep\ta\t\(devel\)\t$' +! stdout mod + +-- a/go.mod -- +module a +go 1.17 +-- a/a.go -- +package main + +import "a/dep" + +func main() { + dep.D() +} +-- a/dep/dep.go -- +package dep + +func D() {} +-- b/b.go -- +package b
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt b/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt new file mode 100644 index 0000000..896bbab --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_compiled_concurrent.txt @@ -0,0 +1,42 @@ +env GO111MODULE=on + +[short] skip +[!cgo] skip + +# Regression test for golang.org/issue/29667: +# spurious 'failed to cache compiled Go files' errors. +# This test failed reliably when run with -count=10 +# on a Linux workstation. + +env GOCACHE=$WORK/gocache +mkdir $GOCACHE + +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & +go list -json -compiled -test=false -export=false -deps=true -- . & + +wait + +-- go.mod -- +module sandbox/bar +-- bar.go -- +package bar + +import "C" diff --git a/src/cmd/go/testdata/script/mod_list_deprecated.txt b/src/cmd/go/testdata/script/mod_list_deprecated.txt new file mode 100644 index 0000000..ee985cc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_deprecated.txt @@ -0,0 +1,52 @@ +# 'go list pkg' does not show deprecation. +go list example.com/deprecated/a +stdout '^example.com/deprecated/a$' + +# 'go list -m' does not show deprecation. +go list -m example.com/deprecated/a +stdout '^example.com/deprecated/a v1.9.0$' + +# 'go list -m -versions' does not show deprecation. +go list -m -versions example.com/deprecated/a +stdout '^example.com/deprecated/a v1.0.0 v1.9.0$' + +# 'go list -m -u' shows deprecation. +go list -m -u example.com/deprecated/a +stdout '^example.com/deprecated/a v1.9.0 \(deprecated\)$' + +# 'go list -m -u -f' exposes the deprecation message. +go list -m -u -f {{.Deprecated}} example.com/deprecated/a +stdout '^in example.com/deprecated/a@v1.9.0$' + +# This works even if we use an old version that does not have the deprecation +# message in its go.mod file. +go get example.com/deprecated/a@v1.0.0 +! grep Deprecated: $WORK/gopath/pkg/mod/cache/download/example.com/deprecated/a/@v/v1.0.0.mod +go list -m -u -f {{.Deprecated}} example.com/deprecated/a +stdout '^in example.com/deprecated/a@v1.9.0$' + +# 'go list -m -u' does not show deprecation for the main module. +go list -m -u +! stdout deprecated +go list -m -u -f '{{if not .Deprecated}}ok{{end}}' +stdout ok + +# 'go list -m -u' does not show a deprecation message for a module that is not +# deprecated at the latest version, even if it is deprecated at the current +# version. +go list -m -u example.com/undeprecated +stdout '^example.com/undeprecated v1.0.0 \[v1.0.1\]$' +-- go.mod -- +// Deprecated: main module is deprecated, too! +module example.com/use + +go 1.17 + +require ( + example.com/deprecated/a v1.9.0 + example.com/undeprecated v1.0.0 +) +-- go.sum -- +example.com/deprecated/a v1.9.0 h1:pRyvBIZheJpQVVnNW4Fdg8QuoqDgtkCreqZZbASV3BE= +example.com/deprecated/a v1.9.0/go.mod h1:Z1uUVshSY9kh6l/2hZ8oA9SBviX2yfaeEpcLDz6AZwY= +example.com/undeprecated v1.0.0/go.mod h1:1qiRbdA9VzJXDqlG26Y41O5Z7YyO+jAD9do8XCZQ+Gg= diff --git a/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt b/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt new file mode 100644 index 0000000..48b991f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_deprecated_replace.txt @@ -0,0 +1,68 @@ +# When all versions are replaced, we should not look up a deprecation message. +# We will still look up a deprecation message for the replacement. +cp go.mod.allreplaced go.mod +go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all +stdout '^example.com/deprecated/a@v1.0.0 <> => example.com/deprecated/b@v1.0.0 <in example.com/deprecated/b@v1.9.0>$' + +# When one version is replaced, we should see a deprecation message. +cp go.mod.onereplaced go.mod +go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all +stdout '^example.com/deprecated/a@v1.0.0 <in example.com/deprecated/a@v1.9.0> => example.com/deprecated/b@v1.0.0 <in example.com/deprecated/b@v1.9.0>$' + +# If the replacement is a directory, we won't look that up. +cp go.mod.dirreplacement go.mod +go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all +stdout '^example.com/deprecated/a@v1.0.0 <> => ./a@ <>$' + +# If the latest version of the replacement is replaced, we'll use the content +# from that replacement. +cp go.mod.latestreplaced go.mod +go list -m -u -f '{{.Path}}@{{.Version}} <{{.Deprecated}}>{{with .Replace}} => {{.Path}}@{{.Version}} <{{.Deprecated}}>{{end}}' all +stdout '^example.com/deprecated/a@v1.0.0 <> => example.com/deprecated/b@v1.0.0 <in ./b>$' + +-- go.mod.allreplaced -- +module m + +go 1.17 + +require example.com/deprecated/a v1.0.0 + +replace example.com/deprecated/a => example.com/deprecated/b v1.0.0 +-- go.mod.onereplaced -- +module m + +go 1.17 + +require example.com/deprecated/a v1.0.0 + +replace example.com/deprecated/a v1.0.0 => example.com/deprecated/b v1.0.0 +-- go.mod.dirreplacement -- +module m + +go 1.17 + +require example.com/deprecated/a v1.0.0 + +replace example.com/deprecated/a => ./a +-- go.mod.latestreplaced -- +module m + +go 1.17 + +require example.com/deprecated/a v1.0.0 + +replace ( + example.com/deprecated/a => example.com/deprecated/b v1.0.0 + example.com/deprecated/b v1.9.0 => ./b +) +-- go.sum -- +example.com/deprecated/b v1.0.0/go.mod h1:b19J9ywRGviY7Nq4aJ1WBJ+A7qUlEY9ihp22yI4/F6M= +-- a/go.mod -- +module example.com/deprecated/a + +go 1.17 +-- b/go.mod -- +// Deprecated: in ./b +module example.com/deprecated/b + +go 1.17 diff --git a/src/cmd/go/testdata/script/mod_list_dir.txt b/src/cmd/go/testdata/script/mod_list_dir.txt new file mode 100644 index 0000000..157d3b6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_dir.txt @@ -0,0 +1,36 @@ +[short] skip + +# go list with path to directory should work + +# populate go.sum +go get + +env GO111MODULE=off +go list -f '{{.ImportPath}}' $GOROOT/src/math +stdout ^math$ + +env GO111MODULE=on +go list -f '{{.ImportPath}}' $GOROOT/src/math +stdout ^math$ +go list -f '{{.ImportPath}}' . +stdout ^x$ + +go mod download rsc.io/quote@v1.5.2 +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote$' +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0 +stdout '^rsc.io/sampler$' +go get rsc.io/sampler@v1.3.1 +go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.1 +stdout '^rsc.io/sampler$' +! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/sampler@v1.3.0 +stderr 'outside main module or its selected dependencies' + +-- go.mod -- +module x +require rsc.io/quote v1.5.2 + +-- x.go -- +package x + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_direct.txt b/src/cmd/go/testdata/script/mod_list_direct.txt new file mode 100644 index 0000000..9b7a04c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_direct.txt @@ -0,0 +1,24 @@ +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +[!net] skip +[!exec:git] skip + +# golang.org/issue/33099: if an import path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to the module. +# For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file, +# which would produce a hard error at the subsequent call to GoMod. + +go get + +-- go.mod -- +module example.com +go 1.13 + +-- main.go -- +package main + +import _ "vcs-test.golang.org/git/v3pkg.git/v3" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_list_e_readonly.txt b/src/cmd/go/testdata/script/mod_list_e_readonly.txt new file mode 100644 index 0000000..4969434 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_e_readonly.txt @@ -0,0 +1,15 @@ +# 'go list -mod=readonly -e should attribute errors +# to individual missing packages. +# Verifies golang.org/issue/34829. +go list -mod=readonly -e -deps -f '{{if .Error}}{{.ImportPath}}: {{.Error}}{{end}}' . +stdout 'example.com/missing: use.go:3:8: cannot find module providing package example.com/missing: import lookup disabled by -mod=readonly' + +-- go.mod -- +module example.com/m + +go 1.14 + +-- use.go -- +package use + +import _ "example.com/missing" diff --git a/src/cmd/go/testdata/script/mod_list_pseudo.txt b/src/cmd/go/testdata/script/mod_list_pseudo.txt new file mode 100644 index 0000000..056c093 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_pseudo.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/32715. + +# When using $GOPATH/pkg/mod/cache/download as a proxy, +# 'latest' queries should prefer tagged versions over pseudo-versions. + +go mod download github.com/dmitshur-test/modtest5@v0.0.0-20190619020302-197a620e0c9a +go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha +go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e +cmp $GOPATH/pkg/mod/cache/download/github.com/dmitshur-test/modtest5/@v/list $WORK/modtest5.list + +env GOSUMDB=off # don't verify go.mod files when loading retractions +env GOPROXY=file:///$GOPATH/pkg/mod/cache/download +env GOPATH=$WORK/gopath2 +mkdir $GOPATH + +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' github.com/dmitshur-test/modtest5@latest +stdout '^github.com/dmitshur-test/modtest5 v0.5.0-alpha 2019-06-18$' + +# If the module proxy contains only pseudo-versions, 'latest' should stat +# the version with the most recent timestamp — not the highest semantic +# version — and return its metadata. +env GOPROXY=file:///$WORK/tinyproxy +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' dmitri.shuralyov.com/test/modtest3@latest +stdout '^dmitri.shuralyov.com/test/modtest3 v0.0.0-20181023043359-a85b471d5412 2018-10-22$' + +-- $WORK/modtest5.list -- +v0.0.0-20190619020302-197a620e0c9a +v0.5.0-alpha +v0.5.0-alpha.0.20190619023908-3da23a9deb9e +-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/list -- +v0.1.0-0.20161023043300-000000000000 +v0.0.0-20181023043359-a85b471d5412 +-- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/v0.0.0-20181023043359-a85b471d5412.info -- +{ + "Version": "v0.0.0-20181023043359-a85b471d5412", + "Time": "2018-10-22T21:33:59-07:00" +} diff --git a/src/cmd/go/testdata/script/mod_list_replace_dir.txt b/src/cmd/go/testdata/script/mod_list_replace_dir.txt new file mode 100644 index 0000000..b446543 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -0,0 +1,27 @@ +# Test that "go list" succeeds when given a directory in a replacement +# module within the module cache. +# Verifies golang.org/issue/29548 + +# Populate go.sum and download dependencies. +go get + +# Ensure v1.5.2 is also in the cache so we can list it. +go mod download rsc.io/quote@v1.5.2 + +! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside main module or its selected dependencies$' + +go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.1 +stdout 'rsc.io/quote' + +-- go.mod -- +module example.com/quoter + +require rsc.io/quote v1.5.2 + +replace rsc.io/quote => rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_list_retract.txt b/src/cmd/go/testdata/script/mod_list_retract.txt new file mode 100644 index 0000000..b7147aa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_retract.txt @@ -0,0 +1,110 @@ +# 'go list -mod=vendor -retracted' reports an error. +go mod vendor +! go list -m -retracted -mod=vendor +stderr '^go list -retracted cannot be used when vendoring is enabled$' +rm vendor + +# 'go list -retracted' reports an error in GOPATH mode. +env GO111MODULE=off +! go list -retracted +stderr '^go list -retracted can only be used in module-aware mode$' +env GO111MODULE= + +# 'go list pkg' does not show retraction. +go list -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract +! stdout . + +# 'go list -retracted pkg' shows retraction. +go list -retracted -f '{{with .Module}}{{with .Retracted}}retracted{{end}}{{end}}' example.com/retract +stdout retracted + +# 'go list -m' does not show retraction. +go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract +! stdout . + +# 'go list -m -retracted' shows retraction. +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract + +# 'go list -m mod@version' does not show retraction. +go list -m -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused +! stdout . + +# 'go list -m -retracted mod@version' does not show an error if the module +# that would contain the retraction is unavailable. See #45305. +go list -m -retracted -f '{{.Path}} {{.Version}} {{.Error}}' example.com/retract/missingmod@v1.0.0 +stdout '^example.com/retract/missingmod v1.0.0 <nil>$' +exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info +! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod + +# 'go list -m -retracted mod@version' shows retractions. +go list -m -retracted example.com/retract@v1.0.0-unused +stdout '^example.com/retract v1.0.0-unused \(retracted\)$' +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract@v1.0.0-unused +stdout retracted + +# 'go list -m mod@latest' selects a previous release version, not self-retracted latest. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest +stdout '^v1.1.0$' + +# 'go list -m -retracted mod@latest' selects the self-retracted latest version. +go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@latest +stdout '^v1.9.0 retracted$' + +# 'go list -m mod@latest' selects a pre-release version if all release versions are retracted. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest +stdout '^v1.9.1-pre$' + +# 'go list -m -retracted mod@latest' selects the self-retracted latest version. +go list -m -retracted -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prerelease@latest +stdout '^v1.9.0 retracted$' + +# 'go list -m mod@latest' selects a pseudo-version if all versions are retracted. +# TODO(golang.org/issue/24031): the proxy does not expose the pseudo-version, +# even if all release versions are retracted. +go list -m -e -f '{{.Error.Err}}' example.com/retract/self/pseudo@latest +stdout '^module example.com/retract/self/pseudo: no matching versions for query "latest"$' + +# 'go list -m mod@latest' reports an error if all versions are retracted. +go list -m -e -f '{{.Error.Err}}' example.com/retract/self/all@latest +stdout '^module example.com/retract/self/all: no matching versions for query "latest"$' + +# 'go list -m mod@<v1.10' selects a previous release version, not self-retracted latest. +# The @latest query is not special with respect to retractions. +go list -m -f '{{.Version}}{{with .Retracted}} retracted{{end}}' example.com/retract/self/prev@<v1.10 +stdout '^v1.1.0$' + +# 'go list -m -versions' hides retracted versions. +go list -m -versions example.com/retract +stdout '^example.com/retract v1.0.0-good v1.1.0$' + +# 'go list -m -retracted -versions' shows retracted versions. +go list -m -retracted -versions example.com/retract +stdout '^example.com/retract v1.0.0-bad v1.0.0-good v1.0.0-unused v1.1.0$' + +# 'go list -m -u -versions' loads retractions and does not show retracted versions. +go list -m -u -versions example.com/retract +stdout '^example.com/retract v1.0.0-good v1.1.0$' +go list -m -u -versions -f '{{with .Retracted}}retracted{{end}}' example.com/retract +stdout retracted + +# 'go list -m -u' shows retraction. +go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract +stdout retracted + +# 'go list -m -u' does not suggest an update to a self-retracted latest version. +go list -m -u -f '{{with .Update}}{{.Version}}{{with .Retracted}} retracted{{end}}{{end}}' example.com/retract/self/prev@v1.0.0-bad +stdout '^v1.1.0$' + +-- go.mod -- +module example.com/use + +go 1.15 + +require example.com/retract v1.0.0-bad +-- go.sum -- +example.com/retract v1.0.0-bad h1:liAW69rbtjY67x2CcNzat668L/w+YGgNX3lhJsWIJis= +example.com/retract v1.0.0-bad/go.mod h1:0DvGGofJ9hr1q63cBrOY/jSY52OwhRGA0K47NE80I5Y= +-- use.go -- +package use + +import _ "example.com/retract" diff --git a/src/cmd/go/testdata/script/mod_list_std.txt b/src/cmd/go/testdata/script/mod_list_std.txt new file mode 100644 index 0000000..f4e0433 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_std.txt @@ -0,0 +1,92 @@ +env GO111MODULE=on +env GOPROXY=off + +[!gc] skip +[short] skip + +# Outside of GOROOT, our vendored packages should be reported as part of the standard library. +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd +stdout ^vendor/golang\.org/x/net/http2/hpack +stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm +! stdout ^golang\.org/x/ + +# The dependencies of those packages should also be vendored. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang\.org/x/crypto/internal/subtle + +# cmd/... should match the same packages it used to match in GOPATH mode. +go list cmd/... +stdout ^cmd/compile +! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm + +# GOROOT/src/... should list the packages in std as if it were a module +# dependency: omitting vendored dependencies and stopping at the 'cmd' module +# boundary. + +go list $GOROOT/src/... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ + + +# Vendored dependencies should appear with their 'vendor/' paths in std (they're +# in GOROOT/src, but not in the 'std' module following the usual module-boundary +# rules). + +cd $GOROOT/src + +go list std +stdout ^vendor/golang.org/x/net/http2/hpack +! stdout ^golang\.org/x + +# The dependencies of packages with an explicit 'vendor/' prefix should +# still themselves resolve to vendored packages. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang.org/x/crypto/internal/subtle +! stdout ^golang\.org/x + +# Within the std module, the dependencies of the non-vendored packages within +# std should appear to be packages beginning with 'vendor/', not 'golang.org/…' +# module dependencies. + +go list all +! stdout ^golang.org/x/ +! stdout ^std/ +! stdout ^cmd/ +stdout ^vendor/ + +go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std +! stdout . + +# However, the 'golang.org/…' module dependencies should resolve to those same +# directories. + +go list -f '{{.Dir}}' golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# Within the std module, the packages within the module should omit the 'std/' +# prefix (they retain their own identities), but should respect normal module +# boundaries (vendored packages are not included in the module, even though they +# are included in the 'std' pattern). + +go list ./... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ + + +# Within std, the vendored dependencies of cmd should still appear to be part of cmd. + +go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' cmd +stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm + +go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' cmd +! stdout . + +go list cmd/... +stdout ^cmd/compile +! stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm diff --git a/src/cmd/go/testdata/script/mod_list_sums.txt b/src/cmd/go/testdata/script/mod_list_sums.txt new file mode 100644 index 0000000..6c2f57c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_sums.txt @@ -0,0 +1,32 @@ +# https://golang.org/issue/41297: 'go list -m' should not require go.sum with +# -versions or when all args are version queries. + +go mod init m +go mod edit -require=rsc.io/quote@v1.5.1 + +go list -m -mod=readonly rsc.io/quote@latest +stdout '^rsc\.io/quote v1\.5\.2$' +! stderr . + +go list -m -mod=readonly -versions rsc.io/quote +stdout 'rsc\.io/quote v1\.0\.0 .* v1\.5\.3-pre1$' +! stderr . + +# Incidentally fetching the required version of a module records its checksum, +# just because it happens to be in the build list, and recording the checksum +# triggers an error under -mod=readonly. +# +# TODO(#41297): This should not be an error. +! go list -m -mod=readonly rsc.io/quote@<v1.5.2 +stderr '^go: updates to go.sum needed, disabled by -mod=readonly$' +! stderr 'missing go.sum entry' + +# Attempting to list the versions of a module that is not a root dependency +# causes the build list to be resolved (so that the selected version can *also* +# be identified, even though it is not relevant to this particular output). +# That, in turn, causes us to need checksums for the go.sum files for the +# modules in the module graph. +# +# TODO(#41297): This should not be an error either. +! go list -m -mod=readonly -versions rsc.io/sampler +stderr '^go: rsc\.io/quote@v1\.5\.1: missing go\.sum entry; to add it:\n\tgo mod download rsc\.io/quote$' diff --git a/src/cmd/go/testdata/script/mod_list_test.txt b/src/cmd/go/testdata/script/mod_list_test.txt new file mode 100644 index 0000000..f697af6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_test.txt @@ -0,0 +1,30 @@ +env GO111MODULE=on + +# go list -compiled -test must handle test-only packages +# golang.org/issue/27097. +go list -compiled -test +stdout -count=4 '^.' # 4 lines +stdout '^m$' +stdout '^m\.test$' +stdout '^m \[m\.test\]$' +stdout '^m_test \[m\.test\]$' + +# https://golang.org/issue/39974: test packages should have the Module field populated. +go list -test -f '{{.ImportPath}}{{with .Module}}: {{.Path}}{{end}}' +stdout -count=4 '^.' # 4 lines +stdout '^m: m$' +stdout '^m\.test: m$' +stdout '^m \[m\.test\]: m$' +stdout '^m_test \[m\.test\]: m$' + +-- go.mod -- +module m + +-- x_test.go -- +package x +import "testing" +func Test(t *testing.T) {} +-- x_x_test.go -- +package x_test +import "testing" +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/mod_list_test_cycle.txt b/src/cmd/go/testdata/script/mod_list_test_cycle.txt new file mode 100644 index 0000000..755e50b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_test_cycle.txt @@ -0,0 +1,23 @@ +# https://golang.org/issue/45863: a typo in a test package leading to an +# import cycle should be diagnosed, instead of causing an infinite loop. +# The failure mode of this test prior to the fix was a timeout or OOM crash. + +go list -e -test -deps ./datastore/sql + +-- go.mod -- +module golang.org/issue45863 + +go 1.17 +-- datastore/datastore_health.go -- +package datastore + +import ( + "golang.org/issue45863/datastore" + "golang.org/issue45863/datastore/sql" +) +-- datastore/sql/sql.go -- +package sql +-- datastore/sql/sql_test.go -- +package sql + +import _ "golang.org/issue45863/datastore" diff --git a/src/cmd/go/testdata/script/mod_list_update_nolatest.txt b/src/cmd/go/testdata/script/mod_list_update_nolatest.txt new file mode 100644 index 0000000..7eebe26 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_update_nolatest.txt @@ -0,0 +1,55 @@ +# Check that if a proxy does not have a version of a module that could be +# an upgrade, 'go list -m -u' still succeeds. +# We use a local file proxy, since our test proxy doesn't have the behavior +# we want to test, and we don't want it to be too clever. +# Verifies #45305, where proxy.golang.org serves an empty /@v/list (200) +# but has no /@latest (410) because the go.mod at the tip of the default +# branch has a different major version suffix. +env testproxy=$GOPROXY +env GOPROXY=file:///$WORK/proxy +env GOSUMDB=off + +# If the proxy does not return a list of versions (404/410) +# or a latest version (404/410), we should see no error. +go list -m example.com/noversion +stdout '^example.com/noversion v0.0.0$' +go list -m -u example.com/noversion +stdout '^example.com/noversion v0.0.0$' + +# If the proxy returns an empty list of versions (200, not 404/410) +# but does not have a latest version (404/410), we should see no error. +go list -m example.com/nolatest +stdout '^example.com/nolatest v0.0.0$' +go list -m -u example.com/nolatest +stdout '^example.com/nolatest v0.0.0$' + +# If proxy returns an invalid response, we should see an error. +env GOPROXY=$testproxy/invalid +! go list -m -u example.com/nolatest +stderr '^go: loading module retractions for example.com/nolatest@v0.0.0: invalid response from proxy "[^"]*": invalid character ''i'' looking for beginning of value$' + +-- go.mod -- +module m + +go 1.17 + +require ( + example.com/nolatest v0.0.0 + example.com/noversion v0.0.0 +) +-- go.sum -- +example.com/nolatest v0.0.0/go.mod h1:HnLrCt6SJga5tCtJ7IzG9dOOCniY3G5C0VT7jfMdS0M= +example.com/noversion v0.0.0/go.mod h1:2RUfWiCYsygSXPM2Igxx0FD3Kq33OnVdxm34eDDhXbQ= +-- $WORK/proxy/example.com/nolatest/@v/list -- +-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.info -- +{"Version":"v0.0.0"} +-- $WORK/proxy/example.com/nolatest/@v/v0.0.0.mod -- +module example.com/nolatest + +go 1.17 +-- $WORK/proxy/example.com/noversion/@v/v0.0.0.info -- +{"Version":"v0.0.0"} +-- $WORK/proxy/example.com/noversion/@v/v0.0.0.mod -- +module example.com/noversion + +go 1.17 diff --git a/src/cmd/go/testdata/script/mod_list_upgrade.txt b/src/cmd/go/testdata/script/mod_list_upgrade.txt new file mode 100644 index 0000000..0cef04b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_upgrade.txt @@ -0,0 +1,12 @@ +env GO111MODULE=on + +# Populate go.sum +go list -m -mod=mod all + +# Check for upgrades. +go list -m -u all +stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' + +-- go.mod -- +module x +require rsc.io/quote v1.2.0 diff --git a/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt b/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt new file mode 100644 index 0000000..8e51dfc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_list_upgrade_pseudo.txt @@ -0,0 +1,26 @@ +env GO111MODULE=on + +# For this test module there are three versions: +# * v0.1.1-0.20190429073117-b5426c86b553 +# * v0.1.0 +# * v0.0.0-20190430073000-30950c05d534 +# Only v0.1.0 is tagged. +# +# The v0.1.1 pseudo-version is semantically higher than the latest tag. +# The v0.0.0 pseudo-version is chronologically newer. + +# The latest pseudo-version is semantically higher than the latest tag. +# 'list -u' should not suggest a lower version as an upgrade. + +go get example.com/pseudoupgrade@b5426c8 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.1.1-0.20190429073117-b5426c86b553$' + +go get example.com/pseudoupgrade@v0.0.0-20190430073000-30950c05d534 +go list -m -u all +stdout '^example.com/pseudoupgrade v0.0.0-20190430073000-30950c05d534$' + +-- go.mod -- +module x + +go 1.12 diff --git a/src/cmd/go/testdata/script/mod_load_badchain.txt b/src/cmd/go/testdata/script/mod_load_badchain.txt new file mode 100644 index 0000000..be2a4bc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badchain.txt @@ -0,0 +1,101 @@ +[short] skip +env GO111MODULE=on + +# Download everything to avoid "finding" messages in stderr later. +cp go.mod.orig go.mod +go mod download +go mod download example.com@v1.0.0 +go mod download example.com/badchain/a@v1.1.0 +go mod download example.com/badchain/b@v1.1.0 +go mod download example.com/badchain/c@v1.1.0 + +# Try to update example.com/badchain/a (and its dependencies). +! go get example.com/badchain/a +cmp stderr update-a-expected +cmp go.mod go.mod.orig + +# Try to update the main module. This updates everything, including +# modules that aren't direct requirements, so the error stack is shorter. +! go get -u ./... +cmp stderr update-main-expected +cmp go.mod go.mod.orig + +# Update manually. Listing modules should produce an error. +go mod edit -require=example.com/badchain/a@v1.1.0 +! go list -m all +cmp stderr list-expected + +# Try listing a package that imports a package +# in a module without a requirement. +go mod edit -droprequire example.com/badchain/a +! go list -mod=mod m/use +cmp stderr list-missing-expected + +! go list -mod=mod -test m/testuse +cmp stderr list-missing-test-expected + +-- go.mod.orig -- +module m + +go 1.13 + +require example.com/badchain/a v1.0.0 +-- go.sum -- +example.com/badchain/a v1.0.0 h1:iJDLiHLmpQgr9Zrv+44UqywAE2IG6WkHnH4uG08vf+s= +example.com/badchain/a v1.0.0/go.mod h1:6/gnCYHdVrs6mUgatUYUSbuHxEY+/yWedmTggLz23EI= +example.com/badchain/a v1.1.0 h1:cPxQpsOjaIrn05yDfl4dFFgGSbjYmytLqtIIBfTsEqA= +example.com/badchain/a v1.1.0/go.mod h1:T15b2BEK+RY7h7Lr2dgS38p1pgH5/t7Kf5nQXBlcW/A= +example.com/badchain/b v1.0.0 h1:kjDVlBxpjQavYxHE7ECCyyXhfwsfhWIqvghfRgPktSA= +example.com/badchain/b v1.0.0/go.mod h1:sYsH934pMc3/A2vQZh019qrWmp4+k87l3O0VFUYqL+I= +example.com/badchain/b v1.1.0 h1:iEALV+DRN62FArnYylBR4YwCALn/hCdITvhdagHa0L4= +example.com/badchain/b v1.1.0/go.mod h1:mlCgKO7lRZ+ijwMFIBFRPCGt5r5oqCcHdhSSE0VL4uY= +example.com/badchain/c v1.0.0 h1:lOeUHQKR7SboSH7Bj6eIDWoNHaDQXI0T2GfaH2x9fNA= +example.com/badchain/c v1.0.0/go.mod h1:4U3gzno17SaQ2koSVNxITu9r60CeLSgye9y4/5LnfOE= +example.com/badchain/c v1.1.0 h1:VtTg1g7fOutWKHQf+ag04KLRpdMGSfQ9s9tagVtGW14= +example.com/badchain/c v1.1.0/go.mod h1:tyoJj5qh+qtb48sflwdVvk4R+OjPQEY2UJOoibsVLPk= +-- use/use.go -- +package use + +import _ "example.com/badchain/c" +-- testuse/testuse.go -- +package testuse +-- testuse/testuse_test.go -- +package testuse + +import ( + "testing" + _ "example.com/badchain/c" +) + +func Test(t *testing.T) {} +-- update-main-expected -- +go: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- update-a-expected -- +go: example.com/badchain/a@v1.1.0 requires + example.com/badchain/b@v1.1.0 requires + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-expected -- +go: example.com/badchain/a@v1.1.0 requires + example.com/badchain/b@v1.1.0 requires + example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-missing-expected -- +go: finding module for package example.com/badchain/c +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 +go: m/use imports + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c +-- list-missing-test-expected -- +go: finding module for package example.com/badchain/c +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 +go: m/testuse tested by + m/testuse.test imports + example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: + module declares its path as: badchain.example.com/c + but was required as: example.com/badchain/c diff --git a/src/cmd/go/testdata/script/mod_load_badmod.txt b/src/cmd/go/testdata/script/mod_load_badmod.txt new file mode 100644 index 0000000..fa22e18 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badmod.txt @@ -0,0 +1,25 @@ +# Unknown lines should be ignored in dependency go.mod files. +go list -m -mod=mod all + +# ... and in replaced dependency go.mod files. +cp go.mod go.mod.usesub +go list -m -mod=mod all + +# ... but not in the main module. +cp go.mod.bad go.mod +! go list -m -mod=mod all +stderr 'unknown directive: hello' + +-- go.mod -- +module m +require rsc.io/badmod v1.0.0 +-- go.mod.bad -- +module m +hello world +-- go.mod.usesub -- +module m +require rsc.io/badmod v1.0.0 +replace rsc.io/badmod v1.0.0 => ./sub +-- sub/go.mod -- +module sub +hello world diff --git a/src/cmd/go/testdata/script/mod_load_badzip.txt b/src/cmd/go/testdata/script/mod_load_badzip.txt new file mode 100644 index 0000000..58160b4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_badzip.txt @@ -0,0 +1,13 @@ +# Zip files with unexpected file names inside should be rejected. +env GO111MODULE=on + +! go get rsc.io/badzip +stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' +! grep rsc.io/badzip go.mod + +go mod edit -require rsc.io/badzip@v1.0.0 +! go build -mod=mod rsc.io/badzip +stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt new file mode 100644 index 0000000..2ca8b3c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_load_replace_mismatch.txt @@ -0,0 +1,23 @@ +# If a replacement module declares a module path different from both +# the original module and its location, report an error with all three paths. +# In particular, the "required as" path should be the original. +# Verifies golang.org/issue/38220. +! go mod download +cmp stderr want + +-- go.mod -- +module m + +require rsc.io/quote v1.5.2 + +replace rsc.io/quote v1.5.2 => example.com/quote v1.5.2 + +-- use.go -- +package use + +import _ "rsc.io/quote" + +-- want -- +go: rsc.io/quote@v1.5.2 (replaced by example.com/quote@v1.5.2): parsing go.mod: + module declares its path as: rsc.io/Quote + but was required as: rsc.io/quote diff --git a/src/cmd/go/testdata/script/mod_local_replace.txt b/src/cmd/go/testdata/script/mod_local_replace.txt new file mode 100644 index 0000000..19bc8f3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_local_replace.txt @@ -0,0 +1,23 @@ +# Test that local replacements work even with dummy module names. +# golang.org/issue/24100. + +env GO111MODULE=on + +cd x/y +go list -f '{{.Dir}}' zz +stdout x[/\\]z$ + +-- x/y/go.mod -- +module x/y +require zz v1.0.0 +replace zz v1.0.0 => ../z + +-- x/y/y.go -- +package y +import _ "zz" + +-- x/z/go.mod -- +module x/z + +-- x/z/z.go -- +package z diff --git a/src/cmd/go/testdata/script/mod_missing_repo.txt b/src/cmd/go/testdata/script/mod_missing_repo.txt new file mode 100644 index 0000000..b91a8db --- /dev/null +++ b/src/cmd/go/testdata/script/mod_missing_repo.txt @@ -0,0 +1,15 @@ +# Regression test for golang.org/issue/34094: modules hosted within gitlab.com +# subgroups could not be fetched because the server returned bogus go-import +# tags for prefixes of the module path. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go mod download vcs-test.golang.org/go/missingrepo/missingrepo-git@latest +stderr 'vcs-test.golang.org/go/missingrepo/missingrepo-git: git ls-remote .*: exit status .*' + +go mod download vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing@latest diff --git a/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt new file mode 100644 index 0000000..9c250e7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_missingpkg_prerelease.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on + +! go list -mod=mod -deps use.go +stderr '^use.go:4:2: package example.com/missingpkg/deprecated provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta$' + +-- go.mod -- +module m + +go 1.14 + +-- use.go -- +package use + +import ( + _ "example.com/missingpkg/deprecated" + _ "example.com/usemissingpre" +) diff --git a/src/cmd/go/testdata/script/mod_modinfo.txt b/src/cmd/go/testdata/script/mod_modinfo.txt new file mode 100644 index 0000000..8d77e22 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_modinfo.txt @@ -0,0 +1,89 @@ +# Test to ensure runtime/debug.ReadBuildInfo parses +# the modinfo embedded in a binary by the go tool +# when module is enabled. +env GO111MODULE=on + +cd x +go mod edit -require=rsc.io/quote@v1.5.2 +go mod edit -replace=rsc.io/quote@v1.5.2=rsc.io/quote@v1.0.0 +go mod tidy # populate go.sum + +# Build a binary and ensure that it can output its own debug info. +# The debug info should be accessible before main starts (golang.org/issue/29628). +go build +exec ./x$GOEXE +stderr 'mod\s+x\s+\(devel\)' +stderr 'dep\s+rsc.io/quote\s+v1.5.2\s+' +stderr '=>\s+rsc.io/quote\s+v1.0.0\s+h1:' +stderr 'Hello, world.' + +[short] skip + +# Build a binary that accesses its debug info by reading the binary directly +# (rather than through debug.ReadBuildInfo). +# The debug info should still be present (golang.org/issue/28753). +cd unused +go build +exec ./unused$GOEXE + +-- x/go.mod -- +module x + +-- x/lib/lib.go -- +// Package lib accesses runtime/debug.modinfo before package main's init +// functions have run. +package lib + +import "runtime/debug" + +func init() { + m, ok := debug.ReadBuildInfo() + if !ok { + panic("failed debug.ReadBuildInfo") + } + println("mod", m.Main.Path, m.Main.Version) + for _, d := range m.Deps { + println("dep", d.Path, d.Version, d.Sum) + if r := d.Replace; r != nil { + println("=>", r.Path, r.Version, r.Sum) + } + } +} + +-- x/main.go -- +package main + +import ( + "rsc.io/quote" + _ "x/lib" +) + +func main() { + println(quote.Hello()) +} + +-- x/unused/main.go -- +// The unused binary does not access runtime/debug.modinfo. +package main + +import ( + "bytes" + "encoding/hex" + "log" + "os" + + _ "rsc.io/quote" +) + +func main() { + b, err := os.ReadFile(os.Args[0]) + if err != nil { + log.Fatal(err) + } + + infoStart, _ := hex.DecodeString("3077af0c9274080241e1c107e6d618e6") + if !bytes.Contains(b, infoStart) { + log.Fatal("infoStart not found in binary") + } + log.Println("ok") +} diff --git a/src/cmd/go/testdata/script/mod_multirepo.txt b/src/cmd/go/testdata/script/mod_multirepo.txt new file mode 100644 index 0000000..bbefb78 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_multirepo.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on + +# initial standalone module should use no downloaded modules +go list -deps -f {{.Dir}} +! stdout 'pkg[\\/]mod' + +# v2 import should use a downloaded module +# both without an explicit go.mod entry ... +cp tmp/use_v2.go x.go +go get . +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +# ... and with one ... +cp tmp/use_v2.mod go.mod +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +# ... and even if there is a v2 module in a subdirectory. +mkdir v2 +cp x.go v2/x.go +cp tmp/v2.mod v2/go.mod +go list -deps -f {{.Dir}} +stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' + +-- go.mod -- +module rsc.io/quote + +-- x.go -- +package quote + +-- tmp/use_v2.go -- +package quote +import _ "rsc.io/quote/v2" + +-- tmp/use_v2.mod -- +module rsc.io/quote +require rsc.io/quote/v2 v2.0.1 + +-- tmp/v2.mod -- +package rsc.io/quote/v2 diff --git a/src/cmd/go/testdata/script/mod_no_gopath.txt b/src/cmd/go/testdata/script/mod_no_gopath.txt new file mode 100644 index 0000000..ed91f5d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_no_gopath.txt @@ -0,0 +1,15 @@ +# https://golang.org/issue/43938: 'go build' should succeed +# if GOPATH and the variables needed for its default value +# are all unset but not relevant to the specific command. + +env HOME='' +env home='' +env GOPATH='' + +go list -deps main.go +stdout '^io$' + +-- main.go -- +package main + +import _ "io" diff --git a/src/cmd/go/testdata/script/mod_nomod.txt b/src/cmd/go/testdata/script/mod_nomod.txt new file mode 100644 index 0000000..7e0f55a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_nomod.txt @@ -0,0 +1,43 @@ +# Test go commands with no module. +env GO111MODULE=on + +# go mod edit fails unless given explicit mod file argument +! go mod edit -json +go mod edit -json x.mod + +# bug succeeds +[exec:echo] env BROWSER=echo +[exec:echo] go bug + +# commands that load the package in the current directory fail +! go build +! go fmt +! go generate +! go get +! go install +! go list +! go run +! go test +! go vet + +# clean succeeds, even with -modcache +go clean -modcache + +# doc succeeds for standard library +go doc unsafe + +# env succeeds +go env + +# tool succeeds +go tool -n test2json + +# version succeeds +go version + +-- x.mod -- +module m + +-- x.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/mod_notall.txt b/src/cmd/go/testdata/script/mod_notall.txt new file mode 100644 index 0000000..1657c8d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_notall.txt @@ -0,0 +1,99 @@ +# This test demonstrates go commands that combine the 'all' pattern +# with packages outside of 'all'. + +# With -deps, 'all' should include test dependencies of packages in the main +# module, but not should not include test dependencies of packages imported only +# by other root patterns. + +env GOFLAGS=-mod=mod +cp go.mod go.mod.orig + +go list -deps all x/otherroot + +stdout '^x/inall$' +stdout '^x/inall/fromtest$' +stdout '^x/inall/fromtestinall$' +stdout '^x/otherroot$' +stdout '^x/otherdep$' + +! stdout '^x/fromotherroottest$' +! stdout '^y/fromotherdeptest$' + +cmp go.mod go.mod.orig + +# With -deps -test, test dependencies of other roots should be included, +# but test dependencies of non-roots should not. + +go list -deps -test all x/otherroot +stdout '^x/inall$' +stdout '^x/inall/fromtest$' +stdout '^x/inall/fromtestinall$' +stdout '^x/otherroot$' +stdout '^x/otherdep$' + +stdout '^x/fromotherroottest$' +! stdout '^y/fromotherdeptest$' + +cmp go.mod go.mod.orig + +-- m.go -- +package m + +import _ "x/inall" +-- m_test.go -- +package m_test + +import _ "x/inall/fromtest" +-- go.mod -- +module m + +go 1.15 + +require x v0.1.0 + +replace ( + x v0.1.0 => ./x + y v0.1.0 => ./y +) +-- x/go.mod -- +module x + +go 1.15 +-- x/inall/inall.go -- +package inall +-- x/inall/inall_test.go -- +package inall_test + +import _ "x/inall/fromtestinall" +-- x/inall/fromtest/fromtest.go -- +package fromtest +-- x/inall/fromtestinall/fromtestinall.go -- +package fromtestinall +-- x/otherroot/otherroot.go -- +package otherroot + +import _ "x/otherdep" +-- x/otherroot/otherroot_test.go -- +package otherroot_test + +import _ "x/fromotherroottest" +-- x/fromotherroottest/fromotherroottest.go -- +package fromotherroottest +-- x/otherdep/otherdep.go -- +package otherdep +-- x/otherdep/otherdep_test.go -- +package otherdep_test + +import _ "y/fromotherdeptest" +-- x/otherroot/testonly/testonly.go -- +package testonly +-- y/go.mod -- +module y + +go 1.15 +-- y/fromotherdeptest/fromotherdeptest.go -- +// Package fromotherdeptest is a test dependency of x/otherdep that is +// not declared in x/go.mod. If the loader resolves this package, +// it will add this module to the main module's go.mod file, +// and we can detect the mistake. +package fromotherdeptest diff --git a/src/cmd/go/testdata/script/mod_off.txt b/src/cmd/go/testdata/script/mod_off.txt new file mode 100644 index 0000000..a73a58d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_off.txt @@ -0,0 +1,35 @@ +env GO111MODULE=off + +# This script tests that running go mod with +# GO111MODULE=off when outside of GOPATH will fatal +# with an error message, even with some source code in the directory and a go.mod. +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod graph +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod verify +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod download +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' + +# Same result in an empty directory +mkdir z +cd z +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod graph +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod verify +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' +! go mod download +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' + +-- sample.go -- +package sample + +func main() {} + +-- go.mod -- +module sample + +go 1.12 diff --git a/src/cmd/go/testdata/script/mod_off_init.txt b/src/cmd/go/testdata/script/mod_off_init.txt new file mode 100644 index 0000000..2aec0b3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_off_init.txt @@ -0,0 +1,5 @@ +# 'go mod init' should refuse to initialize a module if it will be +# ignored anyway due to GO111MODULE=off. +env GO111MODULE=off +! go mod init +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt new file mode 100644 index 0000000..f88e2ae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_outside.txt @@ -0,0 +1,319 @@ +env GO111MODULE=on +[short] skip + +# This script tests commands in module mode outside of any module. +# +# First, ensure that we really are in module mode, and that we really don't have +# a go.mod file. +go env GOMOD +stdout 'NUL|/dev/null' + + +# 'go list' without arguments implicitly operates on the current directory, +# which is not in a module. +! go list +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +go list -m +stdout '^command-line-arguments$' +# 'go list' in the working directory should fail even if there is a a 'package +# main' present: without a main module, we do not know its package path. +! go list ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go list all' lists the transitive import graph of the main module, +# which is empty if there is no main module. +go list all +! stdout . +stderr 'warning: "all" matched no packages' + +# 'go list' on standard-library packages should work, since they do not depend +# on the contents of any module. +go list -deps cmd +stdout '^fmt$' +stdout '^cmd/go$' + +go list $GOROOT/src/fmt +stdout '^fmt$' + +# 'go list' should work with file arguments. +go list ./needmod/needmod.go +stdout 'command-line-arguments' + +# 'go list' on a package from a module should fail. +! go list example.com/printversion +stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go list -m' with an explicit version should resolve that version. +go list -m example.com/version@latest +stdout 'example.com/version v1.1.0' + +# 'go list -m -versions' should succeed even without an explicit version. +go list -m -versions example.com/version +stdout 'v1.0.0\s+v1.0.1\s+v1.1.0' + +# 'go list -m all' should fail. "all" is not meaningful outside of a module. +! go list -m all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go list -m <mods> all' should also fail. +! go list -m example.com/printversion@v1.0.0 all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! stdout 'example.com/version' + +# 'go list -m <mods>' should fail if any of the mods lacks an explicit version. +! go list -m example.com/printversion +stderr 'go: cannot match "example.com/printversion" without -versions or an explicit version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! stdout 'example.com/version' + +# 'go list -m' with wildcards should fail. Wildcards match modules in the +# build list, so they aren't meaningful outside a module. +! go list -m ... +stderr 'go: cannot match "...": go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go list -m rsc.io/quote/... +stderr 'go: cannot match "rsc.io/quote/...": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go clean' should skip the current directory if it isn't in a module. +go clean -n +! stdout . +! stderr . + +# 'go mod graph' should fail, since there's no module graph. +! go mod graph +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go mod why' should fail, since there is no main module to depend on anything. +! go mod why -m example.com/version +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go mod edit', 'go mod tidy', and 'go mod fmt' should fail: +# there is no go.mod file to edit. +! go mod tidy +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go mod edit -fmt +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go mod edit -require example.com/version@v1.0.0 +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod download' without arguments should report an error. +! go mod download +stderr 'no modules specified' + +# 'go mod download' should download exactly the requested module without dependencies. +rm -r $GOPATH/pkg/mod/cache/download/example.com +go mod download example.com/printversion@v1.0.0 +exists $GOPATH/pkg/mod/cache/download/example.com/printversion/@v/v1.0.0.zip +! exists $GOPATH/pkg/mod/cache/download/example.com/version/@v/v1.0.0.zip + +# 'go mod download all' should fail. "all" is not meaningful outside of a module. +! go mod download all +stderr 'go: cannot match "all": go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod vendor' should fail: it starts by clearing the existing vendor +# directory, and we don't know where that is. +! go mod vendor +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go mod verify' should fail: we have no modules to verify. +! go mod verify +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go get' has no go.mod file to update outside a module and should fail. +! go get +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' +! go get -u +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' +! go get -u ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' +! go get -u all +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' +! go get example.com/printversion@v1.0.0 example.com/version@none +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' + +# 'go get' should not download anything. +go clean -modcache +! go get example.com/printversion@v1.0.0 +stderr '^go: go.mod file not found in current directory or any parent directory.$' +stderr '^\t''go get'' is no longer supported outside a module.$' +! exists $GOPATH/pkg/mod/example.com/printversion@v1.0.0 +! exists $GOPATH/pkg/mod/example.com/version@v1.0.0 + + +# 'go build' without arguments implicitly operates on the current directory, and should fail. +cd needmod +! go build +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' +cd .. + +# 'go build' of a non-module directory should fail too. +! go build ./needmod +stderr '^go: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go build' of source files should fail if they import anything outside std. +! go build -n ./needmod/needmod.go +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go build' of source files should succeed if they do not import anything outside std. +go build -n -o ignore ./stdonly/stdonly.go + +# 'go build' should succeed for standard-library packages. +go build -n fmt + +# 'go build' should use the latest version of the Go language. +go build ./newgo/newgo.go + +# 'go doc' without arguments implicitly operates on the current directory, and should fail. +# TODO(golang.org/issue/32027): currently, it succeeds. +cd needmod +go doc +cd .. + +# 'go doc' of a non-module directory should also succeed. +go doc ./needmod + +# 'go doc' should succeed for standard-library packages. +go doc fmt + +# 'go doc' should fail for a package path outside a module. +! go doc example.com/version +stderr 'doc: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go install' with a version should succeed if all constraints are met. +# See mod_install_pkg_version. +rm $GOPATH/bin +go install example.com/printversion@v0.1.0 +exists $GOPATH/bin/printversion$GOEXE + +# 'go install' should fail if a package argument must be resolved to a module. +! go install example.com/printversion +stderr '^go: ''go install'' requires a version when current directory is not in a module\n\tTry ''go install example.com/printversion@latest'' to install the latest version$' + +# 'go install' should fail if a source file imports a package that must be +# resolved to a module. +! go install ./needmod/needmod.go +stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go install' should succeed with a package in GOROOT. +go install cmd/addr2line +! stderr . + +# 'go run' should fail if a package argument must be resolved to a module. +! go run example.com/printversion +stderr '^no required module provides package example.com/printversion: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + +# 'go run' should fail if a source file imports a package that must be +# resolved to a module. +! go run ./needmod/needmod.go +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$' + + +# 'go fmt' should be able to format files outside of a module. +go fmt needmod/needmod.go + + +# The remainder of the test checks dependencies by linking and running binaries. + +# 'go run' should work with file arguments if they don't import anything +# outside std. +go run ./stdonly/stdonly.go +stdout 'path is command-line-arguments$' +stdout 'main is $' + +# 'go generate' should work with file arguments. +[exec:touch] go generate ./needmod/needmod.go +[exec:touch] exists ./needmod/gen.txt + +# 'go install' should work with file arguments. +go install ./stdonly/stdonly.go + +# 'go test' should work with file arguments. +go test -v ./stdonly/stdonly_test.go +stdout 'stdonly was tested' + +# 'go vet' should work with file arguments. +go vet ./stdonly/stdonly.go + + +-- README.txt -- +There is no go.mod file in the working directory. + +-- needmod/needmod.go -- +//go:generate touch gen.txt + +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, ok := debug.ReadBuildInfo() + if !ok { + panic("missing build info") + } + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} + +-- stdonly/stdonly.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" +) + +func main() { + info, ok := debug.ReadBuildInfo() + if !ok { + panic("missing build info") + } + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} + +-- stdonly/stdonly_test.go -- +package main + +import ( + "fmt" + "testing" +) + +func Test(t *testing.T) { + fmt.Println("stdonly was tested") +} + +-- newgo/newgo.go -- +// Package newgo requires Go 1.14 or newer. +package newgo + +import "io" + +const C = 299_792_458 + +type ReadWriteCloser interface { + io.ReadCloser + io.WriteCloser +} diff --git a/src/cmd/go/testdata/script/mod_overlay.txt b/src/cmd/go/testdata/script/mod_overlay.txt new file mode 100644 index 0000000..da35be6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_overlay.txt @@ -0,0 +1,254 @@ +# Test overlays that affect go.mod files + +# The go.mod file can exist only in the overlay. +cd $WORK/gopath/src/no-go-mod +go list -overlay overlay.json . +stdout example.com/simple + +# Check content of overlaid go.mod is used. +cd $WORK/gopath/src/overlay-go-mod +go list -overlay overlay.json . +stdout use.this/module/name + +# Check content of overlaid go.mod in a replacement module is used. +# The go.mod in the replacement module is missing a requirement +# that the overlay has, so it will fail to list without the overlay. +cd $WORK/gopath/src/overlay-replaced-go-mod +! go list -deps . +go list -deps -overlay overlay.json . + +# Overlaid go.mod is not rewritten by 'go get'. +cd $WORK/gopath/src/get-doesnt-add-dep +cp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod +! go get -overlay overlay.json . +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' +cmp $WORK/overlay/get_doesnt_add_dep_go_mod $WORK/want_go_mod + +# Content of overlaid go.sum is used. +# The go.sum in the module directory has garbage values for its +# hashes, but the overlaid file has the correct values. If +# the correct go.sum is used with the overlay, 'go get .' should +# not report a security error. +cd $WORK/gopath/src/overlay-sum-used +! go get . +stderr 'SECURITY ERROR' +! go mod verify +stderr 'SECURITY ERROR' +go get -overlay overlay.json . +go mod verify -overlay overlay.json +# Overlaid go.sum is not rewritten. +# Copy an incomplete file to the overlay file, and expect an error +# attempting to update the file +cp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go get -overlay overlay.json . +stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums +! go mod tidy -overlay overlay.json +stderr '^go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay$' +cmp incomplete-sum-file $WORK/overlay/overlay-sum-used-correct-sums + +# -overlay works with -modfile. +# There's an empty go.mod file in the directory, and the file alternate.mod is +# overlaid to the true go.mod file, so the -modfile flag and the overlay +# mechanism need to work together to determine the name of the module. +cd $WORK/gopath/src/overlay-and-dash-modfile +go list -modfile=alternate.mod -overlay overlay.json . +stdout 'found.the/module' +# Even with -modfile, overlaid files can't be opened for write. +! go get -modfile=alternate.mod -overlay overlay.json rsc.io/quote +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' + +# Carving out a module by adding an overlaid go.mod file +cd $WORK/gopath/src/carve +go list ./... # without an overlay, hasmod is carved out and nomod isn't +stdout carve/nomod +! stdout carve/hasmod +go list -overlay overlay_carve_module.json ./... # The overlay carves out nomod, leaving nothing +! stdout . +stderr 'matched no packages' +go list -overlay overlay_uncarve_module.json ./... # The overlay uncarves out hasmod +stdout carve/nomod +stdout carve/hasmod + +# Carving out a module by adding an overlaid go.mod file and using +# -modfile to write to that file. +cd $WORK/gopath/src/carve2/nomod +go list -overlay overlay.json all +! stdout ^carve2$ +stdout ^carve2/nomod$ +# Editing go.mod file fails because overlay is read only +! go get -overlay overlay.json rsc.io/quote +stderr '^go: updates to go.mod needed, but go.mod is part of the overlay specified with -overlay$' +! grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod +# Editing go.mod file succeeds because we use -modfile to redirect to same file +go get -overlay overlay.json -modfile $WORK/overlay/carve2-nomod-go.mod rsc.io/quote +grep rsc.io/quote $WORK/overlay/carve2-nomod-go.mod + +-- no-go-mod/file.go -- +package simple +-- no-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/simple_go_mod" + } +} +-- $WORK/overlay/simple_go_mod -- +module example.com/simple +-- overlay-go-mod/file.go -- +package name +-- overlay-go-mod/go.mod -- +module dont.use/this/module/name +-- overlay-go-mod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/use_this_go_mod" + } +} +-- $WORK/overlay/use_this_go_mod -- +module use.this/module/name +-- overlay-replaced-go-mod/go.mod -- +module m + +go 1.15 + +require replaced/mod v1.0.0 +replace replaced/mod v1.0.0 => ../replaced-mod +replace dep/mod v1.0.0 => ../dep-mod +-- overlay-replaced-go-mod/source.go -- +package m + +import "replaced/mod/foo" + +func main() { + foo.f() +} +-- overlay-replaced-go-mod/overlay.json -- +{ + "Replace": { + "../replaced-mod/go.mod": "../../../overlay/replacement_module_go_mod" + } +} +-- replaced-mod/go.mod -- +module replaced/mod +-- replaced-mod/foo/foo.go -- +package foo + +import "dep/mod/foo" + +func f() { foo.g() } +-- dep-mod/go.mod -- +invalid +-- dep-mod/foo/foo.go -- +package foo + +func g() { fmt.Println("hello") } +-- $WORK/overlay/replacement_module_go_mod -- +module replaced/mod + +require dep/mod v1.0.0 + +-- get-doesnt-add-dep/overlay.json -- +{ + "Replace": { + "go.mod": "../../../overlay/get_doesnt_add_dep_go_mod" + } +} +-- get-doesnt-add-dep/p.go -- +package p + +import "dependency/mod" + +func f() { mod.G() } +-- get-doesnt-add-dep-dependency/go.mod -- +module dependency/mod +-- get-doesnt-add-dep-dependency/mod.go -- +package mod + +func G() {} +-- $WORK/overlay/get_doesnt_add_dep_go_mod -- +module get.doesnt/add/dep + +replace dependency/mod v1.0.0 => ../get-doesnt-add-dep-dependency +-- overlay-sum-used/go.mod -- +module overlay.sum/used + +require rsc.io/quote v1.5.0 +-- overlay-sum-used/p.go -- +package p + +import "rsc.io/quote" + +func f() string { + return quote.Hello() +} +-- overlay-sum-used/incomplete-sum-file -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +-- overlay-sum-used/overlay.json -- +{ + "Replace": { + "go.sum": "../../../overlay/overlay-sum-used-correct-sums" + } +} +-- overlay-sum-used/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:garbage+hash +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:garbage+hash +rsc.io/quote v1.5.0 h1:garbage+hash +rsc.io/quote v1.5.0/go.mod h1:garbage+hash +rsc.io/sampler v1.3.0 h1:garbage+hash +rsc.io/sampler v1.3.0/go.mod h1:garbage+hash +-- $WORK/overlay/overlay-sum-used-correct-sums -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/quote v1.5.0/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- overlay-and-dash-modfile/p.go -- +package module +-- overlay-and-dash-modfile/go.mod -- +-- overlay-and-dash-modfile/overlay.json -- +{ + "Replace": { + "alternate.mod": "../../../overlay/overlay-and-dash-modfile-alternate-mod" + } +} +-- $WORK/overlay/overlay-and-dash-modfile-alternate-mod -- +module found.the/module +-- carve/go.mod -- +module carve +-- carve/overlay_carve_module.json -- +{ + "Replace": { + "nomod/go.mod": "../../../overlay/carve-nomod-go-mod" + } +} +-- carve/overlay_uncarve_module.json -- +{ + "Replace": { + "hasmod/go.mod": "" + } +} +-- carve/hasmod/a.go -- +package hasmod +-- carve/hasmod/go.mod -- +module carve/hasmod +-- carve/nomod/b.go -- +package nomod +-- $WORK/overlay/carve-nomod-go-mod -- +module carve/nomod +-- carve2/go.mod -- +module carve2 +-- carve2/p.go -- +package p +-- carve2/nomod/overlay.json -- +{ + "Replace": { + "go.mod": "../../../../overlay/carve2-nomod-go.mod" + } +} +-- carve2/nomod/b.go -- +package nomod +-- $WORK/overlay/carve2-nomod-go.mod -- +module carve2/nomod diff --git a/src/cmd/go/testdata/script/mod_patterns.txt b/src/cmd/go/testdata/script/mod_patterns.txt new file mode 100644 index 0000000..1b4b438 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_patterns.txt @@ -0,0 +1,78 @@ +env GO111MODULE=on +[short] skip + +cd m + +# 'go list all' should list all of the packages used (directly or indirectly) by +# the packages in the main module, but no other packages from the standard +# library or active modules. +# +# 'go list ...' should list packages in all active modules and the standard library. +# +# 'go list example.com/m/...' should list packages in all modules that begin with 'example.com/m/'. +# +# 'go list ./...' should list only packages in the current module, not other active modules. +# +# Warnings about unmatched patterns should only be printed once. +# +# And the go command should be able to keep track of all this! +go list -f '{{.ImportPath}}: {{.Match}}' all ... example.com/m/... ./... ./xyz... +stdout 'example.com/m/useunicode: \[all \.\.\. example.com/m/... ./...\]' +stdout 'example.com/m/useunsafe: \[all \.\.\. example.com/m/... ./...\]' +[cgo] stdout 'example.com/m/useC: \[all \.\.\. example.com/m/... ./...\]' +[!cgo] ! stdout example.com/m/useC +stdout 'example.com/unused/useerrors: \[\.\.\.\]' # but not "all" +stdout 'example.com/m/nested/useencoding: \[\.\.\. example.com/m/...\]' # but NOT "all" or "./..." +stdout '^unicode: \[all \.\.\.\]' +stdout '^unsafe: \[all \.\.\.\]' +stdout 'index/suffixarray: \[\.\.\.\]' +stdout 'cmd/pprof: \[\.\.\.\]' + +stderr -count=1 '^go: warning: "./xyz..." matched no packages$' + +# 'go list ./...' should not try to resolve the main module. +cd ../empty +go list -deps ./... +! stdout . +! stderr 'finding' +stderr -count=1 '^go: warning: "./..." matched no packages' + +# disabling cgo should drop useC +[short] skip +env CGO_ENABLED=0 +go list -f '{{.ImportPath}}: {{.Match}}' all ... example.com/m/... ./... ./xyz... +! stdout example.com/m/useC + +-- m/go.mod -- +module example.com/m + +require example.com/unused v0.0.0 // indirect +replace example.com/unused => ../unused + +require example.com/m/nested v0.0.0 // indirect +replace example.com/m/nested => ../nested + +-- m/useC/useC.go -- +package useC +import _ "C" // "C" is a pseudo-package, not an actual one +-- m/useunicode/useunicode.go -- +package useunicode +import _ "unicode" +-- m/useunsafe/useunsafe.go -- +package useunsafe +import _ "unsafe" + +-- unused/go.mod -- +module example.com/unused +-- unused/useerrors/useerrors.go -- +package useerrors +import _ "errors" + +-- nested/go.mod -- +module example.com/m/nested +-- nested/useencoding/useencoding.go -- +package useencoding +import _ "encoding" + +-- empty/go.mod -- +module example.com/empty diff --git a/src/cmd/go/testdata/script/mod_patterns_vendor.txt b/src/cmd/go/testdata/script/mod_patterns_vendor.txt new file mode 100644 index 0000000..b4dc401 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_patterns_vendor.txt @@ -0,0 +1,28 @@ +env GO111MODULE=on + +go list -mod=vendor example.com/... +stdout ^example.com/x$ +stdout ^example.com/x/y$ +! stdout ^example.com/x/vendor + +-- go.mod -- +module example.com/m + +-- vendor/modules.txt -- +# example.com/x v0.0.0 +example.com/x +# example.com/x/y v0.1.0 +example.com/x/y + +-- vendor/example.com/x/go.mod -- +module example.com/x +-- vendor/example.com/x/x.go -- +package x + +-- vendor/example.com/x/y/go.mod -- +module example.com/x/y +-- vendor/example.com/x/y/y.go -- +package y + +-- vendor/example.com/x/vendor/z/z.go -- +package z diff --git a/src/cmd/go/testdata/script/mod_permissions.txt b/src/cmd/go/testdata/script/mod_permissions.txt new file mode 100644 index 0000000..77e2508 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_permissions.txt @@ -0,0 +1,57 @@ +# Regression test for golang.org/issue/34634: permissions for the go.sum and +# go.mod files should be preserved when overwriting them. + +env GO111MODULE=on +[short] skip + +# Skip platforms that do not have Unix-style file permissions. +[windows] skip +[plan9] skip + +chmod 0640 go.mod +chmod 0604 go.sum +go mod edit -module=golang.org/issue/34634 + +go get +cmp go.mod go.mod.want +cmp go.sum go.sum.want + +go run . +stdout 'go.mod: 0640' +stdout 'go.sum: 0604' + +-- read_perm.go -- +package main + +import ( + "fmt" + "os" + _ "rsc.io/sampler" +) + +func main() { + for _, name := range []string{"go.mod", "go.sum"} { + fi, err := os.Stat(name) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", err) + continue + } + fmt.Printf("%s: 0%o\n", name, fi.Mode().Perm()) + } +} +-- go.mod -- +module TODO + +go 1.14 +-- go.sum -- +-- go.mod.want -- +module golang.org/issue/34634 + +go 1.14 + +require rsc.io/sampler v1.99.99 +-- go.sum.want -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/sampler v1.99.99 h1:iMG9lbEG/8MdeR4lgL+Q8IcwbLNw7ijW7fTiK8Miqts= +rsc.io/sampler v1.99.99/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_prefer_compatible.txt b/src/cmd/go/testdata/script/mod_prefer_compatible.txt new file mode 100644 index 0000000..8e88997 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_prefer_compatible.txt @@ -0,0 +1,65 @@ +# Regression test for golang.org/issue/34189 and golang.org/issue/34165: +# @latest, @upgrade, and @patch should prefer compatible versions over +# +incompatible ones, even if offered by a proxy. + +[!net] skip + +env GO111MODULE=on +env GOPROXY= +env GOSUMDB= + +# github.com/russross/blackfriday v2.0.0+incompatible exists, +# and should be resolved if we ask for v2.0 explicitly. + +go list -m github.com/russross/blackfriday@v2.0 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# blackfriday v1.5.2 has a go.mod file, so v1.5.2 should be preferred over +# v2.0.0+incompatible when resolving latest, upgrade, and patch. + +go list -m github.com/russross/blackfriday@latest +stdout '^github.com/russross/blackfriday v1\.' + +go list -m github.com/russross/blackfriday@upgrade +stdout '^github.com/russross/blackfriday v1\.' + +! go list -m github.com/russross/blackfriday@patch +stderr '^go: github.com/russross/blackfriday@patch: can''t query version "patch" of module github.com/russross/blackfriday: no existing version is required$' + +# If we're fetching directly from version control, ignored +incompatible +# versions should also be omitted by 'go list'. + +# (Note that they may still be included in results from a proxy: in proxy mode, +# we would need to fetch the whole zipfile for the latest compatible version in +# order to determine whether it contains a go.mod file, and part of the point of +# the proxy is to avoid fetching unnecessary data.) + +[!exec:git] stop +env GOPROXY=direct + +go list -versions -m github.com/russross/blackfriday github.com/russross/blackfriday +stdout '^github.com/russross/blackfriday v1\.5\.1 v1\.5\.2' # and possibly others +! stdout ' v2\.' + +# However, if the latest compatible version does not include a go.mod file, +# +incompatible versions should still be listed, as they may still reflect the +# intent of the module author. + +go list -versions -m github.com/rsc/legacytest +stdout '^github.com/rsc/legacytest v1\.0\.0 v1\.1\.0-pre v1\.2\.0 v2\.0\.0\+incompatible' + +# If we're fetching directly from version control, asking for a commit hash +# corresponding to a +incompatible version should continue to produce the +# +incompatible version tagged for that commit, even if it is no longer listed. + +go list -m github.com/russross/blackfriday@cadec560ec52 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# Similarly, requesting an untagged commit should continue to produce a +incompatible +# pseudo-version. + +go list -m github.com/rsc/legacytest@7303f7796364 +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.20180717164253-7303f7796364\+incompatible$' + +-- go.mod -- +module github.com/golang.org/issue/34165 diff --git a/src/cmd/go/testdata/script/mod_proxy_errors.txt b/src/cmd/go/testdata/script/mod_proxy_errors.txt new file mode 100644 index 0000000..9cd1a82 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_errors.txt @@ -0,0 +1,19 @@ +[!net] skip + +env GO111MODULE=on +env GOSUMDB=off +env GOPROXY=direct + +# Server responses should be truncated to some reasonable number of lines. +# (For now, exactly eight.) +! go list -m vcs-test.golang.org/auth/ormanylines@latest +stderr '\tserver response:\n(.|\n)*\tline 8\n\t\[Truncated: too many lines.\]$' + +# Server responses should be truncated to some reasonable number of characters. +! go list -m vcs-test.golang.org/auth/oronelongline@latest +! stderr 'blah{40}' +stderr '\tserver response: \[Truncated: too long\.\]$' + +# Responses from servers using the 'mod' protocol should be propagated. +! go list -m vcs-test.golang.org/go/modauth404@latest +stderr '\tserver response: File\? What file\?' diff --git a/src/cmd/go/testdata/script/mod_proxy_https.txt b/src/cmd/go/testdata/script/mod_proxy_https.txt new file mode 100644 index 0000000..a5e28dd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_https.txt @@ -0,0 +1,20 @@ +env GO111MODULE=on + +# GOPROXY file paths must provide the "file://" prefix explicitly. +env GOPROXY=$WORK/proxydir +! go list -versions -m golang.org/x/text +stderr 'invalid proxy URL.*proxydir' + +[!net] stop + +# GOPROXY HTTPS paths may elide the "https://" prefix. +# (See golang.org/issue/32191.) +env GOPROXY=proxy.golang.org +env GOSUMDB= +go list -versions -m golang.org/x/text + +-- go.mod -- +module example.com +go 1.13 +-- $WORK/proxydir/README.md -- +This proxy contains no data. diff --git a/src/cmd/go/testdata/script/mod_proxy_invalid.txt b/src/cmd/go/testdata/script/mod_proxy_invalid.txt new file mode 100644 index 0000000..63980b8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_invalid.txt @@ -0,0 +1,8 @@ +env GO111MODULE=on +env GOPROXY=$GOPROXY/invalid + +! go list -m rsc.io/quote@latest +stderr '^go: module rsc.io/quote: invalid response from proxy "'$GOPROXY'": invalid character ''i'' looking for beginning of value$' + +! go list -m rsc.io/quote@1.5.2 +stderr '^go: rsc.io/quote@1.5.2: invalid version: invalid response from proxy "'$GOPROXY'": invalid character ''i'' looking for beginning of value$' diff --git a/src/cmd/go/testdata/script/mod_proxy_list.txt b/src/cmd/go/testdata/script/mod_proxy_list.txt new file mode 100644 index 0000000..849cf2c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_proxy_list.txt @@ -0,0 +1,37 @@ +env GO111MODULE=on +env proxy=$GOPROXY + +# Proxy that can't serve should fail. +env GOPROXY=$proxy/404 +! go get rsc.io/quote@v1.0.0 +stderr '404 Not Found' + +# get should walk down the proxy list past 404 and 410 responses. +env GOPROXY=$proxy/404,$proxy/410,$proxy +go get rsc.io/quote@v1.1.0 + +# get should not walk past other 4xx errors if proxies are separated with ','. +env GOPROXY=$proxy/403,$proxy +! go get rsc.io/quote@v1.2.0 +stderr 'reading.*/403/rsc.io/.*: 403 Forbidden' + +# get should not walk past non-4xx errors if proxies are separated with ','. +env GOPROXY=$proxy/500,$proxy +! go get rsc.io/quote@v1.3.0 +stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error' + +# get should walk past other 4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/403|https://0.0.0.0|$proxy +go get rsc.io/quote@v1.2.0 + +# get should walk past non-4xx errors if proxies are separated with '|'. +env GOPROXY=$proxy/500|https://0.0.0.0|$proxy +go get rsc.io/quote@v1.3.0 + +# get should return the final error if that's all we have. +env GOPROXY=$proxy/404,$proxy/410 +! go get rsc.io/quote@v1.4.0 +stderr 'reading.*/410/rsc.io/.*: 410 Gone' + +-- go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_pseudo_cache.txt b/src/cmd/go/testdata/script/mod_pseudo_cache.txt new file mode 100644 index 0000000..dd89614 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_pseudo_cache.txt @@ -0,0 +1,29 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Regression test for golang.org/issue/27171: after resolving an older +# pseudo-version of a commit, future resolution of that commit by hash should +# choose the highest appropriate pseudo-version instead of the cached one. + +go mod download -json golang.org/x/text@v0.0.0-20171215141712-a1b916ed6726 +stdout '"Version": "v0.0.0-20171215141712-a1b916ed6726",' + +# If GOPROXY is 'off', lookups should use whatever pseudo-version is available. +env GOPROXY=off +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.0.0-20171215141712-a1b916ed6726",' + +# If we can re-resolve the commit to a pseudo-version, fetching the commit by +# hash should use the highest such pseudo-version appropriate to the commit. +env GOPROXY=direct +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.3.1-0.20171215141712-a1b916ed6726",' + +# If GOPROXY is 'off', lookups should use the highest pseudo-version in the cache. +env GOPROXY=off +go mod download -json golang.org/x/text@a1b916ed6726 +stdout '"Version": "v0.3.1-0.20171215141712-a1b916ed6726",' diff --git a/src/cmd/go/testdata/script/mod_query.txt b/src/cmd/go/testdata/script/mod_query.txt new file mode 100644 index 0000000..3758732 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query.txt @@ -0,0 +1,43 @@ +env GO111MODULE=on + +# TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands +# below depend on the build list. + +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' + +# Latest rsc.io/quote should be v1.5.2, not v1.5.3-pre1. +go list -m rsc.io/quote@latest +stdout 'rsc.io/quote v1.5.2$' + +# Same for rsc.io/quote@v1 and rsc.io/quote@v1.5 (with no patch version). +go list -m rsc.io/quote@v1 +stdout 'rsc.io/quote v1.5.2$' +go list -m rsc.io/quote@v1.5 +stdout 'rsc.io/quote v1.5.2$' + +# We should fall back to prereleases if no release tags match... +go list -m rsc.io/quote@>v1.5.2 +stdout 'rsc.io/quote v1.5.3-pre1$' + +# ...but prefer release versions when given the option. +go list -m rsc.io/quote@<v1.5.4 +stdout 'rsc.io/quote v1.5.2$' + +! go list -m rsc.io/quote@>v1.5.3 +stderr 'go: module rsc.io/quote: no matching versions for query ">v1.5.3"' + +go list -m -e -f '{{.Error.Err}}' rsc.io/quote@>v1.5.3 +stdout 'no matching versions for query ">v1.5.3"' + +-- go.mod -- +module x +require rsc.io/quote v1.0.0 + +-- go.sum -- +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_query_empty.txt b/src/cmd/go/testdata/script/mod_query_empty.txt new file mode 100644 index 0000000..1c39eae --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_empty.txt @@ -0,0 +1,73 @@ +env GO111MODULE=on +env GOSUMDB=off + +go mod download example.com/join@v1.1.0 + +# If the proxy serves a bogus result for the @latest version, +# reading that version should cause 'go get' to fail. +env GOPROXY=file:///$WORK/badproxy +cp go.mod.orig go.mod +! go get example.com/join/subpkg +stderr 'go: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' + +# If @v/list is empty, the 'go' command should still try to resolve +# other module paths. +env GOPROXY=file:///$WORK/emptysub +cp go.mod.orig go.mod +go get example.com/join/subpkg +go list -m example.com/join/... +! stdout 'example.com/join/subpkg' +stdout 'example.com/join v1.1.0' + +# If @v/list includes a version that the proxy does not actually serve, +# that version is treated as nonexistent. +env GOPROXY=file:///$WORK/notfound +cp go.mod.orig go.mod +go get example.com/join/subpkg +go list -m example.com/join/... +! stdout 'example.com/join/subpkg' +stdout 'example.com/join v1.1.0' + +# If the proxy provides an empty @v/list but rejects @latest with +# some other explicit error (for example, a "permission denied" error), +# that error should be reported to the user (and override a successful +# result for other possible module paths). +# +# Depending on how the specific platform enforces permissions, the 'go get' may +# fail either due to the intended permission error or due to a parse error. +# We accept either failure message. +env GOPROXY=file:///$WORK/gatekeeper +chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest +cp go.mod.orig go.mod +! go get example.com/join/subpkg +stderr 'go: module example.com/join/subpkg: (invalid response from proxy ".+": invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' + +-- go.mod.orig -- +module example.com/othermodule +go 1.13 +-- $WORK/badproxy/example.com/join/subpkg/@v/list -- +v0.0.0-20190624000000-123456abcdef +-- $WORK/badproxy/example.com/join/subpkg/@v/v0.0.0-20190624000000-123456abcdef.info -- +This file is not valid JSON. +-- $WORK/badproxy/example.com/join/@v/list -- +v1.1.0 +-- $WORK/badproxy/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/emptysub/example.com/join/subpkg/@v/list -- +-- $WORK/emptysub/example.com/join/@v/list -- +v1.1.0 +-- $WORK/emptysub/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/notfound/example.com/join/subpkg/@v/list -- +v1.0.0-does-not-exist +-- $WORK/notfound/example.com/join/@v/list -- +v1.1.0 +-- $WORK/notfound/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} +-- $WORK/gatekeeper/example.com/join/subpkg/@v/list -- +-- $WORK/gatekeeper/example.com/join/subpkg/@latest -- +ERROR: Latest version is forbidden. +-- $WORK/gatekeeper/example.com/join/@v/list -- +v1.1.0 +-- $WORK/gatekeeper/example.com/join/@v/v1.1.0.info -- +{"Version": "v1.1.0"} diff --git a/src/cmd/go/testdata/script/mod_query_exclude.txt b/src/cmd/go/testdata/script/mod_query_exclude.txt new file mode 100644 index 0000000..f76b20c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_exclude.txt @@ -0,0 +1,46 @@ +env GO111MODULE=on + +# list excluded version +go list -modfile=go.exclude.mod -m rsc.io/quote@v1.5.0 +stdout '^rsc.io/quote v1.5.0$' + +# list versions should not print excluded versions +go list -m -versions rsc.io/quote +stdout '\bv1.5.0\b' +go list -modfile=go.exclude.mod -m -versions rsc.io/quote +! stdout '\bv1.5.0\b' + +# list query with excluded version +go list -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.0$' +go list -modfile=go.exclude.mod -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.1$' + +# get excluded version +cp go.exclude.mod go.exclude.mod.orig +! go get -modfile=go.exclude.mod rsc.io/quote@v1.5.0 +stderr '^go: rsc.io/quote@v1.5.0: excluded by go.mod$' + +# get non-excluded version +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod rsc.io/quote@v1.5.1 +stderr 'rsc.io/quote v1.5.1' + +# get query with excluded version +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod rsc.io/quote@>=v1.5 +go list -modfile=go.exclude.mod -m ...quote +stdout 'rsc.io/quote v1.5.[1-9]' + +-- go.mod -- +module x + +-- go.exclude.mod -- +module x + +exclude rsc.io/quote v1.5.0 + +-- x.go -- +package x +import _ "rsc.io/quote" + diff --git a/src/cmd/go/testdata/script/mod_query_main.txt b/src/cmd/go/testdata/script/mod_query_main.txt new file mode 100644 index 0000000..2a2fa42 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_query_main.txt @@ -0,0 +1,43 @@ +# 'go mod download' can download specific versions of the main module. +go mod download rsc.io/quote@5d9f230b +go mod download rsc.io/quote@v1.5.2 +go mod download rsc.io/quote@latest + +# 'go mod download' will not download @upgrade or @patch, since they always +# resolve to the main module. +go mod download rsc.io/quote@upgrade +stderr '^go: skipping download of rsc.io/quote@upgrade that resolves to the main module$' +go mod download rsc.io/quote@patch +stderr '^go: skipping download of rsc.io/quote@patch that resolves to the main module$' + +# 'go list -m' can show a version of the main module. +go list -m rsc.io/quote@5d9f230b +stdout '^rsc.io/quote v0.0.0-20180710144737-5d9f230bcfba$' +go list -m rsc.io/quote@v1.5.2 +stdout '^rsc.io/quote v1.5.2$' +go list -m rsc.io/quote@latest +stdout '^rsc.io/quote v1.5.2$' + +# 'go list -m -versions' shows available versions. +go list -m -versions rsc.io/quote +stdout '^rsc.io/quote.*v1.5.2' + +# 'go list -m' resolves @upgrade and @patch to the main module. +go list -m rsc.io/quote@upgrade +stdout '^rsc.io/quote$' +go list -m rsc.io/quote@patch +stdout '^rsc.io/quote$' + +# 'go get' will not attempt to upgrade the main module to any specific version. +# See also: mod_get_main.txt. +! go get rsc.io/quote@5d9f230b +stderr '^go: can''t request version "5d9f230b" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@v1.5.2 +stderr '^go: can''t request version "v1.5.2" of the main module \(rsc.io/quote\)$' +! go get rsc.io/quote@latest +stderr '^go: can''t request version "latest" of the main module \(rsc.io/quote\)$' + +-- go.mod -- +module rsc.io/quote + +go 1.16 diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt new file mode 100644 index 0000000..9e950c3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_readonly.txt @@ -0,0 +1,131 @@ +env GO111MODULE=on +[short] skip + +# -mod=readonly must not resolve missing modules nor update go.mod +env GOFLAGS=-mod=readonly +go mod edit -fmt +cp go.mod go.mod.empty +! go list all +stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly' +! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one. +cmp go.mod go.mod.empty + +# -mod=readonly should be set by default. +env GOFLAGS= +! go list all +stderr '^x.go:2:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc\.io/quote$' +cmp go.mod go.mod.empty + +env GOFLAGS=-mod=readonly + +# update go.mod - go get allowed +go get rsc.io/quote +grep rsc.io/quote go.mod + +# update go.mod - go mod tidy allowed +cp go.mod.empty go.mod +go mod tidy +cp go.mod go.mod.tidy + +# -mod=readonly must succeed once go.mod is up-to-date... +go list all + +# ... even if it needs downloads +go clean -modcache +go list all + +# -mod=readonly must not cause 'go list -m' to fail. +# (golang.org/issue/36478) +go list -m all +! stderr 'cannot query module' + +# -mod=readonly should reject inconsistent go.mod files +# (ones that would be rewritten). +go get rsc.io/sampler@v1.2.0 +go mod edit -require rsc.io/quote@v1.5.2 +cp go.mod go.mod.inconsistent +! go list +stderr 'go: updates to go.mod needed, disabled by -mod=readonly' +cmp go.mod go.mod.inconsistent + +# We get a different message when -mod=readonly is used by default. +env GOFLAGS= +! go list +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy' + +# However, it should not reject files missing a 'go' directive, +# since that was not always required. +cp go.mod.nogo go.mod +go list all +cmp go.mod go.mod.nogo + +# Nor should it reject files with redundant (not incorrect) +# requirements. +cp go.mod.redundant go.mod +go list all +cmp go.mod go.mod.redundant + +cp go.mod.indirect go.mod +go list all +cmp go.mod go.mod.indirect + + +# If we identify a missing package as a dependency of some other package in the +# main module, we should suggest 'go mod tidy' instead of resolving it. + +cp go.mod.untidy go.mod +! go list all +stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + +! go list -deps . +stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + +# However, if we didn't see an import from the main module, we should suggest +# 'go get' instead, because we don't know whether 'go mod tidy' would add it. +! go list rsc.io/quote +stderr '^no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$' + + +-- go.mod -- +module m + +go 1.16 + +-- x.go -- +package x +import _ "rsc.io/quote" +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.redundant -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.indirect -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.untidy -- +module m + +go 1.16 + +require ( + rsc.io/sampler v1.3.0 // indirect +) diff --git a/src/cmd/go/testdata/script/mod_replace.txt b/src/cmd/go/testdata/script/mod_replace.txt new file mode 100644 index 0000000..26b1551 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace.txt @@ -0,0 +1,129 @@ +env GO111MODULE=on +[short] skip + +cp go.mod go.mod.orig + +# Make sure the test builds without replacement. +go build -mod=mod -o a1.exe . +exec ./a1.exe +stdout 'Don''t communicate by sharing memory' + +# Modules can be replaced by local packages. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3 +go build -o a2.exe . +exec ./a2.exe +stdout 'Concurrency is not parallelism.' + +# The module path of the replacement doesn't need to match. +# (For example, it could be a long-running fork with its own import path.) +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/not-rsc.io/quote/v3 +go build -o a3.exe . +exec ./a3.exe +stdout 'Clear is better than clever.' + +# However, the same module can't be used as two different paths. +cp go.mod.orig go.mod +go mod edit -replace=not-rsc.io/quote/v3@v3.0.0=rsc.io/quote/v3@v3.0.0 -require=not-rsc.io/quote/v3@v3.0.0 +! go build -o a4.exe . +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +# Modules that do not (yet) exist upstream can be replaced too. +cp go.mod.orig go.mod +go mod edit -replace=not-rsc.io/quote/v3@v3.1.0=./local/rsc.io/quote/v3 +go build -mod=mod -o a5.exe ./usenewmodule +! stderr 'finding not-rsc.io/quote/v3' +grep 'not-rsc.io/quote/v3 v3.1.0' go.mod +exec ./a5.exe +stdout 'Concurrency is not parallelism.' + +# Error messages for modules not found in replacements should +# indicate the replacement module. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3 +! go get rsc.io/quote/v3/missing-package +stderr 'module rsc.io/quote/v3@upgrade found \(v3.0.0, replaced by ./local/rsc.io/quote/v3\), but does not contain package' + +# The reported Dir and GoMod for a replaced module should be accurate. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=not-rsc.io/quote@v0.1.0-nomod +go mod download rsc.io/quote/v3 +go list -m -f '{{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{with .Replace}} => {{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' rsc.io/quote/v3 +stdout '^rsc.io/quote/v3 v3.0.0 '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod => not-rsc.io/quote v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod$' + +-- go.mod -- +module quoter + +require rsc.io/quote/v3 v3.0.0 + +-- main.go -- +package main + +import ( + "fmt" + "rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} + +-- usenewmodule/main.go -- +package main + +import ( + "fmt" + "not-rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} + +-- local/rsc.io/quote/v3/go.mod -- +module rsc.io/quote/v3 + +require rsc.io/sampler v1.3.0 + +-- local/rsc.io/quote/v3/quote.go -- +// Copyright 2018 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 quote collects pithy sayings. +package quote + +import "rsc.io/sampler" + +// Hello returns a greeting. +func HelloV3() string { + return sampler.Hello() +} + +// Glass returns a useful phrase for world travelers. +func GlassV3() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a REPLACED Go proverb. +func GoV3() string { + return "Concurrency is not parallelism." +} + +// Opt returns a optimization truth. +func OptV3() string { + // Wisdom from ken. + return "If a program is too slow, it must have a loop." +} + +-- local/not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +-- local/not-rsc.io/quote/v3/quote.go -- +package quote + +func GoV3() string { + return "Clear is better than clever." +} diff --git a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt new file mode 100644 index 0000000..8cb034c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt @@ -0,0 +1,83 @@ +# Regression test for golang.org/issue/34254: +# a clone of gopkg.in/[…].vN should be replaceable by +# a fork hosted at corp.example.com/[…]/vN, +# even if there is an explicit go.mod file containing the +# gopkg.in path. + +skip 'skipping test that depends on an unreliable third-party server; see https://go.dev/issue/54503' + # TODO(#54043): Make this test hermetic and re-enable it. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off +env GOFLAGS=-mod=mod + +# Replacing gopkg.in/[…].vN with a repository with a root go.mod file +# specifying […].vN and a compatible version should succeed, even if +# the replacement path is not a gopkg.in path. +cd 4-to-4 +go list -m gopkg.in/src-d/go-git.v4 + +# Previous versions of the "go" command accepted v0 and v1 pseudo-versions +# as replacements for gopkg.in/[…].v4. +# As a special case, we continue to accept those. + +cd ../4-to-0 +go list -m gopkg.in/src-d/go-git.v4 + +cd ../4-to-1 +go list -m gopkg.in/src-d/go-git.v4 + +cd ../4-to-incompatible +go list -m gopkg.in/src-d/go-git.v4 + +# A mismatched gopkg.in path should not be able to replace a different major version. +cd ../3-to-gomod-4 +! go list -m gopkg.in/src-d/go-git.v3 +stderr '^go: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$' + +-- 4-to-4/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1 +-- 4-to-1/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v1.0.1-0.20190801152248-0d1a009cbb60 +-- 4-to-0/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v0.0.0-20190801152248-0d1a009cbb60 +-- 4-to-incompatible/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git v4.6.0+incompatible +-- 3-to-gomod-4/go.mod -- +module golang.org/issue/34254 +go 1.13 + +require gopkg.in/src-d/go-git.v3 v3.2.0 + +// This replacement has a go.mod file declaring its path to be +// gopkg.in/src-d/go-git.v4, so it cannot be used as a replacement for v3. +replace gopkg.in/src-d/go-git.v3 v3.2.0 => gopkg.in/src-d/go-git.v3 v3.0.0-20190801152248-0d1a009cbb60 diff --git a/src/cmd/go/testdata/script/mod_replace_import.txt b/src/cmd/go/testdata/script/mod_replace_import.txt new file mode 100644 index 0000000..7bf3a86 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_import.txt @@ -0,0 +1,144 @@ +env GO111MODULE=on + +# 'go list' should not add requirements even if they can be resolved locally. +cp go.mod go.mod.orig +! go list all +cmp go.mod go.mod.orig + +# 'go list' should resolve imports using replacements. +go get +go list all +stdout 'example.com/a/b$' +stdout 'example.com/x/v3$' +stdout 'example.com/y/z/w$' +stdout 'example.com/v' + +# The selected modules should prefer longer paths, +# but should try shorter paths if needed. +# Modules with a major-version suffix should have a corresponding pseudo-version. +# Replacements that specify a version should use the latest such version. +go list -m all +stdout 'example.com/a/b v0.0.0-00010101000000-000000000000 => ./b' +stdout 'example.com/y v0.0.0-00010101000000-000000000000 => ./y' +stdout 'example.com/x/v3 v3.0.0-00010101000000-000000000000 => ./v3' +stdout 'example.com/v v1.12.0 => ./v12' + +# The go command should print an informative error when the matched +# module does not contain a package. +# TODO(#26909): Ideally these errors should include line numbers for the imports within the main module. +cd fail +! go mod tidy +stderr '^localhost.fail imports\n\tw: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' +stderr '^localhost.fail imports\n\tnonexist: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' + +-- go.mod -- +module example.com/m + +replace ( + example.com/a => ./a + example.com/a/b => ./b +) + +replace ( + example.com/x => ./x + example.com/x/v3 => ./v3 +) + +replace ( + example.com/y/z/w => ./w + example.com/y => ./y +) + +replace ( + example.com/v v1.11.0 => ./v11 + example.com/v v1.12.0 => ./v12 + example.com/v => ./v +) + +replace ( + example.com/i v2.0.0+incompatible => ./i2 +) + +-- m.go -- +package main +import ( + _ "example.com/a/b" + _ "example.com/x/v3" + _ "example.com/y/z/w" + _ "example.com/v" + _ "example.com/i" +) +func main() {} + +-- a/go.mod -- +module a.localhost +-- a/a.go -- +package a +-- a/b/b.go-- +package b + +-- b/go.mod -- +module a.localhost/b +-- b/b.go -- +package b + +-- x/go.mod -- +module x.localhost +-- x/x.go -- +package x +-- x/v3.go -- +package v3 +import _ "x.localhost/v3" + +-- v3/go.mod -- +module x.localhost/v3 +-- v3/x.go -- +package x + +-- w/go.mod -- +module w.localhost +-- w/skip/skip.go -- +// Package skip is nested below nonexistent package w. +package skip + +-- y/go.mod -- +module y.localhost +-- y/z/w/w.go -- +package w + +-- v12/go.mod -- +module v.localhost +-- v12/v.go -- +package v + +-- v11/go.mod -- +module v.localhost +-- v11/v.go -- +package v + +-- v/go.mod -- +module v.localhost +-- v/v.go -- +package v + +-- i2/go.mod -- +module example.com/i +-- i2/i.go -- +package i + +-- fail/m.go -- +package main + +import ( + _ "w" + _ "nonexist" +) + +func main() {} + +-- fail/go.mod -- +module localhost.fail + +replace w => ../w + +replace nonexist v0.1.0 => ../nonexist diff --git a/src/cmd/go/testdata/script/mod_replace_readonly.txt b/src/cmd/go/testdata/script/mod_replace_readonly.txt new file mode 100644 index 0000000..5c1226b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_replace_readonly.txt @@ -0,0 +1,62 @@ +# Check that with -mod=readonly, when we load a package in a module that is +# replaced but not required, we emit an error with the command to add the +# requirement. +# Verifies golang.org/issue/41416, golang.org/issue/41577. +cp go.mod go.mod.orig + +# Replace all versions of a module without requiring it. +# With -mod=mod, we'd add a requirement for a "zero" pseudo-version, but we +# can't in readonly mode, since its go.mod may alter the build list. +go mod edit -replace rsc.io/quote=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote$' +go get rsc.io/quote +cmp go.mod go.mod.latest +go list rsc.io/quote +cp go.mod.orig go.mod + +# Same test with a specific version. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.0.0-doesnotexist$' +go get rsc.io/quote@v1.0.0-doesnotexist +cmp go.mod go.mod.specific +go list rsc.io/quote +cp go.mod.orig go.mod + +# If there are multiple versions, the highest is suggested. +go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote +go mod edit -replace rsc.io/quote@v1.1.0-doesnotexist=./quote +! go list rsc.io/quote +stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.1.0-doesnotexist$' + +-- go.mod -- +module m + +go 1.16 +-- go.mod.latest -- +module m + +go 1.16 + +replace rsc.io/quote => ./quote + +require rsc.io/quote v1.5.2 // indirect +-- go.mod.specific -- +module m + +go 1.16 + +replace rsc.io/quote v1.0.0-doesnotexist => ./quote + +require rsc.io/quote v1.0.0-doesnotexist // indirect +-- use.go -- +package use + +import _ "rsc.io/quote" +-- quote/go.mod -- +module rsc.io/quote + +go 1.16 +-- quote/quote.go -- +package quote diff --git a/src/cmd/go/testdata/script/mod_require_exclude.txt b/src/cmd/go/testdata/script/mod_require_exclude.txt new file mode 100644 index 0000000..0946dbf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_require_exclude.txt @@ -0,0 +1,96 @@ +# build with no newer version to satisfy exclude +env GO111MODULE=on +cp go.mod go.mod.orig + +# With the selected version excluded, commands that query that version without +# updating go.mod should fail. + +! go list -mod=readonly -m all +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go: updates to go.mod needed, disabled by -mod=readonly; to update it:\n\tgo mod tidy$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +! go list -mod=vendor -m rsc.io/sampler +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go: updates to go.mod needed, disabled by -mod=vendor; to update it:\n\tgo mod tidy$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +# The failure message should be clear when -mod=vendor is implicit. + +go mod edit -go=1.14 +! go list -m rsc.io/sampler +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go: updates to go.mod needed, disabled by -mod=vendor\n\t\(Go version in go.mod is at least 1.14 and vendor directory exists\.\)\n\tto update it:\n\tgo mod tidy$' +! stdout '^rsc.io/sampler v1.99.99' +go mod edit -go=1.13 +cmp go.mod go.mod.orig + + +# With the selected version excluded, commands that load only modules should +# drop the excluded module. + +go list -m -mod=mod all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x$' +! stdout '^rsc.io/sampler' +cmp go.mod go.moddrop + +# With the latest version excluded, 'go list' should resolve needed packages +# from the next-highest version. + +cp go.mod.orig go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x $' +! stdout '^rsc.io/sampler v1.99.99' +stdout '^rsc.io/sampler v1.3.0' + +# build with newer version available +cp go.mod2 go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/quote v1\.5\.1$' +stdout 'rsc.io/quote v1.5.2' + +# build with excluded newer version +cp go.mod3 go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +! stderr '^go: dropping requirement' +stdout 'rsc.io/quote v1.5.1' + +-- x.go -- +package x +import _ "rsc.io/quote" + +-- go.mod -- +module x + +go 1.13 + +exclude rsc.io/sampler v1.99.99 + +require rsc.io/sampler v1.99.99 +-- vendor/modules.txt -- +# rsc.io/sampler v1.99.99 +## explicit +-- go.moddrop -- +module x + +go 1.13 + +exclude rsc.io/sampler v1.99.99 +-- go.mod2 -- +module x + +go 1.13 + +exclude rsc.io/quote v1.5.1 +require rsc.io/quote v1.5.1 +-- go.mod3 -- +module x + +go 1.13 + +exclude rsc.io/quote v1.5.2 +require rsc.io/quote v1.5.1 diff --git a/src/cmd/go/testdata/script/mod_retention.txt b/src/cmd/go/testdata/script/mod_retention.txt new file mode 100644 index 0000000..9d30026 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retention.txt @@ -0,0 +1,150 @@ +# Regression test for golang.org/issue/34822: the 'go' command should prefer not +# to update the go.mod file if the changes only affect formatting, and should only +# remove redundant requirements in 'go mod tidy'. + +env GO111MODULE=on +[short] skip + +# Control case: verify that go.mod.tidy is actually tidy. +cp go.mod.tidy go.mod +go list -mod=mod all +cmp go.mod go.mod.tidy + + +# If the only difference in the go.mod file is the line endings, +# it should not be overwritten automatically. +cp go.mod.crlf go.mod +go list all +cmp go.mod go.mod.crlf + +# However, 'go mod tidy' should fix whitespace even if there are no other changes. +go mod tidy +cmp go.mod go.mod.tidy + + +# Out-of-order requirements should not be overwritten automatically... +cp go.mod.unsorted go.mod +go list all +cmp go.mod go.mod.unsorted + +# ...but 'go mod edit -fmt' should sort them. +go mod edit -fmt +cmp go.mod go.mod.tidy + + +# "// indirect" comments should be removed if direct dependencies are seen. +# changes. +cp go.mod.indirect go.mod +go list -mod=mod all +cmp go.mod go.mod.tidy + +# "// indirect" comments should be added if appropriate. +# TODO(#42504): add case for 'go list -mod=mod -tags=any all' when -tags=any +# is supported. Only a command that loads "all" without build constraints +# (except "ignore") has enough information to add "// indirect" comments. +# 'go mod tidy' and 'go mod vendor' are the only commands that do that, +# but 'go mod vendor' cannot write go.mod. +cp go.mod.toodirect go.mod +go list all +cmp go.mod go.mod.toodirect + + +# Redundant requirements should be preserved... +cp go.mod.redundant go.mod +go list all +cmp go.mod go.mod.redundant +go mod vendor +cmp go.mod go.mod.redundant +rm -r vendor + +# ...except by 'go mod tidy'. +go mod tidy +cmp go.mod go.mod.tidy + + +# A missing "go" version directive should be added. +# However, that should not remove other redundant requirements. +# In fact, it may *add* redundant requirements due to activating lazy loading. +cp go.mod.nogo go.mod +go list -mod=mod all +cmpenv go.mod go.mod.addedgo + + +-- go.mod.tidy -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- x.go -- +package x +import _ "rsc.io/quote" +-- go.mod.crlf -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.unsorted -- +module m + +go 1.14 + +require ( + rsc.io/testonly v1.0.0 // indirect + rsc.io/quote v1.5.2 +) +-- go.mod.indirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.toodirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 +) +-- go.mod.redundant -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.addedgo -- +module m + +go $goversion + +require rsc.io/quote v1.5.2 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) diff --git a/src/cmd/go/testdata/script/mod_retract.txt b/src/cmd/go/testdata/script/mod_retract.txt new file mode 100644 index 0000000..37aae48 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract.txt @@ -0,0 +1,45 @@ +cp go.mod go.mod.orig + +# 'go list pkg' does not report an error when a retracted version is used. +go list -e -f '{{if .Error}}{{.Error}}{{end}}' ./use +! stdout . +cmp go.mod go.mod.orig + +# Nor does 'go build'. +[!short] go build ./use +[!short] ! stderr . +[!short] cmp go.mod go.mod.orig + +# Neither 'go list' nor 'go build' should download go.mod from the version +# that would list retractions. +exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.0.0-bad.mod +! exists $GOPATH/pkg/mod/cache/download/example.com/retract/@v/v1.1.0.mod + +# Importing a package from a module with a retracted latest version will +# select the latest non-retracted version. +go get ./use_self_prev +go list -m example.com/retract/self/prev +stdout '^example.com/retract/self/prev v1.1.0$' +exists $GOPATH/pkg/mod/cache/download/example.com/retract/self/prev/@v/v1.9.0.mod + +-- go.mod -- +module example.com/use + +go 1.15 + +require example.com/retract v1.0.0-bad + +-- go.sum -- +example.com/retract v1.0.0-bad h1:liAW69rbtjY67x2CcNzat668L/w+YGgNX3lhJsWIJis= +example.com/retract v1.0.0-bad/go.mod h1:0DvGGofJ9hr1q63cBrOY/jSY52OwhRGA0K47NE80I5Y= +example.com/retract/self/prev v1.1.0 h1:0/8I/GTG+1eJTFeDQ/fUbgrMsVHHyKhh3Z8DSZp1fuA= +example.com/retract/self/prev v1.1.0/go.mod h1:xl2EcklWuZZHVtHWcpzfSJQmnzAGpKZYpA/Wto7SZN4= +-- use/use.go -- +package use + +import _ "example.com/retract" + +-- use_self_prev/use.go -- +package use_self_prev + +import _ "example.com/retract/self/prev" diff --git a/src/cmd/go/testdata/script/mod_retract_fix_version.txt b/src/cmd/go/testdata/script/mod_retract_fix_version.txt new file mode 100644 index 0000000..9ae49f5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_fix_version.txt @@ -0,0 +1,48 @@ +# retract must not be used without a module directive. +! go list -m all +stderr 'go.mod:3: no module directive found, so retract cannot be used$' + +# Commands that update go.mod should fix non-canonical versions in +# retract directives. +# Verifies #44494. +go mod edit -module=rsc.io/quote/v2 +! go list -m all +stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy$' +go mod tidy +go list -m all +cmp go.mod go.mod.want + +# If a retracted version doesn't match the module's major version suffx, +# an error should be reported. +! go mod edit -retract=v3.0.1 +stderr '^go: -retract=v3.0.1: version "v3.0.1" invalid: should be v2, not v3$' +cp go.mod.mismatch-v2 go.mod +! go list -m all +stderr 'go.mod:3: retract rsc.io/quote/v2: version "v3.0.1" invalid: should be v2, not v3$' + +cp go.mod.mismatch-v1 go.mod +! go list -m all +stderr 'go.mod:3: retract rsc.io/quote: version "v3.0.1" invalid: should be v0 or v1, not v3$' + +-- go.mod -- +go 1.16 + +retract latest +-- go.mod.want -- +go 1.16 + +retract v2.0.1 + +module rsc.io/quote/v2 +-- go.mod.mismatch-v2 -- +go 1.16 + +retract v3.0.1 + +module rsc.io/quote/v2 +-- go.mod.mismatch-v1 -- +go 1.16 + +retract v3.0.1 + +module rsc.io/quote diff --git a/src/cmd/go/testdata/script/mod_retract_incompatible.txt b/src/cmd/go/testdata/script/mod_retract_incompatible.txt new file mode 100644 index 0000000..5d09532 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_incompatible.txt @@ -0,0 +1,15 @@ +# The current version of a module should not be considered when loading +# retractions. If the current version is +incompatible, we should not prefer +# +incompatible versions when looking for retractions. +# Verifies #42601. + +go mod init m + +# Request a +incompatible version retracted in v1.0.0. +go get example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' + +# We should still see a warning if the +incompatible was previously in the +# build list. +go get example.com/retract/incompatible@v2.0.0+incompatible +stderr '^go: warning: example.com/retract/incompatible@v2.0.0\+incompatible: retracted by module author$' diff --git a/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt new file mode 100644 index 0000000..27c2b67 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt @@ -0,0 +1,62 @@ +# When converting a commit to a pseudo-version, don't use a retracted version +# as the base. +# Verifies golang.org/issue/41700. + +[!net] skip +[!exec:git] skip +env GOPROXY=direct +env GOSUMDB=off +go mod init m + +# Control: check that v1.0.0 is the only version and is retracted. +go list -m -versions vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git$' +go list -m -versions -retracted vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.0$' + +# 713affd19d7b is a commit after v1.0.0. Don't use v1.0.0 as the base. +go list -m vcs-test.golang.org/git/retract-pseudo.git@713affd19d7b +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-713affd19d7b$' + +# 64c061ed4371 is the commit v1.0.0 refers to. Don't convert to v1.0.0. +go list -m vcs-test.golang.org/git/retract-pseudo.git@64c061ed4371 +stdout '^vcs-test.golang.org/git/retract-pseudo.git v0.0.0-20201009173747-64c061ed4371' + +# A retracted version is a valid base. Retraction should not validate existing +# pseudo-versions, nor should it turn invalid pseudo-versions valid. +go get vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-713affd19d7b +go list -m vcs-test.golang.org/git/retract-pseudo.git +stdout '^vcs-test.golang.org/git/retract-pseudo.git v1.0.1-0.20201009173747-713affd19d7b$' + +! go get vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371 +stderr '^go: vcs-test.golang.org/git/retract-pseudo.git@v1.0.1-0.20201009173747-64c061ed4371: invalid pseudo-version: tag \(v1.0.0\) found on revision 64c061ed4371 is already canonical, so should not be replaced with a pseudo-version derived from that tag$' + +-- retract-pseudo.sh -- +#!/bin/bash + +# This is not part of the test. +# Run this to generate and update the repository on vcs-test.golang.org. + +set -euo pipefail + +rm -rf retract-pseudo +mkdir retract-pseudo +cd retract-pseudo +git init + +# Create the module. +# Retract v1.0.0 and tag v1.0.0 at the same commit. +# The module has no unretracted release versions. +go mod init vcs-test.golang.org/git/retract-pseudo.git +go mod edit -retract v1.0.0 +echo 'package p' >p.go +git add -A +git commit -m 'create module retract-pseudo' +git tag v1.0.0 + +# Commit a trivial change so the default branch does not point to v1.0.0. +git mv p.go q.go +git commit -m 'trivial change' + +zip -r ../retract-pseudo.zip . +gsutil cp ../retract-pseudo.zip gs://vcs-test/git/retract-pseudo.zip diff --git a/src/cmd/go/testdata/script/mod_retract_rationale.txt b/src/cmd/go/testdata/script/mod_retract_rationale.txt new file mode 100644 index 0000000..92e9b7d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_rationale.txt @@ -0,0 +1,79 @@ +# When there is no rationale, 'go get' should print a hard-coded message. +go get example.com/retract/rationale@v1.0.0-empty +stderr '^go: warning: example.com/retract/rationale@v1.0.0-empty: retracted by module author$' + +# 'go list' should print the same hard-coded message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[retracted by module author\]$' + + +# When there is a multi-line message, 'go get' should print the first line. +go get example.com/retract/rationale@v1.0.0-multiline1 +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline1: retracted by module author: short description$' +! stderr 'detail' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +cmp stdout multiline + +# 'go get' output should be the same whether the retraction appears at top-level +# or in a block. +go get example.com/retract/rationale@v1.0.0-multiline2 +stderr '^go: warning: example.com/retract/rationale@v1.0.0-multiline2: retracted by module author: short description$' +! stderr 'detail' + +# Same for 'go list'. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +cmp stdout multiline + + +# 'go get' should omit long messages. +go get example.com/retract/rationale@v1.0.0-long +stderr '^go: warning: example.com/retract/rationale@v1.0.0-long: retracted by module author: \(message omitted: too long\)' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[lo{500}ng\]$' + + +# 'go get' should omit messages with unprintable characters. +go get example.com/retract/rationale@v1.0.0-unprintable +stderr '^go: warning: example.com/retract/rationale@v1.0.0-unprintable: retracted by module author: \(message omitted: contains non-printable characters\)' + +# 'go list' should show the full message. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale +stdout '^\[Ends with a BEL character. Beep!\x07\]$' + + +# When there is a comment on a block, but not on individual retractions within +# the block, the rationale should come from the block comment. +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-block +stdout '^\[block comment\]$' +go list -m -retracted -f '{{.Retracted}}' example.com/retract/rationale@v1.0.0-blockwithcomment +stdout '^\[inner comment\]$' + + +# When a version is covered by multiple retractions, all retractions should +# be reported in the order they appear in the file. +go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.0-order +stdout '^degenerate range,single version,$' +go list -m -retracted -f '{{range .Retracted}}{{.}},{{end}}' example.com/retract/rationale@v1.0.1-order +stdout '^single version,degenerate range,$' + +# 'go get' will only report the first retraction to avoid being too verbose. +go get example.com/retract/rationale@v1.0.0-order +stderr '^go: warning: example.com/retract/rationale@v1.0.0-order: retracted by module author: degenerate range$' +go get example.com/retract/rationale@v1.0.1-order +stderr '^go: warning: example.com/retract/rationale@v1.0.1-order: retracted by module author: single version$' + +-- go.mod -- +module m + +go 1.14 + +-- multiline -- +[short description +more + +detail +suffix] diff --git a/src/cmd/go/testdata/script/mod_retract_rename.txt b/src/cmd/go/testdata/script/mod_retract_rename.txt new file mode 100644 index 0000000..38986f3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_rename.txt @@ -0,0 +1,28 @@ +# Populate go.sum. +go get + +# 'go list -m -retracted' should load retractions, even if the version +# containing retractions has a different module path. +go list -m -retracted -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go list -m -u' should load retractions, too. +go list -m -u -f '{{with .Retracted}}retracted{{end}}' example.com/retract/rename + +# 'go get' should warn about the retracted version. +go get +stderr '^go: warning: example.com/retract/rename@v1.0.0-bad: retracted by module author: bad$' + +# We can't upgrade, since this latest version has a different module path. +! go get example.com/retract/rename +stderr 'module declares its path as: example.com/retract/newname' + +-- go.mod -- +module example.com/use + +go 1.16 + +require example.com/retract/rename v1.0.0-bad +-- use.go -- +package use + +import _ "example.com/retract/rename" diff --git a/src/cmd/go/testdata/script/mod_retract_replace.txt b/src/cmd/go/testdata/script/mod_retract_replace.txt new file mode 100644 index 0000000..788968f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_replace.txt @@ -0,0 +1,63 @@ +# If the latest unretracted version of a module is replaced, 'go list' should +# obtain retractions from the replacement. + +# Populate go.sum. +go get + +# The latest version, v1.9.0, is not available on the proxy. +go list -m -retracted example.com/retract/missingmod +stdout '^example.com/retract/missingmod v1.0.0$' +exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.info +! exists $GOPATH/pkg/mod/cache/download/example.com/retract/missingmod/@v/v1.9.0.mod + +# If we replace that version, we should see retractions. +go mod edit -replace=example.com/retract/missingmod@v1.9.0=./missingmod-v1.9.0 +go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract/missingmod +stdout '^bad version$' + +# If we replace the retracted version, we should not see a retraction. +go mod edit -replace=example.com/retract/missingmod=./missingmod-v1.9.0 +go list -m -retracted -f '{{if not .Retracted}}good version{{end}}' example.com/retract/missingmod +stdout '^good version$' + + +# If a replacement version is retracted, we should see a retraction. +# It should appear in both the replaced module and the replacement, as other +# fields like GoMod do. +go list -m -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract +! stdout . +go list -m -retracted -f '{{if .Replace}}replaced{{end}}' example.com/retract +! stdout . +go mod edit -replace example.com/retract@v1.0.0-good=example.com/retract@v1.0.0-bad +go list -m -mod=mod -retracted -f '{{range .Retracted}}{{.}}{{end}}' example.com/retract +stdout '^bad$' +go list -m -mod=mod -retracted -f '{{with .Replace}}{{range .Retracted}}{{.}}{{end}}{{end}}' example.com/retract +stdout '^bad$' + +-- go.mod -- +module m + +go 1.14 + +require ( + example.com/retract v1.0.0-good + example.com/retract/missingmod v1.0.0 +) +-- use.go -- +package use + +import ( + _ "example.com/retract" + _ "example.com/retract/missingmod" +) +-- missingmod-v1.0.0/go.mod -- +module example.com/retract/missingmod + +go 1.14 +-- missingmod-v1.9.0/go.mod -- +module example.com/retract/missingmod + +go 1.14 + +// bad version +retract v1.0.0 diff --git a/src/cmd/go/testdata/script/mod_retract_versions.txt b/src/cmd/go/testdata/script/mod_retract_versions.txt new file mode 100644 index 0000000..012fa15 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_retract_versions.txt @@ -0,0 +1,22 @@ +# https://golang.org/issue/44296: the --versions flag should not affect +# the version reported by 'go list' in case of retractions. + +env FMT='{{.Path}}{{with .Error}}: {{printf "%q" .Err}}{{end}} {{printf "%q" .Version}}{{with .Versions}} {{.}}{{end}}' + +go list -m -e -f $FMT example.com/retract/self/pseudo +stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: not a known dependency" ""$' + +go list -m -e -f $FMT example.com/retract/self/pseudo@latest +stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: no matching versions for query \\"latest\\"" "latest"$' + + +go list -m -e -f $FMT --versions example.com/retract/self/pseudo +stdout '^example.com/retract/self/pseudo ""$' + +go list -m -e -f $FMT --versions example.com/retract/self/pseudo@latest +stdout '^example.com/retract/self/pseudo: "module example.com/retract/self/pseudo: no matching versions for query \\"latest\\"" "latest"$' + +-- go.mod -- +module test + +go 1.17 diff --git a/src/cmd/go/testdata/script/mod_run_issue52331.txt b/src/cmd/go/testdata/script/mod_run_issue52331.txt new file mode 100644 index 0000000..917e890 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_issue52331.txt @@ -0,0 +1,35 @@ +# Regression test for https://go.dev/issue/52331: 'go run -mod=mod' +# failed to write go.mod and go.sum with the resolved dependencies. + +[short] skip + +! go run main.go +# stderr '^main\.go:6:2: no required module provides package example\.com/version; to add it:\n\tgo get example\.com/version\n\z' + +go run -mod=mod main.go +cmp go.mod go.mod.want +grep -count=1 '^example\.com/version v1.1.0 h1:' go.sum +grep -count=1 '^example\.com/version v1.1.0/go.mod h1:' go.sum + +-- go.mod -- +module example + +go 1.17 +-- go.mod.want -- +module example + +go 1.17 + +require example.com/version v1.1.0 // indirect +-- main.go -- +package main + +import ( + "fmt" + + "example.com/version" +) + +func main() { + fmt.Println(version.V) +} diff --git a/src/cmd/go/testdata/script/mod_run_nonmain.txt b/src/cmd/go/testdata/script/mod_run_nonmain.txt new file mode 100644 index 0000000..8435fc0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_nonmain.txt @@ -0,0 +1,18 @@ +! go run $PWD +! stderr 'no packages loaded' +stderr '^package example.net/nonmain is not a main package$' + +! go run . +stderr '^package example.net/nonmain is not a main package$' + +! go run ./... +stderr '^go: warning: "\./\.\.\." matched only non-main packages$' +stderr '^go: no packages loaded from \./\.\.\.$' + +-- go.mod -- +module example.net/nonmain + +go 1.17 +-- nonmain.go -- +// Package nonmain is not a main package. +package nonmain diff --git a/src/cmd/go/testdata/script/mod_run_path.txt b/src/cmd/go/testdata/script/mod_run_path.txt new file mode 100644 index 0000000..4369ee4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_path.txt @@ -0,0 +1,15 @@ +# Test that go run does not get confused by conflict +# between go.mod's module path and what you'd +# expect from GOPATH. golang.org/issue/26046. + +env GO111MODULE=on + +cd $GOPATH/src/example.com/hello +go run main.go + +-- $GOPATH/src/example.com/hello/go.mod -- +module example.com/hello/v2 + +-- $GOPATH/src/example.com/hello/main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/mod_run_pkg_version.txt b/src/cmd/go/testdata/script/mod_run_pkg_version.txt new file mode 100644 index 0000000..c3a218d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_pkg_version.txt @@ -0,0 +1,103 @@ +# This test checks the behavior of 'go run' with a 'cmd@version' argument. +# Most of 'go run' is covered in other tests. +# mod_install_pkg_version covers most of the package loading functionality. +# This test focuses on 'go run' behavior specific to this mode. +[short] skip + +# 'go run pkg@version' works outside a module. +env GO111MODULE=auto +go run example.com/cmd/a@v1.0.0 +stdout '^a@v1.0.0$' + + +# 'go run pkg@version' reports an error if modules are disabled. +env GO111MODULE=off +! go run example.com/cmd/a@v1.0.0 +stderr '^go: modules disabled by GO111MODULE=off; see ''go help modules''$' +env GO111MODULE=on + + +# 'go run pkg@version' ignores go.mod in the current directory. +cd m +cp go.mod go.mod.orig +! go list -m all +stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$' +go run example.com/cmd/a@v1.0.0 +stdout '^a@v1.0.0$' +cmp go.mod go.mod.orig +cd .. + + +# 'go install pkg@version' works on a module that doesn't have a go.mod file +# and with a module whose go.mod file has missing requirements. +# With a proxy, the two cases are indistinguishable. +go run rsc.io/fortune@v1.0.0 +stderr '^go: found rsc.io/quote in rsc.io/quote v1.5.2$' +stderr '^Hello, world.$' + + +# 'go run pkg@version' should report an error if pkg is not a main package. +! go run example.com/cmd/err@v1.0.0 +stderr '^package example.com/cmd/err is not a main package$' + + +# 'go run pkg@version' should report errors if the module contains +# replace or exclude directives. +go mod download example.com/cmd@v1.0.0-replace +! go run example.com/cmd/a@v1.0.0-replace +cmp stderr replace-err + +go mod download example.com/cmd@v1.0.0-exclude +! go run example.com/cmd/a@v1.0.0-exclude +cmp stderr exclude-err + + +# 'go run dir@version' works like a normal 'go run' command if +# dir is a relative or absolute path. +go mod download rsc.io/fortune@v1.0.0 +! go run $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +! go run ../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^go: go\.mod file not found in current directory or any parent directory; see ''go help modules''$' +mkdir tmp +cd tmp +go mod init tmp +go mod edit -require=rsc.io/fortune@v1.0.0 +! go run -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$' +! go run -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0 +stderr '^missing go\.sum entry for module providing package rsc\.io/fortune; to add:\n\tgo mod download rsc\.io/fortune$' +cd .. +rm tmp + + +# 'go run' does not interpret @version arguments after the first. +go run example.com/cmd/a@v1.0.0 example.com/doesnotexist@v1.0.0 +stdout '^a@v1.0.0$' + + +# 'go run pkg@version' succeeds when -mod=readonly is set explicitly. +# Verifies #43278. +go run -mod=readonly example.com/cmd/a@v1.0.0 +stdout '^a@v1.0.0$' + +-- m/go.mod -- +module m + +go 1.16 + +require example.com/cmd v1.1.0-doesnotexist +-- x/x.go -- +package main + +func main() {} +-- replace-err -- +go: example.com/cmd/a@v1.0.0-replace (in example.com/cmd@v1.0.0-replace): + The go.mod file for the module providing named packages contains one or + more replace directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. +-- exclude-err -- +go: example.com/cmd/a@v1.0.0-exclude (in example.com/cmd@v1.0.0-exclude): + The go.mod file for the module providing named packages contains one or + more exclude directives. It must not contain directives that would cause + it to be interpreted differently than if it were the main module. diff --git a/src/cmd/go/testdata/script/mod_run_pkgerror.txt b/src/cmd/go/testdata/script/mod_run_pkgerror.txt new file mode 100644 index 0000000..48f900d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_run_pkgerror.txt @@ -0,0 +1,32 @@ +# https://golang.org/issue/39986: files reported as invalid by go/build should +# be listed in InvalidGoFiles. + +go list -e -f '{{.Incomplete}}{{"\n"}}{{.Error}}{{"\n"}}{{.InvalidGoFiles}}{{"\n"}}' . +stdout '^true\nfound packages m \(m\.go\) and main \(main\.go\) in '$PWD'\n\[main.go\]\n' + + +# https://golang.org/issue/45827: 'go run .' should report the same package +# errors as 'go build' and 'go list'. + +! go build +stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$' + +! go list . +stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$' + +! go run . +! stderr 'no packages loaded' +stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$' + +! go run ./... +! stderr 'no packages loaded' +stderr '^found packages m \(m\.go\) and main \(main\.go\) in '$PWD'$' + +-- go.mod -- +module m + +go 1.17 +-- m.go -- +package m +-- main.go -- +package main diff --git a/src/cmd/go/testdata/script/mod_skip_write.txt b/src/cmd/go/testdata/script/mod_skip_write.txt new file mode 100644 index 0000000..9fdb6fc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_skip_write.txt @@ -0,0 +1,92 @@ +# Commands used to debug the module graph should not write go.mod or go.sum +# or report errors when those files need to be updated. + +# Everything's okay initially. +go list -m all + +# Downgrading sampler makes go.mod inconsistent, but 'go mod graph', +# 'go mod verify', and 'go mod why' still work. +cp go.mod go.mod.orig +go mod edit -require=rsc.io/sampler@v1.2.0 +cp go.mod go.mod.edit +! go list -m all +stderr 'updates to go.mod needed' + +go mod graph +cmp stdout graph.want +cmp go.mod go.mod.edit + +go mod verify +stdout '^all modules verified$' +cmp go.mod go.mod.edit + +go mod why rsc.io/sampler +cmp stdout why.want +cmp go.mod go.mod.edit + +go mod why -m rsc.io/sampler +cmp stdout why.want +cmp go.mod go.mod.edit + +cp go.mod.orig go.mod + +# Removing go.sum breaks other commands, but 'go mod graph' and +# 'go mod why' still work. +rm go.sum +! go list -m all +stderr 'missing go.sum entry' + +go mod graph +cmp stdout graph.want +! exists go.sum + +go mod verify +stdout '^all modules verified$' +! exists go.sum + +go mod why rsc.io/sampler +cmp stdout why.want +! exists go.sum + +go mod why -m rsc.io/sampler +cmp stdout why.want +! exists go.sum + +-- go.mod -- +module m + +go 1.18 + +require rsc.io/quote v1.5.2 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.2.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= +-- use.go -- +package use + +import _ "rsc.io/quote" +-- graph.want -- +m golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +m rsc.io/quote@v1.5.2 +m rsc.io/sampler@v1.3.0 +m rsc.io/testonly@v1.0.0 +rsc.io/quote@v1.5.2 rsc.io/sampler@v1.3.0 +rsc.io/sampler@v1.3.0 golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c +-- why.want -- +# rsc.io/sampler +m +rsc.io/quote +rsc.io/sampler diff --git a/src/cmd/go/testdata/script/mod_std_vendor.txt b/src/cmd/go/testdata/script/mod_std_vendor.txt new file mode 100644 index 0000000..c3cde52 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_std_vendor.txt @@ -0,0 +1,78 @@ +env GO111MODULE=on +env GOPROXY=off + +[!gc] skip + +# 'go list' should report imports from _test.go in the TestImports field. +go list -f '{{.TestImports}}' +stdout net/http # from .TestImports + +# 'go list' should find standard-vendored packages. +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# 'go list -test' should report vendored transitive dependencies of _test.go +# imports in the Deps field. +go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' +stdout ^vendor/golang.org/x/crypto # dep of .TestImports + + +# Modules outside the standard library should not use the packages vendored there... +cd broken +! go build -mod=readonly +stderr 'disabled by -mod=readonly' +! go build -mod=vendor +stderr 'cannot find package' +stderr 'hpack' + +# ...even if they explicitly use the "cmd/vendor/" or "vendor/" prefix. +cd ../importcmd +! go build . +stderr 'use of vendored package' + +cd ../importstd +! go build . +stderr 'use of vendored package' + + +# When run within the 'std' module, 'go list -test' should report vendored +# transitive dependencies at their vendored paths. +cd $GOROOT/src +go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' net/http +! stdout ^golang.org/x/net/http2/hpack +stdout ^vendor/golang.org/x/net/http2/hpack + +-- go.mod -- +module m + +-- x.go -- +package x + +-- x_test.go -- +package x +import "testing" +import _ "net/http" +func Test(t *testing.T) {} + +-- broken/go.mod -- +module broken +-- broken/http.go -- +package broken + +import ( + _ "net/http" + _ "golang.org/x/net/http2/hpack" +) + +-- importcmd/go.mod -- +module importcmd +-- importcmd/x.go -- +package importcmd + +import _ "cmd/vendor/golang.org/x/tools/go/analysis" +-- importstd/go.mod -- +module importvendor +-- importstd/x.go -- +package importstd + +import _ "vendor/golang.org/x/net/http2/hpack" diff --git a/src/cmd/go/testdata/script/mod_string_alias.txt b/src/cmd/go/testdata/script/mod_string_alias.txt new file mode 100644 index 0000000..5c3d428 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_string_alias.txt @@ -0,0 +1,14 @@ +[short] skip + +env GO111MODULE=on + +go mod init golang.org/issue/27584 + +go build . + +-- main.go -- +package main + +type string = []int + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_sum_ambiguous.txt b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt new file mode 100644 index 0000000..07c6659 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_ambiguous.txt @@ -0,0 +1,62 @@ +# Confirm our build list. +cp go.sum.buildlist-only go.sum +go list -m all +stdout '^example.com/ambiguous/a v1.0.0$' +stdout '^example.com/ambiguous/a/b v0.0.0-empty$' + +# If two modules could provide a package, but only one does, +# 'go mod tidy' should retain sums for both zips. +go mod tidy +grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum +grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum + +# 'go mod download' should also add sums. +cp go.sum.buildlist-only go.sum +go mod download example.com/ambiguous/a +grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum +! grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum +go mod download example.com/ambiguous/a/b +grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum + +# If two modules could provide a package, and we're missing a sum for one, +# we should see a missing sum error, even if we have a sum for a module that +# provides the package. +cp go.sum.a-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module; to add:\n\tgo mod download example.com/ambiguous/a/b$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry needed to verify package example.com/ambiguous/a/b \(imported by m\) is provided by exactly one module; to add:\n\tgo get m$' + +cp go.sum.b-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$' + +cp go.sum.buildlist-only go.sum +! go list example.com/ambiguous/a/b +stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a example.com/ambiguous/a/b$' +! go list -deps . +stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$' + +-- go.mod -- +module m + +go 1.15 + +require example.com/ambiguous/a v1.0.0 +-- go.sum.buildlist-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.a-only -- +example.com/ambiguous/a v1.0.0 h1:pGZhTXy6+titE2rNfwHwJykSjXDR4plO52PfZrBM0T8= +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- go.sum.b-only -- +example.com/ambiguous/a v1.0.0/go.mod h1:TrBl/3xTPFJ2gmMIYz53h2gkNtg0dokszEMuyS1QEb0= +example.com/ambiguous/a/b v0.0.0-empty h1:xS29ReXXuhjT7jc79mo91h/PevaZ2oS9PciF1DucXtg= +example.com/ambiguous/a/b v0.0.0-empty/go.mod h1:MajJq5jPEBnnXP+NTWIeXX7kwaPS1sbVEJdooTmsePQ= +-- use.go -- +package use + +import _ "example.com/ambiguous/a/b" diff --git a/src/cmd/go/testdata/script/mod_sum_lookup.txt b/src/cmd/go/testdata/script/mod_sum_lookup.txt new file mode 100644 index 0000000..7513f7f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_lookup.txt @@ -0,0 +1,34 @@ +# When we attempt to resolve an import that doesn't exist, we should not save +# hashes for downloaded modules. +# Verifies golang.org/issue/36260. +# TODO(golang.org/issue/26603): use 'go mod tidy -e' when implemented. +go list -e -mod=mod -tags=ignore ./noexist +! exists go.sum + +# When an import is resolved successfully, we should only save hashes for +# the module that provides the package, not for other modules looked up. +# Verifies golang.org/issue/31580. +go get ./exist +grep '^example.com/join v1.1.0 h1:' go.sum +! grep '^example.com/join/subpkg' go.sum +cp go.sum go.list.sum +go mod tidy +cmp go.sum go.list.sum + +-- go.mod -- +module m + +go 1.15 + +-- noexist/use.go -- +// ignore tags prevents errors in 'go mod tidy' +// +build ignore + +package use + +import _ "example.com/join/subpkg/noexist" + +-- exist/use.go -- +package use + +import _ "example.com/join/subpkg" diff --git a/src/cmd/go/testdata/script/mod_sum_readonly.txt b/src/cmd/go/testdata/script/mod_sum_readonly.txt new file mode 100644 index 0000000..57c5bbe --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_readonly.txt @@ -0,0 +1,87 @@ +# Test that go.sum does not get updated when -mod=readonly flag is set +env GO111MODULE=on + +# When a sum is needed to load the build list, we get an error for the +# specific module. The .mod file is not downloaded, and go.sum is not written. +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +! exists go.sum + +# If go.sum exists but contains hashes from an algorithm we don't know about, +# we should see the same error. +cp go.sum.h2only go.sum +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +cmp go.sum go.sum.h2only +rm go.sum + +# If we replace a module, we should see a missing sum error for the replacement. +cp go.mod go.mod.orig +go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1 +! go list -m all +stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod +! exists go.sum +cp go.mod.orig go.mod + +# Control: when sums are present, loading the build list downloads .mod files. +cp go.sum.buildlistonly go.sum +go list -m all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod + + +# When a sum is needed to load a .mod file for a package outside the build list, +# we get a generic missing import error. +! go list example.com/doesnotexist +stderr '^no required module provides package example.com/doesnotexist; to add it:\n\tgo get example.com/doesnotexist$' + +# When a sum is needed to load a .zip file, we get a more specific error. +# The .zip file is not downloaded. +! go list rsc.io/quote +stderr '^missing go.sum entry for module providing package rsc.io/quote; to add:\n\tgo mod download rsc.io/quote$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# The error is attached to the package from the missing module. We can load +# a package that imports it without that error. +go list -e -deps -f '{{.ImportPath}}{{with .Error}} {{.Err}}{{end}}' . +stdout '^m$' +stdout '^rsc.io/quote missing go.sum entry for module providing package rsc.io/quote \(imported by m\); to add:\n\tgo get m$' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +# go.sum should not have been written. +cmp go.sum go.sum.buildlistonly + +# Control: when sums are present, 'go list' downloads .zip files. +cp go.sum.tidy go.sum +go list . +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip + +-- go.mod -- +module m + +go 1.15 + +require rsc.io/quote v1.5.2 +-- use.go -- +package use + +import _ "rsc.io/quote" +-- go.sum.h2only -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h2:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h2:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h2:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.buildlistonly -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- go.sum.tidy -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= diff --git a/src/cmd/go/testdata/script/mod_sum_replaced.txt b/src/cmd/go/testdata/script/mod_sum_replaced.txt new file mode 100644 index 0000000..6c322a0 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sum_replaced.txt @@ -0,0 +1,28 @@ +env GO111MODULE=on + +# After 'go get', the go.sum file should contain the sum for the module. +go get rsc.io/quote@v1.5.0 +grep 'rsc.io/quote v1.5.0' go.sum + +# If we replace the module and run 'go mod tidy', we should get a sum for the replacement. +go mod edit -replace rsc.io/quote@v1.5.0=rsc.io/quote@v1.5.1 +go mod tidy +grep 'rsc.io/quote v1.5.1' go.sum +cp go.sum go.sum.tidy + +# 'go mod vendor' should preserve that sum, and should not need to add any new entries. +go mod vendor +grep 'rsc.io/quote v1.5.1' go.sum +cmp go.sum go.sum.tidy + +-- go.mod -- +module golang.org/issue/27868 + +require rsc.io/quote v1.5.0 + +-- main.go -- +package main + +import _ "rsc.io/quote" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_sumdb.txt b/src/cmd/go/testdata/script/mod_sumdb.txt new file mode 100644 index 0000000..d06db4a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb.txt @@ -0,0 +1,45 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB +env dbname=localhost.localdev/sumdb + +# disagreeing with the sumdb produces security errors +# (this also populates tiles on the sumdb server). +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong +! go get rsc.io/quote +stderr 'go: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' +stderr 'downloaded: h1:3fEy' +stderr 'localhost.localdev/sumdb: h1:wrong' +stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.' +! go get rsc.io/sampler +! go get golang.org/x/text + +go mod edit -require rsc.io/quote@v1.5.2 +! go mod tidy +stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch' +stderr 'SECURITY ERROR\n' + +rm go.sum + +# switching to truthful sumdb detects timeline inconsistency +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +! go get rsc.io/fortune +stderr 'SECURITY ERROR\ngo.sum database server misbehavior detected!' +stderr 'proof of misbehavior:' + +# removing the cached wrong tree head and cached tiles clears the bad data +rm $GOPATH/pkg/sumdb/$dbname/latest +go clean -modcache +go get rsc.io/fortune + +-- go.mod.orig -- +module m + +go 1.16 +-- m.go -- +package m + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_sumdb_cache.txt b/src/cmd/go/testdata/script/mod_sumdb_cache.txt new file mode 100644 index 0000000..063fd20 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_cache.txt @@ -0,0 +1,47 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB + +# rejected proxy fails verification +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy/sumdb-503 +! go get rsc.io/quote +stderr 503 + +# fetch through working proxy is OK +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy +go get rsc.io/quote + +# repeated fetch works entirely from cache, does not consult sumdb +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=$proxy/sumdb-503 +go get rsc.io/quote +rm go.sum + +# fetch specific module can work without proxy, using cache or go.sum +cp go.mod.orig go.mod +rm go.sum +env GOPROXY=off +go get rsc.io/quote@v1.5.2 # using cache +rm $GOPATH/pkg/mod/cache/download/sumdb/localhost.localdev/sumdb/lookup/rsc.io/quote@v1.5.2 +go get rsc.io/quote@v1.5.2 # using go.sum + +# fetch fails once we lose access to both cache and go.sum +rm go.sum +env GOPROXY=$proxy/sumdb-504 +! go get rsc.io/quote@v1.5.2 +stderr 504 + +# GOINSECURE does not bypass checksum lookup +env GOINSECURE=rsc.io +env GOPROXY=$proxy/sumdb-504 +! go get rsc.io/quote@v1.5.2 +stderr 504 + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt new file mode 100644 index 0000000..a834c48 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt @@ -0,0 +1,56 @@ +[!net] skip + +env GO111MODULE=on +env GOSUMDB= +env GOPATH=$WORK/gopath1 + +# With a file-based proxy with an empty checksum directory, +# downloading a new module should fail, even if a subsequent +# proxy contains a more complete mirror of the sum database. +# +# TODO(bcmills): The error message here is a bit redundant. +# It comes from the sumweb package, which isn't yet producing structured errors. +[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org +! go get golang.org/x/text@v0.3.2 +stderr '^go: golang.org/x/text@v0.3.2: verifying module: golang.org/x/text@v0.3.2: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/text@v0.3.2: (no such file or directory|.*cannot find the path specified.*)' + +# If the proxy does not claim to support the database, +# checksum verification should fall through to the next proxy, +# and downloading should succeed. +[windows] env GOPROXY=file:///$WORK/emptyproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org +go get golang.org/x/text@v0.3.2 + +# After a successful sumdb lookup, the lookup can be repeated +# using the download cache as a proxy. +cp supported $GOPATH/pkg/mod/cache/download/sumdb/sum.golang.org/supported +[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy +[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy +env GOPATH=$WORK/gopath2 +rm go.sum +go get -x -v golang.org/x/text@v0.3.2 + +# Once the checksum is present in the go.sum file, +# an empty file-based sumdb can be used in conjunction with +# a fallback module mirror. +grep golang.org/x/text go.sum +env GOPATH=$WORK/gopath3 +[windows] env GOPROXY=file:///$WORK/sumproxy +[!windows] env GOPROXY=file://$WORK/sumproxy +! go get golang.org/x/text@v0.3.2 +[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org +[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org +go get golang.org/x/text@v0.3.2 + +-- supported -- + +-- go.mod -- +module example.com +go 1.13 +-- $WORK/emptyproxy/README.md -- +This proxy contains no modules. +-- $WORK/sumproxy/README.md -- +This proxy contains no modules. +-- $WORK/sumproxy/sumdb/sum.golang.org/supported -- +This proxy blocks checksum downloads from sum.golang.org. diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt new file mode 100644 index 0000000..a48a5ba --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -0,0 +1,82 @@ +# Test default GOPROXY and GOSUMDB +env GOPROXY= +env GOSUMDB= +go env GOPROXY +stdout '^https://proxy.golang.org,direct$' +go env GOSUMDB +stdout '^sum.golang.org$' +env GOPROXY=https://proxy.golang.org +go env GOSUMDB +stdout '^sum.golang.org$' + +# Download direct from github. + +[!net] skip +[!exec:git] skip +env GOSUMDB=sum.golang.org +env GOPROXY=direct + +go get rsc.io/quote@v1.5.2 +cp go.sum saved.sum + + +# Download from proxy.golang.org with go.sum entry already. +# Use 'go list' instead of 'go get' since the latter may download extra go.mod +# files not listed in go.sum. + +go clean -modcache +env GOSUMDB= +env GOPROXY= + +go list -x -m all # Download go.mod files. +! stderr github +stderr proxy.golang.org/rsc.io/quote +! stderr sum.golang.org/tile +! stderr sum.golang.org/lookup/rsc.io/quote + +go list -x -deps rsc.io/quote # Download module source. +! stderr github +stderr proxy.golang.org/rsc.io/quote +! stderr sum.golang.org/tile +! stderr sum.golang.org/lookup/rsc.io/quote + +cmp go.sum saved.sum + + +# Download again. +# Should use the checksum database to validate new go.sum lines, +# but not need to fetch any new data from the proxy. + +rm go.sum + +go list -mod=mod -x -m all # Add checksums for go.mod files. +stderr sum.golang.org/tile +! stderr github +! stderr proxy.golang.org/rsc.io/quote +stderr sum.golang.org/lookup/rsc.io/quote + +go list -mod=mod -x rsc.io/quote # Add checksums for module source. +! stderr . # Adds checksums, but for entities already in the module cache. + +cmp go.sum saved.sum + + +# test fallback to direct + +env TESTGOPROXY404=1 +go clean -modcache +rm go.sum + +go list -mod=mod -x -m all # Download go.mod files +stderr 'proxy.golang.org.*404 testing' +stderr github.com/rsc + +go list -mod=mod -x rsc.io/quote # Download module source. +stderr 'proxy.golang.org.*404 testing' +stderr github.com/rsc + +cmp go.sum saved.sum + + +-- go.mod -- +module m diff --git a/src/cmd/go/testdata/script/mod_sumdb_proxy.txt b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt new file mode 100644 index 0000000..194c0c9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -0,0 +1,65 @@ +env GO111MODULE=on +env sumdb=$GOSUMDB +env proxy=$GOPROXY +env GOPROXY GONOPROXY GOSUMDB GONOSUMDB + +# basic fetch (through proxy) works +cp go.mod.orig go.mod +go get rsc.io/fortune@v1.0.0 # note: must use test proxy, does not exist in real world +rm $GOPATH/pkg/mod/cache/download/sumdb # rm sumdb cache but NOT package download cache +rm go.sum + +# can fetch by explicit URL +cp go.mod.orig go.mod +env GOSUMDB=$sumdb' '$proxy/sumdb-direct +go get rsc.io/fortune@v1.0.0 +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# direct access fails (because localhost.localdev does not exist) +# web.get is providing the error message - there's no actual network access. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=direct +! go get rsc.io/fortune@v1.0.0 +stderr 'verifying module: rsc.io/fortune@v1.0.0: .*: no such host localhost.localdev' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# proxy 404 falls back to direct access (which fails) +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-404 +! go get rsc.io/fortune@v1.0.0 +stderr 'verifying.*localhost.localdev' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# proxy non-200/404/410 stops direct access +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-503 +! go get rsc.io/fortune@v1.0.0 +stderr '503 Service Unavailable' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# the error from the last attempted proxy should be returned. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-404,$proxy/sumdb-503 +! go get rsc.io/fortune@v1.0.0 +stderr '503 Service Unavailable' +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +# if proxies are separated with '|', fallback is allowed on any error. +cp go.mod.orig go.mod +env GOSUMDB=$sumdb +env GOPROXY=$proxy/sumdb-503|https://0.0.0.0|$proxy +go get rsc.io/fortune@v1.0.0 +rm $GOPATH/pkg/mod/cache/download/sumdb +rm go.sum + +-- go.mod.orig -- +module m diff --git a/src/cmd/go/testdata/script/mod_symlink.txt b/src/cmd/go/testdata/script/mod_symlink.txt new file mode 100644 index 0000000..0604e1a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_symlink.txt @@ -0,0 +1,45 @@ +env GO111MODULE=on +[!symlink] skip + +# 'go get' should resolve modules of imported packages. +go get +go list -deps -f '{{.Module}}' . +stdout golang.org/x/text + +go get ./subpkg +go list -deps -f '{{.Module}}' ./subpkg +stdout golang.org/x/text + +# Create a copy of the module using symlinks in src/links. +mkdir links +symlink links/go.mod -> $GOPATH/src/go.mod +symlink links/go.sum -> $GOPATH/src/go.sum +symlink links/issue.go -> $GOPATH/src/issue.go +mkdir links/subpkg +symlink links/subpkg/issue.go -> $GOPATH/src/subpkg/issue.go + +# We should see the copy as a valid module root. +cd links +go env GOMOD +stdout links[/\\]go.mod +go list -m +stdout golang.org/issue/28107 + +# The symlink-based copy should contain the same packages +# and have the same dependencies as the original. +go list -deps -f '{{.Module}}' . +stdout golang.org/x/text +go list -deps -f '{{.Module}}' ./subpkg +stdout golang.org/x/text + +-- go.mod -- +module golang.org/issue/28107 + +-- issue.go -- +package issue + +import _ "golang.org/x/text/language" +-- subpkg/issue.go -- +package issue + +import _ "golang.org/x/text/language" diff --git a/src/cmd/go/testdata/script/mod_symlink_dotgo.txt b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt new file mode 100644 index 0000000..d4cc143 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_symlink_dotgo.txt @@ -0,0 +1,17 @@ +env GO111MODULE=on +[!symlink] skip + +symlink dir.go -> dir + +# Issue #39841: symlinks to directories should be ignored, not treated as source files. +go list -f '{{range .GoFiles}}{{.}}{{"\n"}}{{end}}' . +stdout 'p\.go$' +! stdout 'dir\.go$' + +-- go.mod -- +module example.com +go 1.15 +-- p.go -- +package p +-- dir/README.txt -- +This file exists to ensure that dir is a directory. diff --git a/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt b/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt new file mode 100644 index 0000000..0491acb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tagged_import_cycle.txt @@ -0,0 +1,106 @@ +# Because 'go mod' subcommands ignore build constraints, they can encounter +# package-import cycles that are not possible in an ordinary build. This test +# verifies that such cycles are handled even when they cross module boundaries. + +# First, verify that the import graph depends on build tags as expected. +go list -deps example.com/left +stdout '^example.com/right$' +go list -deps example.com/right +! stdout left + +env GOFLAGS=-tags=mirror +go list -deps example.com/left +! stdout right +go list -deps example.com/right +stdout '^example.com/left$' +env GOFLAGS='' + +# 'go mod why' should be agnostic to build tags. +go mod why example.com/left +stdout '^example.com/chiral$\n^example.com/left$' +go mod why example.com/right +stdout '^example.com/chiral$\n^example.com/right$' + +env GOFLAGS='-tags=mirror' +go mod why example.com/left +stdout '^example.com/chiral$\n^example.com/left$' +go mod why example.com/right +stdout '^example.com/chiral$\n^example.com/right$' +env GOFLAGS='' + +# 'go mod tidy' should successfully handle the cycle. +env GOFLAGS=-mod=readonly +go mod tidy + +# 'go mod vendor' should copy in both packages without crashing. +go mod vendor +exists vendor/example.com/left/default.go +exists vendor/example.com/left/mirror.go +exists vendor/example.com/right/default.go +exists vendor/example.com/right/mirror.go + +-- go.mod -- +module example.com/chiral + +go 1.14 + +require ( + example.com/left v0.1.0 + example.com/right v0.1.0 +) + +replace ( + example.com/left => ./left + example.com/right => ./right +) +-- chiral.go -- +// Package chiral imports packages in an order that depends on build tags. +package chiral +-- default.go -- +// +build !mirror + +package chiral + +import _ "example.com/left" +-- mirror.go -- +// +build mirror + +package chiral + +import _ "example.com/right" +-- left/go.mod -- +module example.com/left + +go 1.14 + +require example.com/right v0.1.0 + +replace example.com/right v0.1.0 => ../right +-- left/default.go -- +// +build !mirror + +package left + +import _ "example.com/right" +-- left/mirror.go -- +// +build mirror + +package left +-- right/go.mod -- +module example.com/right + +go 1.14 + +require example.com/left v0.1.0 + +replace example.com/left v0.1.0 => ../left +-- right/default.go -- +// +build !mirror + +package right +-- right/mirror.go -- +// +build mirror + +package right + +import _ "example.com/left" diff --git a/src/cmd/go/testdata/script/mod_test.txt b/src/cmd/go/testdata/script/mod_test.txt new file mode 100644 index 0000000..76f1d7a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test.txt @@ -0,0 +1,130 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# TODO(bcmills): Convert the 'go test' calls below to 'go list -test' once 'go +# list' is more sensitive to package loading errors. + +# A test in the module's root package should work. +cd a/ +cp go.mod.empty go.mod +go list -test +! stderr error + +cp go.mod.empty go.mod +go list -deps +! stdout ^testing$ + +# list all should include test dependencies, like testing +cp go.mod.empty go.mod +go list all +stdout ^testing$ +stdout ^rsc.io/quote$ +stdout ^rsc.io/testonly$ + +# list -deps -tests should also include testing +# but not deps of tests of deps (rsc.io/testonly). +go list -deps -test +stdout ^testing$ +stdout ^rsc.io/quote$ +! stdout ^rsc.io/testonly$ + +# list -test all should succeed +cp go.mod.empty go.mod +go list -test all +stdout '^testing' + +cp go.mod.empty go.mod +go list -test +! stderr error + +# A test with the "_test" suffix in the module root should also work. +cd ../b/ +go list -test +! stderr error + +# A test with the "_test" suffix of a *package* with a "_test" suffix should +# even work (not that you should ever do that). +cd ../c_test +go list -test +! stderr error + +cd ../d_test +go list -test +! stderr error + +cd ../e +go list -test +! stderr error + +-- a/go.mod.empty -- +module example.com/user/a + +go 1.11 + +-- a/a.go -- +package a + +-- a/a_test.go -- +package a + +import "testing" +import _ "rsc.io/quote" + +func Test(t *testing.T) {} + +-- b/go.mod -- +module example.com/user/b + +-- b/b.go -- +package b + +-- b/b_test.go -- +package b_test + +import "testing" + +func Test(t *testing.T) {} + +-- c_test/go.mod -- +module example.com/c_test + +-- c_test/umm.go -- +// Package c_test is the non-test package for its import path! +package c_test + +-- c_test/c_test_test.go -- +package c_test_test + +import "testing" + +func Test(t *testing.T) {} + +-- d_test/go.mod -- +// Package d is an ordinary package in a deceptively-named directory. +module example.com/d + +-- d_test/d.go -- +package d + +-- d_test/d_test.go -- +package d_test + +import "testing" + +func Test(t *testing.T) {} + +-- e/go.mod -- +module example.com/e_test + +-- e/wat.go -- +// Package e_test is the non-test package for its import path, +// in a deceptively-named directory! +package e_test + +-- e/e_test.go -- +package e_test_test + +import "testing" + +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/mod_test_cached.txt b/src/cmd/go/testdata/script/mod_test_cached.txt new file mode 100644 index 0000000..3da4358 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test_cached.txt @@ -0,0 +1,76 @@ +[short] skip + +env GO111MODULE=on +env GOCACHE=$WORK/gocache +env GODEBUG=gocachetest=1 + +# The first run of a test should not be cached. +# The second run should be. +go test -run=WriteTmp . +! stdout '(cached)' +go test -run=WriteTmp . +stdout '(cached)' + +# 'go test' without arguments should never be cached. +go test -run=WriteTmp +! stdout '(cached)' +go test -run=WriteTmp +! stdout '(cached)' + +# We should never cache a test run from command-line files. +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' +go test -run=WriteTmp ./foo_test.go +! stdout '(cached)' + +[!exec:sleep] stop +# The go command refuses to cache access to files younger than 2s, so sleep that long. +exec sleep 2 + +# Touching a file that the test reads from within its testdata should invalidate the cache. +go test -run=ReadTestdata . +! stdout '(cached)' +go test -run=ReadTestdata . +stdout '(cached)' +cp testdata/bar.txt testdata/foo.txt +go test -run=ReadTestdata . +! stdout '(cached)' + +-- go.mod -- +module golang.org/issue/29111/foo + +-- foo.go -- +package foo + +-- testdata/foo.txt -- +foo +-- testdata/bar.txt -- +bar + +-- foo_test.go -- +package foo_test + +import ( + "os" + "path/filepath" + "testing" +) + +func TestWriteTmp(t *testing.T) { + dir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + err = os.WriteFile(filepath.Join(dir, "x"), nil, 0666) + if err != nil { + t.Fatal(err) + } +} + +func TestReadTestdata(t *testing.T) { + _, err := os.ReadFile("testdata/foo.txt") + if err != nil { + t.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/mod_test_files.txt b/src/cmd/go/testdata/script/mod_test_files.txt new file mode 100644 index 0000000..6f520c7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_test_files.txt @@ -0,0 +1,50 @@ +env GO111MODULE=on + +cd foo + +# Testing an explicit source file should use the same import visibility as the +# package in the same directory. +go list -test -deps +go list -test -deps foo_test.go + +# If the file is inside the main module's vendor directory, it should have +# visibility based on the vendor-relative import path. +mkdir vendor/example.com/foo +cp foo_test.go vendor/example.com/foo +go list -test -deps vendor/example.com/foo/foo_test.go + +# If the file is outside the main module entirely, it should be treated as outside. +cp foo_test.go ../foo_test.go +! go list -test -deps ../foo_test.go +stderr 'use of internal package' + +-- foo/go.mod -- +module example.com/foo +go 1.12 +require example.com/internal v0.0.0 +replace example.com/internal => ../internal + +-- foo/internal.go -- +package foo +import _ "example.com/internal" + +-- foo/foo_test.go -- +package foo_test + +import ( + "testing" + "example.com/internal" +) + +func TestHacksEnabled(t *testing.T) { + if !internal.Hacks { + t.Fatal("hacks not enabled") + } +} + +-- internal/go.mod -- +module example.com/internal + +-- internal/internal.go -- +package internal +const Hacks = true diff --git a/src/cmd/go/testdata/script/mod_tidy.txt b/src/cmd/go/testdata/script/mod_tidy.txt new file mode 100644 index 0000000..b1d9371 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy.txt @@ -0,0 +1,72 @@ +env GO111MODULE=on + +# tidy removes unused y, but everything else is used +go mod tidy -v +stderr '^unused y.1' +! stderr '^unused [^y]' + +grep 'go 1.10' go.mod + +go list -m all +! stdout '^y' +stdout '^w.1 v1.2.0' +stdout '^z.1 v1.2.0' + +# empty tidy should not crash +cd triv +! grep 'go ' go.mod +go mod tidy + +# tidy should add missing go line +grep 'go ' go.mod + +-- go.mod -- +module m + +go 1.10 + +require ( + x.1 v1.0.0 + y.1 v1.0.0 + w.1 v1.2.0 +) + +replace x.1 v1.0.0 => ./x +replace y.1 v1.0.0 => ./y +replace z.1 v1.1.0 => ./z +replace z.1 v1.2.0 => ./z +replace w.1 => ./w + +-- m.go -- +package m + +import _ "x.1" +import _ "z.1/sub" + +-- w/go.mod -- +module w + +-- w/w.go -- +package w + +-- x/go.mod -- +module x +require w.1 v1.1.0 +require z.1 v1.1.0 + +-- x/x.go -- +package x +import _ "w.1" + +-- y/go.mod -- +module y +require z.1 v1.2.0 + +-- z/go.mod -- +module z + +-- z/sub/sub.go -- +package sub + +-- triv/go.mod -- +module triv diff --git a/src/cmd/go/testdata/script/mod_tidy_compat.txt b/src/cmd/go/testdata/script/mod_tidy_compat.txt new file mode 100644 index 0000000..18b297d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat.txt @@ -0,0 +1,95 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# This module has the same module dependency graph in Go 1.16 as in Go 1.17, +# but in 1.16 requires (checksums for) additional (irrelevant) go.mod files. +# +# The module graph under both versions looks like: +# +# m ---- example.com/version v1.1.0 +# | +# + ---- example.net/lazy v0.1.0 ---- example.com/version v1.0.1 +# +# Go 1.17 avoids loading the go.mod file for example.com/version v1.0.1 +# (because it is lower than the version explicitly required by m, +# and the module that requires it — m — specifies 'go 1.17'). +# +# That go.mod file happens not to affect the final 1.16 module graph anyway, +# so the pruned graph is equivalent to the unpruned one. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +go list -m all +cmp stdout m_all.txt + +go mod edit -go=1.16 +go list -m all +cmp stdout m_all.txt + + +# If we explicitly drop compatibility with 1.16, we retain fewer checksums, +# which gives a cleaner go.sum file but causes 1.16 to fail in readonly mode. + +cp go.mod.orig go.mod +go mod tidy -compat=1.17 +cmp go.mod go.mod.orig + +go list -m all +cmp stdout m_all.txt + +go mod edit -go=1.16 +! go list -m all +stderr '^go: example.net/lazy@v0.1.0 requires\n\texample.com/version@v1.0.1: missing go.sum entry; to add it:\n\tgo mod download example.com/version$' + + +-- go.mod -- +// Module m happens to have the exact same build list as what would be +// selected under Go 1.16, but computes that build list without looking at +// as many go.mod files. +module example.com/m + +go 1.17 + +replace example.net/lazy v0.1.0 => ./lazy + +require ( + example.com/version v1.1.0 + example.net/lazy v0.1.0 +) +-- m_all.txt -- +example.com/m +example.com/version v1.1.0 +example.net/lazy v0.1.0 => ./lazy +-- compatible.go -- +package compatible + +import ( + _ "example.com/version" + _ "example.net/lazy" +) +-- lazy/go.mod -- +// Module lazy requires example.com/version v1.0.1. +// +// However, since this module is lazy, its dependents +// should not need checksums for that version of the module +// unless they actually import packages from it. +module example.net/lazy + +go 1.17 + +require example.com/version v1.0.1 +-- lazy/lazy.go -- +package lazy + +import _ "example.com/version" diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_added.txt b/src/cmd/go/testdata/script/mod_tidy_compat_added.txt new file mode 100644 index 0000000..94fa79b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_added.txt @@ -0,0 +1,105 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# For this module, Go 1.17 produces an error for one module, and Go 1.16 +# produces a different error for a different module. + +cp go.mod go.mod.orig + +! go mod tidy + +stderr '^example\.com/m imports\n\texample\.net/added: module example\.net/added@latest found \(v0\.3\.0, replaced by \./a1\), but does not contain package example\.net/added$' + +cmp go.mod go.mod.orig + + +# When we run 'go mod tidy -e', we should proceed past the first error and follow +# it with a second error describing the version descrepancy. +# +# We should not provide advice on how to push past the version descrepancy, +# because the '-e' flag should already do that, writing out an otherwise-tidied +# go.mod file. + +go mod tidy -e + +stderr '^example\.com/m imports\n\texample\.net/added: module example\.net/added@latest found \(v0\.3\.0, replaced by \./a1\), but does not contain package example\.net/added\nexample\.net/added failed to load from any module,\n\tbut go 1\.16 would load it from example\.net/added@v0\.2\.0$' + +! stderr '\n\tgo mod tidy' + +cmp go.mod go.mod.tidy + + +-- go.mod -- +module example.com/m + +go 1.17 + +replace ( + example.net/added v0.1.0 => ./a1 + example.net/added v0.2.0 => ./a2 + example.net/added v0.3.0 => ./a1 + example.net/lazy v0.1.0 => ./lazy + example.net/pruned v0.1.0 => ./pruned +) + +require ( + example.net/added v0.1.0 + example.net/lazy v0.1.0 +) +-- go.mod.tidy -- +module example.com/m + +go 1.17 + +replace ( + example.net/added v0.1.0 => ./a1 + example.net/added v0.2.0 => ./a2 + example.net/added v0.3.0 => ./a1 + example.net/lazy v0.1.0 => ./lazy + example.net/pruned v0.1.0 => ./pruned +) + +require example.net/lazy v0.1.0 +-- m.go -- +package m + +import ( + _ "example.net/added" + _ "example.net/lazy" +) + +-- a1/go.mod -- +module example.net/added + +go 1.17 +-- a2/go.mod -- +module example.net/added + +go 1.17 +-- a2/added.go -- +package added + +-- lazy/go.mod -- +module example.net/lazy + +go 1.17 + +require example.net/pruned v0.1.0 +-- lazy/lazy.go -- +package lazy + +-- pruned/go.mod -- +module example.net/pruned + +go 1.17 + +require example.net/added v0.2.0 diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt new file mode 100644 index 0000000..a45de5a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_ambiguous.txt @@ -0,0 +1,97 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + +# For this module, the dependency providing package +# example.net/ambiguous/nested/pkg is unambiguous in Go 1.17 (because only one +# root of the module graph contains the package), whereas it is ambiguous in +# Go 1.16 (because two different modules contain plausible packages and Go 1.16 +# does not privilege roots above other dependencies). +# +# However, the overall build list is identical for both versions. + +cp go.mod go.mod.orig + +! go mod tidy + +stderr '^example\.com/m imports\n\texample\.net/indirect imports\n\texample\.net/ambiguous/nested/pkg loaded from example\.net/ambiguous/nested@v0\.1\.0,\n\tbut go 1.16 would fail to locate it:\n\tambiguous import: found package example\.net/ambiguous/nested/pkg in multiple modules:\n\texample\.net/ambiguous v0.1.0 \(.*\)\n\texample\.net/ambiguous/nested v0.1.0 \(.*\)\n\n' + +stderr '\n\nTo proceed despite packages unresolved in go 1\.16:\n\tgo mod tidy -e\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' + +cmp go.mod go.mod.orig + + +# If we run 'go mod tidy -e', we should still save enough checksums to run +# 'go list -m all' reproducibly with go 1.16, even though we can't list +# the specific package. + +go mod tidy -e +! stderr '\n\tgo mod tidy' +cmp go.mod go.mod.orig + +go list -m all +cmp stdout all-m.txt + +go list -f $MODFMT example.net/ambiguous/nested/pkg +stdout '^example.net/ambiguous/nested v0\.1\.0$' +! stderr . + +go mod edit -go=1.16 +go list -m all +cmp stdout all-m.txt + +! go list -f $MODFMT example.net/ambiguous/nested/pkg +stderr '^ambiguous import: found package example\.net/ambiguous/nested/pkg in multiple modules:\n\texample\.net/ambiguous v0\.1\.0 \(.*\)\n\texample\.net/ambiguous/nested v0\.1\.0 \(.*\)\n' + + +# On the other hand, if we use -compat=1.17, 1.16 can't even load +# the build list (due to missing checksums). + +cp go.mod.orig go.mod +go mod tidy -compat=1.17 +! stderr . +go list -m all +cmp stdout all-m.txt + +go mod edit -go=1.16 +! go list -m all +stderr '^go: example\.net/indirect@v0\.1\.0 requires\n\texample\.net/ambiguous@v0\.1\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.net/ambiguous\n' + + +-- go.mod -- +module example.com/m + +go 1.17 + +replace example.net/indirect v0.1.0 => ./indirect + +require example.net/indirect v0.1.0 + +require example.net/ambiguous/nested v0.1.0 // indirect +-- all-m.txt -- +example.com/m +example.net/ambiguous v0.1.0 +example.net/ambiguous/nested v0.1.0 +example.net/indirect v0.1.0 => ./indirect +-- m.go -- +package m + +import _ "example.net/indirect" + +-- indirect/go.mod -- +module example.net/indirect + +go 1.17 + +require example.net/ambiguous v0.1.0 +-- indirect/indirect.go -- +package indirect + +import _ "example.net/ambiguous/nested/pkg" diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt new file mode 100644 index 0000000..dcf13e2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_deleted.txt @@ -0,0 +1,128 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# For this module, the "deleted" dependency contains an imported package, but +# Go 1.16 selects a higher version (in which that package has been deleted). + +cp go.mod go.mod.orig + +! go mod tidy + +stderr '^example\.com/m imports\n\texample\.net/deleted loaded from example\.net/deleted@v0\.1\.0,\n\tbut go 1\.16 would fail to locate it in example\.net/deleted@v0\.2\.0\n\n' + +stderr '\n\nTo upgrade to the versions selected by go 1.16, leaving some packages unresolved:\n\tgo mod tidy -e -go=1\.16 && go mod tidy -e -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1\.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' + + +# The suggested 'go mod tidy -e' command should proceed anyway. + +go mod tidy -e +cmp go.mod go.mod.tidy + + +# In 'go 1.16' mode we should error out in the way we claimed. + +cd 116-outside +! go list -deps -f $MODFMT example.com/m +stderr '^\.\.[/\\]m\.go:4:2: no required module provides package example\.net/deleted; to add it:\n\tgo get example\.net/deleted$' +cd .. + +go mod edit -go=1.16 +! go list -deps -f $MODFMT example.com/m +stderr '^go: updates to go\.mod needed; to update it:\n\tgo mod tidy$' + +! go mod tidy +stderr '^example\.com/m imports\n\texample\.net/deleted: module example\.net/deleted@latest found \(v0\.2\.0, replaced by \./d2\), but does not contain package example\.net/deleted$' + + +-- go.mod -- +module example.com/m + +go 1.17 + +replace ( + example.net/deleted v0.1.0 => ./d1 + example.net/deleted v0.2.0 => ./d2 + example.net/lazy v0.1.0 => ./lazy + example.net/pruned v0.1.0 => ./pruned +) + +require ( + example.net/deleted v0.1.0 + example.net/deleted v0.1.0 // redundant + example.net/lazy v0.1.0 +) +-- go.mod.tidy -- +module example.com/m + +go 1.17 + +replace ( + example.net/deleted v0.1.0 => ./d1 + example.net/deleted v0.2.0 => ./d2 + example.net/lazy v0.1.0 => ./lazy + example.net/pruned v0.1.0 => ./pruned +) + +require ( + example.net/deleted v0.1.0 + example.net/lazy v0.1.0 +) +-- 116-outside/go.mod -- +module outside + +go 1.16 + +replace ( + example.com/m => ../ + example.net/deleted v0.1.0 => ../d1 + example.net/deleted v0.2.0 => ../d2 + example.net/lazy v0.1.0 => ../lazy + example.net/pruned v0.1.0 => ../pruned +) + +require example.com/m v0.1.0 +-- m.go -- +package m + +import ( + _ "example.net/deleted" + _ "example.net/lazy" +) + +-- d1/go.mod -- +module example.net/deleted + +go 1.17 +-- d1/deleted.go -- +package deleted +-- d2/go.mod -- +module example.net/deleted + +go 1.17 +-- d2/README -- +There is no longer a Go package here. + +-- lazy/go.mod -- +module example.net/lazy + +go 1.17 + +require example.net/pruned v0.1.0 +-- lazy/lazy.go -- +package lazy + +-- pruned/go.mod -- +module example.net/pruned + +go 1.17 + +require example.net/deleted v0.2.0 diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt new file mode 100644 index 0000000..186a3f8 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_implicit.txt @@ -0,0 +1,129 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# For this module, Go 1.16 selects the same versions of all explicit dependencies +# as Go 1.17 does. However, Go 1.16 selects a higher version of an *implicit* +# dependency, imported by a test of one of the (external) imported packages. +# As a result, Go 1.16 also needs checksums for the module sources for that higher +# version. +# +# The Go 1.16 module graph looks like: +# +# m ---- lazy v0.1.0 ---- incompatible v1.0.0 +# | +# + ------------- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible +# +# The Go 1.17 module graph is the same except that the dependencies of +# requireincompatible are pruned out (because the module that requires +# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to +# the main module). + +# 'go mod tidy' should by default diagnose the difference in dependencies as an +# error, with useful suggestions about how to resolve it. + +cp go.mod go.mod.orig +! go mod tidy +stderr '^example\.com/m imports\n\texample\.net/lazy tested by\n\texample\.net/lazy.test imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n' +stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' + +cmp go.mod go.mod.orig + +# The suggested '-compat' flag to ignore differences should silence the error +# and leave go.mod unchanged, resulting in checksum errors when Go 1.16 tries +# to load a module pruned out by Go 1.17. + +go mod tidy -compat=1.17 +! stderr . +cmp go.mod go.mod.orig + +go list -deps -test -f $MODFMT all +stdout '^example\.com/retract/incompatible v1\.0\.0$' + +go mod edit -go=1.16 +! go list -deps -test -f $MODFMT all + + # TODO(#46160): -count=1 instead of -count=2. +stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v1\.0\.0: missing go\.sum entry; to add it:\n\tgo mod download example\.com/retract/incompatible$' + + +# If we combine a Go 1.16 go.sum file... +go mod tidy -go=1.16 + +# ...with a Go 1.17 go.mod file... +cp go.mod.orig go.mod + +# ...then Go 1.17 no longer works. 😞 +! go list -deps -test -f $MODFMT all +stderr -count=1 '^can''t load test package: lazy[/\\]lazy_test.go:3:8: missing go\.sum entry for module providing package example\.com/retract/incompatible \(imported by example\.net/lazy\); to add:\n\tgo get -t example.net/lazy@v0\.1\.0$' + + +# However, if we take the union of the go.sum files... +go list -mod=mod -deps -test all +cmp go.mod go.mod.orig + +# ...then Go 1.17 continues to work... +go list -deps -test -f $MODFMT all +stdout '^example\.com/retract/incompatible v1\.0\.0$' + +# ...and 1.16 also works(‽), but selects a different version for the +# external-test dependency. +go mod edit -go=1.16 +go list -deps -test -f $MODFMT all +stdout '^example\.com/retract/incompatible v2\.0\.0\+incompatible$' + + +-- go.mod -- +// Module m imports packages from the same versions under Go 1.17 +// as under Go 1.16, but under 1.16 its (implicit) external test dependencies +// are higher. +module example.com/m + +go 1.17 + +replace ( + example.net/lazy v0.1.0 => ./lazy + example.net/requireincompatible v0.1.0 => ./requireincompatible +) + +require example.net/lazy v0.1.0 +-- implicit.go -- +package implicit + +import _ "example.net/lazy" +-- lazy/go.mod -- +// Module lazy requires example.com/retract/incompatible v1.0.0. +// +// When viewed from the outside it also has a transitive dependency +// on v2.0.0+incompatible, but in lazy mode that transitive dependency +// is pruned out. +module example.net/lazy + +go 1.17 + +exclude example.com/retract/incompatible v2.0.0+incompatible + +require ( + example.com/retract/incompatible v1.0.0 + example.net/requireincompatible v0.1.0 +) +-- lazy/lazy.go -- +package lazy +-- lazy/lazy_test.go -- +package lazy_test + +import _ "example.com/retract/incompatible" +-- requireincompatible/go.mod -- +module example.net/requireincompatible + +go 1.15 + +require example.com/retract/incompatible v2.0.0+incompatible diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt new file mode 100644 index 0000000..11313f1 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_incompatible.txt @@ -0,0 +1,134 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# For this module, Go 1.17 prunes out a (transitive and otherwise-irrelevant) +# requirement on a retracted higher version of a dependency. +# However, when Go 1.16 reads the same requirements from the go.mod file, +# it does not prune out that requirement, and selects the retracted version. +# +# The Go 1.16 module graph looks like: +# +# m ---- lazy v0.1.0 ---- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible +# | | +# + -------+------------- incompatible v1.0.0 +# +# The Go 1.17 module graph is the same except that the dependencies of +# requireincompatible are pruned out (because the module that requires +# it — lazy v0.1.0 — specifies 'go 1.17', and it is not otherwise relevant to +# the main module). + + +# 'go mod tidy' should by default diagnose the difference in dependencies as an +# error, with useful suggestions about how to resolve it. + +cp go.mod go.mod.orig +! go mod tidy +stderr '^example\.com/m imports\n\texample\.net/lazy imports\n\texample\.com/retract/incompatible loaded from example\.com/retract/incompatible@v1\.0\.0,\n\tbut go 1\.16 would select v2\.0\.0\+incompatible\n\n' +stderr '\n\nTo upgrade to the versions selected by go 1\.16:\n\tgo mod tidy -go=1\.16 && go mod tidy -go=1\.17\nIf reproducibility with go 1\.16 is not needed:\n\tgo mod tidy -compat=1.17\nFor other options, see:\n\thttps://golang\.org/doc/modules/pruning\n' + +cmp go.mod go.mod.orig + + +# The suggested '-compat' flag to ignore differences should silence the error +# and leave go.mod unchanged, resulting in checksum errors when Go 1.16 tries +# to load a module pruned out by Go 1.17. + +go mod tidy -compat=1.17 +! stderr . +cmp go.mod go.mod.orig + +go mod edit -go=1.16 +! go list -f $MODFMT -deps ./... + # TODO(#46160): -count=1 instead of -count=2. +stderr -count=2 '^go: example\.net/lazy@v0\.1\.0 requires\n\texample\.net/requireincompatible@v0\.1\.0 requires\n\texample\.com/retract/incompatible@v2\.0\.0\+incompatible: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$' + + +# There are two ways for the module author to bring the two into alignment. +# One is to *explicitly* 'exclude' the version that is already *implicitly* +# pruned out under 1.17. + +go mod edit -exclude=example.com/retract/incompatible@v2.0.0+incompatible +go list -f $MODFMT -deps ./... +stdout '^example.com/retract/incompatible v1\.0\.0$' +! stdout 'v2\.0\.0' + + +# The other is to explicitly upgrade the version required under Go 1.17 +# to match the version selected by Go 1.16. The commands suggested by +# 'go mod tidy' should do exactly that. + +cp go.mod.orig go.mod + +go mod tidy -go=1.16 +go list -f $MODFMT -deps ./... +stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$' +! stdout 'v1\.0\.0' + +go mod tidy -go=1.17 +go list -f $MODFMT -deps ./... +stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$' +! stdout 'v1\.0\.0' + +go mod edit -go=1.16 +go list -f $MODFMT -deps ./... +stdout '^example.com/retract/incompatible v2\.0\.0\+incompatible$' +! stdout 'v1\.0\.0' + + +-- go.mod -- +// Module m indirectly imports a package from +// example.com/retract/incompatible. Its selected version of +// that module is lower under Go 1.17 semantics than under Go 1.16. +module example.com/m + +go 1.17 + +replace ( + example.net/lazy v0.1.0 => ./lazy + example.net/requireincompatible v0.1.0 => ./requireincompatible +) + +require example.net/lazy v0.1.0 + +require example.com/retract/incompatible v1.0.0 // indirect +-- incompatible.go -- +package incompatible + +import _ "example.net/lazy" + +-- lazy/go.mod -- +// Module lazy requires example.com/retract/incompatible v1.0.0. +// +// When viewed from the outside it also has a transitive dependency +// on v2.0.0+incompatible, but in lazy mode that transitive dependency +// is pruned out. +module example.net/lazy + +go 1.17 + +exclude example.com/retract/incompatible v2.0.0+incompatible + +require ( + example.com/retract/incompatible v1.0.0 + example.net/requireincompatible v0.1.0 +) +-- lazy/lazy.go -- +package lazy + +import _ "example.com/retract/incompatible" + +-- requireincompatible/go.mod -- +module example.net/requireincompatible + +go 1.15 + +require example.com/retract/incompatible v2.0.0+incompatible diff --git a/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt b/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt new file mode 100644 index 0000000..7c22fca --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_compat_irrelevant.txt @@ -0,0 +1,99 @@ +# https://golang.org/issue/46141: 'go mod tidy' for a Go 1.17 module should by +# default preserve enough checksums for the module to be used by Go 1.16. +# +# We don't have a copy of Go 1.16 handy, but we can simulate it by editing the +# 'go' version in the go.mod file to 1.16, without actually updating the +# requirements to match. + +[short] skip + +env MODFMT='{{with .Module}}{{.Path}} {{.Version}}{{end}}' + + +# This module selects the same versions in Go 1.16 and 1.17 for all modules +# that provide packages (or test dependencies of packages) imported by the +# main module. However, in Go 1.16 it selects a higher version of a +# transitive module dependency that is not otherwise relevant to the main module. +# As a result, Go 1.16 needs an additional checksum for the go.mod file of +# that irrelevant dependency. +# +# The Go 1.16 module graph looks like: +# +# m ---- lazy v0.1.0 ---- incompatible v1.0.0 +# | +# + ------------- requireincompatible v0.1.0 ---- incompatible v2.0.0+incompatible + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +go list -deps -test -f $MODFMT all +cp stdout out-117.txt + +go mod edit -go=1.16 +go list -deps -test -f $MODFMT all +cmp stdout out-117.txt + + +# If we explicitly drop compatibility with 1.16, we retain fewer checksums, +# which gives a cleaner go.sum file but causes 1.16 to fail in readonly mode. + +cp go.mod.orig go.mod +go mod tidy -compat=1.17 +cmp go.mod go.mod.orig + +go list -deps -test -f $MODFMT all +cmp stdout out-117.txt + +go mod edit -go=1.16 +! go list -deps -test -f $MODFMT all + # TODO(#46160): -count=1 instead of -count=2. +stderr -count=2 '^go: example.net/lazy@v0.1.0 requires\n\texample.com/retract/incompatible@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download example.com/retract/incompatible$' + + +-- go.mod -- +// Module m imports packages from the same versions under Go 1.17 +// as under Go 1.16, but under 1.16 its (implicit) external test dependencies +// are higher. +module example.com/m + +go 1.17 + +replace ( + example.net/lazy v0.1.0 => ./lazy + example.net/requireincompatible v0.1.0 => ./requireincompatible +) + +require example.net/lazy v0.1.0 +-- m.go -- +package m + +import _ "example.net/lazy" +-- lazy/go.mod -- +// Module lazy requires example.com/retract/incompatible v1.0.0. +// +// When viewed from the outside it also has a transitive dependency +// on v2.0.0+incompatible, but in lazy mode that transitive dependency +// is pruned out. +module example.net/lazy + +go 1.17 + +exclude example.com/retract/incompatible v2.0.0+incompatible + +require ( + example.com/retract/incompatible v1.0.0 + example.net/requireincompatible v0.1.0 +) +-- lazy/lazy.go -- +package lazy +-- lazy/unimported/unimported.go -- +package unimported + +import _ "example.com/retract/incompatible" +-- requireincompatible/go.mod -- +module example.net/requireincompatible + +go 1.15 + +require example.com/retract/incompatible v2.0.0+incompatible diff --git a/src/cmd/go/testdata/script/mod_tidy_convergence.txt b/src/cmd/go/testdata/script/mod_tidy_convergence.txt new file mode 100644 index 0000000..be0a8e9 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_convergence.txt @@ -0,0 +1,202 @@ +# This test demonstrates a simple case in which 'go mod tidy' may resolve a +# missing package, only to remove that package when resolving its dependencies. +# +# If we naively iterate 'go mod tidy' until the dependency graph converges, this +# scenario may fail to converge. + +# The import graph used in this test looks like: +# +# m --- x +# | +# x_test --- y +# +# The module dependency graph of m is initially empty. +# Modules x and y look like: +# +# x.1 (provides package x that imports y, but does not depend on module y) +# +# x.2-pre (no dependencies, but does not provide package x) +# +# y.1 (no dependencies, but provides package y) +# +# y.2 --- x.2-pre (provides package y) +# +# +# When we resolve the missing import of y in x_test, we add y@latest — which is +# y.2, not y.1 — as a new dependency. That upgrades to x to x.2-pre, which +# removes package x (and also the need for module y). We can then safely remove +# the dependency on module y, because nothing imports package y any more! +# +# We might be tempted to remove the dependency on module x for the same reason: +# it no longer provides any imported package. However, that would cause 'go mod +# tidy -e' to become unstable: with x.2-pre out of the way, we could once again +# resolve the missing import of package x by re-adding x.1. + +cp go.mod go.mod.orig + +# 'go mod tidy' without -e should fail without modifying go.mod, +# because it cannot resolve x and y simultaneously. +! go mod tidy + +cmp go.mod go.mod.orig + +stderr '^go: found example\.net/y in example\.net/y v0.2.0$' +stderr '^go: finding module for package example\.net/x$' + + # TODO: This error message should be clearer — it doesn't indicate why v0.2.0-pre is required. +stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' + + +# 'go mod tidy -e' should follow upgrades to try to resolve the modules that it +# can, and then stop. When we resolve example.net/y, we upgrade to example.net/x +# to v0.2.0-pre. At that version, package x no longer exists and no longer +# imports package y, so the import of x should be left unsatisfied and the +# existing dependency on example.net/x removed. +# +# TODO(bcmills): It would be ever better if we could keep the original +# dependency on example.net/x v0.1.0, but I don't see a way to do that without +# making the algorithm way too complicated. (We would have to detect that the +# new dependency on example.net/y interferes with the package that caused us to +# to add that dependency in the first place, and back out that part of the change +# without also backing out any other needed changes.) + +go mod tidy -e +cmp go.mod go.mod.tidye +stderr '^go: found example\.net/y in example\.net/y v0.2.0$' + + # TODO: This error message should be clearer — it doesn't indicate why v0.2.0-pre is required. +stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' + + +# Since we attempt to resolve the dependencies of package x whenever we add x itself, +# this end state is stable. + +go mod tidy -e +cmp go.mod go.mod.tidye + + +# An explicit 'go get' with the correct versions should allow 'go mod tidy' to +# succeed and remain stable. y.1 does not upgrade x, and can therefore be used +# with it. + +go get example.net/x@v0.1.0 example.net/y@v0.1.0 +go mod tidy +cmp go.mod go.mod.postget + + +# The 'tidy' logic for a lazy main module is somewhat different from that for an +# eager main module, but the overall behavior is the same. + +cp go.mod.orig go.mod +go mod edit -go=1.17 go.mod +go mod edit -go=1.17 go.mod.tidye + +go mod tidy -e +cmp go.mod go.mod.tidye +stderr '^go: found example\.net/y in example\.net/y v0.2.0$' +stderr '^example\.net/m imports\n\texample\.net/x: package example\.net/x provided by example\.net/x at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' + +go get example.net/x@v0.1.0 example.net/y@v0.1.0 +go mod tidy +cmp go.mod go.mod.postget-117 + + +-- go.mod -- +module example.net/m + +go 1.16 + +replace ( + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0 => ./y2 +) + +require ( + example.net/x v0.1.0 +) +-- go.mod.tidye -- +module example.net/m + +go 1.16 + +replace ( + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0 => ./y2 +) +-- go.mod.postget -- +module example.net/m + +go 1.16 + +replace ( + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0 => ./y2 +) + +require ( + example.net/x v0.1.0 + example.net/y v0.1.0 // indirect +) +-- go.mod.postget-117 -- +module example.net/m + +go 1.17 + +replace ( + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0 => ./y2 +) + +require example.net/x v0.1.0 + +require example.net/y v0.1.0 // indirect +-- m.go -- +package m + +import _ "example.net/x" + +-- x1/go.mod -- +module example.net/x + +go 1.16 +-- x1/x.go -- +package x +-- x1/x_test.go -- +package x + +import _ "example.net/y" + +-- x2-pre/go.mod -- +module example.net/x + +go 1.16 +-- x2-pre/README.txt -- +There is no package x here. Use example.com/x/subpkg instead. +-- x2-pre/subpkg/subpkg.go -- +package subpkg // import "example.net/x/subpkg" + +-- y1/go.mod -- +module example.net/y + +go 1.16 +-- y1/y.go -- +package y + +-- y2/go.mod -- +module example.net/y + +go 1.16 + +require example.net/x v0.2.0-pre +-- y2/y.go -- +package y + +import _ "example.net/x/subpkg" diff --git a/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt b/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt new file mode 100644 index 0000000..99599e5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_convergence_loop.txt @@ -0,0 +1,329 @@ +# This test demonstrates a simple case in which 'go mod tidy' may resolve a +# missing package, only to remove that package when resolving its dependencies. +# +# If we naively iterate 'go mod tidy' until the dependency graph converges, this +# scenario may fail to converge. + +# The import graph used in this test looks like: +# +# m --- w +# | +# + --- x +# | +# + --- y +# | +# + --- z +# +# The module dependency graph of m initially contains w.1 (and, by extension, +# y.2-pre and z.2-pre). This is an arbitrary point in the cycle of possible +# configurations. +# +# w.1 requires y.2-pre and z.2-pre +# x.1 requires z.2-pre and w.2-pre +# y.1 requires w.2-pre and x.2-pre +# z.1 requires x.2-pre and y.2-pre +# +# At each point, exactly one missing package can be resolved by adding a +# dependency on the .1 release of the module that provides that package. +# However, adding that dependency causes the module providing another package to +# roll over from its .1 release to its .2-pre release, which removes the +# package. Once the package is removed, 'go mod tidy -e' no longer sees the +# module as relevant to the main module, and will happily remove the existing +# dependency on it. +# +# The cycle is of length 4 so that at every step only one package can be +# resolved. This is important because it prevents the iteration from ever +# reaching a state in which every package is simultaneously over-upgraded — such +# a state is stable and does not exhibit failure to converge. + +cp go.mod go.mod.orig + +# 'go mod tidy' without -e should fail without modifying go.mod, +# because it cannot resolve x, y, and z simultaneously. +! go mod tidy + +cmp go.mod go.mod.orig + +stderr '^go: finding module for package example\.net/w$' +stderr '^go: finding module for package example\.net/x$' +stderr -count=2 '^go: finding module for package example\.net/y$' +stderr -count=2 '^go: finding module for package example\.net/z$' +stderr '^go: found example\.net/x in example\.net/x v0.1.0$' + + # TODO: These error messages should be clearer — it doesn't indicate why v0.2.0-pre is required. +stderr '^example\.net/m imports\n\texample\.net/w: package example\.net/w provided by example\.net/w at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' +stderr '^example\.net/m imports\n\texample\.net/y: package example\.net/y provided by example\.net/y at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' +stderr '^example\.net/m imports\n\texample\.net/z: package example\.net/z provided by example\.net/z at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' + + +# 'go mod tidy -e' should preserve all of the upgrades to modules that could +# provide the missing packages but don't. That would at least explain why they +# are missing, and why no individual module can be upgraded in order to satisfy +# a missing import. +# +# TODO(bcmills): Today, it doesn't preserve those upgrades, and instead advances +# the state by one through the cycle of semi-tidy states. + +go mod tidy -e + +cmp go.mod go.mod.tidye1 + +stderr '^go: finding module for package example\.net/w$' +stderr '^go: finding module for package example\.net/x$' +stderr -count=2 '^go: finding module for package example\.net/y$' +stderr -count=2 '^go: finding module for package example\.net/z$' +stderr '^go: found example\.net/x in example\.net/x v0.1.0$' + +stderr '^example\.net/m imports\n\texample\.net/w: package example\.net/w provided by example\.net/w at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' +stderr '^example\.net/m imports\n\texample\.net/y: package example\.net/y provided by example\.net/y at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' +stderr '^example\.net/m imports\n\texample\.net/z: package example\.net/z provided by example\.net/z at latest version v0\.1\.0 but not at required version v0\.2\.0-pre$' + + +go mod tidy -e +cmp go.mod go.mod.tidye2 + +go mod tidy -e +cmp go.mod go.mod.tidye3 + +go mod tidy -e +cmp go.mod go.mod.orig + + +# If we upgrade away all of the packages simultaneously, the resulting tidy +# state converges at "no dependencies", because simultaneously adding all of the +# packages simultaneously over-upgrades all of the dependencies, and 'go mod +# tidy' treats "no package can be added" as a terminal state. + +go get example.net/w@v0.2.0-pre example.net/x@v0.2.0-pre example.net/y@v0.2.0-pre example.net/z@v0.2.0-pre +go mod tidy -e +cmp go.mod go.mod.postget +go mod tidy -e +cmp go.mod go.mod.postget + + +# The 'tidy' logic for a lazy main module requires more iterations to converge, +# because it is willing to drop dependencies on non-root modules that do not +# otherwise provide imported packages. +# +# On the first iteration, it adds x.1 as a root, which upgrades z and w, +# dropping w.1's requirement on y. w.1 was initially a root, so the upgraded +# w.2-pre is retained as a root. +# +# On the second iteration, it adds y.1 as a root, which upgrades w and x, +# dropping x.1's requirement on z. x.1 was added as a root in the previous step, +# so the upgraded x.2-pre is retained as a root. +# +# On the third iteration, it adds z.1 as a root, which upgrades x and y. +# x and y were already roots (from the previous steps), so their upgraded versions +# are retained (not dropped) and the iteration stops. +# +# At that point, we have z.1 as a root providing package z, +# and w, x, and y have all been upgraded to no longer provide any packages. +# So only z is retained as a new root. +# +# (From the above, we can see that in a lazy module we still cycle through the +# same possible root states, but in a different order from the eager case.) +# +# TODO(bcmills): if we retained the upgrades on w, x, and y (since they are +# lexical prefixes for unresolved packages w, x, and y, respectively), then 'go +# mod tidy -e' itself would become stable and no longer cycle through states. + +cp go.mod.orig go.mod +go mod edit -go=1.17 go.mod +cp go.mod go.mod.117 +go mod edit -go=1.17 go.mod.tidye1 +go mod edit -go=1.17 go.mod.tidye2 +go mod edit -go=1.17 go.mod.tidye3 +go mod edit -go=1.17 go.mod.postget + +go list -m all + +go mod tidy -e +cmp go.mod go.mod.tidye3 + +go mod tidy -e +cmp go.mod go.mod.tidye2 + +go mod tidy -e +cmp go.mod go.mod.tidye1 + +go mod tidy -e +cmp go.mod go.mod.117 + + +# As in the eager case, for the lazy module the fully-upgraded dependency graph +# becomes empty, and the empty graph is stable. + +go get example.net/w@v0.2.0-pre example.net/x@v0.2.0-pre example.net/y@v0.2.0-pre example.net/z@v0.2.0-pre +go mod tidy -e +cmp go.mod go.mod.postget +go mod tidy -e +cmp go.mod go.mod.postget + + +-- m.go -- +package m + +import ( + _ "example.net/w" + _ "example.net/x" + _ "example.net/y" + _ "example.net/z" +) + +-- go.mod -- +module example.net/m + +go 1.16 + +replace ( + example.net/w v0.1.0 => ./w1 + example.net/w v0.2.0-pre => ./w2-pre + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0-pre => ./y2-pre + example.net/z v0.1.0 => ./z1 + example.net/z v0.2.0-pre => ./z2-pre +) + +require example.net/w v0.1.0 +-- go.mod.tidye1 -- +module example.net/m + +go 1.16 + +replace ( + example.net/w v0.1.0 => ./w1 + example.net/w v0.2.0-pre => ./w2-pre + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0-pre => ./y2-pre + example.net/z v0.1.0 => ./z1 + example.net/z v0.2.0-pre => ./z2-pre +) + +require example.net/x v0.1.0 +-- go.mod.tidye2 -- +module example.net/m + +go 1.16 + +replace ( + example.net/w v0.1.0 => ./w1 + example.net/w v0.2.0-pre => ./w2-pre + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0-pre => ./y2-pre + example.net/z v0.1.0 => ./z1 + example.net/z v0.2.0-pre => ./z2-pre +) + +require example.net/y v0.1.0 +-- go.mod.tidye3 -- +module example.net/m + +go 1.16 + +replace ( + example.net/w v0.1.0 => ./w1 + example.net/w v0.2.0-pre => ./w2-pre + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0-pre => ./y2-pre + example.net/z v0.1.0 => ./z1 + example.net/z v0.2.0-pre => ./z2-pre +) + +require example.net/z v0.1.0 +-- go.mod.postget -- +module example.net/m + +go 1.16 + +replace ( + example.net/w v0.1.0 => ./w1 + example.net/w v0.2.0-pre => ./w2-pre + example.net/x v0.1.0 => ./x1 + example.net/x v0.2.0-pre => ./x2-pre + example.net/y v0.1.0 => ./y1 + example.net/y v0.2.0-pre => ./y2-pre + example.net/z v0.1.0 => ./z1 + example.net/z v0.2.0-pre => ./z2-pre +) +-- w1/go.mod -- +module example.net/w + +go 1.16 + +require ( + example.net/y v0.2.0-pre + example.net/z v0.2.0-pre +) +-- w1/w.go -- +package w +-- w2-pre/go.mod -- +module example.net/w + +go 1.16 +-- w2-pre/README.txt -- +Package w has been removed. + +-- x1/go.mod -- +module example.net/x + +go 1.16 + +require ( + example.net/z v0.2.0-pre + example.net/w v0.2.0-pre +) +-- x1/x.go -- +package x +-- x2-pre/go.mod -- +module example.net/x + +go 1.16 +-- x2-pre/README.txt -- +Package x has been removed. + +-- y1/go.mod -- +module example.net/y + +go 1.16 + +require ( + example.net/w v0.2.0-pre + example.net/x v0.2.0-pre +) +-- y1/y.go -- +package y + +-- y2-pre/go.mod -- +module example.net/y + +go 1.16 +-- y2-pre/README.txt -- +Package y has been removed. + +-- z1/go.mod -- +module example.net/z + +go 1.16 + +require ( + example.net/x v0.2.0-pre + example.net/y v0.2.0-pre +) +-- z1/z.go -- +package z + +-- z2-pre/go.mod -- +module example.net/z + +go 1.16 +-- z2-pre/README.txt -- +Package z has been removed. diff --git a/src/cmd/go/testdata/script/mod_tidy_cycle.txt b/src/cmd/go/testdata/script/mod_tidy_cycle.txt new file mode 100644 index 0000000..e46f37d --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_cycle.txt @@ -0,0 +1,75 @@ +# Regression test for https://golang.org/issue/34086: +# 'go mod tidy' produced different go.mod file from other +# subcommands when certain kinds of cycles were present +# in the build graph. + +env GO111MODULE=on + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +# If the go.mod file is already tidy, 'go mod graph' should not modify it. +go mod graph +cmp go.mod go.mod.orig + +-- go.mod -- +module root + +go 1.13 + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + b v0.2.0 => ./b2 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) + +require ( + a v0.1.0 + b v0.2.0 // indirect +) +-- main.go -- +package main + +import _ "a" + +func main() {} + +-- a1/go.mod -- +module a + +go 1.13 + +require b v0.1.0 +-- a1/a.go -- +package a + +import _ "c" +-- b1/go.mod -- +module b + +go 1.13 + +require c v0.1.0 +-- b2/go.mod -- +module b + +go 1.13 + +require c v0.2.0 +-- c1/go.mod -- +module c + +go 1.13 +-- c2/c.go -- +package c +-- c2/go.mod -- +module c + +go 1.13 + +require b v0.2.0 +-- c2/c.go -- +package c diff --git a/src/cmd/go/testdata/script/mod_tidy_downgrade_ambiguous.txt b/src/cmd/go/testdata/script/mod_tidy_downgrade_ambiguous.txt new file mode 100644 index 0000000..8b508c7 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_downgrade_ambiguous.txt @@ -0,0 +1,58 @@ +# Verifies golang.org/issue/47738. + +# In this test, the user has rewritten their imports to use rsc.io/quote/v3, +# but their go.mod still requires rsc.io/quote@v1.5.2, and they indirectly +# require rsc.io/quote@v1.5.1 but don't import anything from it. +go list -m -f '{{.Path}}@{{.Version}}{{if .Indirect}} indirect{{end}}' all +stdout '^rsc.io/quote@v1.5.2$' +! stdout 'rsc.io/quote/v3' +go list -e all +! stdout '^rsc.io/quote$' + +# 'go mod tidy' should preserve the requirement on rsc.io/quote but mark it +# indirect. This prevents a downgrade to v1.5.1, which could introduce +# an ambiguity. +go mod tidy +go list -m -f '{{.Path}}@{{.Version}}{{if .Indirect}} indirect{{end}}' all +stdout '^rsc.io/quote@v1.5.2 indirect$' +stdout '^rsc.io/quote/v3@v3.0.0$' + +-- go.mod -- +module use + +go 1.16 + +require ( + old-indirect v0.0.0 + rsc.io/quote v1.5.2 +) + +replace old-indirect v0.0.0 => ./old-indirect +-- go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.1/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- use.go -- +package use + +import ( + _ "old-indirect/empty" + + _ "rsc.io/quote/v3" +) +-- old-indirect/empty/empty.go -- +package empty +-- old-indirect/go.mod -- +module old-indirect + +go 1.16 + +require rsc.io/quote v1.5.1 +-- old-indirect/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_tidy_error.txt b/src/cmd/go/testdata/script/mod_tidy_error.txt new file mode 100644 index 0000000..51fc65f --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_error.txt @@ -0,0 +1,39 @@ +env GO111MODULE=on + +# Regression test for golang.org/issue/27063: +# 'go mod tidy' and 'go mod vendor' should not hide loading errors. + +! go mod tidy +! stderr 'package nonexist is not in GOROOT' +stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' + +! go mod vendor +! stderr 'package nonexist is not in GOROOT' +stderr '^issue27063 imports\n\tnonexist.example.com: no required module provides package nonexist.example.com; to add it:\n\tgo get nonexist.example.com$' +stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: no required module provides package other.example.com/nonexist; to add it:\n\tgo get other.example.com/nonexist$' + +-- go.mod -- +module issue27063 + +go 1.13 + +require issue27063/other v0.0.0 +replace issue27063/other => ./other +-- x.go -- +package main + +import ( + "nonexist" + + "nonexist.example.com" + "issue27063/other" +) + +func main() {} +-- other/go.mod -- +module issue27063/other +-- other/other.go -- +package other + +import "other.example.com/nonexist" diff --git a/src/cmd/go/testdata/script/mod_tidy_indirect.txt b/src/cmd/go/testdata/script/mod_tidy_indirect.txt new file mode 100644 index 0000000..1f092b2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_indirect.txt @@ -0,0 +1,67 @@ +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +-- go.mod -- +module example.com/tidy + +go 1.16 + +require ( + example.net/incomplete v0.1.0 + example.net/indirect v0.2.0 // indirect + example.net/toolow v0.1.0 +) + +replace ( + example.net/incomplete v0.1.0 => ./incomplete + example.net/indirect v0.1.0 => ./indirect.1 + example.net/indirect v0.2.0 => ./indirect.2 + example.net/toolow v0.1.0 => ./toolow +) +-- tidy.go -- +package tidy + +import ( + _ "example.net/incomplete" + _ "example.net/toolow" +) + +-- incomplete/go.mod -- +module example.net/incomplete + +go 1.16 + +// This module omits a needed requirement on example.net/indirect. +-- incomplete/incomplete.go -- +package incomplete + +import _ "example.net/indirect/newpkg" + +-- toolow/go.mod -- +module example.net/toolow + +go 1.16 + +require example.net/indirect v0.1.0 +-- toolow/toolow.go -- +package toolow + +import _ "example.net/indirect/oldpkg" + +-- indirect.1/go.mod -- +module example.net/indirect + +go 1.16 +-- indirect.1/oldpkg/oldpkg.go -- +package oldpkg + + +-- indirect.2/go.mod -- +module example.net/indirect + +go 1.16 +-- indirect.2/oldpkg/oldpkg.go -- +package oldpkg +-- indirect.2/newpkg/newpkg.go -- +package newpkg diff --git a/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt new file mode 100644 index 0000000..9abbabd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_lazy_self.txt @@ -0,0 +1,66 @@ +# Regression test for https://golang.org/issue/46078: +# 'go mod tidy' should not panic if the main module initially +# requires an older version of itself. + +# A module may require an older version of itself without error. This is +# inconsistent (the required version is never selected), but we still get +# a reproducible build list. +go list -m all +stdout '^golang.org/issue/46078$' + +# 'go mod tidy' should fix this (and not crash). +go mod tidy + + +# We prune out redundant roots very early on in module loading, and at that +# point the indirect requirement on example.net/x v0.1.0 appears to be +# irrelevant. It should be pruned out; when the import of "example.net/x" is +# later resolved, it should resolve at the latest version (v0.2.0), not the +# version implied by the (former) misleading requirement on the older version of +# the main module. + +cmp go.mod go.mod.tidy + + +-- go.mod -- +module golang.org/issue/46078 + +go 1.17 + +replace ( + example.net/x v0.1.0 => ./x + example.net/x v0.2.0 => ./x + golang.org/issue/46078 v0.1.0 => ./old +) + +require golang.org/issue/46078 v0.1.0 +-- go.mod.tidy -- +module golang.org/issue/46078 + +go 1.17 + +replace ( + example.net/x v0.1.0 => ./x + example.net/x v0.2.0 => ./x + golang.org/issue/46078 v0.1.0 => ./old +) + +require example.net/x v0.2.0 +-- issue46078/issue.go -- +package issue46078 + +import _ "example.net/x" + +-- old/go.mod -- +module golang.org/issue/46078 + +go 1.17 + +require example.net/x v0.1.0 + +-- x/go.mod -- +module example.net/x + +go 1.17 +-- x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_tidy_newroot.txt b/src/cmd/go/testdata/script/mod_tidy_newroot.txt new file mode 100644 index 0000000..3abd5ef --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_newroot.txt @@ -0,0 +1,82 @@ +# https://golang.org/issue/45952: 'go mod tidy' in an eager module failed due +# to an erroneous check on root completeness. +# +# Per the issue report: +# > It may have to do with: +# > +# > package A imports package B in go.mod, which imports package C in its own go.mod +# > package A drops direct dependency on package B … +# +# We infer from that that package C is still needed by some other indirect +# dependency, and must be at a higher version than what is required by that +# dependency (or else no new root would be needed). An additional package D +# in its own module satisfies that condition, reproducing the bug. + +go mod tidy +cmp go.mod go.mod.tidy + +-- go.mod -- +module example.net/a + +go 1.16 + +require ( + example.net/b v0.1.0 + example.net/d v0.1.0 +) + +replace ( + example.net/b v0.1.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d +) +-- go.mod.tidy -- +module example.net/a + +go 1.16 + +require ( + example.net/c v0.2.0 // indirect + example.net/d v0.1.0 +) + +replace ( + example.net/b v0.1.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d +) +-- a.go -- +package a + +import _ "example.net/d" + +-- b/go.mod -- +module example.net/b + +go 1.16 + +require example.net/c v0.2.0 +-- b/b.go -- +package b + +import _ "example.net/c" + +-- c/go.mod -- +module example.net/c + +go 1.16 +-- c/c.go -- +package c + +-- d/go.mod -- +module example.net/d + +go 1.16 + +require example.net/c v0.1.0 +-- d/d.go -- +package d + +import _ "example.net/c" diff --git a/src/cmd/go/testdata/script/mod_tidy_old.txt b/src/cmd/go/testdata/script/mod_tidy_old.txt new file mode 100644 index 0000000..7428f0c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_old.txt @@ -0,0 +1,46 @@ +# 'go mod tidy' should remove content sums for module versions that aren't +# in the build list. It should preserve go.mod sums for module versions that +# are in the module graph though. +# Verifies golang.org/issue/33008. +go mod tidy +! grep '^rsc.io/quote v1.5.0 h1:' go.sum +grep '^rsc.io/quote v1.5.0/go.mod h1:' go.sum + +-- go.mod -- +module m + +go 1.15 + +require ( + rsc.io/quote v1.5.2 + example.com/r v0.0.0 +) + +replace example.com/r => ./r + +-- go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.0 h1:6fJa6E+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE= +rsc.io/quote v1.5.0/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/testonly v1.0.0 h1:K/VWHdO+Jv7woUXG0GzVNx1czBXUt3Ib1deaMn+xk64= +rsc.io/testonly v1.0.0/go.mod h1:OqmGbIFOcF+XrFReLOGZ6BhMM7uMBiQwZsyNmh74SzY= + +-- r/go.mod -- +module example.com/r + +require rsc.io/quote v1.5.0 + +-- use.go -- +package use + +import _ "example.com/r" + +-- r/use.go -- +package use + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_tidy_oldgo.txt b/src/cmd/go/testdata/script/mod_tidy_oldgo.txt new file mode 100644 index 0000000..0e88b06 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_oldgo.txt @@ -0,0 +1,21 @@ +# Modules were introduced in Go 1.11, but for various reasons users may +# decide to declare a (much!) older go version in their go.mod file. +# Modules with very old versions should not be rejected, and should have +# the same module-graph semantics as in Go 1.11. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +-- go.mod -- +module example.com/legacy/go1 + +go 1.0 + +require golang.org/x/text v0.3.0 +-- main.go -- +package main + +import _ "golang.org/x/text/language" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_tidy_quote.txt b/src/cmd/go/testdata/script/mod_tidy_quote.txt new file mode 100644 index 0000000..423c7c2 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_quote.txt @@ -0,0 +1,26 @@ +# Check that mod tidy does not introduce repeated +# require statements when input go.mod has quoted requirements. +env GO111MODULE=on + +go mod tidy +grep -count=1 rsc.io/quote go.mod + +cp go.mod2 go.mod +go mod tidy +grep -count=1 rsc.io/quote go.mod + + +-- 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 +) diff --git a/src/cmd/go/testdata/script/mod_tidy_replace.txt b/src/cmd/go/testdata/script/mod_tidy_replace.txt new file mode 100644 index 0000000..274f3bf --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_replace.txt @@ -0,0 +1,145 @@ +env GO111MODULE=on +env GOFLAGS=-mod=mod +[short] skip + +# golang.org/issue/30166: 'go mod tidy' should not crash if a replaced module is +# involved in a cycle. +cd cycle +env GOTRACEBACK=off +go mod tidy +cd .. + +# From inside the module, 'go list -m all' should NOT include transitive +# requirements of modules that have been replaced. +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +! stdout 'rsc.io/sampler' +! stdout 'golang.org/x/text' + +# From outside the module, 'go list -m all' should include them. +cd outside +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +stdout 'rsc.io/sampler v1.3.0' +stdout 'golang.org/x/text' +cd .. + +# 'go list all' should add indirect requirements to satisfy the packages +# imported from replacement modules. +! grep 'rsc.io/sampler' go.mod +! grep 'golang.org/x/text' go.mod +go list all +grep 'rsc.io/sampler' go.mod +grep 'golang.org/x/text' go.mod + +# 'go get' and 'go mod tidy' should follow the requirements of the replacements, +# not the originals, even if that results in a set of versions that are +# misleading or redundant without those replacements. +go get rsc.io/sampler@v1.2.0 +go mod tidy +go list -m all +stdout 'rsc.io/quote/v3 v3.0.0' +stdout 'rsc.io/sampler v1.2.0' +stdout 'golang.org/x/text' + +# The requirements seen from outside may be higher (or lower) +# than those seen from within the module. +grep 'rsc.io/sampler v1.2.0' go.mod +cd outside +go list -m all +stdout 'rsc.io/sampler v1.3.0' +cd .. + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod tidy +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +-- go.mod -- +module example.com/tidy + +require rsc.io/quote/v3 v3.0.0 +replace rsc.io/quote/v3 => ./not-rsc.io/quote/v3 + +-- imports.go -- +package tidy + +import _ "rsc.io/quote/v3" + +-- outside/go.mod -- +module example.com/tidy/outside + +require example.com/tidy v0.0.0 +replace example.com/tidy => ./.. + +-- not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +// No requirements specified! + +-- not-rsc.io/quote/v3/quote.go -- +package quote + +import ( + _ "rsc.io/sampler" + _ "golang.org/x/text/language" +) + +-- cycle/go.mod -- +module golang.org/issue/30166 + +require ( + golang.org/issue/30166/a v0.0.0 + golang.org/issue/30166/b v0.0.0 +) + +replace ( + golang.org/issue/30166/a => ./a + golang.org/issue/30166/b => ./b +) +-- cycle/cycle.go -- +package cycle + +import ( + _ "golang.org/issue/30166/a" + _ "golang.org/issue/30166/b" +) +-- cycle/a/a.go -- +package a +-- cycle/a/go.mod -- +module golang.org/issue/30166/a + +require golang.org/issue/30166/b v0.0.0 +-- cycle/b/b.go -- +package b +-- cycle/b/go.mod -- +module golang.org/issue/30166/b + +require golang.org/issue/30166/a v0.0.0 +-- multiple-paths/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter + +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) + +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 +-- multiple-paths/use.go -- +package quoter + +import ( + _ "not-rsc.io/quote/v3" + _ "rsc.io/quote/v3" +) diff --git a/src/cmd/go/testdata/script/mod_tidy_replace_old.txt b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt new file mode 100644 index 0000000..cfd3792 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_replace_old.txt @@ -0,0 +1,34 @@ +# Regression test for https://golang.org/issue/46659. +# +# If a 'replace' directive specifies an older-than-selected version of a module, +# 'go mod tidy' shouldn't try to add that version to the build list to resolve a +# missing package: it won't be selected, and would cause the module loader to +# loop indefinitely trying to resolve the package. + +cp go.mod go.mod.orig + +! go mod tidy +! stderr panic +stderr '^golang\.org/issue46659 imports\n\texample\.com/missingpkg/deprecated: package example\.com/missingpkg/deprecated provided by example\.com/missingpkg at latest version v1\.0\.0 but not at required version v1\.0\.1-beta$' + +go mod tidy -e + +cmp go.mod go.mod.orig + +-- go.mod -- +module golang.org/issue46659 + +go 1.17 + +replace example.com/missingpkg v1.0.1-alpha => example.com/missingpkg v1.0.0 + +require example.com/usemissingpre v1.0.0 + +require example.com/missingpkg v1.0.1-beta // indirect +-- m.go -- +package m + +import ( + _ "example.com/missingpkg/deprecated" + _ "example.com/usemissingpre" +) diff --git a/src/cmd/go/testdata/script/mod_tidy_sum.txt b/src/cmd/go/testdata/script/mod_tidy_sum.txt new file mode 100644 index 0000000..5a15818 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_sum.txt @@ -0,0 +1,33 @@ +env GO111MODULE=on + +# go.sum should list directly used modules and dependencies +go get rsc.io/quote@v1.5.2 +go mod tidy +grep rsc.io/sampler go.sum + +# go.sum should not normally lose old entries +go get rsc.io/quote@v1.0.0 +grep 'rsc.io/quote v1.0.0' go.sum +grep 'rsc.io/quote v1.5.2' go.sum +grep rsc.io/sampler go.sum + +# go mod tidy should clear dead entries from go.sum +go mod tidy +grep 'rsc.io/quote v1.0.0' go.sum +! grep 'rsc.io/quote v1.5.2' go.sum +! grep rsc.io/sampler go.sum + +# go.sum with no entries is OK to keep +# (better for version control not to delete and recreate.) +cp x.go.noimports x.go +go mod tidy +exists go.sum +! grep . go.sum + +-- go.mod -- +module x +-- x.go -- +package x +import _ "rsc.io/quote" +-- x.go.noimports -- +package x diff --git a/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt b/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt new file mode 100644 index 0000000..d4658c6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_symlink_issue35941.txt @@ -0,0 +1,36 @@ +env GO111MODULE=on +[!symlink] skip + +cd m +symlink symlink -> ../outside + +cp go.mod go.mod.orig + +# Issue 35941: suppress symlink warnings when running 'go mod tidy'. +# 'go mod tidy' should not scan packages in symlinked subdirectories. +go mod tidy +! stderr 'warning: ignoring symlink' +cmp go.mod go.mod.orig + +! go build ./symlink +stderr '^symlink[\\/]symlink.go:3:8: module example.net/unresolved provides package example.net/unresolved and is replaced but not required; to add it:\n\tgo get example.net/unresolved@v0.1.0$' + +-- m/go.mod -- +module example.net/m + +go 1.16 + +replace example.net/unresolved v0.1.0 => ../unresolved +-- m/a.go -- +package a +-- outside/symlink.go -- +package symlink + +import _ "example.net/unresolved" +-- unresolved/go.mod -- +module example.net/unresolved + +go 1.16 +-- unresolved/unresolved.go -- +// Package unresolved exists, but 'go mod tidy' won't add it. +package unresolved diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt new file mode 100644 index 0000000..8c34a99 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt @@ -0,0 +1,57 @@ +# https://golang.org/issue/46142: 'go mod tidy' should error out if the version +# in the go.mod file is newer than the most recent supported version. + +cp go.mod go.mod.orig + + +# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should +# refuse to edit it: we don't know what a tidy go.mod file for that version +# would look like. + +! go mod tidy +stderr 'go: go.mod file indicates go 2000.0, but maximum version supported by tidy is '$goversion'$' +cmp go.mod go.mod.orig + + +# The -e flag should push past the error and edit the file anyway, +# but preserve the too-high version. + +cp go.mod.orig go.mod +go mod tidy -e +stderr 'go: go.mod file indicates go 2000.0, but maximum version supported by tidy is '$goversion'$' +cmp go.mod go.mod.tidy + + +# Explicitly switching to a supported version should suppress the error completely. + +cp go.mod.orig go.mod +go mod tidy -go=1.17 +! stderr 'maximum supported version' +go mod edit -go=1.17 go.mod.tidy +cmp go.mod go.mod.tidy + + +-- go.mod -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m +-- go.mod.tidy -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m + +require example.net/m v0.0.0 +-- x.go -- +package x + +import "example.net/m" +-- m/go.mod -- +module example.net/m + +go 1.17 +-- m/m.go -- +package m diff --git a/src/cmd/go/testdata/script/mod_tidy_version.txt b/src/cmd/go/testdata/script/mod_tidy_version.txt new file mode 100644 index 0000000..3bc97bc --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_version.txt @@ -0,0 +1,262 @@ +# https://golang.org/issue/45094: 'go mod tidy' now accepts a '-go' flag +# to change the language version in use. +# +# The package import graph used in this test looks like: +# +# m --- a --- b +# | +# b_test --- c +# | +# c_test --- d +# +# The module diagram looks like: +# +# m --- a --- b +# | +# + --- c +# | +# + --- d +# +# Module b omits its dependency on c, and module c omits its dependency on d. +# +# In go 1.15, the tidy main module must require a (because it is direct), +# c (because it is a missing test dependency of an imported package), +# and d (because it is a missing transitive test dependency). +# +# In go 1.16, the tidy main module can omit d because it is no longer +# included in "all". +# +# In go 1.17, the main module must explicitly require b +# (because it is transitively imported by the main module). + + +cp go.mod go.mod.orig + + +# An invalid argument should be rejected. + +! go mod tidy -go=bananas +stderr '^invalid value "bananas" for flag -go: expecting a Go version like "'$goversion'"$' +cmp go.mod go.mod.orig + +! go mod tidy -go=0.9 +stderr '^invalid value "0.9" for flag -go: expecting a Go version like "'$goversion'"$' + +! go mod tidy -go=2000.0 +stderr '^invalid value "2000.0" for flag -go: maximum supported Go version is '$goversion'$' + + +# Supported versions should change the go.mod file to be tidy according to the +# indicated version. + +go mod tidy -go=1.15 +cmp go.mod go.mod.115 + +go mod tidy +cmp go.mod go.mod.115 + + +go mod tidy -go=1.16 +cmp go.mod go.mod.116 + +go mod tidy +cmp go.mod go.mod.116 + + +go mod tidy -go=1.17 +cmp go.mod go.mod.117 + +go mod tidy +cmp go.mod go.mod.117 + + +# If we downgrade back to 1.15, we should re-resolve d to v0.2.0 instead +# of the original v0.1.0 (because the original requirement is lost). + +go mod tidy -go=1.15 +cmp go.mod go.mod.115-2 + + +# -go= (with an empty argument) maintains the existing version or adds the +# default version (just like omitting the flag). + +go mod tidy -go='' +cmp go.mod go.mod.115-2 + +cp go.mod.orig go.mod +go mod tidy -go='' +cmpenv go.mod go.mod.latest + + + +-- go.mod -- +module example.com/m + +require example.net/a v0.1.0 + +require ( + example.net/c v0.1.0 // indirect + example.net/d v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- m.go -- +package m + +import _ "example.net/a" + +-- go.mod.115 -- +module example.com/m + +go 1.15 + +require example.net/a v0.1.0 + +require ( + example.net/c v0.1.0 // indirect + example.net/d v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- go.mod.115-2 -- +module example.com/m + +go 1.15 + +require example.net/a v0.1.0 + +require ( + example.net/c v0.1.0 // indirect + example.net/d v0.2.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- go.mod.116 -- +module example.com/m + +go 1.16 + +require example.net/a v0.1.0 + +require example.net/c v0.1.0 // indirect + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- go.mod.117 -- +module example.com/m + +go 1.17 + +require example.net/a v0.1.0 + +require ( + example.net/b v0.1.0 // indirect + example.net/c v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- go.mod.latest -- +module example.com/m + +go $goversion + +require example.net/a v0.1.0 + +require ( + example.net/b v0.1.0 // indirect + example.net/c v0.1.0 // indirect +) + +replace ( + example.net/a v0.1.0 => ./a + example.net/a v0.2.0 => ./a + example.net/b v0.1.0 => ./b + example.net/b v0.2.0 => ./b + example.net/c v0.1.0 => ./c + example.net/c v0.2.0 => ./c + example.net/d v0.1.0 => ./d + example.net/d v0.2.0 => ./d +) +-- a/go.mod -- +module example.net/a + +go 1.15 + +require example.net/b v0.1.0 +-- a/a.go -- +package a + +import _ "example.net/b" + +-- b/go.mod -- +module example.net/b + +go 1.15 +-- b/b.go -- +package b +-- b/b_test.go -- +package b_test + +import _ "example.net/c" + +-- c/go.mod -- +module example.net/c + +go 1.15 +-- c/c.go -- +package c +-- c/c_test.go -- +package c_test + +import _ "example.net/d" + +-- d/go.mod -- +module example.net/d + +go 1.15 +-- d/d.go -- +package d diff --git a/src/cmd/go/testdata/script/mod_update_sum_readonly.txt b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt new file mode 100644 index 0000000..41f12e4 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_update_sum_readonly.txt @@ -0,0 +1,34 @@ +# When finding the latest version of a module, we should not download version +# contents. Previously, we downloaded .zip files to determine whether a real +# .mod file was present in order to decide whether +incompatible versions +# could be "latest". +# +# Verifies #47377. + +# rsc.io/breaker has two versions, neither of which has a .mod file. +go list -m -versions rsc.io/breaker +stdout '^rsc.io/breaker v1.0.0 v2.0.0\+incompatible$' +go mod download rsc.io/breaker@v1.0.0 +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.mod +go mod download rsc.io/breaker@v2.0.0+incompatible +! grep '^go' $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.mod + +# Delete downloaded .zip files. +go clean -modcache + +# Check for updates. +go list -m -u rsc.io/breaker +stdout '^rsc.io/breaker v1.0.0 \[v2.0.0\+incompatible\]$' + +# We should not have downloaded zips. +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v1.0.0.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/breaker/@v/v2.0.0+incompatible.zip + +-- go.mod -- +module m + +go 1.16 + +require rsc.io/breaker v1.0.0 +-- go.sum -- +rsc.io/breaker v1.0.0/go.mod h1:s5yxDXvD88U1/ESC23I2FK3Lkv4YIKaB1ij/Hbm805g= diff --git a/src/cmd/go/testdata/script/mod_upgrade_patch.txt b/src/cmd/go/testdata/script/mod_upgrade_patch.txt new file mode 100644 index 0000000..79a9808 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_upgrade_patch.txt @@ -0,0 +1,110 @@ +env GO111MODULE=on +[short] skip + +# Initially, we are at v1.0.0 for all dependencies. +go get +cp go.mod go.mod.orig +go list -m all +stdout '^patch.example.com/direct v1.0.0' +stdout '^patch.example.com/indirect v1.0.0' +! stdout '^patch.example.com/depofdirectpatch' + +# @patch should be rejected for modules not already in the build list. +! go get patch.example.com/depofdirectpatch@patch +stderr '^go: can''t query version "patch" of module patch.example.com/depofdirectpatch: no existing version is required$' +cmp go.mod.orig go.mod + +# get -u=patch, with no arguments, should patch-update all dependencies +# of the package in the current directory, pulling in transitive dependencies +# and also patching those. +cp go.mod.orig go.mod +go get -u=patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# 'get all@patch' should patch the modules that provide packages in 'all'. +cp go.mod.orig go.mod +go get all@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# ...but 'all@patch' should fail if any of the affected modules do not already +# have a selected version. +cp go.mod.orig go.mod +go mod edit -droprequire=patch.example.com/direct +cp go.mod go.mod.dropped +! go get all@patch +stderr '^go: all@patch: can''t query version "patch" of module patch.example.com/direct: no existing version is required$' +cmp go.mod.dropped go.mod + +# Requesting the direct dependency with -u=patch but without an explicit version +# should patch-update it and its dependencies. +cp go.mod.orig go.mod +go get -u=patch patch.example.com/direct +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.1' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# Requesting only the indirect dependency should not update the direct one. +cp go.mod.orig go.mod +go get -u=patch patch.example.com/indirect +go list -m all +stdout '^patch.example.com/direct v1.0.0' +stdout '^patch.example.com/indirect v1.0.1' +! stdout '^patch.example.com/depofdirectpatch' + +# @patch should apply only to the specific module, +# but the result must reflect its upgraded requirements. +cp go.mod.orig go.mod +go get patch.example.com/direct@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.0.0' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# An explicit @patch should override a general -u. +cp go.mod.orig go.mod +go get -u patch.example.com/direct@patch +go list -m all +stdout '^patch.example.com/direct v1.0.1' +stdout '^patch.example.com/indirect v1.1.0' +stdout '^patch.example.com/depofdirectpatch v1.0.0' + +# An explicit @latest should override a general -u=patch. +cp go.mod.orig go.mod +go get -u=patch patch.example.com/direct@latest +go list -m all +stdout '^patch.example.com/direct v1.1.0' +stdout '^patch.example.com/indirect v1.0.1' +! stdout '^patch.example.com/depofdirectpatch' + +# Standard library packages cannot be upgraded explicitly. +cp go.mod.orig go.mod +! go get cmd/vet@patch +stderr 'go: can''t request explicit version "patch" of standard library package cmd/vet$' + +# However, standard-library packages without explicit versions are fine. +go get -u=patch cmd/go + +# We can upgrade to a new version of a module with no root package. +go get example.com/noroot@v1.0.0 +go list -m all +stdout '^example.com/noroot v1.0.0$' +go get example.com/noroot@patch +go list -m all +stdout '^example.com/noroot v1.0.1$' + + +-- go.mod -- +module x + +require patch.example.com/direct v1.0.0 + +-- main.go -- +package x +import _ "patch.example.com/direct" diff --git a/src/cmd/go/testdata/script/mod_vcs_missing.txt b/src/cmd/go/testdata/script/mod_vcs_missing.txt new file mode 100644 index 0000000..9e6e371 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vcs_missing.txt @@ -0,0 +1,28 @@ +[exec:bzr] skip 'tests NOT having bzr' +[!net] skip + +env GO111MODULE=on +env GOPROXY=direct + +cd empty +! go get launchpad.net/gocheck +stderr '"bzr": executable file not found' +cd .. + +# 1.11 used to give the cryptic error "cannot find module for path" here, but +# only for a main package. +cd main +! go build -mod=mod +stderr '"bzr": executable file not found' +cd .. + +-- empty/go.mod -- +module m +-- main/go.mod -- +module m +-- main/main.go -- +package main + +import _ "launchpad.net/gocheck" + +func main() {} diff --git a/src/cmd/go/testdata/script/mod_vendor.txt b/src/cmd/go/testdata/script/mod_vendor.txt new file mode 100644 index 0000000..a2727dd --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor.txt @@ -0,0 +1,354 @@ +env GO111MODULE=on + +# Without vendoring, a build should succeed unless -mod=vendor is set. +[!short] go build +[!short] ! go build -mod=vendor + +# Without vendoring, 'go list' should report the replacement directory for +# a package in a replaced module. +go list -f {{.Dir}} x +stdout 'src[\\/]x' + +# 'go mod vendor' should copy all replaced modules to the vendor directory. +go mod vendor -v +stderr '^# x v1.0.0 => ./x' +stderr '^x' +stderr '^# y v1.0.0 => ./y' +stderr '^y' +stderr '^# z v1.0.0 => ./z' +stderr '^z' +! stderr '^w' +grep 'a/foo/bar/b\na/foo/bar/c' vendor/modules.txt # must be sorted + +# An explicit '-mod=mod' should ignore the vendor directory. +go list -mod=mod -f {{.Dir}} x +stdout 'src[\\/]x' + +go list -mod=mod -f {{.Dir}} -m x +stdout 'src[\\/]x' + +# An explicit '-mod=vendor' should report package directories within +# the vendor directory. +go list -mod=vendor -f {{.Dir}} x +stdout 'src[\\/]vendor[\\/]x' + +# 'go list -mod=vendor -m' should successfully list vendored modules, +# but should not provide a module directory because no directory contains +# the complete module. +go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m x +stdout '^v1.0.0 $' + +# -mod=vendor should cause 'go list' flags that look up versions to fail. +! go list -mod=vendor -versions -m x +stderr '^go: can''t determine available versions using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$' +! go list -mod=vendor -u -m x +stderr '^go: can''t determine available upgrades using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)$' + +# 'go list -mod=vendor -m' on a transitive dependency that does not +# provide vendored packages should give a helpful error rather than +# 'not a known dependency'. +! go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m diamondright +stderr 'go: module diamondright: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# 'go list -mod=mod' should report packages outside the import graph, +# but 'go list -mod=vendor' should error out for them. +go list -mod=mod -f {{.Dir}} w +stdout 'src[\\/]w' +! go list -mod=vendor -f {{.Dir}} w +stderr 'src[\\/]vendor[\\/]w' + +go list -mod=mod -f {{.Dir}} diamondright +stdout 'src[\\/]diamondright' + +# Test dependencies should not be copied. +! exists vendor/x/testdata +! exists vendor/a/foo/bar/b/ignored.go +! exists vendor/a/foo/bar/b/main_test.go + +# Licenses and other metadata for each module should be copied +# if any package within their module is copied. +exists vendor/a/foo/AUTHORS.txt +exists vendor/a/foo/CONTRIBUTORS +exists vendor/a/foo/LICENSE +exists vendor/a/foo/PATENTS +exists vendor/a/foo/COPYING +exists vendor/a/foo/COPYLEFT +exists vendor/x/NOTICE! +exists vendor/mysite/myname/mypkg/LICENSE.txt + +! exists vendor/a/foo/licensed-to-kill +! exists vendor/w +! exists vendor/w/LICENSE +! exists vendor/x/x2 +! exists vendor/x/x2/LICENSE + +# 'go mod vendor' should work with an alternative vendor directory if the -o flag is provided. +go mod vendor -v -o alternative-vendor-dir +exists alternative-vendor-dir/modules.txt +exists alternative-vendor-dir/a/foo/LICENSE + +# 'go mod vendor' should interpret paths relative to the current working directory when the -o flag is provided. +mkdir dir1 +mkdir dir2 + +cd dir1 +go mod vendor -v -o relative-vendor-dir + +go mod vendor -v -o ../dir2/relative-vendor-dir + +cd .. +exists dir1/relative-vendor-dir/modules.txt +exists dir1/relative-vendor-dir/a/foo/LICENSE +exists dir2/relative-vendor-dir/modules.txt +exists dir2/relative-vendor-dir/a/foo/LICENSE + +# 'go mod vendor' should fall back to the default 'vendor' directory when an empty argument is passed to the -o flag +# the same behavior should be exhibited both on the module root directory, as well as nested subdirectories + +go mod vendor -v -o '' +exists vendor/modules.txt + +env GOFLAGS=-o=foo +go mod vendor -v -o '' +exists vendor/modules.txt +env GOFLAGS='' + +mkdir -p nested/dir +cd nested/dir +go mod vendor -v -o '' +! exists vendor/ +exists ../../vendor/modules.txt +cd ../.. + +# 'go mod vendor' should work with absolute paths as well +go mod vendor -v -o $WORK/tmp/absolute-vendor-dir +exists $WORK/tmp/absolute-vendor-dir/modules.txt + +[short] stop + +# 'go build' and 'go test' using vendored packages should succeed. +go build -mod=mod +go build -mod=vendor +go test -mod=vendor . ./subdir +go test -mod=vendor ./... +go fmt -mod=vendor ./... + +-- go.mod -- +module m + +go 1.13 + +require ( + a v1.0.0 + diamondroot v0.0.0 + mysite/myname/mypkg v1.0.0 + w v1.0.0 // indirect + x v1.0.0 + y v1.0.0 + z v1.0.0 +) + +replace ( + a v1.0.0 => ./a + diamondleft => ./diamondleft + diamondpoint => ./diamondpoint + diamondright => ./diamondright + diamondroot => ./diamondroot + mysite/myname/mypkg v1.0.0 => ./mypkg + w v1.0.0 => ./w + x v1.0.0 => ./x + y v1.0.0 => ./y + z v1.0.0 => ./z +) + +-- a/foo/AUTHORS.txt -- +-- a/foo/CONTRIBUTORS -- +-- a/foo/LICENSE -- +-- a/foo/PATENTS -- +-- a/foo/COPYING -- +-- a/foo/COPYLEFT -- +-- a/foo/licensed-to-kill -- +-- w/LICENSE -- +-- x/NOTICE! -- +-- x/x2/LICENSE -- +-- mypkg/LICENSE.txt -- + +-- a/foo/bar/b/main.go -- +package b +-- a/foo/bar/b/ignored.go -- +// This file is intended for use with "go run"; it isn't really part of the package. + +// +build ignore + +package main + +func main() {} +-- a/foo/bar/b/main_test.go -- +package b + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/main.go -- +package c +import _ "a/foo/bar/b" +-- a/foo/bar/c/main_test.go -- +package c + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../../../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/testdata/1 -- +-- a/foo/bar/testdata/1 -- +-- a/go.mod -- +module a +-- a/main.go -- +package a +-- a/main_test.go -- +package a + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/testdata/1 -- +-- appengine.go -- +// +build appengine + +package m + +import _ "appengine" +import _ "appengine/datastore" +-- mypkg/go.mod -- +module me +-- mypkg/mydir/d.go -- +package mydir +-- subdir/v1_test.go -- +package m + +import _ "mysite/myname/mypkg/mydir" +-- testdata1.go -- +package m + +import _ "a" +-- testdata2.go -- +package m + +import _ "a/foo/bar/c" +-- v1.go -- +package m + +import _ "x" +-- v2.go -- +// +build abc + +package mMmMmMm + +import _ "y" +-- v3.go -- +// +build !abc + +package m + +import _ "z" +-- v4.go -- +// +build notmytag + +package m + +import _ "x/x1" +-- importdiamond.go -- +package m + +import _ "diamondroot" +-- w/go.mod -- +module w +-- w/w.go -- +package w +-- x/go.mod -- +module x +-- x/testdata/x.txt -- +placeholder - want directory with no go files +-- x/x.go -- +package x +-- x/x1/x1.go -- +// +build notmytag + +package x1 +-- x/x2/dummy.txt -- +dummy +-- x/x_test.go -- +package x + +import _ "w" +-- y/go.mod -- +module y +-- y/y.go -- +package y +-- z/go.mod -- +module z +-- z/z.go -- +package z + +-- diamondroot/go.mod -- +module diamondroot + +require ( + diamondleft v0.0.0 + diamondright v0.0.0 +) +-- diamondroot/x.go -- +package diamondroot + +import _ "diamondleft" +-- diamondroot/unused/unused.go -- +package unused + +import _ "diamondright" +-- diamondleft/go.mod -- +module diamondleft + +require ( + diamondpoint v0.0.0 +) +-- diamondleft/x.go -- +package diamondleft + +import _ "diamondpoint" +-- diamondright/go.mod -- +module diamondright + +require ( + diamondpoint v0.0.0 +) +-- diamondright/x.go -- +package diamondright + +import _ "diamondpoint" +-- diamondpoint/go.mod -- +module diamondpoint +-- diamondpoint/x.go -- +package diamondpoint diff --git a/src/cmd/go/testdata/script/mod_vendor_auto.txt b/src/cmd/go/testdata/script/mod_vendor_auto.txt new file mode 100644 index 0000000..3cace73 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_auto.txt @@ -0,0 +1,256 @@ +# Integration test for golang.org/issue/33848: automatically check and use vendored packages. + +env GO111MODULE=on + +[short] skip + +cd $WORK/auto +cp go.mod go.mod.orig +cp $WORK/modules-1.13.txt $WORK/auto/modules.txt + +# An explicit -mod=vendor should force use of the vendor directory. +env GOFLAGS=-mod=vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +! go list -m all +stderr 'go: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# An explicit -mod=mod should force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# If the main module's "go" directive says 1.13, we should default to -mod=mod. +env GOFLAGS= +go mod edit -go=1.13 + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# A 'go 1.14' directive in the main module's go.mod file should enable +# -mod=vendor by default, along with stronger checks for consistency +# between the go.mod file and vendor/modules.txt. +# A 'go 1.13' vendor/modules.txt file is not usually sufficient +# to pass those checks. +go mod edit -go=1.14 + +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# Module-specific subcommands should continue to load the full module graph. +go mod graph +stdout '^example.com/printversion@v1.0.0 example.com/version@v1.0.0$' + +# An explicit -mod=mod should still force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# 'go mod vendor' should repair vendor/modules.txt so that the implicit +# -mod=vendor works again. +env GOFLAGS= + +go mod edit -go=1.14 +go mod vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but 'go list -m' should continue to fail, this time without +# referring to a -mod default that the user didn't set. +! go list -m all +stderr 'go: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + + +# 'go mod init' should work if there is already a GOPATH-mode vendor directory +# present. If there are no module dependencies, -mod=vendor should be used by +# default and should not fail the consistency check even though no module +# information is present. + +rm go.mod +rm vendor/modules.txt + +go mod init example.com/auto +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# If information about dependencies is added to a 1.14 go.mod file, subsequent +# list commands should error out if vendor/modules.txt is missing or incomplete. + +cp go.mod.orig go.mod +go mod edit -go=1.14 +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# If -mod=vendor is set, limited consistency checks should apply even when +# the go version is 1.13 or earlier. +# An incomplete or missing vendor/modules.txt should resolve the vendored packages... +go mod edit -go=1.13 +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but a version mismatch for an explicit dependency should be noticed. +cp $WORK/modules-bad-1.13.txt vendor/modules.txt +! go list -mod=vendor -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but vendor/modules.txt indicates example.com/printversion@v1.1.0$' +stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$' + +# If the go version is still 1.13, 'go mod vendor' should write a +# matching vendor/modules.txt containing the corrected 1.13 data. +go mod vendor +cmp $WORK/modules-1.13.txt vendor/modules.txt + +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# When the version is upgraded to 1.14, 'go mod vendor' should write a +# vendor/modules.txt with the updated 1.14 annotations. +go mod edit -go=1.14 +go mod vendor +cmp $WORK/modules-1.14.txt vendor/modules.txt + +# Then, -mod=vendor should kick in automatically and succeed. +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# 'go get' should update from the network or module cache, +# even if a vendor directory is present. +go get example.com/version@v1.1.0 +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring' + +-- $WORK/auto/go.mod -- +module example.com/auto + +go 1.13 + +require example.com/printversion v1.0.0 + +replace ( + example.com/unused => nonexistent.example.com/unused v1.0.0-whatever + example.com/version v1.0.0 => ./replacement-version + example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +) +-- $WORK/auto/tools.go -- +// +build tools + +package auto + +import _ "example.com/printversion" +-- $WORK/auto/auto.go -- +package auto +-- $WORK/auto/replacement-version/go.mod -- +module example.com/version +-- $WORK/auto/replacement-version/version.go -- +package version + +const V = "v1.0.0-replaced" +-- $WORK/modules-1.14.txt -- +# example.com/printversion v1.0.0 +## explicit +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +# example.com/unused => nonexistent.example.com/unused v1.0.0-whatever +# example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +-- $WORK/modules-1.13.txt -- +# example.com/printversion v1.0.0 +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +-- $WORK/modules-bad-1.13.txt -- +# example.com/printversion v1.1.0 +example.com/printversion +# example.com/version v1.1.0 +example.com/version +-- $WORK/auto/vendor/example.com/printversion/go.mod -- +module example.com/printversion + +require example.com/version v1.0.0 +replace example.com/version v1.0.0 => ../oops v0.0.0 +exclude example.com/version v1.0.1 +-- $WORK/auto/vendor/example.com/printversion/printversion.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, _ := debug.ReadBuildInfo() + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} +-- $WORK/auto/vendor/example.com/version/version.go -- +package version + +const V = "v1.0.0-replaced" diff --git a/src/cmd/go/testdata/script/mod_vendor_build.txt b/src/cmd/go/testdata/script/mod_vendor_build.txt new file mode 100644 index 0000000..4efda55 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_build.txt @@ -0,0 +1,41 @@ +env GO111MODULE=on +[short] skip + +# Populate go.mod and go.sum. +go mod tidy + +# initial conditions: using sampler v1.3.0, not listed in go.mod. +go list -deps +stdout rsc.io/sampler +! grep 'rsc.io/sampler v1.3.0' go.mod + +# update to v1.3.1, now indirect in go.mod. +go get rsc.io/sampler@v1.3.1 +grep 'rsc.io/sampler v1.3.1 // indirect' go.mod +cp go.mod go.mod.good + +# vendoring can but should not need to make changes. +go mod vendor +cmp go.mod go.mod.good + +# go list -mod=vendor (or go build -mod=vendor) must not modify go.mod. +# golang.org/issue/26704 +go list -mod=vendor +cmp go.mod go.mod.good + +# With a clean (and empty) module cache, 'go list -mod=vendor' should not download modules. +go clean -modcache +env GOPROXY=off +! go list ... +go list -mod=vendor ... + +# However, it should still list packages in the main module. +go list -mod=vendor m/... +stdout m + +-- go.mod -- +module m +go 1.12 +-- x.go -- +package x +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/mod_vendor_embed.txt b/src/cmd/go/testdata/script/mod_vendor_embed.txt new file mode 100644 index 0000000..b14fd99 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_embed.txt @@ -0,0 +1,179 @@ +go mod vendor +cmp vendor/example.com/a/samedir_embed.txt a/samedir_embed.txt +cmp vendor/example.com/a/subdir/embed.txt a/subdir/embed.txt +cmp vendor/example.com/a/subdir/test/embed.txt a/subdir/test/embed.txt +cmp vendor/example.com/a/subdir/test/xtest/embed.txt a/subdir/test/xtest/embed.txt + +cd broken_no_matching_files +! go mod vendor +stderr 'go: pattern foo.txt: no matching files found' + +cd ../broken_bad_pattern +! go mod vendor +stderr 'go: pattern ../foo.txt: invalid pattern syntax' + +# matchPotentialSourceFile prunes out tests and unbuilt code. +# Make sure that they are vendored if they are embedded files. +cd ../embed_unbuilt +go mod vendor +cmp vendor/example.com/dep/unbuilt.go dep/unbuilt.go +cmp vendor/example.com/dep/dep_test.go dep/dep_test.go +! exists vendor/example.com/dep/not_embedded_unbuilt.go +! exists vendor/example.com/dep/not_embedded_dep_test.go +-- go.mod -- +module example.com/foo +go 1.16 + +require ( + example.com/a v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a +) +-- foo.go -- +package main + +import ( + "fmt" + + "example.com/a" +) + +func main() { + fmt.Println(a.Str()) +} +-- a/go.mod -- +module example.com/a +-- a/a.go -- +package a + +import _ "embed" + +//go:embed samedir_embed.txt +var sameDir string + +//go:embed subdir/embed.txt +var subDir string + +func Str() string { + return sameDir + subDir +} +-- a/a_test.go -- +package a + +import _ "embed" + +//go:embed subdir/test/embed.txt +var subderTest string +-- a/a_x_test.go -- +package a_test + +import _ "embed" + +//go:embed subdir/test/xtest/embed.txt +var subdirXtest string +-- a/samedir_embed.txt -- +embedded file in same directory as package +-- a/subdir/embed.txt -- +embedded file in subdirectory of package +-- a/subdir/test/embed.txt -- +embedded file of test in subdirectory of package +-- a/subdir/test/xtest/embed.txt -- +embedded file of xtest in subdirectory of package +-- broken_no_matching_files/go.mod -- +module example.com/broken +go 1.16 + +require ( + example.com/brokendep v0.1.0 +) + +replace ( + example.com/brokendep v0.1.0 => ./brokendep +) +-- broken_no_matching_files/f.go -- +package broken + +import _ "example.com/brokendep" + +func F() {} +-- broken_no_matching_files/brokendep/go.mod -- +module example.com/brokendep +go 1.16 +-- broken_no_matching_files/brokendep/f.go -- +package brokendep + +import _ "embed" + +//go:embed foo.txt +var foo string +-- broken_bad_pattern/go.mod -- +module example.com/broken +go 1.16 + +require ( + example.com/brokendep v0.1.0 +) + +replace ( + example.com/brokendep v0.1.0 => ./brokendep +) +-- broken_bad_pattern/f.go -- +package broken + +import _ "example.com/brokendep" + +func F() {} +-- broken_bad_pattern/brokendep/go.mod -- +module example.com/brokendep +go 1.16 +-- broken_bad_pattern/brokendep/f.go -- +package brokendep + +import _ "embed" + +//go:embed ../foo.txt +var foo string +-- embed_unbuilt/go.mod -- +module example.com/foo +go 1.16 + +require ( + example.com/dep v0.1.0 +) + +replace ( + example.com/dep v0.1.0 => ./dep +) +-- embed_unbuilt/foo.go -- +package a + +import _ "example.com/dep" + +func F() {} +-- embed_unbuilt/dep/go.mod -- +module example.com/dep +go 1.16 +-- embed_unbuilt/dep/dep.go -- +package dep + +import _ "embed" + +//go:embed unbuilt.go +var unbuilt string + +//go:embed dep_test.go +var depTest string +-- embed_unbuilt/dep/unbuilt.go -- +// +build ignore + +package dep +-- embed_unbuilt/dep/not_embedded_unbuilt.go -- +// +build ignore + +package dep +-- embed_unbuilt/dep/dep_test.go -- +package dep +-- embed_unbuilt/dep/not_embedded_dep_test.go -- +package dep diff --git a/src/cmd/go/testdata/script/mod_vendor_gomod.txt b/src/cmd/go/testdata/script/mod_vendor_gomod.txt new file mode 100644 index 0000000..3f6ea35 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_gomod.txt @@ -0,0 +1,38 @@ +# https://golang.org/issue/42970: As of Go 1.17, go.mod and go.sum files should +# be stripped from vendored dependencies. + +go mod vendor +cd vendor/example.net/x +go list all +! stdout '^example.net/m' +stdout '^example.net/x$' +exists ./go.sum + +cd ../../.. +go mod edit -go=1.17 +go mod vendor +cd vendor/example.net/x +go list all +stdout '^example.net/m$' +stdout '^example.net/x$' +! exists ./go.sum + +-- go.mod -- +module example.net/m + +go 1.16 + +require example.net/x v0.1.0 + +replace example.net/x v0.1.0 => ./x +-- m.go -- +package m + +import _ "example.net/x" +-- x/go.mod -- +module example.net/x + +go 1.16 +-- x/go.sum -- +-- x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_vendor_goversion.txt b/src/cmd/go/testdata/script/mod_vendor_goversion.txt new file mode 100644 index 0000000..9e3618a --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_goversion.txt @@ -0,0 +1,102 @@ +# https://golang.org/issue/36876: As of Go 1.17, vendor/modules.txt should +# indicate the language version used by each dependency. + +[short] skip + +# Control case: without a vendor directory, need117 builds and bad114 doesn't. + +go build example.net/need117 +! go build example.net/bad114 +stderr '^bad114[/\\]bad114.go:15:2: duplicate method Y$' + + +# With a vendor/modules.txt lacking language versions, the world is topsy-turvy, +# because we have to guess a uniform version for everything. +# +# We always guess Go 1.16, because that was the last version for which +# 'go mod vendor' failed to record dependency versions, and it has most of +# the language features added since modules were introduced in Go 1.11. +# +# Even so, modules that declare 'go 1.17' and use 1.17 features spuriously fail +# to build, and modules that declare an older version and use features from a +# newer one spuriously build (instead of failing as they ought to). + +go mod vendor + +! grep 1.17 vendor/modules.txt +! go build example.net/need117 +stderr '^vendor[/\\]example\.net[/\\]need117[/\\]need117.go:5:1[89]:' +stderr 'conversion of slices to array pointers requires go1\.17 or later' + +! grep 1.13 vendor/modules.txt +go build example.net/bad114 + + +# Upgrading the main module to 1.17 adds version annotations. +# Then everything is once again consistent with the non-vendored world. + +go mod edit -go=1.17 +go mod vendor + +grep '^## explicit; go 1.17$' vendor/modules.txt +go build example.net/need117 + +grep '^## explicit; go 1.13$' vendor/modules.txt +! go build example.net/bad114 +stderr '^vendor[/\\]example\.net[/\\]bad114[/\\]bad114.go:15:2: duplicate method Y$' + +-- go.mod -- +module example.net/m + +go 1.16 + +require ( + example.net/bad114 v0.1.0 + example.net/need117 v0.1.0 +) + +replace ( + example.net/bad114 v0.1.0 => ./bad114 + example.net/need117 v0.1.0 => ./need117 +) +-- m.go -- +package m + +import _ "example.net/bad114" +import _ "example.net/need117" + +-- bad114/go.mod -- +// Module bad114 requires Go 1.14 or higher, but declares Go 1.13. +module example.net/bad114 + +go 1.13 +-- bad114/bad114.go -- +package bad114 + +type XY interface { + X() + Y() +} + +type YZ interface { + Y() + Z() +} + +type XYZ interface { + XY + YZ +} + +-- need117/go.mod -- +// Module need117 requires Go 1.17 or higher. +module example.net/need117 + +go 1.17 +-- need117/need117.go -- +package need117 + +func init() { + s := make([]byte, 4) + _ = (*[4]byte)(s) +} diff --git a/src/cmd/go/testdata/script/mod_vendor_issue46867.txt b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt new file mode 100644 index 0000000..38ae87b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_issue46867.txt @@ -0,0 +1,31 @@ +# Regression test for golang.org/issue/46867: +# 'go mod vendor' on Windows attempted to open and copy +# files from directories outside of the module. + +cd subdir +go mod vendor +! exists vendor/example.net/NOTICE +exists vendor/example.net/m/NOTICE + +-- subdir/go.mod -- +module golang.org/issue46867 + +go 1.17 + +replace example.net/m v0.1.0 => ./m + +require example.net/m v0.1.0 +-- subdir/issue.go -- +package issue + +import _ "example.net/m/n" +-- subdir/m/go.mod -- +module example.net/m + +go 1.17 +-- subdir/m/n/n.go -- +package n +-- subdir/m/NOTICE -- +This notice is in module m and SHOULD be vendored. +-- subdir/NOTICE -- +This notice is outside of module m and SHOULD NOT be vendored. diff --git a/src/cmd/go/testdata/script/mod_vendor_nodeps.txt b/src/cmd/go/testdata/script/mod_vendor_nodeps.txt new file mode 100644 index 0000000..e9a84ca --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_nodeps.txt @@ -0,0 +1,9 @@ +env GO111MODULE=on + +go mod vendor +stderr '^go: no dependencies to vendor' + +-- go.mod -- +module x +-- x.go -- +package x diff --git a/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt new file mode 100644 index 0000000..3f6f5c5 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_redundant_requirement.txt @@ -0,0 +1,29 @@ +# 'go list -mod=vendor' should succeed even when go.mod contains redundant +# requirements. Verifies #47565. +go list -mod=vendor + +-- go.mod -- +module m + +go 1.17 + +require example.com/m v0.0.0 +require example.com/m v0.0.0 + +replace example.com/m v0.0.0 => ./m +-- m/go.mod -- +module example.com/m + +go 1.17 +-- m/m.go -- +package m +-- use.go -- +package use + +import _ "example.com/m" +-- vendor/example.com/m/m.go -- +package m +-- vendor/modules.txt -- +# example.com/m v0.0.0 => ./m +## explicit; go 1.17 +example.com/m diff --git a/src/cmd/go/testdata/script/mod_vendor_replace.txt b/src/cmd/go/testdata/script/mod_vendor_replace.txt new file mode 100644 index 0000000..1820af6 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_replace.txt @@ -0,0 +1,69 @@ +env GO111MODULE=on + +# Before vendoring, we expect to see the original directory. +go list -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 +stdout 'v3.0.0' +stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' + +# Since all dependencies are replaced, 'go mod vendor' should not +# have to download anything from the network. +go mod vendor +! stderr 'downloading' +! stderr 'finding' + +# After vendoring, we expect to see the replacement in the vendor directory, +# without attempting to look up the non-replaced version. +cmp vendor/rsc.io/quote/v3/quote.go local/not-rsc.io/quote/v3/quote.go + +go list -mod=vendor -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 +stdout 'v3.0.0' +stdout '.*[/\\]vendor[/\\]rsc.io[/\\]quote[/\\]v3' +! stderr 'finding' +! stderr 'lookup disabled' + +# 'go list' should provide the original replacement directory as the module's +# replacement path. +go list -mod=vendor -f '{{with .Module}}{{with .Replace}}{{.Path}}{{end}}{{end}}' rsc.io/quote/v3 +stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod vendor +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + +-- go.mod -- +module example.com/replace + +require rsc.io/quote/v3 v3.0.0 +replace rsc.io/quote/v3 => ./local/not-rsc.io/quote/v3 +-- imports.go -- +package replace + +import _ "rsc.io/quote/v3" + +-- local/not-rsc.io/quote/v3/go.mod -- +module not-rsc.io/quote/v3 + +-- local/not-rsc.io/quote/v3/quote.go -- +package quote + +-- multiple-paths/main.go -- +package main +import ( + "fmt" + "rsc.io/quote/v3" +) +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 +-- multiple-paths/go.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote/v3 v3.0.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_vendor_trimpath.txt b/src/cmd/go/testdata/script/mod_vendor_trimpath.txt new file mode 100644 index 0000000..d9d9d98 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_trimpath.txt @@ -0,0 +1,49 @@ +# Check that when -trimpath and -mod=vendor are used together, +# paths in vendored packages are properly trimmed. +# Verifies golang.org/issue/36566. + +[short] skip + +# Only the main module has a root directory in vendor mode. +go mod vendor +go list -f {{.Module.Dir}} example.com/main +stdout $PWD +go list -f {{.Module.Dir}} example.com/stack +! stdout . + +# The program prints a file name from a vendored package. +# Without -trimpath, the name should include the vendor directory. +go run main.go +stdout vendor + +# With -trimpath, everything before the package path should be trimmed. +# As with -mod=mod, the version should appear as part of the module path. +go run -mod=vendor -trimpath main.go +stdout '^example.com/stack@v1.0.0/stack.go$' + +# With pristinely vendored source code, a trimmed binary built from vendored +# code should have the same behavior as one build from the module cache. +go run -mod=mod -trimpath main.go +stdout '^example.com/stack@v1.0.0/stack.go$' + +-- go.mod -- +module example.com/main + +go 1.17 + +require example.com/stack v1.0.0 +-- go.sum -- +example.com/stack v1.0.0 h1:IEDLeew5NytZ8vrgCF/QVem3H3SR3QMttdu9HfJvk9I= +example.com/stack v1.0.0/go.mod h1:7wFEbaV5e5O7wJ8aBdqQOR//UXppm/pwnwziMKViuI4= +-- main.go -- +package main + +import ( + "fmt" + + "example.com/stack" +) + +func main() { + fmt.Println(stack.TopFile()) +} diff --git a/src/cmd/go/testdata/script/mod_vendor_unused.txt b/src/cmd/go/testdata/script/mod_vendor_unused.txt new file mode 100644 index 0000000..96251bb --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_unused.txt @@ -0,0 +1,67 @@ +# Auxiliary test for inclusion of otherwise-unused replacements in +# vendor/modules.txt for golang.org/issue/33848. +# We need metadata about replacements in order to verify that modules.txt +# remains in sync with the main module's go.mod file. + +env GO111MODULE=on + +go mod vendor +cmp go1.14-modules.txt vendor/modules.txt + +-- go.mod -- +module example.com/foo +go 1.14 + +require ( + example.com/a v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0-unused => ./b2 + example.com/c => ./c + example.com/d v0.1.0 => ./d1 + example.com/d v0.2.0 => ./d2 + example.com/e => example.com/e v0.1.0-unused +) +-- foo.go -- +package foo +import _ "example.com/a" +-- a/go.mod -- +module example.com/a +require ( + example.com/b v0.1.0 // indirect + example.com/c v0.1.0 // indirect +) +-- a/a.go -- +package a +import _ "example.com/d" +-- b1/go.mod -- +module example.com/b +require example.com/d v0.1.0 +-- b2/go.mod -- +module example.com/b +require example.com/c v0.2.0 +-- c/go.mod -- +module example.com/c +require example.com/d v0.2.0 +-- d1/go.mod -- +module example.com/d +-- d1/d1.go -- +package d +-- d2/go.mod -- +module example.com/d +-- d2/d2.go -- +package d +-- go1.14-modules.txt -- +# example.com/a v0.1.0 => ./a +## explicit +example.com/a +# example.com/d v0.2.0 => ./d2 +example.com/d +# example.com/b v0.1.0 => ./b1 +# example.com/b v0.2.0-unused => ./b2 +# example.com/c => ./c +# example.com/d v0.1.0 => ./d1 +# example.com/e => example.com/e v0.1.0-unused diff --git a/src/cmd/go/testdata/script/mod_vendor_unused_only.txt b/src/cmd/go/testdata/script/mod_vendor_unused_only.txt new file mode 100644 index 0000000..accd9f3 --- /dev/null +++ b/src/cmd/go/testdata/script/mod_vendor_unused_only.txt @@ -0,0 +1,19 @@ +# Ensure that we generate a vendor/modules.txt file even when the only +# requirements in go.mod are unused. Regression test for +# golang.org/issue/36580 + +env GO111MODULE=on + +go mod vendor +cmp go1.14-modules.txt vendor/modules.txt + +-- go.mod -- +module example.com/m +go 1.14 + +require example.com v1.0.0 // indirect +-- go.sum -- +example.com v1.0.0/go.mod h1:WRiieAqDBb1hVdDXLLdxNtCDWNfehn7FWyPC5Oz2vB4= +-- go1.14-modules.txt -- +# example.com v1.0.0 +## explicit diff --git a/src/cmd/go/testdata/script/mod_verify.txt b/src/cmd/go/testdata/script/mod_verify.txt new file mode 100644 index 0000000..018709e --- /dev/null +++ b/src/cmd/go/testdata/script/mod_verify.txt @@ -0,0 +1,82 @@ +env GO111MODULE=on +[short] skip + +# With good go.sum, verify succeeds by avoiding download. +cp go.sum.good go.sum +go mod verify +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With bad go.sum, verify succeeds by avoiding download. +cp go.sum.bad go.sum +go mod verify +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With bad go.sum, sync (which must download) fails. +rm go.sum +cp go.sum.bad go.sum +! go mod tidy +stderr 'checksum mismatch' +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip + +# With good go.sum, sync works. +rm go.sum +cp go.sum.good go.sum +go mod tidy +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip +exists $GOPATH/pkg/mod/rsc.io/quote@v1.1.0/quote.go + +# go.sum should have the new checksum for go.mod +grep '^rsc.io/quote v1.1.0/go.mod ' go.sum + +# verify should work +go mod verify + +# basic loading of module graph should detect incorrect go.mod files. +go mod graph +cp go.sum.bad2 go.sum +! go mod graph +stderr 'go.mod: checksum mismatch' + +# go.sum should be created and updated automatically. +rm go.sum +go mod tidy +grep '^rsc.io/quote v1.1.0/go.mod ' go.sum +grep '^rsc.io/quote v1.1.0 ' go.sum + +# verify should fail on a missing ziphash. tidy should restore it. +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash +! go mod verify +stderr '^rsc.io/quote v1.1.0: missing ziphash: open '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]rsc.io[/\\]quote[/\\]@v[/\\]v1.1.0.ziphash' +go mod tidy +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.ziphash +go mod verify + +# Packages below module root should not be mentioned in go.sum. +rm go.sum +go mod edit -droprequire rsc.io/quote +go get rsc.io/quote/buggy +grep '^rsc.io/quote v1.5.2/go.mod ' go.sum +! grep buggy go.sum + +# non-existent packages below module root should not be mentioned in go.sum +go mod edit -droprequire rsc.io/quote +! go list rsc.io/quote/morebuggy +grep '^rsc.io/quote v1.5.2/go.mod ' go.sum +! grep buggy go.sum + +-- go.mod -- +module x +require rsc.io/quote v1.1.0 + +-- x.go -- +package x +import _ "rsc.io/quote" + +-- go.sum.good -- +rsc.io/quote v1.1.0 h1:a3YaZoizPtXyv6ZsJ74oo2L4/bwOSTKMY7MAyo4O/0c= + +-- go.sum.bad -- +rsc.io/quote v1.1.0 h1:a3YaZoizPtXyv6ZsJ74oo2L4/bwOSTKMY7MAyo4O/1c= + +-- go.sum.bad2 -- +rsc.io/quote v1.1.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl1= diff --git a/src/cmd/go/testdata/script/mod_versions.txt b/src/cmd/go/testdata/script/mod_versions.txt new file mode 100644 index 0000000..9e6322b --- /dev/null +++ b/src/cmd/go/testdata/script/mod_versions.txt @@ -0,0 +1,14 @@ +# Test rejection of pkg@version in GOPATH mode. +env GO111MODULE=off +! go get rsc.io/quote@v1.5.1 +stderr '^go: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' +! go build rsc.io/quote@v1.5.1 +stderr '^package rsc.io/quote@v1.5.1: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' + +env GO111MODULE=on +cd x +! go build rsc.io/quote@v1.5.1 +stderr '^package rsc.io/quote@v1.5.1: can only use path@version syntax with ''go get'' and ''go install'' in module-aware mode$' + +-- x/go.mod -- +module x diff --git a/src/cmd/go/testdata/script/mod_why.txt b/src/cmd/go/testdata/script/mod_why.txt new file mode 100644 index 0000000..b3036fa --- /dev/null +++ b/src/cmd/go/testdata/script/mod_why.txt @@ -0,0 +1,130 @@ +env GO111MODULE=on +[short] skip + +# Populate go.sum. +go mod tidy +cp go.mod go.mod.orig + +go list -test all +stdout rsc.io/quote +stdout golang.org/x/text/language + +# why a package? +go mod why golang.org/x/text/language +cmp stdout why-language.txt + +# why a module? +go mod why -m golang.org... +cmp stdout why-text-module.txt + +# why a package used only in tests? +go mod why rsc.io/testonly +cmp stdout why-testonly.txt + +# why a module used only in a test of a dependency? +go mod why -m rsc.io/testonly +cmp stdout why-testonly.txt + +# test package not needed +go mod why golang.org/x/text/unused +cmp stdout why-unused.txt + +# vendor doesn't use packages used only in tests. +go mod why -vendor rsc.io/testonly +cmp stdout why-vendor.txt + +# vendor doesn't use modules used only in tests. +go mod why -vendor -m rsc.io/testonly +cmp stdout why-vendor-module.txt + +# test multiple packages +go mod why golang.org/x/text/language golang.org/x/text/unused +cmp stdout why-both.txt + +# test multiple modules +go mod why -m rsc.io/quote rsc.io/sampler +cmp stdout why-both-module.txt + +# package in a module that isn't even in the module graph +# (https://golang.org/issue/26977) +go mod why rsc.io/fortune +cmp stdout why-missing.txt + +# None of these command should have changed the go.mod file. +cmp go.mod go.mod.orig + +-- go.mod -- +module mymodule +require rsc.io/quote v1.5.2 + +-- x/x.go -- +package x +import _ "mymodule/z" + +-- y/y.go -- +package y + +-- y/y_test.go -- +package y +import _ "rsc.io/quote" + +-- z/z.go -- +package z +import _ "mymodule/y" + + +-- why-language.txt -- +# golang.org/x/text/language +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language +-- why-unused.txt -- +# golang.org/x/text/unused +(main module does not need package golang.org/x/text/unused) +-- why-text-module.txt -- +# golang.org/x/text +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language +-- why-testonly.txt -- +# rsc.io/testonly +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +rsc.io/sampler.test +rsc.io/testonly +-- why-vendor.txt -- +# rsc.io/testonly +(main module does not need to vendor package rsc.io/testonly) +-- why-vendor-module.txt -- +# rsc.io/testonly +(main module does not need to vendor module rsc.io/testonly) +-- why-both.txt -- +# golang.org/x/text/language +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +golang.org/x/text/language + +# golang.org/x/text/unused +(main module does not need package golang.org/x/text/unused) +-- why-both-module.txt -- +# rsc.io/quote +mymodule/y +mymodule/y.test +rsc.io/quote + +# rsc.io/sampler +mymodule/y +mymodule/y.test +rsc.io/quote +rsc.io/sampler +-- why-missing.txt -- +# rsc.io/fortune +(main module does not need package rsc.io/fortune) diff --git a/src/cmd/go/testdata/script/modfile_flag.txt b/src/cmd/go/testdata/script/modfile_flag.txt new file mode 100644 index 0000000..398e523 --- /dev/null +++ b/src/cmd/go/testdata/script/modfile_flag.txt @@ -0,0 +1,98 @@ +# Tests the behavior of the -modfile flag in commands that support it. +# The go.mod file exists but should not be read or written. +# Same with go.sum. + +env GOFLAGS=-modfile=go.alt.mod +cp go.mod go.mod.orig +cp go.sum go.sum.orig + + +# go mod init should create a new file, even though go.mod already exists. +go mod init example.com/m +grep example.com/m go.alt.mod + +# 'go env GOMOD' should print the path to the real file. +# 'go env' does not recognize the '-modfile' flag. +go env GOMOD +stdout '^\$WORK[/\\]gopath[/\\]src[/\\]go.mod$' + +# 'go list -m' should print the effective go.mod file as GoMod though. +go list -m -f '{{.GoMod}}' +stdout '^go.alt.mod$' + +# go mod edit should operate on the alternate file +go mod edit -require rsc.io/quote@v1.5.2 +grep rsc.io/quote go.alt.mod + +# 'go list -m' should add sums to the alternate go.sum. +go list -m -mod=mod all +grep '^rsc.io/quote v1.5.2/go.mod ' go.alt.sum +! grep '^rsc.io/quote v1.5.2 ' go.alt.sum + +# other 'go mod' commands should work. 'go mod vendor' is tested later. +go mod download rsc.io/quote +go mod graph +stdout rsc.io/quote +go mod tidy +grep rsc.io/quote go.alt.sum +go mod verify +go mod why rsc.io/quote + + +# 'go list' and other commands with build flags should work. +# They should update the alternate go.mod when a dependency is missing. +go mod edit -droprequire rsc.io/quote +go list -mod=mod . +grep rsc.io/quote go.alt.mod +go build -n -mod=mod . +go test -n -mod=mod . +go get rsc.io/quote + + +# 'go mod vendor' should work. +go mod vendor +exists vendor + +# Automatic vendoring should be broken by editing an explicit requirement +# in the alternate go.mod file. +go mod edit -require rsc.io/quote@v1.5.1 +! go list . +go list -mod=mod +rm vendor + + +# 'go generate' should use the alternate file when resolving packages. +# Recursive go commands started with 'go generate' should not get an explicitly +# passed -modfile, but they should see arguments from GOFLAGS. +cp go.alt.mod go.gen.mod +env OLD_GOFLAGS=$GOFLAGS +env GOFLAGS=-modfile=go.gen.mod +go generate -modfile=go.alt.mod . +env GOFLAGS=$OLD_GOFLAGS +grep example.com/exclude go.gen.mod +! grep example.com/exclude go.alt.mod + + +# The original files should not have been modified. +cmp go.mod go.mod.orig +cmp go.sum go.sum.orig + + +# If the alternate mod file does not have a ".mod" suffix, an error +# should be reported. +cp go.alt.mod goaltmod +! go mod tidy -modfile=goaltmod +stderr '-modfile=goaltmod: file does not have .mod extension' + +-- go.mod -- +ʕ◔ϖ◔ʔ +-- go.sum -- +ʕ◔ϖ◔ʔ +-- use.go -- +package main + +import _ "rsc.io/quote" +-- gen.go -- +//go:generate go mod edit -exclude example.com/exclude@v1.0.0 + +package main diff --git a/src/cmd/go/testdata/script/noncanonical_import.txt b/src/cmd/go/testdata/script/noncanonical_import.txt new file mode 100644 index 0000000..018cb01 --- /dev/null +++ b/src/cmd/go/testdata/script/noncanonical_import.txt @@ -0,0 +1,19 @@ +env GO111MODULE=off + +! go build canonical/d +stderr '^canonical[/\\]b[/\\]b.go:3:8: non-canonical import path "canonical/a/": should be "canonical/a"$' + +-- canonical/a/a.go -- +package a + +import _ "c" +-- canonical/b/b.go -- +package b + +import _ "canonical/a/" +-- canonical/a/vendor/c/c.go -- +package c +-- canonical/d/d.go -- +package d + +import _ "canonical/b" diff --git a/src/cmd/go/testdata/script/pattern_syntax_error.txt b/src/cmd/go/testdata/script/pattern_syntax_error.txt new file mode 100644 index 0000000..9a1f5e5 --- /dev/null +++ b/src/cmd/go/testdata/script/pattern_syntax_error.txt @@ -0,0 +1,12 @@ +env GO111MODULE=off + +# patterns match directories with syntax errors +! go list ./... +! go build ./... +! go install ./... + +-- mypkg/x.go -- +package mypkg + +-- mypkg/y.go -- +pkg mypackage diff --git a/src/cmd/go/testdata/script/prevent_sys_unix_import.txt b/src/cmd/go/testdata/script/prevent_sys_unix_import.txt new file mode 100644 index 0000000..ea1ad78 --- /dev/null +++ b/src/cmd/go/testdata/script/prevent_sys_unix_import.txt @@ -0,0 +1,6 @@ +# Policy decision: we shouldn't vendor golang.org/x/sys/unix in std +# See https://golang.org/issue/32102 + +env GO111MODULE=on +go list std +! stdout vendor/golang.org/x/sys/unix diff --git a/src/cmd/go/testdata/script/run_dirs.txt b/src/cmd/go/testdata/script/run_dirs.txt new file mode 100644 index 0000000..bd5cfbe --- /dev/null +++ b/src/cmd/go/testdata/script/run_dirs.txt @@ -0,0 +1,21 @@ +cd rundir + +! go run x.go sub/sub.go +stderr 'named files must all be in one directory; have . and sub' +! go run sub/sub.go x.go +stderr 'named files must all be in one directory; have sub and .' + +cd ../ +go run rundir/foo.go ./rundir/bar.go +stderr 'hello world' + +-- rundir/sub/sub.go -- +package main +-- rundir/x.go -- +package main +-- rundir/foo.go -- +package main +func main() { println(msg) } +-- rundir/bar.go -- +package main +const msg = "hello world" diff --git a/src/cmd/go/testdata/script/run_hello.txt b/src/cmd/go/testdata/script/run_hello.txt new file mode 100644 index 0000000..939b661 --- /dev/null +++ b/src/cmd/go/testdata/script/run_hello.txt @@ -0,0 +1,9 @@ +env GO111MODULE=off + +# hello world +go run hello.go +stderr 'hello world' + +-- hello.go -- +package main +func main() { println("hello world") } diff --git a/src/cmd/go/testdata/script/run_hello_pkg.txt b/src/cmd/go/testdata/script/run_hello_pkg.txt new file mode 100644 index 0000000..ea2b4d7 --- /dev/null +++ b/src/cmd/go/testdata/script/run_hello_pkg.txt @@ -0,0 +1,17 @@ +go run m/hello +stderr 'hello, world' + +cd hello +go run . +stderr 'hello, world' + +-- go.mod -- +module m + +go 1.16 +-- hello/hello.go -- +package main + +func main() { + println("hello, world") +} diff --git a/src/cmd/go/testdata/script/run_internal.txt b/src/cmd/go/testdata/script/run_internal.txt new file mode 100644 index 0000000..d021850 --- /dev/null +++ b/src/cmd/go/testdata/script/run_internal.txt @@ -0,0 +1,64 @@ +env GO111MODULE=off + +go list -e -f '{{.Incomplete}}' m/runbad1.go +stdout true +! go run m/runbad1.go +stderr 'use of internal package m/x/internal not allowed' + +go list -e -f '{{.Incomplete}}' m/runbad2.go +stdout true +! go run m/runbad2.go +stderr 'use of internal package m/x/internal/y not allowed' + +go list -e -f '{{.Incomplete}}' m/runok.go +stdout false +go run m/runok.go + +cd m +env GO111MODULE=on + +go list -e -f '{{.Incomplete}}' runbad1.go +stdout true +! go run runbad1.go +stderr 'use of internal package m/x/internal not allowed' + +go list -e -f '{{.Incomplete}}' runbad2.go +stdout true +! go run runbad2.go +stderr 'use of internal package m/x/internal/y not allowed' + +go list -e -f '{{.Incomplete}}' runok.go +stdout false +go run runok.go + + +-- m/go.mod -- +module m + +-- m/x/internal/internal.go -- +package internal + +-- m/x/internal/y/y.go -- +package y + +-- m/internal/internal.go -- +package internal + +-- m/internal/z/z.go -- +package z + +-- m/runbad1.go -- +package main +import _ "m/x/internal" +func main() {} + +-- m/runbad2.go -- +package main +import _ "m/x/internal/y" +func main() {} + +-- m/runok.go -- +package main +import _ "m/internal" +import _ "m/internal/z" +func main() {} diff --git a/src/cmd/go/testdata/script/run_issue11709.txt b/src/cmd/go/testdata/script/run_issue11709.txt new file mode 100644 index 0000000..c8ba998 --- /dev/null +++ b/src/cmd/go/testdata/script/run_issue11709.txt @@ -0,0 +1,15 @@ +# 'go run' should not pass extraneous environment variables to the subprocess. +go run run.go +! stdout . +! stderr . + +-- run.go -- +package main + +import "os" + +func main() { + if os.Getenv("TERM") != "" { + os.Exit(1) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/run_issue51125.txt b/src/cmd/go/testdata/script/run_issue51125.txt new file mode 100644 index 0000000..8fa4486 --- /dev/null +++ b/src/cmd/go/testdata/script/run_issue51125.txt @@ -0,0 +1,54 @@ +# Regression test for https://go.dev/issue/51125: +# Relative import paths (a holdover from GOPATH) were accidentally allowed in module mode. + +cd $WORK + +# Relative imports should not be allowed with a go.mod file. + +! go run driver.go +stderr '^driver.go:3:8: "./mypkg" is relative, but relative import paths are not supported in module mode$' + +go list -e -f '{{with .Error}}{{.}}{{end}}' -deps driver.go +stdout '^driver.go:3:8: "./mypkg" is relative, but relative import paths are not supported in module mode$' +! stderr . + + +# Relative imports should not be allowed in module mode even without a go.mod file. +rm go.mod + +! go run driver.go +stderr '^driver.go:3:8: "./mypkg" is relative, but relative import paths are not supported in module mode$' + +go list -e -f '{{with .Error}}{{.}}{{end}}' -deps driver.go +stdout '^driver.go:3:8: "./mypkg" is relative, but relative import paths are not supported in module mode$' +! stderr . + + +# In GOPATH mode, they're still allowed (but only outside of GOPATH/src). +env GO111MODULE=off + +[!short] go run driver.go + +go list -deps driver.go + + +-- $WORK/go.mod -- +module example + +go 1.17 +-- $WORK/driver.go -- +package main + +import "./mypkg" + +func main() { + mypkg.MyFunc() +} +-- $WORK/mypkg/code.go -- +package mypkg + +import "fmt" + +func MyFunc() { + fmt.Println("Hello, world!") +} diff --git a/src/cmd/go/testdata/script/run_set_executable_name.txt b/src/cmd/go/testdata/script/run_set_executable_name.txt new file mode 100644 index 0000000..54ddee9 --- /dev/null +++ b/src/cmd/go/testdata/script/run_set_executable_name.txt @@ -0,0 +1,50 @@ +env GO111MODULE=on +[short] skip + +# Check for correct naming of temporary executable + +#Test for single file specified +cd x/y/z +go run foo.go +stderr 'foo' + +#Test for current directory +go run . +stderr 'z' + +#Test for set path +go run m/x/y/z/ +stderr 'z' + +-- m/x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- x/y/z/foo.go -- +package main +import( + "os" + "path/filepath" +) +func main() { + println(filepath.Base(os.Args[0])) +} + +-- go.mod -- +module m
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/run_vendor.txt b/src/cmd/go/testdata/script/run_vendor.txt new file mode 100644 index 0000000..46cac06 --- /dev/null +++ b/src/cmd/go/testdata/script/run_vendor.txt @@ -0,0 +1,34 @@ +# Run +env GO111MODULE=off +cd vend/hello +go run hello.go +stdout 'hello, world' + +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/run_wildcard.txt b/src/cmd/go/testdata/script/run_wildcard.txt new file mode 100644 index 0000000..3e7e7b7 --- /dev/null +++ b/src/cmd/go/testdata/script/run_wildcard.txt @@ -0,0 +1,7 @@ +env GO111MODULE=off + +# Fix for https://github.com/golang/go/issues/28696: +# go run x/... should not panic when directory x doesn't exist. + +! go run nonexistent/... +stderr '^go: no packages loaded from nonexistent/...$' diff --git a/src/cmd/go/testdata/script/run_work_versioned.txt b/src/cmd/go/testdata/script/run_work_versioned.txt new file mode 100644 index 0000000..eb0f22d --- /dev/null +++ b/src/cmd/go/testdata/script/run_work_versioned.txt @@ -0,0 +1,16 @@ +[short] skip +go run example.com/printversion@v0.1.0 +stdout '^main is example.com/printversion v0.1.0$' + +-- go.work -- +go 1.18 + +use ( + . +) +-- go.mod -- +module example + +go 1.18 + +require example.com/printversion v1.0.0 diff --git a/src/cmd/go/testdata/script/script_wait.txt b/src/cmd/go/testdata/script/script_wait.txt new file mode 100644 index 0000000..acaccfe --- /dev/null +++ b/src/cmd/go/testdata/script/script_wait.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +[!exec:echo] skip +[!exec:false] skip + +exec echo foo +stdout foo + +exec echo foo & +exec echo bar & +! exec false & + +# Starting a background process should clear previous output. +! stdout foo + +# Wait should set the output to the concatenated outputs of the background +# programs, in the order in which they were started. +wait +stdout 'foo\nbar' + +# The end of the test should interrupt or kill any remaining background +# programs, but that should not cause the test to fail if it does not +# care about the exit status of those programs. +[!exec:sleep] stop +? exec sleep 86400 & diff --git a/src/cmd/go/testdata/script/std_vendor.txt b/src/cmd/go/testdata/script/std_vendor.txt new file mode 100644 index 0000000..6cb015f --- /dev/null +++ b/src/cmd/go/testdata/script/std_vendor.txt @@ -0,0 +1,43 @@ +env GO111MODULE=off + +[!gc] skip + +# 'go list' should report imports from _test.go in the TestImports field. +go list -f '{{.TestImports}}' +stdout net/http # from .TestImports + +# 'go list' should report standard-vendored packages by path. +go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor + +# 'go list -test' should report vendored transitive dependencies of _test.go +# imports in the Deps field, with a 'vendor' prefix on their import paths. +go list -test -f '{{.Deps}}' +stdout golang.org/x/crypto # dep of .TestImports + +# Packages outside the standard library should not use its copy of vendored packages. +cd broken +! go build +stderr 'cannot find package' + +-- go.mod -- +module m + +-- x.go -- +package x + +-- x_test.go -- +package x +import "testing" +import _ "net/http" +func Test(t *testing.T) {} + +-- broken/go.mod -- +module broken +-- broken/http.go -- +package broken + +import ( + _ "net/http" + _ "golang.org/x/net/http/httpproxy" +) diff --git a/src/cmd/go/testdata/script/test_bad_example.txt b/src/cmd/go/testdata/script/test_bad_example.txt new file mode 100644 index 0000000..1d147b6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_bad_example.txt @@ -0,0 +1,13 @@ +# Tests that invalid examples are ignored. +# Verifies golang.org/issue/35284 +go test x_test.go + +-- x_test.go -- +package x + +import "fmt" + +func ExampleThisShouldNotHaveAParameter(thisShouldntExist int) { + fmt.Println("X") + // Output: +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_badtest.txt b/src/cmd/go/testdata/script/test_badtest.txt new file mode 100644 index 0000000..e79fc51 --- /dev/null +++ b/src/cmd/go/testdata/script/test_badtest.txt @@ -0,0 +1,49 @@ +env GO111MODULE=off + +! go test badtest/badexec +! stdout ^ok +stdout ^FAIL\tbadtest/badexec + +! go test badtest/badsyntax +! stdout ^ok +stdout ^FAIL\tbadtest/badsyntax + +! go test badtest/badvar +! stdout ^ok +stdout ^FAIL\tbadtest/badvar + +! go test notest +! stdout ^ok +stderr '^notest.hello.go:6:1: syntax error: non-declaration statement outside function body' # Exercise issue #7108 + +-- badtest/badexec/x_test.go -- +package badexec + +func init() { + panic("badexec") +} + +-- badtest/badsyntax/x.go -- +package badsyntax + +-- badtest/badsyntax/x_test.go -- +package badsyntax + +func func func func func! + +-- badtest/badvar/x.go -- +package badvar + +-- badtest/badvar/x_test.go -- +package badvar_test + +func f() { + _ = notdefined +} +-- notest/hello.go -- +package notest + +func hello() { + println("hello world") +} +Hello world
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_1x.txt b/src/cmd/go/testdata/script/test_benchmark_1x.txt new file mode 100644 index 0000000..b1d4c39 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_1x.txt @@ -0,0 +1,37 @@ +# Test that -benchtime 1x only runs a total of 1 loop iteration. +# See golang.org/issue/32051. + +go test -run ^$ -bench . -benchtime 1x + +-- go.mod -- +module bench + +go 1.16 +-- x_test.go -- +package bench + +import ( + "fmt" + "os" + "testing" +) + +var called = false + +func TestMain(m *testing.M) { + m.Run() + if !called { + fmt.Println("benchmark never called") + os.Exit(1) + } +} + +func Benchmark(b *testing.B) { + if b.N > 1 { + b.Fatalf("called with b.N=%d; want b.N=1 only", b.N) + } + if called { + b.Fatal("called twice") + } + called = true +} diff --git a/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt b/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt new file mode 100644 index 0000000..6031ead --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_chatty_fail.txt @@ -0,0 +1,32 @@ +# Run chatty tests. Assert on CONT lines. +! go test chatty_test.go -v -bench . chatty_bench + +# Sanity check that output occurs. +stdout -count=2 'this is sub-0' +stdout -count=2 'this is sub-1' +stdout -count=2 'this is sub-2' +stdout -count=1 'error from sub-0' +stdout -count=1 'error from sub-1' +stdout -count=1 'error from sub-2' + +# Benchmarks should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_bench + +import ( + "testing" + "fmt" +) + +func BenchmarkChatty(b *testing.B) { + for i := 0; i < 3; i++ { + b.Run(fmt.Sprintf("sub-%d", i), func(b *testing.B) { + for j := 0; j < 2; j++ { + b.Logf("this is sub-%d", i) + } + b.Errorf("error from sub-%d", i) + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt b/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt new file mode 100644 index 0000000..a1c0d65 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_chatty_success.txt @@ -0,0 +1,29 @@ +# Run chatty tests. Assert on CONT lines. +go test chatty_test.go -v -bench . chatty_bench + +# Sanity check that output happens. We don't provide -count because the amount +# of output is variable. +stdout 'this is sub-0' +stdout 'this is sub-1' +stdout 'this is sub-2' + +# Benchmarks should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_bench + +import ( + "testing" + "fmt" +) + +func BenchmarkChatty(b *testing.B) { + for i := 0; i < 3; i++ { + b.Run(fmt.Sprintf("sub-%d", i), func(b *testing.B) { + for j := 0; j < 2; j++ { + b.Logf("this is sub-%d", i) + } + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_benchmark_fatal.txt b/src/cmd/go/testdata/script/test_benchmark_fatal.txt new file mode 100644 index 0000000..e281379 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_fatal.txt @@ -0,0 +1,19 @@ +# Test that calling t.Fatal in a benchmark causes a non-zero exit status. + +! go test -run '^$' -bench . benchfatal +! stdout ^ok +! stderr ^ok +stdout FAIL.*benchfatal + +-- go.mod -- +module benchfatal + +go 1.16 +-- x_test.go -- +package benchfatal + +import "testing" + +func BenchmarkThatCallsFatal(b *testing.B) { + b.Fatal("called by benchmark") +} diff --git a/src/cmd/go/testdata/script/test_benchmark_labels.txt b/src/cmd/go/testdata/script/test_benchmark_labels.txt new file mode 100644 index 0000000..6b424c1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_labels.txt @@ -0,0 +1,23 @@ +# Tests that go test -bench prints out goos, goarch, and pkg. + +# Check for goos, goarch, and pkg. +go test -run ^$ -bench . bench +stdout '^goos: '$GOOS +stdout '^goarch: '$GOARCH +stdout '^pkg: bench' + +# Check go test does not print pkg multiple times +! stdout 'pkg:.*pkg: ' +! stderr 'pkg:.*pkg:' + +-- go.mod -- +module bench + +go 1.16 +-- x_test.go -- +package bench + +import "testing" + +func Benchmark(b *testing.B) { +} diff --git a/src/cmd/go/testdata/script/test_benchmark_timeout.txt b/src/cmd/go/testdata/script/test_benchmark_timeout.txt new file mode 100644 index 0000000..4bae7e7 --- /dev/null +++ b/src/cmd/go/testdata/script/test_benchmark_timeout.txt @@ -0,0 +1,18 @@ +# Tests issue #18845 +[short] skip + +go test -bench . -timeout=750ms timeoutbench_test.go +stdout ok +stdout PASS + +-- timeoutbench_test.go -- +package timeoutbench_test + +import ( + "testing" + "time" +) + +func BenchmarkSleep1s(b *testing.B) { + time.Sleep(1 * time.Second) +} diff --git a/src/cmd/go/testdata/script/test_build_failure.txt b/src/cmd/go/testdata/script/test_build_failure.txt new file mode 100644 index 0000000..e8c984f --- /dev/null +++ b/src/cmd/go/testdata/script/test_build_failure.txt @@ -0,0 +1,31 @@ +[short] skip + +! go test -x coverbad +! stderr '[\\/]coverbad\.test( |$)' # 'go test' should not claim to have run the test. +stderr 'undefined: g' +[cgo] stderr 'undefined: j' + +-- go.mod -- +module coverbad + +go 1.16 +-- p.go -- +package p + +func f() { + g() +} +-- p1.go -- +package p + +import "C" + +func h() { + j() +} +-- p_test.go -- +package p + +import "testing" + +func Test(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_buildvcs.txt b/src/cmd/go/testdata/script/test_buildvcs.txt new file mode 100644 index 0000000..a669966 --- /dev/null +++ b/src/cmd/go/testdata/script/test_buildvcs.txt @@ -0,0 +1,94 @@ +# https://go.dev/issue/51723: 'go test' should not stamp VCS metadata +# in the build settings. (It isn't worth the latency hit, given that +# test binaries are almost never distributed to users.) + +[short] skip +[!exec:git] skip + +env GOFLAGS=-buildvcs # override default -buildvcs=auto in GOFLAGS, as a user might + +exec git init + +# The test binaries should not have VCS settings stamped. +# (The test itself verifies that.) +go test . ./testonly + + +# Remove 'git' from $PATH. The test should still build. +# This ensures that we aren't loading VCS metadata that +# we subsequently throw away. +env PATH='' +env path='' + +# Compiling the test should not require the VCS tool. +go test -c -o $devnull . + + +# When listing a main package, in general we need its VCS metadata to determine +# the .Stale and .StaleReason fields. +! go list . +stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.' + +# Adding the -test flag should be strictly additive — it should not suppress the error. +! go list -test . +stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.' + +# Adding the suggested flag should suppress the error. +go list -test -buildvcs=false . +! stderr . + + +# Since the ./testonly package can't produce an actual binary, we shouldn't +# invoke a VCS tool to compute a build stamp when listing it. +go list ./testonly +! stderr . +go list -test ./testonly +! stderr . + + +-- go.mod -- +module example + +go 1.18 +-- example.go -- +package main +-- example_test.go -- +package main + +import ( + "runtime/debug" + "strings" + "testing" +) + +func TestDetail(t *testing.T) { + bi, ok := debug.ReadBuildInfo() + if !ok { + t.Fatal("BuildInfo not present") + } + for _, s := range bi.Settings { + if strings.HasPrefix(s.Key, "vcs.") { + t.Fatalf("unexpected VCS setting: %s=%s", s.Key, s.Value) + } + } +} +-- testonly/main_test.go -- +package main + +import ( + "runtime/debug" + "strings" + "testing" +) + +func TestDetail(t *testing.T) { + bi, ok := debug.ReadBuildInfo() + if !ok { + t.Fatal("BuildInfo not present") + } + for _, s := range bi.Settings { + if strings.HasPrefix(s.Key, "vcs.") { + t.Fatalf("unexpected VCS setting: %s=%s", s.Key, s.Value) + } + } +} diff --git a/src/cmd/go/testdata/script/test_cache_inputs.txt b/src/cmd/go/testdata/script/test_cache_inputs.txt new file mode 100644 index 0000000..3705c70 --- /dev/null +++ b/src/cmd/go/testdata/script/test_cache_inputs.txt @@ -0,0 +1,270 @@ +env GO111MODULE=off + +# Test that cached test results are invalidated in response to +# changes to the external inputs to the test. + +[short] skip +[GODEBUG:gocacheverify=1] skip + +# We're testing cache behavior, so start with a clean GOCACHE. +env GOCACHE=$WORK/cache + +# Build a helper binary to invoke os.Chtimes. +go build -o mkold$GOEXE mkold.go + +# Make test input files appear to be a minute old. +exec ./mkold$GOEXE 1m testcache/file.txt +exec ./mkold$GOEXE 1m testcache/script.sh + +# If the test reads an environment variable, changes to that variable +# should invalidate cached test results. +env TESTKEY=x +go test testcache -run=TestLookupEnv +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +env TESTKEY=y +go test testcache -run=TestLookupEnv +! stdout '\(cached\)' +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +# Changes in arguments forwarded to the test should invalidate cached test +# results. +go test testcache -run=TestOSArgs -v hello +! stdout '\(cached\)' +stdout 'hello' +go test testcache -run=TestOSArgs -v goodbye +! stdout '\(cached\)' +stdout 'goodbye' + +# golang.org/issue/36134: that includes the `-timeout` argument. +go test testcache -run=TestOSArgs -timeout=20m -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]20m' +go test testcache -run=TestOSArgs -timeout=5s -v +! stdout '\(cached\)' +stdout '-test\.timeout[= ]5s' + +# If the test stats a file, changes to the file should invalidate the cache. +go test testcache -run=FileSize +go test testcache -run=FileSize +stdout '\(cached\)' + +cp 4x.txt testcache/file.txt +go test testcache -run=FileSize +! stdout '\(cached\)' +go test testcache -run=FileSize +stdout '\(cached\)' + +# Files should be tracked even if the test changes its working directory. +go test testcache -run=Chdir +go test testcache -run=Chdir +stdout '\(cached\)' +cp 6x.txt testcache/file.txt +go test testcache -run=Chdir +! stdout '\(cached\)' +go test testcache -run=Chdir +stdout '\(cached\)' + +# The content of files should affect caching, provided that the mtime also changes. +exec ./mkold$GOEXE 1m testcache/file.txt +go test testcache -run=FileContent +go test testcache -run=FileContent +stdout '\(cached\)' +cp 2y.txt testcache/file.txt +exec ./mkold$GOEXE 50s testcache/file.txt +go test testcache -run=FileContent +! stdout '\(cached\)' +go test testcache -run=FileContent +stdout '\(cached\)' + +# Directory contents read via os.ReadDirNames should affect caching. +go test testcache -run=DirList +go test testcache -run=DirList +stdout '\(cached\)' +rm testcache/file.txt +go test testcache -run=DirList +! stdout '\(cached\)' +go test testcache -run=DirList +stdout '\(cached\)' + +# Files outside GOROOT and GOPATH should not affect caching. +env TEST_EXTERNAL_FILE=$WORK/external.txt +go test testcache -run=ExternalFile +go test testcache -run=ExternalFile +stdout '\(cached\)' + +rm $WORK/external.txt +go test testcache -run=ExternalFile +stdout '\(cached\)' + +# The -benchtime flag without -bench should not affect caching. +go test testcache -run=Benchtime -benchtime=1x +go test testcache -run=Benchtime -benchtime=1x +stdout '\(cached\)' + +go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x +go test testcache -run=Benchtime -bench=Benchtime -benchtime=1x +! stdout '\(cached\)' + +# golang.org/issue/47355: that includes the `-failfast` argument. +go test testcache -run=TestOSArgs -failfast +! stdout '\(cached\)' +go test testcache -run=TestOSArgs -failfast +stdout '\(cached\)' + +# Executables within GOROOT and GOPATH should affect caching, +# even if the test does not stat them explicitly. + +[!exec:/bin/sh] skip +chmod 0755 ./testcache/script.sh + +exec ./mkold$GOEXEC 1m testcache/script.sh +go test testcache -run=Exec +go test testcache -run=Exec +stdout '\(cached\)' + +exec ./mkold$GOEXE 50s testcache/script.sh +go test testcache -run=Exec +! stdout '\(cached\)' +go test testcache -run=Exec +stdout '\(cached\)' + +-- testcache/file.txt -- +xx +-- 4x.txt -- +xxxx +-- 6x.txt -- +xxxxxx +-- 2y.txt -- +yy +-- $WORK/external.txt -- +This file is outside of GOPATH. +-- testcache/script.sh -- +#!/bin/sh +exit 0 +-- testcache/testcache_test.go -- +// Copyright 2017 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 testcache + +import ( + "io" + "os" + "testing" +) + +func TestChdir(t *testing.T) { + os.Chdir("..") + defer os.Chdir("testcache") + info, err := os.Stat("testcache/file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileContent(t *testing.T) { + f, err := os.Open("file.txt") + if err != nil { + t.Fatal(err) + } + data, err := io.ReadAll(f) + f.Close() + if err != nil { + t.Fatal(err) + } + if len(data)%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileSize(t *testing.T) { + info, err := os.Stat("file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddGetenv(t *testing.T) { + val := os.Getenv("TESTKEY") + if len(val)%2 != 1 { + t.Fatal("even env value") + } +} + +func TestLookupEnv(t *testing.T) { + _, ok := os.LookupEnv("TESTKEY") + if !ok { + t.Fatal("env missing") + } +} + +func TestDirList(t *testing.T) { + f, err := os.Open(".") + if err != nil { + t.Fatal(err) + } + f.Readdirnames(-1) + f.Close() +} + +func TestExec(t *testing.T) { + // Note: not using os/exec to make sure there is no unexpected stat. + p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr)) + if err != nil { + t.Fatal(err) + } + ps, err := p.Wait() + if err != nil { + t.Fatal(err) + } + if !ps.Success() { + t.Fatalf("script failed: %v", err) + } +} + +func TestExternalFile(t *testing.T) { + os.Open(os.Getenv("TEST_EXTERNAL_FILE")) + _, err := os.Stat(os.Getenv("TEST_EXTERNAL_FILE")) + if err != nil { + t.Fatal(err) + } +} + +func TestOSArgs(t *testing.T) { + t.Log(os.Args) +} + +func TestBenchtime(t *testing.T) { +} + +-- mkold.go -- +package main + +import ( + "log" + "os" + "time" +) + +func main() { + d, err := time.ParseDuration(os.Args[1]) + if err != nil { + log.Fatal(err) + } + path := os.Args[2] + old := time.Now().Add(-d) + err = os.Chtimes(path, old, old) + if err != nil { + log.Fatal(err) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_fail.txt b/src/cmd/go/testdata/script/test_chatty_fail.txt new file mode 100644 index 0000000..a5ef559 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_fail.txt @@ -0,0 +1,32 @@ +# Run chatty tests. Assert on CONT lines. +! go test chatty_test.go -v + +# Sanity check that output occurs. +stdout -count=2 'this is sub-0' +stdout -count=2 'this is sub-1' +stdout -count=2 'this is sub-2' +stdout -count=1 'error from sub-0' +stdout -count=1 'error from sub-1' +stdout -count=1 'error from sub-2' + +# Non-parallel tests should not print CONT. +! stdout CONT + +-- chatty_test.go -- +package chatty_test + +import ( + "testing" + "fmt" +) + +func TestChatty(t *testing.T) { + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + for j := 0; j < 2; j++ { + t.Logf("this is sub-%d", i) + } + t.Errorf("error from sub-%d", i) + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt new file mode 100644 index 0000000..f8faa93 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt @@ -0,0 +1,58 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +! go test -parallel 3 chatty_parallel_test.go -v + +stdout -count=1 '^=== CONT TestChattyParallel/sub-0\n chatty_parallel_test.go:38: error from sub-0$' +stdout -count=1 '^=== CONT TestChattyParallel/sub-1\n chatty_parallel_test.go:38: error from sub-1$' +stdout -count=1 '^=== CONT TestChattyParallel/sub-2\n chatty_parallel_test.go:38: error from sub-2$' + +# Run parallel chatty tests with -json. Assert on CONT lines as above - make +# sure there are CONT lines before each output line. +! go test -json -parallel 3 chatty_parallel_test.go -v +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":" chatty_parallel_test.go:38: error from sub-0\\n"}' +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":" chatty_parallel_test.go:38: error from sub-1\\n"}' +stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":" chatty_parallel_test.go:38: error from sub-2\\n"}' + +-- chatty_parallel_test.go -- +package chatty_parallel_test + +import ( + "testing" + "fmt" + "flag" +) + +// This test ensures the order of CONT lines in parallel chatty tests. +func TestChattyParallel(t *testing.T) { + t.Parallel() + + // The number of concurrent tests running. This is closely tied to the + // -parallel test flag, so we grab it from the flag rather than setting it + // to some constant. + parallel := flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) + + // ready is a synchronization mechanism that causes subtests to execute + // round robin. + ready := make([]chan bool, parallel) + for i := range ready { + ready[i] = make(chan bool, 1) + } + ready[0] <- true + + for i := range ready { + i := i + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + t.Parallel() + + // Some basic log output to precede the failures. + <-ready[i] + t.Logf("this is sub-%d", i) + ready[(i+1)%len(ready)] <- true + + // The actual failure messages we care about. + <-ready[i] + t.Errorf("error from sub-%d", i) + ready[(i+1)%len(ready)] <- true + }) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt new file mode 100644 index 0000000..63034fa --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt @@ -0,0 +1,52 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +go test -parallel 3 chatty_parallel_test.go -v +stdout -count=2 '^=== CONT TestChattyParallel/sub-0\n chatty_parallel_test.go:32: this is sub-0$' +stdout -count=2 '^=== CONT TestChattyParallel/sub-1\n chatty_parallel_test.go:32: this is sub-1$' +stdout -count=2 '^=== CONT TestChattyParallel/sub-2\n chatty_parallel_test.go:32: this is sub-2$' + +# Run parallel chatty tests with -json. Assert on CONT lines as above - make +# sure there are CONT lines before each output line. +go test -json -parallel 3 chatty_parallel_test.go -v +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":" chatty_parallel_test.go:32: this is sub-0\\n"}' +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":" chatty_parallel_test.go:32: this is sub-1\\n"}' +stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":" chatty_parallel_test.go:32: this is sub-2\\n"}' + +-- chatty_parallel_test.go -- +package chatty_parallel_test + +import ( + "testing" + "fmt" + "flag" +) + +// This test ensures the order of CONT lines in parallel chatty tests. +func TestChattyParallel(t *testing.T) { + t.Parallel() + + // The number of concurrent tests running. This is closely tied to the + // -parallel test flag, so we grab it from the flag rather than setting it + // to some constant. + parallel := flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) + + // ready is a synchronization mechanism that causes subtests to execute + // round robin. + ready := make([]chan bool, parallel) + for i := range ready { + ready[i] = make(chan bool, 1) + } + ready[0] <- true + + for i := range ready { + i := i + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + t.Parallel() + for j := 0; j < 2; j++ { + <-ready[i] + t.Logf("this is sub-%d", i) + ready[(i+1)%len(ready)] <- true + } + }) + } +} diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt new file mode 100644 index 0000000..e651a7e --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_parallel_success_sleepy.txt @@ -0,0 +1,39 @@ +# Run parallel chatty tests. Assert on CONT lines. This test makes sure that +# multiple parallel outputs have the appropriate CONT lines between them. +go test -parallel 3 chatty_parallel_test.go -v + +stdout '--- PASS: TestFast \([0-9.]{4}s\)\n=== CONT TestSlow\n chatty_parallel_test.go:31: this is the second TestSlow log\n--- PASS: TestSlow \([0-9.]{4}s\)' + +-- chatty_parallel_test.go -- +package chatty_parallel_test + +import ( + "testing" + "time" +) + +var ( + run = make(chan struct{}) + afterFirstLog = make(chan struct{}) + afterPass = make(chan struct{}) +) + +func TestFast(t *testing.T) { + t.Parallel() + + <-afterFirstLog + t.Cleanup(func() { + close(afterPass) + }) +} + +func TestSlow(t *testing.T) { + t.Parallel() + + t.Logf("this is the first TestSlow log") + close(afterFirstLog) + + <-afterPass + time.Sleep(100 * time.Millisecond) + t.Logf("this is the second TestSlow log") +} diff --git a/src/cmd/go/testdata/script/test_chatty_success.txt b/src/cmd/go/testdata/script/test_chatty_success.txt new file mode 100644 index 0000000..8bfa569 --- /dev/null +++ b/src/cmd/go/testdata/script/test_chatty_success.txt @@ -0,0 +1,27 @@ +# Run chatty tests. Assert on CONT lines. +go test chatty_test.go -v + +# Non-parallel tests should not print CONT. +! stdout CONT + +# The assertion is condensed into one line so that it precisely matches output, +# rather than skipping lines and allow rogue CONT lines. +stdout '=== RUN TestChatty\n=== RUN TestChatty/sub-0\n chatty_test.go:12: this is sub-0\n chatty_test.go:12: this is sub-0\n=== RUN TestChatty/sub-1\n chatty_test.go:12: this is sub-1\n chatty_test.go:12: this is sub-1\n=== RUN TestChatty/sub-2\n chatty_test.go:12: this is sub-2\n chatty_test.go:12: this is sub-2\n--- PASS: TestChatty' + +-- chatty_test.go -- +package chatty_test + +import ( + "testing" + "fmt" +) + +func TestChatty(t *testing.T) { + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("sub-%d", i), func(t *testing.T) { + for j := 0; j < 2; j++ { + t.Logf("this is sub-%d", i) + } + }) + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_cleanup_failnow.txt b/src/cmd/go/testdata/script/test_cleanup_failnow.txt new file mode 100644 index 0000000..0737a93 --- /dev/null +++ b/src/cmd/go/testdata/script/test_cleanup_failnow.txt @@ -0,0 +1,47 @@ +# For issue 41355 +[short] skip + +# This test could fail if the testing package does not wait until +# a panicking test does the panic. Turn off multithreading, GC, and +# async preemption to increase the probability of such a failure. +env GOMAXPROCS=1 +env GOGC=off +env GODEBUG=asyncpreempt=off + +# If the test exits with 'no tests to run', it means the testing package +# implementation is incorrect and does not wait until a test panic. +# If the test exits with '(?s)panic: die.*panic: die', it means +# the testing package did an extra panic for a panicking test. + +! go test -v cleanup_failnow/panic_nocleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +! go test -v cleanup_failnow/panic_withcleanup_test.go +! stdout 'no tests to run' +stdout '(?s)panic: die \[recovered\].*panic: die' +! stdout '(?s)panic: die \[recovered\].*panic: die.*panic: die' + +-- cleanup_failnow/panic_nocleanup_test.go -- +package panic_nocleanup_test +import "testing" +func TestX(t *testing.T) { + t.Run("x", func(t *testing.T) { + panic("die") + }) +} + +-- cleanup_failnow/panic_withcleanup_test.go -- +package panic_withcleanup_test +import "testing" +func TestCleanupWithFailNow(t *testing.T) { + t.Cleanup(func() { + t.FailNow() + }) + t.Run("x", func(t *testing.T) { + t.Run("y", func(t *testing.T) { + panic("die") + }) + }) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_compile_binary.txt b/src/cmd/go/testdata/script/test_compile_binary.txt new file mode 100644 index 0000000..63bb8ec --- /dev/null +++ b/src/cmd/go/testdata/script/test_compile_binary.txt @@ -0,0 +1,8 @@ +env GO111MODULE=off + +! go test -c compile_binary/... +stderr 'build comment' + +-- compile_binary/foo_test.go -- +// +build foo +package foo diff --git a/src/cmd/go/testdata/script/test_compile_tempfile.txt b/src/cmd/go/testdata/script/test_compile_tempfile.txt new file mode 100644 index 0000000..05f721a --- /dev/null +++ b/src/cmd/go/testdata/script/test_compile_tempfile.txt @@ -0,0 +1,11 @@ +[short] skip + +# Ensure that the target of 'go build -o' can be an existing, empty file so that +# its name can be reserved using os.CreateTemp or the 'mktemp` command. + +go build -o empty-file$GOEXE main.go + +-- main.go -- +package main +func main() {} +-- empty-file$GOEXE -- diff --git a/src/cmd/go/testdata/script/test_deadline.txt b/src/cmd/go/testdata/script/test_deadline.txt new file mode 100644 index 0000000..06ae16f --- /dev/null +++ b/src/cmd/go/testdata/script/test_deadline.txt @@ -0,0 +1,54 @@ +[short] skip + +go test -timeout=0 -run=TestNoDeadline +go test -timeout=1m -run=TestDeadlineWithinMinute +go test -timeout=1m -run=TestSubtestDeadlineWithinMinute + +-- go.mod -- +module m + +go 1.16 +-- deadline_test.go -- +package testing_test + +import ( + "testing" + "time" +) + +func TestNoDeadline(t *testing.T) { + d, ok := t.Deadline() + if ok || !d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want 0, false", d, ok) + } +} + +func TestDeadlineWithinMinute(t *testing.T) { + now := time.Now() + d, ok := t.Deadline() + if !ok || d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want nonzero deadline", d, ok) + } + if !d.After(now) { + t.Fatalf("t.Deadline() = %v; want after start of test (%v)", d, now) + } + if d.Sub(now) > time.Minute { + t.Fatalf("t.Deadline() = %v; want within one minute of start of test (%v)", d, now) + } +} + +func TestSubtestDeadlineWithinMinute(t *testing.T) { + t.Run("sub", func(t *testing.T) { + now := time.Now() + d, ok := t.Deadline() + if !ok || d.IsZero() { + t.Fatalf("t.Deadline() = %v, %v; want nonzero deadline", d, ok) + } + if !d.After(now) { + t.Fatalf("t.Deadline() = %v; want after start of test (%v)", d, now) + } + if d.Sub(now) > time.Minute { + t.Fatalf("t.Deadline() = %v; want within one minute of start of test (%v)", d, now) + } + }) +} diff --git a/src/cmd/go/testdata/script/test_empty.txt b/src/cmd/go/testdata/script/test_empty.txt new file mode 100644 index 0000000..5ebbecd --- /dev/null +++ b/src/cmd/go/testdata/script/test_empty.txt @@ -0,0 +1,53 @@ +[!race] skip + +cd $GOPATH/src/empty/pkg +go test -cover -coverpkg=. -race + +[short] stop # Only run first case in short mode + +cd $GOPATH/src/empty/test +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/xtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgxtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/pkgtestxtest +go test -cover -coverpkg=. -race + +cd $GOPATH/src/empty/testxtest +go test -cover -coverpkg=. -race + +-- empty/go.mod -- +module empty + +go 1.16 +-- empty/pkg/pkg.go -- +package p +-- empty/pkgtest/pkg.go -- +package p +-- empty/pkgtest/test_test.go -- +package p +-- empty/pkgtestxtest/pkg.go -- +package p +-- empty/pkgtestxtest/test_test.go -- +package p +-- empty/pkgtestxtest/xtest_test.go -- +package p_test +-- empty/pkgxtest/pkg.go -- +package p +-- empty/pkgxtest/xtest_test.go -- +package p_test +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test diff --git a/src/cmd/go/testdata/script/test_env_term.txt b/src/cmd/go/testdata/script/test_env_term.txt new file mode 100644 index 0000000..8a5f79a --- /dev/null +++ b/src/cmd/go/testdata/script/test_env_term.txt @@ -0,0 +1,15 @@ +# Tests golang.org/issue/12096 + +env TERM='' +go test test_test.go +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +-- test_test.go -- +package main +import ("os"; "testing") +func TestEnv(t *testing.T) { + if os.Getenv("TERM") != "" { + t.Fatal("TERM is set") + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_example_goexit.txt b/src/cmd/go/testdata/script/test_example_goexit.txt new file mode 100644 index 0000000..984f434 --- /dev/null +++ b/src/cmd/go/testdata/script/test_example_goexit.txt @@ -0,0 +1,29 @@ +# For issue golang.org/issue/41084 +[short] skip + +! go test -v examplegoexit +stdout '(?s)--- PASS.*--- FAIL.*' +stdout 'panic: test executed panic\(nil\) or runtime\.Goexit' + +-- go.mod -- +module examplegoexit + +go 1.16 +-- example_test.go -- +package main + +import ( + "fmt" + "runtime" +) + +func ExamplePass() { + fmt.Println("pass") + // Output: + // pass +} + +func ExampleGoexit() { + runtime.Goexit() + // Output: +} diff --git a/src/cmd/go/testdata/script/test_exit.txt b/src/cmd/go/testdata/script/test_exit.txt new file mode 100644 index 0000000..3703ba5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_exit.txt @@ -0,0 +1,131 @@ +# Builds and runs test binaries, so skip in short mode. +[short] skip + +env GO111MODULE=on + +# If a test invoked by 'go test' exits with a zero status code, +# it will panic. +! go test ./zero +! stdout ^ok +! stdout 'exit status' +stdout 'panic' +stdout ^FAIL + +# If a test exits with a non-zero status code, 'go test' fails normally. +! go test ./one +! stdout ^ok +stdout 'exit status' +! stdout 'panic' +stdout ^FAIL + +# Ensure that other flags still do the right thing. +go test -list=. ./zero +stdout ExitZero + +! go test -bench=. ./zero +stdout 'panic' + +# 'go test' with no args streams output without buffering. Ensure that it still +# catches a zero exit with missing output. +cd zero +! go test +stdout 'panic' +cd ../normal +go test +stdout ^ok +cd .. + +# If a TestMain exits with a zero status code, 'go test' shouldn't +# complain about that. It's a common way to skip testing a package +# entirely. +go test ./main_zero +! stdout 'skipping all tests' +stdout ^ok + +# With -v, we'll see the warning from TestMain. +go test -v ./main_zero +stdout 'skipping all tests' +stdout ^ok + +# Listing all tests won't actually give a result if TestMain exits. That's okay, +# because this is how TestMain works. If we decide to support -list even when +# TestMain is used to skip entire packages, we can change this test case. +go test -list=. ./main_zero +stdout 'skipping all tests' +! stdout TestNotListed + +# Running the test directly still fails, if we pass the flag. +go test -c -o ./zero.exe ./zero +! exec ./zero.exe -test.paniconexit0 + +# Using -json doesn't affect the exit status. +! go test -json ./zero +! stdout '"Output":"ok' +! stdout 'exit status' +stdout 'panic' +stdout '"Output":"FAIL' + +# Running the test via test2json also fails. +! go tool test2json ./zero.exe -test.v -test.paniconexit0 +! stdout '"Output":"ok' +! stdout 'exit status' +stdout 'panic' + +-- go.mod -- +module m + +-- ./normal/normal.go -- +package normal +-- ./normal/normal_test.go -- +package normal + +import "testing" + +func TestExitZero(t *testing.T) { +} + +-- ./zero/zero.go -- +package zero +-- ./zero/zero_test.go -- +package zero + +import ( + "os" + "testing" +) + +func TestExitZero(t *testing.T) { + os.Exit(0) +} + +-- ./one/one.go -- +package one +-- ./one/one_test.go -- +package one + +import ( + "os" + "testing" +) + +func TestExitOne(t *testing.T) { + os.Exit(1) +} + +-- ./main_zero/zero.go -- +package zero +-- ./main_zero/zero_test.go -- +package zero + +import ( + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + fmt.Println("skipping all tests") + os.Exit(0) +} + +func TestNotListed(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_fail_fast.txt b/src/cmd/go/testdata/script/test_fail_fast.txt new file mode 100644 index 0000000..132ea70 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fail_fast.txt @@ -0,0 +1,113 @@ +[short] skip + +# test fail fast +! go test ./failfast_test.go -run='TestFailingA' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailing[AB]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# mix with non-failing tests +! go test ./failfast_test.go -run='TestA|TestFailing[AB]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestA|TestFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# mix with parallel tests +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailingA' -failfast=true +stdout -count=2 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailingA' -failfast=false +stdout -count=2 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]' -failfast=true +stdout -count=3 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]' -failfast=false +stdout -count=3 'FAIL - ' + +# mix with parallel sub-tests +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA' -failfast=true +stdout -count=3 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingB|TestParallelFailing[AB]|TestParallelFailingSubtestsA' -failfast=false +stdout -count=5 'FAIL - ' +! go test ./failfast_test.go -run='TestParallelFailingSubtestsA' -failfast=true +stdout -count=1 'FAIL - ' + +# only parallels +! go test ./failfast_test.go -run='TestParallelFailing[AB]' -failfast=false +stdout -count=2 'FAIL - ' + +# non-parallel subtests +! go test ./failfast_test.go -run='TestFailingSubtestsA' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFailingSubtestsA' -failfast=false +stdout -count=2 'FAIL - ' + +# fatal test +! go test ./failfast_test.go -run='TestFatal[CD]' -failfast=true +stdout -count=1 'FAIL - ' +! go test ./failfast_test.go -run='TestFatal[CD]' -failfast=false +stdout -count=2 'FAIL - ' + +-- failfast_test.go -- +// Copyright 2017 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 failfast + +import "testing" + +func TestA(t *testing.T) { + // Edge-case testing, mixing unparallel tests too + t.Logf("LOG: %s", t.Name()) +} + +func TestFailingA(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) +} + +func TestB(t *testing.T) { + // Edge-case testing, mixing unparallel tests too + t.Logf("LOG: %s", t.Name()) +} + +func TestParallelFailingA(t *testing.T) { + t.Parallel() + t.Errorf("FAIL - %s", t.Name()) +} + +func TestParallelFailingB(t *testing.T) { + t.Parallel() + t.Errorf("FAIL - %s", t.Name()) +} + +func TestParallelFailingSubtestsA(t *testing.T) { + t.Parallel() + t.Run("TestFailingSubtestsA1", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) + t.Run("TestFailingSubtestsA2", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) +} + +func TestFailingSubtestsA(t *testing.T) { + t.Run("TestFailingSubtestsA1", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) + t.Run("TestFailingSubtestsA2", func(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) + }) +} + +func TestFailingB(t *testing.T) { + t.Errorf("FAIL - %s", t.Name()) +} + +func TestFatalC(t *testing.T) { + t.Fatalf("FAIL - %s", t.Name()) +} + +func TestFatalD(t *testing.T) { + t.Fatalf("FAIL - %s", t.Name()) +} diff --git a/src/cmd/go/testdata/script/test_fail_newline.txt b/src/cmd/go/testdata/script/test_fail_newline.txt new file mode 100644 index 0000000..43cee56 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fail_newline.txt @@ -0,0 +1,65 @@ +[short] skip + +# In package list mode, output is buffered. +# Check that a newline is printed after the buffer's contents. +cd fail +! go test . +! stderr . +stdout '^exitcode=1\n' +stdout '^FAIL\s+example/fail' + +# In local directory mode output is streamed, so we don't know +# whether the test printed anything at all, so we print the exit code +# (just in case it failed without emitting any output at all), +# and that happens to add the needed newline as well. +! go test +! stderr . +stdout '^exitcode=1exit status 1\n' +stdout '^FAIL\s+example/fail' + +# In package list mode, if the test passes the 'ok' message appears +# on its own line. +cd ../skip +go test -v . +! stderr . +stdout '^skipping\n' +stdout '^ok\s+example/skip' + +# If the output is streamed and the test passes, we can't tell whether it ended +# in a partial line, and don't want to emit any extra output in the +# overwhelmingly common case that it did not. +# (In theory we could hook the 'os' package to report whether output +# was emitted and whether it ended in a newline, but that seems too invasive.) +go test +! stderr . +stdout '^skippingok\s+example/skip' + + +-- go.mod -- +module example + +go 1.18 +-- fail/fail_test.go -- +package fail + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Stderr.WriteString("exitcode=1") + os.Exit(1) +} +-- skip/skip_test.go -- +package skip + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Stderr.WriteString("skipping") + os.Exit(0) +} diff --git a/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt b/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt new file mode 100644 index 0000000..8db821e --- /dev/null +++ b/src/cmd/go/testdata/script/test_finished_subtest_goroutines.txt @@ -0,0 +1,52 @@ +# Regression test for https://golang.org/issue/45127: +# Goroutines for completed parallel subtests should exit immediately, +# not block until earlier subtests have finished. + +[short] skip + +! go test . +stdout 'panic: slow failure' +! stdout '\[chan send' + +-- go.mod -- +module golang.org/issue45127 + +go 1.16 +-- issue45127_test.go -- +package main + +import ( + "fmt" + "runtime" + "runtime/debug" + "sync" + "testing" +) + +func TestTestingGoroutineLeak(t *testing.T) { + debug.SetTraceback("all") + + var wg sync.WaitGroup + const nFast = 10 + + t.Run("slow", func(t *testing.T) { + t.Parallel() + wg.Wait() + for i := 0; i < nFast; i++ { + // If the subtest goroutines are going to park on the channel + // send, allow them to park now. If they're not going to park, + // make sure they have had a chance to run to completion so + // that they aren't spuriously parked when we panic. + runtime.Gosched() + } + panic("slow failure") + }) + + wg.Add(nFast) + for i := 0; i < nFast; i++ { + t.Run(fmt.Sprintf("leaky%d", i), func(t *testing.T) { + t.Parallel() + wg.Done() + }) + } +} diff --git a/src/cmd/go/testdata/script/test_flag.txt b/src/cmd/go/testdata/script/test_flag.txt new file mode 100644 index 0000000..d168cfe --- /dev/null +++ b/src/cmd/go/testdata/script/test_flag.txt @@ -0,0 +1,40 @@ +[short] skip + +go test flag_test.go -v -args -v=7 # Two distinct -v flags +go test -v flag_test.go -args -v=7 # Two distinct -v flags + +# Using a custom flag mixed with regular 'go test' flags should be OK. +go test -count=1 -custom -args -v=7 + +# However, it should be an error to use custom flags when -i or -c are used, +# since we know for sure that no test binary will run at all. +! go test -i -custom +stderr '^go: unknown flag -custom cannot be used with -i$' +! go test -c -custom +stderr '^go: unknown flag -custom cannot be used with -c$' + +# The same should apply even if -c or -i come after a custom flag. +! go test -custom -c +stderr '^go: unknown flag -custom cannot be used with -c$' + +-- go.mod -- +module m +-- flag_test.go -- +package flag_test + +import ( + "flag" + "log" + "testing" +) + +var v = flag.Int("v", 0, "v flag") + +var custom = flag.Bool("custom", false, "") + +// Run this as go test pkg -v=7 +func TestVFlagIsSet(t *testing.T) { + if *v != 7 { + log.Fatal("v flag not set") + } +} diff --git a/src/cmd/go/testdata/script/test_flags.txt b/src/cmd/go/testdata/script/test_flags.txt new file mode 100644 index 0000000..63385e6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_flags.txt @@ -0,0 +1,132 @@ +env GO111MODULE=on + +[short] skip + +# Arguments after the flag terminator should be ignored. +# If we pass '-- -test.v', we should not get verbose output +# *and* output from the test should not be echoed. +go test ./x -- -test.v +stdout '\Aok\s+example.com/x\s+[0-9.s]+\n\z' +! stderr . + +# For backward-compatibility with previous releases of the 'go' command, +# arguments that appear after unrecognized flags should not be treated +# as packages, even if they are unambiguously not arguments to flags. +# Even though ./x looks like a package path, the real package should be +# the implicit '.'. +! go test --answer=42 ./x +stderr '^no Go files in .+$' +! stderr '/x' + +# However, *flags* that appear after unrecognized flags should still be +# interpreted as flags, under the (possibly-erroneous) assumption that +# unrecognized flags are non-boolean. + +go test -v -x ./x -timeout 24h -boolflag=true foo -timeout 25h +stdout 'args: foo -timeout 25h' +stdout 'timeout: 24h0m0s$' # -timeout is unambiguously not a flag, so the real flag wins. + +go test -v -x ./x -timeout 24h -boolflag foo -timeout 25h +stdout 'args: foo -test\.timeout=25h0m0s' # For legacy reasons, '-timeout ' is erroneously rewritten to -test.timeout; see https://golang.org/issue/40763. +stdout 'timeout: 24h0m0s$' # Actual flag wins. + +go test -v -x ./x -timeout 24h -stringflag foo -timeout 25h +stdout 'args: $' +stdout 'timeout: 25h0m0s$' # Later flag wins. + +# An explicit '-outputdir=' argument should set test.outputdir +# to the 'go' command's working directory, not zero it out +# for the test binary. +go test -x -coverprofile=cover.out '-outputdir=' ./x +stderr '-test.outputdir=[^ ]' +exists ./cover.out +! exists ./x/cover.out + +# Test flags from GOFLAGS should be forwarded to the test binary, +# with the 'test.' prefix in the GOFLAGS entry... +env GOFLAGS='-test.timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# ...or without. +env GOFLAGS='-timeout=24h0m0s -count=1' +go test -v -x ./x +stdout 'timeout: 24h0m0s$' +stderr '-test.count=1' + +# Arguments from the command line should override GOFLAGS... +go test -v -x -timeout=25h0m0s ./x +stdout 'timeout: 25h0m0s$' +stderr '-test.count=1' + +# ...even if they use a different flag name. +go test -v -x -test.timeout=26h0m0s ./x +stdout 'timeout: 26h0m0s$' +stderr '-test\.timeout=26h0m0s' +! stderr 'timeout=24h0m0s' +stderr '-test.count=1' + +# Invalid flags should be reported exactly once. +! go test -covermode=walrus ./x +stderr -count=1 'invalid value "walrus" for flag -covermode: valid modes are .*$' +stderr '^usage: go test .*$' +stderr '^Run ''go help test'' and ''go help testflag'' for details.$' + +# Passing -help to the test binary should show flag help. +go test ./x -args -help +stdout 'usage_message' + +# -covermode, -coverpkg, and -coverprofile should imply -cover +go test -covermode=set ./x +stdout '\s+coverage:\s+' + +go test -coverpkg=encoding/binary ./x +stdout '\s+coverage:\s+' + +go test -coverprofile=cover.out ./x +stdout '\s+coverage:\s+' +exists ./cover.out +rm ./cover.out + +# -*profile and -trace flags should force output to the current working directory +# or -outputdir, not the directory containing the test. + +go test -memprofile=mem.out ./x +exists ./mem.out +rm ./mem.out + +go test -trace=trace.out ./x +exists ./trace.out +rm ./trace.out + +# Relative paths with -outputdir should be relative to the go command's working +# directory, not the directory containing the test. +mkdir profiles +go test -memprofile=mem.out -outputdir=./profiles ./x +exists ./profiles/mem.out +rm profiles + +-- go.mod -- +module example.com +go 1.14 +-- x/x_test.go -- +package x + +import ( + "flag" + "strings" + "testing" +) + +var _ = flag.String("usage_message", "", "dummy flag to check usage message") +var boolflag = flag.Bool("boolflag", false, "ignored boolean flag") +var stringflag = flag.String("stringflag", "", "ignored string flag") + +func TestLogTimeout(t *testing.T) { + t.Logf("timeout: %v", flag.Lookup("test.timeout").Value) +} + +func TestLogArgs(t *testing.T) { + t.Logf("args: %s", strings.Join(flag.Args(), " ")) +} diff --git a/src/cmd/go/testdata/script/test_fuzz.txt b/src/cmd/go/testdata/script/test_fuzz.txt new file mode 100644 index 0000000..3e048e0 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz.txt @@ -0,0 +1,498 @@ +[!fuzz] skip + +# Test that running a fuzz target that returns without failing or calling +# f.Fuzz fails and causes a non-zero exit status. +! go test noop_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that fuzzing a fuzz target that returns without failing or calling +# f.Fuzz fails and causes a non-zero exit status. +! go test -fuzz=Fuzz -fuzztime=1x noop_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that calling f.Error in a fuzz target causes a non-zero exit status. +! go test -fuzz=Fuzz -fuzztime=1x error_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that calling f.Fatal in a fuzz target causes a non-zero exit status. +! go test fatal_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that successful test exits cleanly. +go test success_fuzz_test.go +stdout ^ok +! stdout FAIL + +# Test that successful fuzzing exits cleanly. +go test -fuzz=Fuzz -fuzztime=1x success_fuzz_test.go +stdout ok +! stdout FAIL + +# Test that calling f.Fatal while fuzzing causes a non-zero exit status. +! go test -fuzz=Fuzz -fuzztime=1x fatal_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test error with seed corpus in f.Fuzz +! go test -run FuzzError fuzz_add_test.go +! stdout ^ok +stdout FAIL +stdout 'error here' + +[short] stop + +# Test that calling panic(nil) in a fuzz target causes a non-zero exit status. +! go test panic_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that skipped test exits cleanly. +go test skipped_fuzz_test.go +stdout ok +! stdout FAIL + +# Test that f.Fatal within f.Fuzz panics +! go test fatal_fuzz_fn_fuzz_test.go +! stdout ^ok +! stdout 'fatal here' +stdout FAIL +stdout 'fuzz target' + +# Test that f.Error within f.Fuzz panics +! go test error_fuzz_fn_fuzz_test.go +! stdout ^ok +! stdout 'error here' +stdout FAIL +stdout 'fuzz target' + +# Test that f.Fail within f.Fuzz panics +! go test fail_fuzz_fn_fuzz_test.go +! stdout ^ok +stdout FAIL +stdout 'fuzz target' + +# Test that f.Skip within f.Fuzz panics +! go test skip_fuzz_fn_fuzz_test.go +! stdout ^ok +! stdout 'skip here' +stdout FAIL +stdout 'fuzz target' + +# Test that f.Skipped within f.Fuzz panics +! go test skipped_fuzz_fn_fuzz_test.go +! stdout ^ok +! stdout 'f.Skipped is' +stdout FAIL +stdout 'fuzz target' +stdout 't.Skipped is false' + +# Test that runtime.Goexit within the fuzz function is an error. +! go test goexit_fuzz_fn_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that a call to f.Fatal after the Fuzz func is executed. +! go test fatal_after_fuzz_func_fuzz_test.go +! stdout ok +stdout FAIL + +# Test that missing *T in f.Fuzz causes a non-zero exit status. +! go test incomplete_fuzz_call_fuzz_test.go +! stdout ^ok +stdout FAIL + +# Test that a panic in the Cleanup func is executed. +! go test cleanup_fuzz_test.go +! stdout ^ok +stdout FAIL +stdout 'failed some precondition' + +# Test success with seed corpus in f.Fuzz +go test -run FuzzPass fuzz_add_test.go +stdout ok +! stdout FAIL +! stdout 'off by one error' + +# Test fatal with seed corpus in f.Fuzz +! go test -run FuzzFatal fuzz_add_test.go +! stdout ^ok +stdout FAIL +stdout 'fatal here' + +# Test panic with seed corpus in f.Fuzz +! go test -run FuzzPanic fuzz_add_test.go +! stdout ^ok +stdout FAIL +stdout 'off by one error' + +# Test panic(nil) with seed corpus in f.Fuzz +! go test -run FuzzNilPanic fuzz_add_test.go +! stdout ^ok +stdout FAIL + +# Test panic with unsupported seed corpus +! go test -run FuzzUnsupported fuzz_add_test.go +! stdout ^ok +stdout FAIL + +# Test panic with different number of args to f.Add +! go test -run FuzzAddDifferentNumber fuzz_add_test.go +! stdout ^ok +stdout FAIL + +# Test panic with different type of args to f.Add +! go test -run FuzzAddDifferentType fuzz_add_test.go +! stdout ^ok +stdout FAIL + +# Test that the wrong type given with f.Add will fail. +! go test -run FuzzWrongType fuzz_add_test.go +! stdout ^ok +stdout '\[string int\], want \[\[\]uint8 int8\]' +stdout FAIL + +# Test fatal with testdata seed corpus +! go test -run FuzzFail corpustesting/fuzz_testdata_corpus_test.go +! stdout ^ok +stdout FAIL +stdout 'fatal here' + +# Test pass with testdata seed corpus +go test -run FuzzPass corpustesting/fuzz_testdata_corpus_test.go +stdout ok +! stdout FAIL +! stdout 'fatal here' + +# Test pass with testdata and f.Add seed corpus +go test -run FuzzPassString corpustesting/fuzz_testdata_corpus_test.go +stdout ok +! stdout FAIL + +# Fuzzing pass with testdata and f.Add seed corpus (skip running tests first) +go test -run=None -fuzz=FuzzPassString corpustesting/fuzz_testdata_corpus_test.go -fuzztime=10x +stdout ok +! stdout FAIL + +# Fuzzing pass with testdata and f.Add seed corpus +go test -run=FuzzPassString -fuzz=FuzzPassString corpustesting/fuzz_testdata_corpus_test.go -fuzztime=10x +stdout ok +! stdout FAIL + +# Test panic with malformed seed corpus +! go test -run FuzzFail corpustesting/fuzz_testdata_corpus_test.go +! stdout ^ok +stdout FAIL + +# Test pass with file in other nested testdata directory +go test -run FuzzInNestedDir corpustesting/fuzz_testdata_corpus_test.go +stdout ok +! stdout FAIL +! stdout 'fatal here' + +# Test fails with file containing wrong type +! go test -run FuzzWrongType corpustesting/fuzz_testdata_corpus_test.go +! stdout ^ok +stdout FAIL + +-- noop_fuzz_test.go -- +package noop_fuzz + +import "testing" + +func Fuzz(f *testing.F) {} + +-- error_fuzz_test.go -- +package error_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Error("error in target") +} + +-- fatal_fuzz_test.go -- +package fatal_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fatal("fatal in target") +} + +-- panic_fuzz_test.go -- +package panic_fuzz + +import "testing" + +func FuzzPanic(f *testing.F) { + panic(nil) +} + +-- success_fuzz_test.go -- +package success_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fuzz(func (*testing.T, []byte) {}) +} + +-- skipped_fuzz_test.go -- +package skipped_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Skip() +} + +-- fatal_fuzz_fn_fuzz_test.go -- +package fatal_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + f.Fatal("fatal here") + }) +} + +-- error_fuzz_fn_fuzz_test.go -- +package error_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + f.Error("error here") + }) +} + +-- fail_fuzz_fn_fuzz_test.go -- +package skip_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + f.Fail() + }) +} + +-- skip_fuzz_fn_fuzz_test.go -- +package skip_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + f.Skip("skip here") + }) +} + +-- skipped_fuzz_fn_fuzz_test.go -- +package skipped_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + t.Logf("t.Skipped is %t\n", t.Skipped()) + t.Logf("f.Skipped is %t\n", f.Skipped()) + }) +} + +-- goexit_fuzz_fn_fuzz_test.go -- +package goexit_fuzz_fn_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + runtime.Goexit() + }) +} + +-- fatal_after_fuzz_func_fuzz_test.go -- +package fatal_after_fuzz_func_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + // no-op + }) + f.Fatal("this shouldn't be called") +} + +-- incomplete_fuzz_call_fuzz_test.go -- +package incomplete_fuzz_call_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fuzz(func(b []byte) { + // this is missing *testing.T as the first param, so should panic + }) +} + +-- cleanup_fuzz_test.go -- +package cleanup_fuzz_test + +import "testing" + +func Fuzz(f *testing.F) { + f.Cleanup(func() { + panic("failed some precondition") + }) + f.Fuzz(func(t *testing.T, b []byte) { + // no-op + }) +} + +-- fuzz_add_test.go -- +package fuzz_add + +import "testing" + +func add(f *testing.F) { + f.Helper() + f.Add([]byte("123")) + f.Add([]byte("12345")) + f.Add([]byte("")) +} + +func FuzzPass(f *testing.F) { + add(f) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == -1 { + t.Fatal("fatal here") // will not be executed + } + }) +} + +func FuzzError(f *testing.F) { + add(f) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == 3 { + t.Error("error here") + } + }) +} + +func FuzzFatal(f *testing.F) { + add(f) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == 0 { + t.Fatal("fatal here") + } + }) +} + +func FuzzPanic(f *testing.F) { + add(f) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == 5 { + panic("off by one error") + } + }) +} + +func FuzzNilPanic(f *testing.F) { + add(f) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == 3 { + panic(nil) + } + }) +} + +func FuzzUnsupported(f *testing.F) { + m := make(map[string]bool) + f.Add(m) + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzAddDifferentNumber(f *testing.F) { + f.Add([]byte("a")) + f.Add([]byte("a"), []byte("b")) + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzAddDifferentType(f *testing.F) { + f.Add(false) + f.Add(1234) + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzWrongType(f *testing.F) { + f.Add("hello", 50) + f.Fuzz(func(*testing.T, []byte, int8) {}) +} + +-- corpustesting/fuzz_testdata_corpus_test.go -- +package fuzz_testdata_corpus + +import "testing" + +func fuzzFn(f *testing.F) { + f.Helper() + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) == "12345" { + t.Fatal("fatal here") + } + }) +} + +func FuzzFail(f *testing.F) { + fuzzFn(f) +} + +func FuzzPass(f *testing.F) { + fuzzFn(f) +} + +func FuzzPassString(f *testing.F) { + f.Add("some seed corpus") + f.Fuzz(func(*testing.T, string) {}) +} + +func FuzzPanic(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) {}) +} + +func FuzzInNestedDir(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) {}) +} + +func FuzzWrongType(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) {}) +} + +-- corpustesting/testdata/fuzz/FuzzFail/1 -- +go test fuzz v1 +[]byte("12345") +-- corpustesting/testdata/fuzz/FuzzPass/1 -- +go test fuzz v1 +[]byte("00000") +-- corpustesting/testdata/fuzz/FuzzPassString/1 -- +go test fuzz v1 +string("hello") +-- corpustesting/testdata/fuzz/FuzzPanic/1 -- +malformed +-- corpustesting/testdata/fuzz/FuzzInNestedDir/anotherdir/1 -- +go test fuzz v1 +[]byte("12345") +-- corpustesting/testdata/fuzz/FuzzWrongType/1 -- +go test fuzz v1 +int("00000") diff --git a/src/cmd/go/testdata/script/test_fuzz_cache.txt b/src/cmd/go/testdata/script/test_fuzz_cache.txt new file mode 100644 index 0000000..552966b --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_cache.txt @@ -0,0 +1,97 @@ +[!fuzz-instrumented] skip + +[short] skip +env GOCACHE=$WORK/cache + +# Fuzz cache should not exist after a regular test run. +go test . +exists $GOCACHE +! exists $GOCACHE/fuzz + +# Fuzzing should write interesting values to the cache. +go test -fuzz=FuzzY -fuzztime=100x . +go run ./contains_files $GOCACHE/fuzz/example.com/y/FuzzY + +# 'go clean -cache' should not delete the fuzz cache. +go clean -cache +exists $GOCACHE/fuzz + +# 'go clean -fuzzcache' should delete the fuzz cache but not the build cache. +go list -f {{.Stale}} ./empty +stdout true +go install ./empty +go list -f {{.Stale}} ./empty +stdout false +go clean -fuzzcache +! exists $GOCACHE/fuzz +go list -f {{.Stale}} ./empty +stdout false + +# Fuzzing indicates that one new interesting value was found with an empty +# corpus, and the total size of the cache is now 1. +go clean -fuzzcache +go test -fuzz=FuzzEmpty -fuzztime=10000x . +stdout 'new interesting: 1' +stdout 'total: 1' + +# Fuzzing again with a small fuzztime does not find any other interesting +# values but still indicates that the cache size is 1. +go test -fuzz=FuzzEmpty -fuzztime=2x . +stdout 'new interesting: 0' +stdout 'total: 1' + +-- go.mod -- +module example.com/y + +go 1.16 +-- y_test.go -- +package y + +import ( + "io" + "testing" +) + +func FuzzEmpty(f *testing.F) { + f.Fuzz(func (*testing.T, []byte) {}) +} + +func FuzzY(f *testing.F) { + f.Add([]byte("y")) + f.Fuzz(func(t *testing.T, b []byte) { Y(io.Discard, b) }) +} +-- y.go -- +package y + +import ( + "bytes" + "io" +) + +func Y(w io.Writer, b []byte) { + if !bytes.Equal(b, []byte("y")) { + w.Write([]byte("not equal")) + } +} +-- empty/empty.go -- +package empty +-- contains_files/contains_files.go -- +package main + +import ( + "fmt" + "path/filepath" + "io/ioutil" + "os" +) + +func main() { + infos, err := ioutil.ReadDir(filepath.Clean(os.Args[1])) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if len(infos) == 0 { + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_fuzz_chatty.txt b/src/cmd/go/testdata/script/test_fuzz_chatty.txt new file mode 100644 index 0000000..d07fe50 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_chatty.txt @@ -0,0 +1,102 @@ +[!fuzz] skip +[short] skip + +# Run chatty fuzz targets with an error. +! go test -v chatty_error_fuzz_test.go +! stdout '^ok' +stdout 'FAIL' +stdout 'error in target' + +# Run chatty fuzz targets with a fatal. +! go test -v chatty_fatal_fuzz_test.go +! stdout '^ok' +stdout 'FAIL' +stdout 'fatal in target' + +# Run chatty fuzz target with a panic +! go test -v chatty_panic_fuzz_test.go +! stdout ^ok +stdout FAIL +stdout 'this is bad' + +# Run skipped chatty fuzz targets. +go test -v chatty_skipped_fuzz_test.go +stdout ok +stdout SKIP +! stdout FAIL + +# Run successful chatty fuzz targets. +go test -v chatty_fuzz_test.go +stdout ok +stdout PASS +stdout 'all good here' +! stdout FAIL + +# Fuzz successful chatty fuzz target that includes a separate unit test. +go test -v chatty_with_test_fuzz_test.go -fuzz=Fuzz -fuzztime=1x +stdout ok +stdout PASS +! stdout FAIL +stdout -count=1 'all good here' +# Verify that the unit test is only run once. +stdout -count=1 'logged foo' + +-- chatty_error_fuzz_test.go -- +package chatty_error_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Error("error in target") +} + +-- chatty_fatal_fuzz_test.go -- +package chatty_fatal_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fatal("fatal in target") +} + +-- chatty_panic_fuzz_test.go -- +package chatty_panic_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + panic("this is bad") +} + +-- chatty_skipped_fuzz_test.go -- +package chatty_skipped_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Skip() +} + +-- chatty_fuzz_test.go -- +package chatty_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Log("all good here") + f.Fuzz(func(*testing.T, []byte) {}) +} + +-- chatty_with_test_fuzz_test.go -- +package chatty_with_test_fuzz + +import "testing" + +func TestFoo(t *testing.T) { + t.Log("logged foo") +} + +func Fuzz(f *testing.F) { + f.Log("all good here") + f.Fuzz(func(*testing.T, []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_cleanup.txt b/src/cmd/go/testdata/script/test_fuzz_cleanup.txt new file mode 100644 index 0000000..b65022b --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_cleanup.txt @@ -0,0 +1,66 @@ +[!fuzz] skip +[short] skip + +# Cleanup should run after F.Skip. +go test -run=FuzzTargetSkip +stdout cleanup + +# Cleanup should run after F.Fatal. +! go test -run=FuzzTargetFatal +stdout cleanup + +# Cleanup should run after an unexpected runtime.Goexit. +! go test -run=FuzzTargetGoexit +stdout cleanup + +# Cleanup should run after panic. +! go test -run=FuzzTargetPanic +stdout cleanup + +# Cleanup should run in fuzz function on seed corpus. +go test -v -run=FuzzFunction +stdout '(?s)inner.*outer' + +# TODO(jayconrod): test cleanup while fuzzing. For now, the worker process's +# stdout and stderr is connected to the coordinator's, but it should eventually +# be connected to os.DevNull, so we wouldn't see t.Log output. + +-- go.mod -- +module cleanup + +go 1.15 +-- cleanup_test.go -- +package cleanup + +import ( + "runtime" + "testing" +) + +func FuzzTargetSkip(f *testing.F) { + f.Cleanup(func() { f.Log("cleanup") }) + f.Skip() +} + +func FuzzTargetFatal(f *testing.F) { + f.Cleanup(func() { f.Log("cleanup") }) + f.Fatal() +} + +func FuzzTargetGoexit(f *testing.F) { + f.Cleanup(func() { f.Log("cleanup") }) + runtime.Goexit() +} + +func FuzzTargetPanic(f *testing.F) { + f.Cleanup(func() { f.Log("cleanup") }) + panic("oh no") +} + +func FuzzFunction(f *testing.F) { + f.Add([]byte{0}) + f.Cleanup(func() { f.Log("outer") }) + f.Fuzz(func(t *testing.T, b []byte) { + t.Cleanup(func() { t.Logf("inner") }) + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_cov.txt b/src/cmd/go/testdata/script/test_fuzz_cov.txt new file mode 100644 index 0000000..05b6348 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_cov.txt @@ -0,0 +1,33 @@ +# Test that coverage instrumentation is working. Without the instrumentation +# it is _extremely_ unlikely that the fuzzer would produce this particular +# input in any reasonable amount of time. + +[short] skip +[!fuzz-instrumented] skip + +! go test -fuzz=FuzzCov +! stderr 'cov instrumentation working' + +-- go.mod -- +module test + +-- cov_test.go -- +package cov + +import "testing" + +func FuzzCov(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) == 8 && + b[0] == 'h' && + b[1] == 'e' && + b[2] == 'l' && + b[3] == 'l' && + b[4] == 'o' && + b[5] == ' ' && + b[6] == ':' && + b[7] == ')' { + panic("cov instrumentation working") + } + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_deadline.txt b/src/cmd/go/testdata/script/test_fuzz_deadline.txt new file mode 100644 index 0000000..5ba76a3 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_deadline.txt @@ -0,0 +1,35 @@ +[!fuzz] skip +[short] skip + +# The fuzz function should be able to detect whether -timeout +# was set with T.Deadline. Note there is no F.Deadline, and +# there is no timeout while fuzzing, even if -fuzztime is set. +go test -run=FuzzDeadline -wantdeadline=true # -timeout defaults to 10m +go test -run=FuzzDeadline -timeout=0 -wantdeadline=false +! go test -run=FuzzDeadline -timeout=1s -wantdeadline=false +go test -run=FuzzDeadline -timeout=1s -wantdeadline=true +go test -fuzz=FuzzDeadline -timeout=0 -fuzztime=1s -wantdeadline=false +go test -fuzz=FuzzDeadline -timeout=0 -fuzztime=100x -wantdeadline=false + +-- go.mod -- +module fuzz + +go 1.16 +-- fuzz_deadline_test.go -- +package fuzz_test + +import ( + "flag" + "testing" +) + +var wantDeadline = flag.Bool("wantdeadline", false, "whether the test should have a deadline") + +func FuzzDeadline(f *testing.F) { + f.Add("run once") + f.Fuzz(func (t *testing.T, _ string) { + if _, hasDeadline := t.Deadline(); hasDeadline != *wantDeadline { + t.Fatalf("function got %v; want %v", hasDeadline, *wantDeadline) + } + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_dup_cache.txt b/src/cmd/go/testdata/script/test_fuzz_dup_cache.txt new file mode 100644 index 0000000..52d44a2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_dup_cache.txt @@ -0,0 +1,52 @@ +[!fuzz] skip +[short] skip + +# This test checks that cached corpus loading properly handles duplicate entries (this can +# happen when a f.Add value has a duplicate entry in the cached corpus.) Duplicate entries +# should be discarded, and the rest of the cache should be loaded as normal. + +env GOCACHE=$WORK/cache +env GODEBUG=fuzzdebug=1 + +mkdir -p $GOCACHE/fuzz/fuzztest/FuzzTarget +go run ./populate $GOCACHE/fuzz/fuzztest/FuzzTarget + +go test -fuzz=FuzzTarget -fuzztime=10x . +stdout 'entries: 5' + +-- go.mod -- +module fuzztest + +go 1.17 + +-- fuzz_test.go -- +package fuzz + +import "testing" + +func FuzzTarget(f *testing.F) { + f.Add(int(0)) + f.Fuzz(func(t *testing.T, _ int) {}) +} + +-- populate/main.go -- +package main + +import ( + "path/filepath" + "fmt" + "os" +) + +func main() { + for i := 0; i < 10; i++ { + b := byte(0) + if i > 5 { + b = byte(i) + } + tmpl := "go test fuzz v1\nint(%d)\n" + if err := os.WriteFile(filepath.Join(os.Args[1], fmt.Sprint(i)), []byte(fmt.Sprintf(tmpl, b)), 0777); err != nil { + panic(err) + } + } +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_fuzz_fuzztime.txt b/src/cmd/go/testdata/script/test_fuzz_fuzztime.txt new file mode 100644 index 0000000..56d94a4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_fuzztime.txt @@ -0,0 +1,121 @@ +[!fuzz] skip +[short] skip + +# There are no seed values, so 'go test' should finish quickly. +go test + +# Fuzzing should exit 0 after fuzztime, even if timeout is short. +go test -timeout=3s -fuzz=FuzzFast -fuzztime=5s + +# We should see the same behavior when invoking the test binary directly. +go test -c +exec ./fuzz.test$GOEXE -test.timeout=3s -test.fuzz=FuzzFast -test.fuzztime=5s -test.parallel=1 -test.fuzzcachedir=$WORK/cache + +# Timeout should not cause inputs to be written as crashers. +! exists testdata/fuzz + +env GOCACHE=$WORK/tmp + +# When we use fuzztime with an "x" suffix, it runs a specific number of times. +# This fuzz function creates a file with a unique name ($pid.$count) on each +# run. We count the files to find the number of runs. +mkdir count +go test -fuzz=FuzzTestCount -fuzztime=1000x -fuzzminimizetime=1x +go run check_file_count.go count 1000 + +# When we use fuzzminimizetime with an "x" suffix, it runs a specific number of +# times while minimizing. This fuzz function creates a file with a unique name +# ($pid.$count) on each run once the first crash has been found. That means that +# there should be one file for each execution of the fuzz function during +# minimization, so we count these to determine how many times minimization was +# run. +mkdir minimizecount +! go test -fuzz=FuzzMinimizeCount -fuzzminimizetime=3x -parallel=1 +go run check_file_count.go minimizecount 3 + +-- go.mod -- +module fuzz + +go 1.16 +-- fuzz_fast_test.go -- +package fuzz_test + +import "testing" + +func FuzzFast(f *testing.F) { + f.Fuzz(func (*testing.T, []byte) {}) +} +-- fuzz_count_test.go -- +package fuzz + +import ( + "fmt" + "os" + "testing" +) + +func FuzzTestCount(f *testing.F) { + pid := os.Getpid() + n := 0 + f.Fuzz(func(t *testing.T, _ []byte) { + name := fmt.Sprintf("count/%v.%d", pid, n) + if err := os.WriteFile(name, nil, 0666); err != nil { + t.Fatal(err) + } + n++ + }) +} +-- fuzz_minimize_count_test.go -- +package fuzz + +import ( + "bytes" + "fmt" + "os" + "testing" +) + +func FuzzMinimizeCount(f *testing.F) { + pid := os.Getpid() + n := 0 + seed := bytes.Repeat([]byte("a"), 357) + f.Add(seed) + crashFound := false + f.Fuzz(func(t *testing.T, b []byte) { + if crashFound { + name := fmt.Sprintf("minimizecount/%v.%d", pid, n) + if err := os.WriteFile(name, nil, 0666); err != nil { + t.Fatal(err) + } + n++ + } + if !bytes.Equal(b, seed) { // this should happen right away + crashFound = true + t.Error("minimize this!") + } + }) +} +-- check_file_count.go -- +// +build ignore + +package main + +import ( + "fmt" + "os" + "strconv" +) + +func main() { + dir, err := os.ReadDir(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + got := len(dir) + want, _ := strconv.Atoi(os.Args[2]) + if got != want { + fmt.Fprintf(os.Stderr, "got %d files; want %d\n", got, want) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_fuzz_io_error.txt b/src/cmd/go/testdata/script/test_fuzz_io_error.txt new file mode 100644 index 0000000..1a0aa64 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_io_error.txt @@ -0,0 +1,101 @@ +# Test that when the coordinator experiences an I/O error communicating +# with a worker, the coordinator stops the worker and reports the error. +# The coordinator should not record a crasher. +# +# We simulate an I/O error in the test by writing garbage to fuzz_out. +# This is unlikely, but possible. It's difficult to simulate interruptions +# due to ^C and EOF errors which are more common. We don't report those. +[short] skip +[!fuzz] skip + +# If the I/O error occurs before F.Fuzz is called, the coordinator should +# stop the worker and say that. +! go test -fuzz=FuzzClosePipeBefore -parallel=1 +stdout '\s*fuzzing process terminated without fuzzing:' +! stdout 'communicating with fuzzing process' +! exists testdata + +# If the I/O error occurs after F.Fuzz is called (unlikely), just exit. +# It's hard to distinguish this case from the worker being interrupted by ^C +# or exiting with status 0 (which it should do when interrupted by ^C). +! go test -fuzz=FuzzClosePipeAfter -parallel=1 +stdout '^\s*communicating with fuzzing process: invalid character ''!'' looking for beginning of value$' +! exists testdata + +-- go.mod -- +module test + +go 1.17 +-- io_error_test.go -- +package io_error + +import ( + "flag" + "testing" + "time" +) + +func isWorker() bool { + f := flag.Lookup("test.fuzzworker") + if f == nil { + return false + } + get, ok := f.Value.(flag.Getter) + if !ok { + return false + } + return get.Get() == interface{}(true) +} + +func FuzzClosePipeBefore(f *testing.F) { + if isWorker() { + sendGarbageToCoordinator(f) + time.Sleep(3600 * time.Second) // pause until coordinator terminates the process + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzClosePipeAfter(f *testing.F) { + f.Fuzz(func(t *testing.T, _ []byte) { + if isWorker() { + sendGarbageToCoordinator(t) + time.Sleep(3600 * time.Second) // pause until coordinator terminates the process + } + }) +} +-- io_error_windows_test.go -- +package io_error + +import ( + "fmt" + "os" + "testing" +) + +func sendGarbageToCoordinator(tb testing.TB) { + v := os.Getenv("GO_TEST_FUZZ_WORKER_HANDLES") + var fuzzInFD, fuzzOutFD uintptr + if _, err := fmt.Sscanf(v, "%x,%x", &fuzzInFD, &fuzzOutFD); err != nil { + tb.Fatalf("parsing GO_TEST_FUZZ_WORKER_HANDLES: %v", err) + } + f := os.NewFile(fuzzOutFD, "fuzz_out") + if _, err := f.Write([]byte("!!")); err != nil { + tb.Fatalf("writing fuzz_out: %v", err) + } +} +-- io_error_notwindows_test.go -- +// +build !windows + +package io_error + +import ( + "os" + "testing" +) + +func sendGarbageToCoordinator(tb testing.TB) { + f := os.NewFile(4, "fuzz_out") + if _, err := f.Write([]byte("!!")); err != nil { + tb.Fatalf("writing fuzz_out: %v", err) + } +} diff --git a/src/cmd/go/testdata/script/test_fuzz_match.txt b/src/cmd/go/testdata/script/test_fuzz_match.txt new file mode 100644 index 0000000..dbf9876 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_match.txt @@ -0,0 +1,38 @@ +[!fuzz] skip + +# Matches only fuzz targets to test. +go test standalone_fuzz_test.go +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +# Matches only for fuzzing. +go test -fuzz Fuzz -fuzztime 1x standalone_fuzz_test.go +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +# Matches none for fuzzing but will run the fuzz target as a test. +go test -fuzz ThisWillNotMatch -fuzztime 1x standalone_fuzz_test.go +! stdout '^ok.*no tests to run' +stdout '^ok' +stdout 'no fuzz tests to fuzz' + +[short] stop + +# Matches only fuzz targets to test with -run. +go test -run Fuzz standalone_fuzz_test.go +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +# Matches no fuzz targets. +go test -run ThisWillNotMatch standalone_fuzz_test.go +stdout '^ok.*no tests to run' +! stdout 'no fuzz tests to fuzz' + +-- standalone_fuzz_test.go -- +package standalone_fuzz + +import "testing" + +func Fuzz(f *testing.F) { + f.Fuzz(func (*testing.T, []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_minimize.txt b/src/cmd/go/testdata/script/test_fuzz_minimize.txt new file mode 100644 index 0000000..a6dc3f1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_minimize.txt @@ -0,0 +1,203 @@ +[!fuzz] skip +[short] skip + +# We clean the fuzz cache during this test. Don't clean the user's cache. +env GOCACHE=$WORK/gocache + +# Test that fuzzminimizetime cannot be negative seconds +! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1ms . +! stdout '^ok' +! stdout 'contains a non-zero byte' +stdout 'invalid duration' +stdout FAIL + +# Test that fuzzminimizetime cannot be negative times +! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1x . +! stdout '^ok' +! stdout 'contains a non-zero byte' +stdout 'invalid count' +stdout FAIL + +# Test that fuzzminimizetime can be zero seconds, and minimization is disabled +! go test -fuzz=FuzzMinimizeZeroDurationSet -run=FuzzMinimizeZeroDurationSet -fuzztime=10000x -fuzzminimizetime=0s . +! stdout '^ok' +! stdout 'minimizing' +stdout 'there was an Error' +stdout FAIL + +# Test that fuzzminimizetime can be zero times, and minimization is disabled +! go test -fuzz=FuzzMinimizeZeroLimitSet -run=FuzzMinimizeZeroLimitSet -fuzztime=10000x -fuzzminimizetime=0x . +! stdout '^ok' +! stdout 'minimizing' +stdout -count=1 'there was an Error' +stdout FAIL + +# Test that minimization is working for recoverable errors. +! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x . +! stdout '^ok' +stdout 'got the minimum size!' +# The error message that was printed should be for the one written to testdata. +stdout 'contains a non-zero byte of length 50' +stdout FAIL + +# Check that the bytes written to testdata are of length 50 (the minimum size) +go run ./check_testdata FuzzMinimizerRecoverable 50 + +# Test that re-running the minimized value causes a crash. +! go test -run=FuzzMinimizerRecoverable . +rm testdata + +# Test that minimization is working for recoverable errors. Run it with -v this +# time to ensure the command line output still looks right. +! go test -v -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x . +! stdout '^ok' +stdout 'got the minimum size!' +# The error message that was printed should be for the one written to testdata. +stdout 'contains a non-zero byte of length 50' +stdout FAIL + +# Check that the bytes written to testdata are of length 50 (the minimum size) +go run ./check_testdata FuzzMinimizerRecoverable 50 + +# Test that re-running the minimized value causes a crash. +! go test -run=FuzzMinimizerRecoverable . +rm testdata + +# Test that minimization doesn't run for non-recoverable errors. +! go test -fuzz=FuzzMinimizerNonrecoverable -run=FuzzMinimizerNonrecoverable -fuzztime=10000x . +! stdout '^ok' +! stdout 'minimizing' +stdout -count=1 '^\s+fuzzing process hung or terminated unexpectedly: exit status 99' +stdout FAIL + +# Check that re-running the value causes a crash. +! go test -run=FuzzMinimizerNonrecoverable . +rm testdata + +# Clear the fuzzing cache. There may already be minimized inputs that would +# interfere with the next stage of the test. +go clean -fuzzcache + +# Test that minimization can be cancelled by fuzzminimizetime and the latest +# crash will still be logged and written to testdata. +! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=100x -fuzzminimizetime=1x . +! stdout '^ok' +stdout 'testdata[/\\]fuzz[/\\]FuzzMinimizerRecoverable[/\\]' +! stdout 'got the minimum size!' # it shouldn't have had enough time to minimize it +stdout FAIL + +# Test that re-running the unminimized value causes a crash. +! go test -run=FuzzMinimizerRecoverable . + +# TODO(jayconrod,katiehockman): add a test which verifies that the right bytes +# are written to testdata in the case of an interrupt during minimization. + +-- go.mod -- +module example.com/y + +go 1.16 +-- y_test.go -- +package y + +import ( + "os" + "testing" +) + +func FuzzMinimizeZeroDurationSet(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) > 5 { + t.Errorf("there was an Error") + } + }) +} + +func FuzzMinimizeZeroLimitSet(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) > 5 { + t.Errorf("there was an Error") + } + }) +} + +func FuzzMinimizerRecoverable(f *testing.F) { + f.Add(make([]byte, 100)) + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) < 50 { + // Make sure that b is large enough that it can be minimized + return + } + // Given the randomness of the mutations, this should allow the + // minimizer to trim down the value a bit. + for _, n := range b { + if n != 0 { + if len(b) == 50 { + t.Log("got the minimum size!") + } + t.Fatalf("contains a non-zero byte of length %d", len(b)) + } + } + }) +} + +func FuzzMinimizerNonrecoverable(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + os.Exit(99) + }) +} +-- empty/empty.go -- +package empty +-- check_testdata/check_testdata.go -- +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" +) + +func main() { + target := os.Args[1] + numBytes, err := strconv.Atoi(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + // Open the file in testdata (there should only be one) + dir := fmt.Sprintf("testdata/fuzz/%s", target) + files, err := ioutil.ReadDir(dir) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if len(files) != 1 { + fmt.Fprintf(os.Stderr, "expected one file, got %d", len(files)) + os.Exit(1) + } + got, err := ioutil.ReadFile(filepath.Join(dir, files[0].Name())) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + // Trim the newline at the end of the file + got = bytes.TrimSpace(got) + + // Make sure that there were exactly 100 bytes written to the corpus entry + prefix := []byte("[]byte(") + i := bytes.Index(got, prefix) + gotBytes := got[i+len(prefix) : len(got)-1] + s, err := strconv.Unquote(string(gotBytes)) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if want, got := numBytes, len(s); want != got { + fmt.Fprintf(os.Stderr, "want %d bytes, got %d\n", want, got) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_fuzz_minimize_dirty_cov.txt b/src/cmd/go/testdata/script/test_fuzz_minimize_dirty_cov.txt new file mode 100644 index 0000000..571bf75 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_minimize_dirty_cov.txt @@ -0,0 +1,84 @@ +# Test that minimization doesn't use dirty coverage snapshots when it +# is unable to actually minimize the input. We do this by checking that +# a expected value appears in the cache. If a dirty coverage map is used +# (i.e. the coverage map generated during the last minimization step, +# rather than the map provided with the initial input) then this value +# is unlikely to appear in the cache, since the map generated during +# the last minimization step should not increase the coverage. + +[short] skip +[!fuzz-instrumented] skip + +env GOCACHE=$WORK/gocache +go test -fuzz=FuzzCovMin -fuzztime=25s -test.fuzzcachedir=$GOCACHE/fuzz +go run check_file/main.go $GOCACHE/fuzz/FuzzCovMin abcd + +-- go.mod -- +module test + +-- covmin_test.go -- +package covmin + +import "testing" + +func FuzzCovMin(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + if len(data) >= 4 && data[0] == 'a' && data[1] == 'b' && data[2] == 'c' && data[3] == 'd' { + return + } + }) +} + +-- check_file/main.go -- +package main + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "regexp" + "strconv" +) + +func checkFile(name, expected string) (bool, error) { + data, err := os.ReadFile(name) + if err != nil { + return false, err + } + for _, line := range bytes.Split(data, []byte("\n")) { + m := valRe.FindSubmatch(line) + if m == nil { + continue + } + fmt.Println(strconv.Unquote(string(m[1]))) + if s, err := strconv.Unquote(string(m[1])); err != nil { + return false, err + } else if s == expected { + return true, nil + } + } + return false, nil +} + +var valRe = regexp.MustCompile(`^\[\]byte\(([^)]+)\)$`) + +func main() { + dir, expected := os.Args[1], os.Args[2] + ents, err := os.ReadDir(dir) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + for _, ent := range ents { + name := filepath.Join(dir, ent.Name()) + if good, err := checkFile(name, expected); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } else if good { + os.Exit(0) + } + } + fmt.Fprintln(os.Stderr, "input over minimized") + os.Exit(1) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_minimize_interesting.txt b/src/cmd/go/testdata/script/test_fuzz_minimize_interesting.txt new file mode 100644 index 0000000..a09e85b --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_minimize_interesting.txt @@ -0,0 +1,240 @@ +[short] skip +[!fuzz-instrumented] skip + +# Test that when an interesting value is discovered (one that expands coverage), +# the fuzzing engine minimizes it before writing it to the cache. +# +# The program below starts with a seed value of length 100, but more coverage +# will be found for any value other than the seed. We should end with a value +# in the cache of length 1 (the minimizer currently does not produce empty +# strings). check_cache.go confirms that. +# +# We would like to verify that ALL values in the cache were minimized to a +# length of 1, but this isn't always possible when new coverage is found in +# functions called by testing or internal/fuzz in the background. + +go test -c -fuzz=. # Build using shared build cache for speed. +env GOCACHE=$WORK/gocache +exec ./fuzz.test$GOEXE -test.fuzzcachedir=$GOCACHE/fuzz -test.fuzz=FuzzMinCache -test.fuzztime=1000x +go run check_cache/check_cache.go $GOCACHE/fuzz/FuzzMinCache + +go test -c -fuzz=. # Build using shared build cache for speed. +env GOCACHE=$WORK/gocache + +# Test that minimization occurs for a crash that appears while minimizing a +# newly found interesting input. There must be only one worker for this test to +# be flaky like we want. +! exec ./fuzz.test$GOEXE -test.fuzzcachedir=$GOCACHE/fuzz -test.fuzz=FuzzMinimizerCrashInMinimization -test.run=FuzzMinimizerCrashInMinimization -test.fuzztime=10000x -test.parallel=1 +! stdout '^ok' +stdout -count=1 'got the minimum size!' +stdout -count=1 'flaky failure' +stdout FAIL +# Check that the input written to testdata will reproduce the error, and is the +# smallest possible. +go run check_testdata/check_testdata.go FuzzMinimizerCrashInMinimization 50 + +# Test that a nonrecoverable error that occurs while minimizing an interesting +# input is reported correctly. +! exec ./fuzz.test$GOEXE -test.fuzzcachedir=$GOCACHE/fuzz -test.fuzz=FuzzMinimizerNonrecoverableCrashInMinimization -test.run=FuzzMinimizerNonrecoverableCrashInMinimization -test.fuzztime=10000x -test.parallel=1 +! stdout '^ok' +stdout -count=1 'fuzzing process hung or terminated unexpectedly while minimizing' +stdout -count=1 'EOF' +stdout FAIL +# Check that the input written to testdata will reproduce the error. +go run check_testdata/check_testdata.go FuzzMinimizerNonrecoverableCrashInMinimization 100 + +-- go.mod -- +module fuzz + +go 1.17 +-- y.go -- +package fuzz + +import ( + "bytes" + "io" +) + +func Y(w io.Writer, s string) { + if !bytes.Equal([]byte(s), []byte("y")) { + w.Write([]byte("not equal")) + } +} +-- fuzz_test.go -- +package fuzz + +import ( + "bytes" + "io" + "os" + "strings" + "testing" + "unicode/utf8" +) + +func FuzzMinimizerCrashInMinimization(f *testing.F) { + seed := strings.Repeat("A", 1000) + f.Add(seed) + i := 3 + f.Fuzz(func(t *testing.T, s string) { + if len(s) < 50 || len(s) > 1100 { + // Make sure that b is large enough that it can be minimized + return + } + if s != seed { + // This should hit a new edge, and the interesting input + // should attempt minimization + Y(io.Discard, s) + } + if i > 0 { + // Don't let it fail right away. + i-- + } else if utf8.RuneCountInString(s) == len(s) && len(s) <= 100 { + // Make sure this only fails if the number of bytes in the + // marshaled string is the same as the unmarshaled string, + // so that we can check the length of the testdata file. + t.Error("flaky failure") + if len(s) == 50 { + t.Error("got the minimum size!") + } + } + }) +} + +func FuzzMinimizerNonrecoverableCrashInMinimization(f *testing.F) { + seed := strings.Repeat("A", 1000) + f.Add(seed) + i := 3 + f.Fuzz(func(t *testing.T, s string) { + if len(s) < 50 || len(s) > 1100 { + return + } + if s != seed { + Y(io.Discard, s) + } + if i > 0 { + i-- + } else if utf8.RuneCountInString(s) == len(s) && len(s) <= 100 { + os.Exit(19) + } + }) +} + +func FuzzMinCache(f *testing.F) { + seed := bytes.Repeat([]byte("a"), 20) + f.Add(seed) + f.Fuzz(func(t *testing.T, buf []byte) { + if bytes.Equal(buf, seed) { + return + } + }) +} +-- check_testdata/check_testdata.go -- +//go:build ignore +// +build ignore + +// check_testdata.go checks that the string written +// is not longer than the provided length. +package main + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" +) + +func main() { + wantLen, err := strconv.Atoi(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + testName := os.Args[1] + dir := filepath.Join("testdata/fuzz", testName) + + files, err := ioutil.ReadDir(dir) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if len(files) == 0 { + fmt.Fprintf(os.Stderr, "expect at least one failure to be written to testdata\n") + os.Exit(1) + } + + fname := files[0].Name() + contents, err := ioutil.ReadFile(filepath.Join(dir, fname)) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + contentsLen := len(contents) - len(`go test fuzz v1 +string("") +`) + if got, want := contentsLen, wantLen; got > want { + fmt.Fprintf(os.Stderr, "expect length <= %d, got %d\n", want, got) + os.Exit(1) + } + fmt.Fprintf(os.Stderr, "%s\n", contents) +} + +-- check_cache/check_cache.go -- +//go:build ignore +// +build ignore + +// check_cache.go checks that each file in the cached corpus has a []byte +// of length at most 1. This verifies that at least one cached input is minimized. +package main + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + "regexp" + "strconv" +) + +func main() { + dir := os.Args[1] + ents, err := os.ReadDir(dir) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + for _, ent := range ents { + name := filepath.Join(dir, ent.Name()) + if good, err := checkCacheFile(name); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } else if good { + os.Exit(0) + } + } + fmt.Fprintln(os.Stderr, "no cached inputs were minimized") + os.Exit(1) +} + +func checkCacheFile(name string) (good bool, err error) { + data, err := os.ReadFile(name) + if err != nil { + return false, err + } + for _, line := range bytes.Split(data, []byte("\n")) { + m := valRe.FindSubmatch(line) + if m == nil { + continue + } + if s, err := strconv.Unquote(string(m[1])); err != nil { + return false, err + } else if len(s) <= 1 { + return true, nil + } + } + return false, nil +} + +var valRe = regexp.MustCompile(`^\[\]byte\(([^)]+)\)$`) diff --git a/src/cmd/go/testdata/script/test_fuzz_modcache.txt b/src/cmd/go/testdata/script/test_fuzz_modcache.txt new file mode 100644 index 0000000..c0f18ea --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_modcache.txt @@ -0,0 +1,58 @@ +# This test demonstrates the fuzz corpus behavior for packages outside of the main module. +# (See https://golang.org/issue/48495.) + +[short] skip + +# Set -modcacherw so that the test behaves the same regardless of whether the +# module cache is writable. (For example, on some platforms it can always be +# written if the user is running as root.) At one point, a failing fuzz test +# in a writable module cache would corrupt module checksums in the cache. +env GOFLAGS=-modcacherw + + +# When the upstream module has no test corpus, running 'go test' should succeed, +# but 'go test -fuzz=.' should error out before running the test. +# (It should NOT corrupt the module cache by writing out new fuzz inputs, +# even if the cache is writable.) + +go get -t example.com/fuzzfail@v0.1.0 +go test example.com/fuzzfail + +! go test -fuzz=. example.com/fuzzfail +! stdout . +stderr '^cannot use -fuzz flag on package outside the main module$' + +go mod verify + + +# If the module does include a test corpus, 'go test' (without '-fuzz') should +# load that corpus and run the fuzz tests against it, but 'go test -fuzz=.' +# should continue to be rejected. + +go get -t example.com/fuzzfail@v0.2.0 + +! go test example.com/fuzzfail +stdout '^\s*fuzzfail_test\.go:7: oops:' + +! go test -fuzz=. example.com/fuzzfail +! stdout . +stderr '^cannot use -fuzz flag on package outside the main module$' + +go mod verify + + +# Packages in 'std' cannot be fuzzed when the corresponding GOROOT module is not +# the main module — either the failures would not be recorded or the behavior of +# the 'std' tests would change globally. + +! go test -fuzz . encoding/json +stderr '^cannot use -fuzz flag on package outside the main module$' + +! go test -fuzz . cmd/buildid +stderr '^cannot use -fuzz flag on package outside the main module$' + + +-- go.mod -- +module example.com/m + +go 1.18 diff --git a/src/cmd/go/testdata/script/test_fuzz_multiple.txt b/src/cmd/go/testdata/script/test_fuzz_multiple.txt new file mode 100644 index 0000000..1ec4985 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_multiple.txt @@ -0,0 +1,49 @@ +# This test checks that 'go test' prints a reasonable error when fuzzing is +# enabled, and multiple package or multiple fuzz targets match. +# TODO(#46312): support fuzzing multiple targets in multiple packages. + +[!fuzz] skip +[short] skip + +# With fuzzing disabled, multiple targets can be tested. +go test ./... + +# With fuzzing enabled, at most one package may be tested, +# even if only one package contains fuzz targets. +! go test -fuzz=. ./... +stderr '^cannot use -fuzz flag with multiple packages$' +! go test -fuzz=. ./zero ./one +stderr '^cannot use -fuzz flag with multiple packages$' +go test -fuzz=. -fuzztime=1x ./one + +# With fuzzing enabled, at most one target in the same package may match. +! go test -fuzz=. ./two +stdout '^testing: will not fuzz, -fuzz matches more than one fuzz test: \[FuzzOne FuzzTwo\]$' +go test -fuzz=FuzzTwo -fuzztime=1x ./two + +-- go.mod -- +module fuzz + +go 1.18 +-- zero/zero.go -- +package zero +-- one/one_test.go -- +package one + +import "testing" + +func FuzzOne(f *testing.F) { + f.Fuzz(func(*testing.T, []byte) {}) +} +-- two/two_test.go -- +package two + +import "testing" + +func FuzzOne(f *testing.F) { + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzTwo(f *testing.F) { + f.Fuzz(func(*testing.T, []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt b/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt new file mode 100644 index 0000000..99bae1d --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt @@ -0,0 +1,323 @@ +[!fuzz] skip + +# Tests that a crash caused by a mutator-discovered input writes the bad input +# to testdata, and fails+reports correctly. This tests the end-to-end behavior +# of the mutator finding a crash while fuzzing, adding it as a regression test +# to the seed corpus in testdata, and failing the next time the test is run. + +[short] skip + +# Running the seed corpus for all of the targets should pass the first +# time, since nothing in the seed corpus will cause a crash. +go test + +# Running the fuzzer should find a crashing input quickly. +! go test -fuzz=FuzzWithBug -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithBug[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzWithBug + +# Now, the failing bytes should have been added to the seed corpus for +# the target, and should fail when run without fuzzing. +! go test +stdout 'FuzzWithBug/[a-f0-9]{64}' +stdout 'this input caused a crash!' + +! go test -run=FuzzWithNilPanic -fuzz=FuzzWithNilPanic -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithNilPanic[/\\]' +stdout 'runtime.Goexit' +go run check_testdata.go FuzzWithNilPanic + +! go test -run=FuzzWithGoexit -fuzz=FuzzWithGoexit -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithGoexit[/\\]' +stdout 'runtime.Goexit' +go run check_testdata.go FuzzWithGoexit + +! go test -run=FuzzWithFail -fuzz=FuzzWithFail -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithFail[/\\]' +go run check_testdata.go FuzzWithFail + +! go test -run=FuzzWithLogFail -fuzz=FuzzWithLogFail -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithLogFail[/\\]' +stdout 'logged something' +go run check_testdata.go FuzzWithLogFail + +! go test -run=FuzzWithErrorf -fuzz=FuzzWithErrorf -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithErrorf[/\\]' +stdout 'errorf was called here' +go run check_testdata.go FuzzWithErrorf + +! go test -run=FuzzWithFatalf -fuzz=FuzzWithFatalf -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithFatalf[/\\]' +stdout 'fatalf was called here' +go run check_testdata.go FuzzWithFatalf + +! go test -run=FuzzWithBadExit -fuzz=FuzzWithBadExit -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithBadExit[/\\]' +stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status' +go run check_testdata.go FuzzWithBadExit + +! go test -run=FuzzDeadlock -fuzz=FuzzDeadlock -fuzztime=100x -fuzzminimizetime=0x +stdout 'testdata[/\\]fuzz[/\\]FuzzDeadlock[/\\]' +stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status' +go run check_testdata.go FuzzDeadlock + +# Running the fuzzer should find a crashing input quickly for fuzzing two types. +! go test -run=FuzzWithTwoTypes -fuzz=FuzzWithTwoTypes -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzWithTwoTypes[/\\]' +stdout 'these inputs caused a crash!' +go run check_testdata.go FuzzWithTwoTypes + +# Running the fuzzer should find a crashing input quickly for an integer. +! go test -run=FuzzInt -fuzz=FuzzInt -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzInt[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzInt + +! go test -run=FuzzUint -fuzz=FuzzUint -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzUint[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzUint + +# Running the fuzzer should find a crashing input quickly for a bool. +! go test -run=FuzzBool -fuzz=FuzzBool -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzBool[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzBool + +# Running the fuzzer should find a crashing input quickly for a float. +! go test -run=FuzzFloat -fuzz=FuzzFloat -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzFloat[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzFloat + +# Running the fuzzer should find a crashing input quickly for a byte. +! go test -run=FuzzByte -fuzz=FuzzByte -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzByte[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzByte + +# Running the fuzzer should find a crashing input quickly for a rune. +! go test -run=FuzzRune -fuzz=FuzzRune -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzRune[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzRune + +# Running the fuzzer should find a crashing input quickly for a string. +! go test -run=FuzzString -fuzz=FuzzString -fuzztime=100x -fuzzminimizetime=1000x +stdout 'testdata[/\\]fuzz[/\\]FuzzString[/\\]' +stdout 'this input caused a crash!' +go run check_testdata.go FuzzString + +-- go.mod -- +module m + +go 1.16 +-- fuzz_crash_test.go -- +package fuzz_crash + +import ( + "os" + "runtime" + "testing" +) + +func FuzzWithBug(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + panic("this input caused a crash!") + } + }) +} + +func FuzzWithNilPanic(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + panic(nil) + } + }) +} + +func FuzzWithGoexit(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + runtime.Goexit() + } + }) +} + +func FuzzWithFail(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + t.Fail() + } + }) +} + +func FuzzWithLogFail(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + t.Log("logged something") + t.Fail() + } + }) +} + +func FuzzWithErrorf(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + t.Errorf("errorf was called here") + } + }) +} + +func FuzzWithFatalf(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + t.Fatalf("fatalf was called here") + } + }) +} + +func FuzzWithBadExit(f *testing.F) { + f.Add([]byte("aa")) + f.Fuzz(func(t *testing.T, b []byte) { + if string(b) != "aa" { + os.Exit(1) + } + }) +} + +func FuzzDeadlock(f *testing.F) { + f.Add(int(0)) + f.Fuzz(func(t *testing.T, n int) { + if n != 0 { + select {} + } + }) +} + +func FuzzWithTwoTypes(f *testing.F) { + f.Fuzz(func(t *testing.T, a, b []byte) { + if len(a) > 0 && len(b) > 0 { + panic("these inputs caused a crash!") + } + }) +} + +func FuzzInt(f *testing.F) { + f.Add(0) + f.Fuzz(func(t *testing.T, a int) { + if a != 0 { + panic("this input caused a crash!") + } + }) +} + +func FuzzUint(f *testing.F) { + f.Add(uint(0)) + f.Fuzz(func(t *testing.T, a uint) { + if a != 0 { + panic("this input caused a crash!") + } + }) +} + +func FuzzBool(f *testing.F) { + f.Add(false) + f.Fuzz(func(t *testing.T, a bool) { + if a { + panic("this input caused a crash!") + } + }) +} + +func FuzzFloat(f *testing.F) { + f.Fuzz(func(t *testing.T, a float64) { + if a != float64(int64(a)) { + // It has a decimal, so it was mutated by division + panic("this input caused a crash!") + } + }) +} + +func FuzzByte(f *testing.F) { + f.Add(byte(0)) + f.Fuzz(func(t *testing.T, a byte) { + if a != 0 { + panic("this input caused a crash!") + } + }) +} + +func FuzzRune(f *testing.F) { + f.Add(rune(0)) + f.Fuzz(func(t *testing.T, a rune) { + if a != 0 { + panic("this input caused a crash!") + } + }) +} + +func FuzzString(f *testing.F) { + f.Add("") + f.Fuzz(func(t *testing.T, a string) { + if a != "" { + panic("this input caused a crash!") + } + }) +} + +-- check_testdata.go -- +// +build ignore + +package main + +import ( + "bytes" + "crypto/sha256" + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +func main() { + target := os.Args[1] + dir := filepath.Join("testdata/fuzz", target) + + files, err := ioutil.ReadDir(dir) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if len(files) == 0 { + fmt.Fprintf(os.Stderr, "expect at least one new mutation to be written to testdata\n") + os.Exit(1) + } + + fname := files[0].Name() + contents, err := ioutil.ReadFile(filepath.Join(dir, fname)) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if bytes.Equal(contents, []byte("aa")) { + fmt.Fprintf(os.Stderr, "newly written testdata entry was not mutated\n") + os.Exit(1) + } + // The hash of the bytes in the file should match the filename. + h := []byte(fmt.Sprintf("%x", sha256.Sum256(contents))) + if !bytes.Equal([]byte(fname), h) { + fmt.Fprintf(os.Stderr, "hash of bytes %q does not match filename %q\n", h, fname) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_fuzz_mutate_fail.txt b/src/cmd/go/testdata/script/test_fuzz_mutate_fail.txt new file mode 100644 index 0000000..b5eab17 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_mutate_fail.txt @@ -0,0 +1,102 @@ +[!fuzz] skip + +# Check that if a worker does not call F.Fuzz or calls F.Fail first, +# 'go test' exits non-zero and no crasher is recorded. + +[short] skip + +! go test -fuzz=FuzzReturn +! exists testdata + +! go test -fuzz=FuzzSkip +! exists testdata + +! go test -fuzz=FuzzFail +! exists testdata + +! go test -fuzz=FuzzPanic +! exists testdata + +! go test -fuzz=FuzzNilPanic +! exists testdata + +! go test -fuzz=FuzzGoexit +! exists testdata + +! go test -fuzz=FuzzExit +! exists testdata + +-- go.mod -- +module m + +go 1.17 +-- fuzz_fail_test.go -- +package fuzz_fail + +import ( + "flag" + "os" + "runtime" + "testing" +) + +func isWorker() bool { + f := flag.Lookup("test.fuzzworker") + if f == nil { + return false + } + get, ok := f.Value.(flag.Getter) + if !ok { + return false + } + return get.Get() == interface{}(true) +} + +func FuzzReturn(f *testing.F) { + if isWorker() { + return + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzSkip(f *testing.F) { + if isWorker() { + f.Skip() + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzFail(f *testing.F) { + if isWorker() { + f.Fail() + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzPanic(f *testing.F) { + if isWorker() { + panic("nope") + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzNilPanic(f *testing.F) { + if isWorker() { + panic(nil) + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzGoexit(f *testing.F) { + if isWorker() { + runtime.Goexit() + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzExit(f *testing.F) { + if isWorker() { + os.Exit(99) + } + f.Fuzz(func(*testing.T, []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_mutator.txt b/src/cmd/go/testdata/script/test_fuzz_mutator.txt new file mode 100644 index 0000000..76b8648 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_mutator.txt @@ -0,0 +1,165 @@ +[!fuzz] skip + +# Test basic fuzzing mutator behavior. +# +# fuzz_test.go has two fuzz targets (FuzzA, FuzzB) which both add a seed value. +# Each fuzz function writes the input to a log file. The coordinator and worker +# use separate log files. check_logs.go verifies that the coordinator only +# tests seed values and the worker tests mutated values on the fuzz target. + +[short] skip + +go test -fuzz=FuzzA -fuzztime=100x -parallel=1 -log=fuzz +go run check_logs.go fuzz fuzz.worker + +# TODO(b/181800488): remove -parallel=1, here and below. For now, when a +# crash is found, all workers keep running, wasting resources and reducing +# the number of executions available to the minimizer, increasing flakiness. + +# Test that the mutator is good enough to find several unique mutations. +! go test -fuzz=FuzzMutator -parallel=1 -fuzztime=100x mutator_test.go +! stdout '^ok' +stdout FAIL +stdout 'mutator found enough unique mutations' + +-- go.mod -- +module m + +go 1.16 +-- fuzz_test.go -- +package fuzz_test + +import ( + "flag" + "fmt" + "os" + "testing" +) + +var ( + logPath = flag.String("log", "", "path to log file") + logFile *os.File +) + +func TestMain(m *testing.M) { + flag.Parse() + var err error + logFile, err = os.OpenFile(*logPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if os.IsExist(err) { + *logPath += ".worker" + logFile, err = os.OpenFile(*logPath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + } + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + os.Exit(m.Run()) +} + +func FuzzA(f *testing.F) { + f.Add([]byte("seed")) + f.Fuzz(func(t *testing.T, b []byte) { + fmt.Fprintf(logFile, "FuzzA %q\n", b) + }) +} + +func FuzzB(f *testing.F) { + f.Add([]byte("seed")) + f.Fuzz(func(t *testing.T, b []byte) { + fmt.Fprintf(logFile, "FuzzB %q\n", b) + }) +} + +-- check_logs.go -- +// +build ignore + +package main + +import ( + "bufio" + "bytes" + "fmt" + "io" + "os" + "strings" +) + +func main() { + coordPath, workerPath := os.Args[1], os.Args[2] + + coordLog, err := os.Open(coordPath) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + defer coordLog.Close() + if err := checkCoordLog(coordLog); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + workerLog, err := os.Open(workerPath) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + defer workerLog.Close() + if err := checkWorkerLog(workerLog); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func checkCoordLog(r io.Reader) error { + b, err := io.ReadAll(r) + if err != nil { + return err + } + if string(bytes.TrimSpace(b)) != `FuzzB "seed"` { + return fmt.Errorf("coordinator: did not test FuzzB seed") + } + return nil +} + +func checkWorkerLog(r io.Reader) error { + scan := bufio.NewScanner(r) + var sawAMutant bool + for scan.Scan() { + line := scan.Text() + if !strings.HasPrefix(line, "FuzzA ") { + return fmt.Errorf("worker: tested something other than target: %s", line) + } + if strings.TrimPrefix(line, "FuzzA ") != `"seed"` { + sawAMutant = true + } + } + if err := scan.Err(); err != nil && err != bufio.ErrTooLong { + return err + } + if !sawAMutant { + return fmt.Errorf("worker: did not test any mutants") + } + return nil +} +-- mutator_test.go -- +package fuzz_test + +import ( + "testing" +) + +// TODO(katiehockman): re-work this test once we have a better fuzzing engine +// (ie. more mutations, and compiler instrumentation) +func FuzzMutator(f *testing.F) { + // TODO(katiehockman): simplify this once we can dedupe crashes (e.g. + // replace map with calls to panic, and simply count the number of crashes + // that were added to testdata) + crashes := make(map[string]bool) + // No seed corpus initiated + f.Fuzz(func(t *testing.T, b []byte) { + crashes[string(b)] = true + if len(crashes) >= 10 { + panic("mutator found enough unique mutations") + } + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt b/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt new file mode 100644 index 0000000..3764dcb --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt @@ -0,0 +1,74 @@ +# TODO(jayconrod): support shared memory on more platforms. +[!darwin] [!linux] [!windows] skip + +# Verify that the fuzzing engine records the actual crashing input, even when +# a worker process terminates without communicating the crashing input back +# to the coordinator. + +[short] skip + +# Start fuzzing. The worker crashes after 100 iterations. +# The fuzz function writes the crashing input to "want" before exiting. +# The fuzzing engine reconstructs the crashing input and saves it to testdata. +! exists want +! go test -fuzz=. -parallel=1 -fuzztime=110x -fuzzminimizetime=10x -v +stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status' +stdout 'Failing input written to testdata' + +# Run the fuzz target without fuzzing. The fuzz function is called with the +# crashing input in testdata. The test passes if that input is identical to +# the one saved in "want". +exists want +go test -want=want + +-- go.mod -- +module fuzz + +go 1.17 +-- fuzz_test.go -- +package fuzz + +import ( + "bytes" + "flag" + "os" + "testing" +) + +var wantFlag = flag.String("want", "", "file containing previous crashing input") + +func FuzzRepeat(f *testing.F) { + i := 0 + f.Fuzz(func(t *testing.T, b []byte) { + i++ + if i == 100 { + f, err := os.OpenFile("want", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + // Couldn't create the file. Return without crashing, and try + // again. + i-- + t.Skip(err) + } + if _, err := f.Write(b); err != nil { + // We already created the file, so if we failed to write it + // there's not much we can do. The test will fail anyway, but + // at least make sure the error is logged to stdout. + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + os.Exit(1) // crash without communicating + } + + if *wantFlag != "" { + want, err := os.ReadFile(*wantFlag) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(want, b) { + t.Fatalf("inputs are not equal!\n got: %q\nwant:%q", b, want) + } + } + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt b/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt new file mode 100644 index 0000000..1051292 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt @@ -0,0 +1,75 @@ +# NOTE: this test is skipped on Windows, since there's no concept of signals. +# When a process terminates another process, it provides an exit code. +[windows] skip +[!fuzz] skip +[short] skip + +# FuzzNonCrash sends itself a signal that does not appear to be a crash. +# We should not save a crasher. +! go test -fuzz=FuzzNonCrash +! exists testdata +! stdout unreachable +! stderr unreachable +stdout 'fuzzing process terminated by unexpected signal; no crash will be recorded: signal: terminated' + +# FuzzKill sends itself a signal that cannot be caught by the worker process +# and does not appear to be a crash. +# We should not save a crasher. +! go test -fuzz=FuzzKill +! exists testdata +! stdout unreachable +! stderr unreachable +stdout 'fuzzing process terminated by unexpected signal; no crash will be recorded: signal: killed' + +# FuzzCrash sends itself a signal that looks like a crash. +# We should save a crasher. +! go test -fuzz=FuzzCrash +exists testdata/fuzz/FuzzCrash +stdout '^\s+fuzzing process hung or terminated unexpectedly: exit status' + +-- go.mod -- +module test + +go 1.17 +-- fuzz_posix_test.go -- +// +build darwin freebsd linux + +package fuzz + +import ( + "syscall" + "testing" +) + +func FuzzNonCrash(f *testing.F) { + f.Fuzz(func(*testing.T, bool) { + pid := syscall.Getpid() + if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { + panic(err) + } + // signal may not be received immediately. Wait for it. + select{} + }) +} + +func FuzzKill(f *testing.F) { + f.Fuzz(func(*testing.T, bool) { + pid := syscall.Getpid() + if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { + panic(err) + } + // signal may not be received immediately. Wait for it. + select{} + }) +} + +func FuzzCrash(f *testing.F) { + f.Fuzz(func(*testing.T, bool) { + pid := syscall.Getpid() + if err := syscall.Kill(pid, syscall.SIGILL); err != nil { + panic(err) + } + // signal may not be received immediately. Wait for it. + select{} + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_parallel.txt b/src/cmd/go/testdata/script/test_fuzz_parallel.txt new file mode 100644 index 0000000..e632520 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_parallel.txt @@ -0,0 +1,66 @@ +[!fuzz] skip +[short] skip + +# When running seed inputs, T.Parallel should let multiple inputs run in +# parallel. +go test -run=FuzzSeed + +# When fuzzing, T.Parallel should be safe to call, but it should have no effect. +# We just check that it doesn't hang, which would be the most obvious +# failure mode. +# TODO(jayconrod): check for the string "after T.Parallel". It's not printed +# by 'go test', so we can't distinguish that crasher from some other panic. +! go test -run=FuzzMutate -fuzz=FuzzMutate +exists testdata/fuzz/FuzzMutate + +# Testdata should now contain a corpus entry which will fail FuzzMutate. +# Run the test without fuzzing, setting -parallel to different values to make +# sure it fails, and doesn't hang. +! go test -run=FuzzMutate -parallel=1 +! go test -run=FuzzMutate -parallel=2 +! go test -run=FuzzMutate -parallel=4 + +-- go.mod -- +module fuzz_parallel + +go 1.17 +-- fuzz_parallel_test.go -- +package fuzz_parallel + +import ( + "sort" + "sync" + "testing" +) + +func FuzzSeed(f *testing.F) { + for _, v := range [][]byte{{'a'}, {'b'}, {'c'}} { + f.Add(v) + } + + var mu sync.Mutex + var before, after []byte + f.Cleanup(func() { + sort.Slice(after, func(i, j int) bool { return after[i] < after[j] }) + got := string(before) + string(after) + want := "abcabc" + if got != want { + f.Fatalf("got %q; want %q", got, want) + } + }) + + f.Fuzz(func(t *testing.T, b []byte) { + before = append(before, b...) + t.Parallel() + mu.Lock() + after = append(after, b...) + mu.Unlock() + }) +} + +func FuzzMutate(f *testing.F) { + f.Fuzz(func(t *testing.T, _ []byte) { + t.Parallel() + t.Error("after T.Parallel") + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_profile_flags.txt b/src/cmd/go/testdata/script/test_fuzz_profile_flags.txt new file mode 100644 index 0000000..5434c72 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_profile_flags.txt @@ -0,0 +1,38 @@ +[!fuzz] skip + +! go test -fuzz=FuzzTrivial -coverprofile=prof +! stdout . +stderr '^cannot use -coverprofile flag with -fuzz flag$' + +! go test -fuzz=FuzzTrivial -blockprofile=prof +! stdout . +stderr '^cannot use -blockprofile flag with -fuzz flag$' + +! go test -fuzz=FuzzTrivial -cpuprofile=prof +! stdout . +stderr '^cannot use -cpuprofile flag with -fuzz flag$' + +! go test -fuzz=FuzzTrivial -memprofile=prof +! stdout . +stderr '^cannot use -memprofile flag with -fuzz flag$' + +! go test -fuzz=FuzzTrivial -mutexprofile=prof +! stdout . +stderr '^cannot use -mutexprofile flag with -fuzz flag$' + +! go test -fuzz=FuzzTrivial -trace=prof +! stdout . +stderr '^cannot use -trace flag with -fuzz flag$' + +-- go.mod -- +module example + +go 1.18 +-- fuzz_test.go -- +package example + +import "testing" + +func FuzzTrivial(f *testing.F) { + f.Fuzz(func(t *testing.T, _ []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_return.txt b/src/cmd/go/testdata/script/test_fuzz_return.txt new file mode 100644 index 0000000..63275aa --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_return.txt @@ -0,0 +1,19 @@ +[short] skip + +! go test . +stdout '^panic: testing: fuzz target must not return a value \[recovered\]$' + +-- go.mod -- +module test +go 1.18 +-- x_test.go -- +package test + +import "testing" + +func FuzzReturnErr(f *testing.F) { + f.Add("hello, validation!") + f.Fuzz(func(t *testing.T, in string) string { + return in + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_run.txt b/src/cmd/go/testdata/script/test_fuzz_run.txt new file mode 100644 index 0000000..99a4413 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_run.txt @@ -0,0 +1,143 @@ +[!fuzz] skip +[short] skip +env GOCACHE=$WORK/cache + +# Tests which verify the behavior and command line output when +# running a fuzz target as a unit test. + +# Tests without -run. + +! go test +stdout FAIL +stdout 'error here' + +! go test -v +stdout FAIL +stdout 'error here' +stdout '=== RUN FuzzFoo/thisfails' +stdout '--- FAIL: FuzzFoo/thisfails' +stdout '=== RUN FuzzFoo/thispasses' +stdout '--- PASS: FuzzFoo/thispasses' + +# Tests where -run matches all seed corpora. + +! go test -run FuzzFoo/this +stdout FAIL +stdout 'error here' +! stdout 'no tests to run' + +! go test -run /this +stdout FAIL +stdout 'error here' +! stdout 'no tests to run' + +! go test -v -run FuzzFoo/this +stdout FAIL +stdout 'error here' +stdout '=== RUN FuzzFoo/thisfails' +stdout '--- FAIL: FuzzFoo/thisfails' +stdout '=== RUN FuzzFoo/thispasses' +stdout '--- PASS: FuzzFoo/thispasses' +! stdout 'no tests to run' + +! go test -v -run /this +stdout FAIL +stdout 'error here' +stdout '=== RUN FuzzFoo/thisfails' +stdout '--- FAIL: FuzzFoo/thisfails' +stdout '=== RUN FuzzFoo/thispasses' +stdout '--- PASS: FuzzFoo/thispasses' +! stdout 'no tests to run' + +# Tests where -run only matches one seed corpus which passes. + +go test -run FuzzFoo/thispasses +stdout ok +! stdout 'no tests to run' + +go test -run /thispasses +stdout ok +! stdout 'no tests to run' + +# Same tests in verbose mode +go test -v -run FuzzFoo/thispasses +stdout '=== RUN FuzzFoo/thispasses' +stdout '--- PASS: FuzzFoo/thispasses' +! stdout '=== RUN FuzzFoo/thisfails' +! stdout 'no tests to run' + +go test -v -run /thispasses +stdout '=== RUN FuzzFoo/thispasses' +stdout '--- PASS: FuzzFoo/thispasses' +! stdout '=== RUN FuzzFoo/thisfails' +! stdout 'no tests to run' + +# Tests where -run only matches one seed corpus which fails. + +! go test -run FuzzFoo/thisfails +stdout FAIL +stdout 'error here' +! stdout 'no tests to run' + +! go test -run /thisfails +stdout FAIL +stdout 'error here' +! stdout 'no tests to run' + +! go test -v -run FuzzFoo/thisfails +stdout 'error here' +stdout '=== RUN FuzzFoo/thisfails' +stdout '--- FAIL: FuzzFoo/thisfails' +! stdout '=== RUN FuzzFoo/thispasses' +! stdout 'no tests to run' + +! go test -v -run /thisfails +stdout 'error here' +stdout '=== RUN FuzzFoo/thisfails' +stdout '--- FAIL: FuzzFoo/thisfails' +! stdout '=== RUN FuzzFoo/thispasses' +! stdout 'no tests to run' + +# Tests where -run doesn't match any seed corpora. + +go test -run FuzzFoo/nomatch +stdout ok + +go test -run /nomatch +stdout ok + +go test -v -run FuzzFoo/nomatch +stdout '=== RUN FuzzFoo' +stdout '--- PASS: FuzzFoo' +stdout ok +! stdout 'no tests to run' + +go test -v -run /nomatch +stdout '=== RUN FuzzFoo' +stdout '--- PASS: FuzzFoo' +stdout ok +! stdout 'no tests to run' + +-- go.mod -- +module example.com/x + +go 1.16 +-- x_test.go -- +package x + +import "testing" + +func FuzzFoo(f *testing.F) { + f.Add("this is fine") + f.Fuzz(func(t *testing.T, s string) { + if s == "fails" { + t.Error("error here") + } + }) +} +-- testdata/fuzz/FuzzFoo/thisfails -- +go test fuzz v1 +string("fails") +-- testdata/fuzz/FuzzFoo/thispasses -- +go test fuzz v1 +string("passes") diff --git a/src/cmd/go/testdata/script/test_fuzz_seed_corpus.txt b/src/cmd/go/testdata/script/test_fuzz_seed_corpus.txt new file mode 100644 index 0000000..57c8a8b --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_seed_corpus.txt @@ -0,0 +1,203 @@ +[!fuzz-instrumented] skip +[short] skip +env GOCACHE=$WORK/cache + +# Test that fuzzing a target with a failure in f.Add prints the crash +# and doesn't write anything to testdata/fuzz +! go test -fuzz=FuzzWithAdd -run=FuzzWithAdd -fuzztime=1x +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithAdd[/\\]' +stdout FAIL + +# Test that fuzzing a target with a sucess in f.Add and a fuzztime of only +# 1 does not produce a crash. +go test -fuzz=FuzzWithGoodAdd -run=FuzzWithGoodAdd -fuzztime=1x +stdout ok +! stdout FAIL + +# Test that fuzzing a target with a failure in testdata/fuzz prints the crash +# and doesn't write anything to testdata/fuzz +! go test -fuzz=FuzzWithTestdata -run=FuzzWithTestdata -fuzztime=1x +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithTestdata[/\\]' +stdout 'failure while testing seed corpus entry: FuzzWithTestdata/1' +stdout FAIL + +# Test that fuzzing a target with no seed corpus or cache finds a crash, prints +# it, and write it to testdata +! go test -fuzz=FuzzWithNoCache -run=FuzzWithNoCache -fuzztime=1x +! stdout ^ok +stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithNoCache[/\\]' +stdout FAIL + +# Write a crashing input to the cache +mkdir $GOCACHE/fuzz/example.com/x/FuzzWithCache +cp cache-file $GOCACHE/fuzz/example.com/x/FuzzWithCache/1 + +# Test that fuzzing a target with a failure in the cache prints the crash +# and writes this as a "new" crash to testdata/fuzz +! go test -fuzz=FuzzWithCache -run=FuzzWithCache -fuzztime=1x +! stdout ^ok +stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithCache[/\\]' +stdout FAIL + +# Write a crashing input to the cache +mkdir $GOCACHE/fuzz/example.com/x/FuzzWithMinimizableCache +cp cache-file-bytes $GOCACHE/fuzz/example.com/x/FuzzWithMinimizableCache/1 + +# Test that fuzzing a target with a failure in the cache minimizes it and writes +# the new crash to testdata/fuzz +! go test -fuzz=FuzzWithMinimizableCache -run=FuzzWithMinimizableCache -fuzztime=10000x +! stdout ^ok +stdout 'gathering baseline coverage' +stdout 'got the minimum size!' +stdout 'contains a non-zero byte of length 10' +stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithMinimizableCache[/\\]' +stdout FAIL +# Make sure this crash didn't come from fuzzing +# (the log line that states fuzzing began shouldn't have printed) +! stdout 'execs' + +# Clear the fuzz cache and make sure it's gone +go clean -fuzzcache +! exists $GOCACHE/fuzz + +# The tests below should operate the exact same as the previous tests. If -fuzz +# is enabled, then whatever target is going to be fuzzed shouldn't be run by +# anything other than the workers. + +# Test that fuzzing a target (with -run=None set) with a failure in f.Add prints +# the crash and doesn't write anything to testdata/fuzz -fuzztime=1x +! go test -fuzz=FuzzWithAdd -run=None +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithAdd[/\\]' +stdout FAIL + +# Test that fuzzing a target (with -run=None set) with a sucess in f.Add and a +# fuzztime of only 1 does not produce a crash. +go test -fuzz=FuzzWithGoodAdd -run=None -fuzztime=1x +stdout ok +! stdout FAIL + +# Test that fuzzing a target (with -run=None set) with a failure in +# testdata/fuzz prints the crash and doesn't write anything to testdata/fuzz +! go test -fuzz=FuzzWithTestdata -run=None -fuzztime=1x +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithTestdata[/\\]' +stdout FAIL + +# Write a crashing input to the cache +mkdir $GOCACHE/fuzz/example.com/x/FuzzRunNoneWithCache +cp cache-file $GOCACHE/fuzz/example.com/x/FuzzRunNoneWithCache/1 + +# Test that fuzzing a target (with -run=None set) with a failure in the cache +# prints the crash and writes this as a "new" crash to testdata/fuzz +! go test -fuzz=FuzzRunNoneWithCache -run=None -fuzztime=1x +! stdout ^ok +stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzRunNoneWithCache[/\\]' +stdout FAIL + +# Clear the fuzz cache and make sure it's gone +go clean -fuzzcache +! exists $GOCACHE/fuzz + +# The tests below should operate the exact same way for the previous tests with +# a seed corpus (namely, they should still fail). However, the binary is built +# without instrumentation, so this should be a "testing only" run which executes +# the seed corpus before attempting to fuzz. + +go test -c +! exec ./x.test$GOEXE -test.fuzz=FuzzWithAdd -test.run=FuzzWithAdd -test.fuzztime=1x -test.fuzzcachedir=$WORK/cache +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithAdd[/\\]' +stdout FAIL +stderr warning + +go test -c +! exec ./x.test$GOEXE -test.fuzz=FuzzWithTestdata -test.run=FuzzWithTestdata -test.fuzztime=1x -test.fuzzcachedir=$WORK/cache +! stdout ^ok +! stdout 'Failing input written to testdata[/\\]fuzz[/\\]FuzzWithTestdata[/\\]' +stdout FAIL +stderr warning + +-- go.mod -- +module example.com/x + +go 1.16 +-- x_test.go -- +package x + +import "testing" + +func FuzzWithAdd(f *testing.F) { + f.Add(10) + f.Fuzz(func(t *testing.T, i int) { + if i == 10 { + t.Error("bad thing here") + } + }) +} + +func FuzzWithGoodAdd(f *testing.F) { + f.Add(10) + f.Fuzz(func(t *testing.T, i int) { + if i != 10 { + t.Error("bad thing here") + } + }) +} + +func FuzzWithTestdata(f *testing.F) { + f.Fuzz(func(t *testing.T, i int) { + if i == 10 { + t.Error("bad thing here") + } + }) +} + +func FuzzWithNoCache(f *testing.F) { + f.Fuzz(func(t *testing.T, i int) { + t.Error("bad thing here") + }) +} + +func FuzzWithCache(f *testing.F) { + f.Fuzz(func(t *testing.T, i int) { + if i == 10 { + t.Error("bad thing here") + } + }) +} + +func FuzzWithMinimizableCache(f *testing.F) { + f.Fuzz(func(t *testing.T, b []byte) { + if len(b) < 10 { + return + } + for _, n := range b { + if n != 0 { + if len(b) == 10 { + t.Log("got the minimum size!") + } + t.Fatalf("contains a non-zero byte of length %d", len(b)) + } + } + }) +} + +func FuzzRunNoneWithCache(f *testing.F) { + f.Fuzz(func(t *testing.T, i int) { + if i == 10 { + t.Error("bad thing here") + } + }) +} +-- testdata/fuzz/FuzzWithTestdata/1 -- +go test fuzz v1 +int(10) +-- cache-file -- +go test fuzz v1 +int(10) +-- cache-file-bytes -- +go test fuzz v1 +[]byte("11111111111111111111") diff --git a/src/cmd/go/testdata/script/test_fuzz_setenv.txt b/src/cmd/go/testdata/script/test_fuzz_setenv.txt new file mode 100644 index 0000000..2924569 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_setenv.txt @@ -0,0 +1,45 @@ +[!fuzz] skip +[short] skip + +go test -fuzz=FuzzA -fuzztime=100x fuzz_setenv_test.go + +-- fuzz_setenv_test.go -- +package fuzz + +import ( + "flag" + "os" + "testing" +) + +func FuzzA(f *testing.F) { + if s := os.Getenv("TEST_FUZZ_SETENV_A"); isWorker() && s == "" { + f.Fatal("environment variable not set") + } else if !isWorker() && s != "" { + f.Fatal("environment variable already set") + } + f.Setenv("TEST_FUZZ_SETENV_A", "A") + if os.Getenv("TEST_FUZZ_SETENV_A") == "" { + f.Fatal("Setenv did not set environment variable") + } + f.Fuzz(func(*testing.T, []byte) {}) +} + +func FuzzB(f *testing.F) { + if os.Getenv("TEST_FUZZ_SETENV_A") != "" { + f.Fatal("environment variable not cleared after FuzzA") + } + f.Skip() +} + +func isWorker() bool { + f := flag.Lookup("test.fuzzworker") + if f == nil { + return false + } + get, ok := f.Value.(flag.Getter) + if !ok { + return false + } + return get.Get() == interface{}(true) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_test_race.txt b/src/cmd/go/testdata/script/test_fuzz_test_race.txt new file mode 100644 index 0000000..9d39cd6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_test_race.txt @@ -0,0 +1,39 @@ +# Test that when both race detection and coverage instrumentation are enabled, +# and seed values are being executed, the race detector isn't mistakenly +# triggered. + +[short] skip +[!fuzz] skip +[!race] skip + +# Test with coverage instrumentation enabled (-fuzz) and race instrumentation +# but without actually fuzzing the target (by using a non-matching pattern) +go test -fuzz=xxx -race -v +! stderr 'race detected during execution of test' + +# Test with just race instrumentation enabled +go test -race -v +! stderr 'race detected during execution of test' + +# Test with coverage and race instrumentation enabled, and a matching fuzz +# pattern +go test -fuzz=FuzzRace -race -v -fuzztime=200x +! stderr 'race detected during execution of test' + +-- go.mod -- +module test + +-- race_test.go -- +package race + +import "testing" + +func FuzzRace(f *testing.F) { + for i := 0; i < 100; i++ { + f.Add(i) + } + + f.Fuzz(func(t *testing.T, i int) { + t.Parallel() + }) +} diff --git a/src/cmd/go/testdata/script/test_fuzz_unsupported.txt b/src/cmd/go/testdata/script/test_fuzz_unsupported.txt new file mode 100644 index 0000000..1ed0b8a --- /dev/null +++ b/src/cmd/go/testdata/script/test_fuzz_unsupported.txt @@ -0,0 +1,18 @@ +[fuzz] skip + +! go test -fuzz=. -fuzztime=1x +! stdout . +stderr '^-fuzz flag is not supported on '$GOOS'/'$GOARCH'$' + +-- go.mod -- +module example + +go 1.18 +-- fuzz_test.go -- +package example + +import "testing" + +func FuzzTrivial(f *testing.F) { + f.Fuzz(func(t *testing.T, _ []byte) {}) +} diff --git a/src/cmd/go/testdata/script/test_generated_main.txt b/src/cmd/go/testdata/script/test_generated_main.txt new file mode 100644 index 0000000..2e991a5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_generated_main.txt @@ -0,0 +1,34 @@ +# Tests that the generated test main file has a generated code comment. +# This is needed by analyzers that access source files through 'go list'. +# Verifies golang.org/issue/31971. +# TODO(jayconrod): This test is brittle. We should write _testmain.go as +# a build action instead of with an ad-hoc WriteFile call +# in internal/test/test.go. Then we could just grep 'go get -n'. +go test x_test.go + +-- x_test.go -- +package x + +import ( + "os" + "path/filepath" + "regexp" + "testing" +) + +func Test(t *testing.T) { + exePath, err := os.Executable() + if err != nil { + t.Fatal(err) + } + testmainPath := filepath.Join(filepath.Dir(exePath), "_testmain.go") + source, err := os.ReadFile(testmainPath) + if err != nil { + t.Fatal(err) + } + if matched, err := regexp.Match(`(?m)^// Code generated .* DO NOT EDIT\.$`, source); err != nil { + t.Fatal(err) + } else if !matched { + t.Error("_testmain.go does not have generated code comment") + } +} diff --git a/src/cmd/go/testdata/script/test_go111module_cache.txt b/src/cmd/go/testdata/script/test_go111module_cache.txt new file mode 100644 index 0000000..ca1de43 --- /dev/null +++ b/src/cmd/go/testdata/script/test_go111module_cache.txt @@ -0,0 +1,15 @@ +env GO111MODULE=on +go mod init foo +go test +stdout ^ok\s+foo +env GO111MODULE=off +go test +stdout ^ok\s+ +! stdout ^ok\s+(cache)$ + +-- main_test.go -- +package main + +import "testing" + +func TestF(t *testing.T) {} diff --git a/src/cmd/go/testdata/script/test_import_error_stack.txt b/src/cmd/go/testdata/script/test_import_error_stack.txt new file mode 100644 index 0000000..6c60f3d --- /dev/null +++ b/src/cmd/go/testdata/script/test_import_error_stack.txt @@ -0,0 +1,31 @@ +env GO111MODULE=off +! go test testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +! go vet testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack + +env GO111MODULE=on +cd testdep +! go test testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack +! go vet testdep/p1 +stderr 'package testdep/p1 \(test\)\n\timports testdep/p2\n\timports testdep/p3: build constraints exclude all Go files ' # check for full import stack + +-- testdep/go.mod -- +module testdep + +go 1.16 +-- testdep/p1/p1.go -- +package p1 +-- testdep/p1/p1_test.go -- +package p1 + +import _ "testdep/p2" +-- testdep/p2/p2.go -- +package p2 + +import _ "testdep/p3" +-- testdep/p3/p3.go -- +// +build ignore + +package ignored diff --git a/src/cmd/go/testdata/script/test_issue45477.txt b/src/cmd/go/testdata/script/test_issue45477.txt new file mode 100644 index 0000000..f435b6a --- /dev/null +++ b/src/cmd/go/testdata/script/test_issue45477.txt @@ -0,0 +1,12 @@ +[short] skip # links and runs a test binary + +go test -v . + +-- go.mod -- +module example.com/pkg_test + +-- pkg.go -- +package pkg_test + +-- pkg_test.go -- +package pkg_test diff --git a/src/cmd/go/testdata/script/test_json.txt b/src/cmd/go/testdata/script/test_json.txt new file mode 100644 index 0000000..cd5b0b9 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json.txt @@ -0,0 +1,74 @@ +[gccgo] skip # gccgo does not have standard packages +[short] skip + +env GOCACHE=$WORK/tmp + +# Run go test -json on errors m/empty/pkg and m/skipper +# It would be nice to test that the output is interlaced +# but it seems to be impossible to do that in a short test +# that isn't also flaky. Just check that we get JSON output. +go test -json -short -v errors m/empty/pkg m/skipper + +# Check errors for run action +stdout '"Package":"errors"' +stdout '"Action":"run","Package":"errors"' + +# Check m/empty/pkg for output and skip actions +stdout '"Action":"output","Package":"m/empty/pkg","Output":".*no test files' +stdout '"Action":"skip","Package":"m/empty/pkg"' + +# Check skipper for output and skip actions +stdout '"Action":"output","Package":"m/skipper","Test":"Test","Output":"--- SKIP:' +stdout '"Action":"skip","Package":"m/skipper","Test":"Test"' + +# Run go test -json on errors and check it's cached +go test -json -short -v errors +stdout '"Action":"output","Package":"errors","Output":".*\(cached\)' + +go test -json -bench=NONE -short -v errors +stdout '"Package":"errors"' +stdout '"Action":"run"' + +# Test running test2json +go test -o $WORK/tmp/errors.test$GOEXE -c errors +go tool test2json -p errors $WORK/tmp/errors.test$GOEXE -test.v -test.short +stdout '"Package":"errors"' +stdout '"Action":"run"' +stdout '\{"Action":"pass","Package":"errors"\}' + +-- go.mod -- +module m + +go 1.16 +-- skipper/skip_test.go -- +package skipper + +import "testing" + +func Test(t *testing.T) { + t.Skip("skipping") +} +-- empty/pkg/pkg.go -- +package p +-- empty/pkgtest/pkg.go -- +package p +-- empty/pkgtest/test_test.go -- +package p +-- empty/pkgtestxtest/pkg.go -- +package p +-- empty/pkgtestxtest/test_test.go -- +package p +-- empty/pkgtestxtest/xtest_test.go -- +package p_test +-- empty/pkgxtest/pkg.go -- +package p +-- empty/pkgxtest/xtest_test.go -- +package p_test +-- empty/test/test_test.go -- +package p +-- empty/testxtest/test_test.go -- +package p +-- empty/testxtest/xtest_test.go -- +package p_test +-- empty/xtest/xtest_test.go -- +package p_test diff --git a/src/cmd/go/testdata/script/test_json_exit.txt b/src/cmd/go/testdata/script/test_json_exit.txt new file mode 100644 index 0000000..dc7ffb0 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_exit.txt @@ -0,0 +1,102 @@ +[short] skip + +go test -c -o mainpanic.exe ./mainpanic & +go test -c -o mainexit0.exe ./mainexit0 & +go test -c -o testpanic.exe ./testpanic & +go test -c -o testbgpanic.exe ./testbgpanic & +wait + +# Test binaries that panic in TestMain should be marked as failing. + +! go test -json ./mainpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./mainpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +# Test binaries that exit with status 0 should be marked as passing. + +go test -json ./mainexit0 +stdout '"Action":"pass"' +! stdout '"Action":"fail"' + +go tool test2json ./mainexit0.exe +stdout '"Action":"pass"' +! stdout '"Action":"fail"' + +# Test functions that panic should never be marked as passing +# (https://golang.org/issue/40132). + +! go test -json ./testpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testpanic.exe -test.v +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +# Tests that panic in a background goroutine should be marked as failing. + +! go test -json ./testbgpanic +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testbgpanic.exe -test.v +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +! go tool test2json ./testbgpanic.exe +stdout '"Action":"fail"' +! stdout '"Action":"pass"' + +-- go.mod -- +module m +go 1.14 +-- mainpanic/mainpanic_test.go -- +package mainpanic_test + +import "testing" + +func TestMain(m *testing.M) { + panic("haha no") +} +-- mainexit0/mainexit0_test.go -- +package mainexit0_test + +import ( + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + fmt.Println("nothing to do") + os.Exit(0) +} +-- testpanic/testpanic_test.go -- +package testpanic_test + +import "testing" + +func TestPanic(*testing.T) { + panic("haha no") +} +-- testbgpanic/testbgpanic_test.go -- +package testbgpanic_test + +import "testing" + +func TestPanicInBackground(*testing.T) { + c := make(chan struct{}) + go func() { + panic("haha no") + close(c) + }() + <-c +} diff --git a/src/cmd/go/testdata/script/test_json_interleaved.txt b/src/cmd/go/testdata/script/test_json_interleaved.txt new file mode 100644 index 0000000..e2d349e --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_interleaved.txt @@ -0,0 +1,27 @@ +# Regression test for https://golang.org/issue/40657: output from the main test +# function should be attributed correctly even if interleaved with the PAUSE +# line for a new parallel subtest. + +[short] skip + +go test -json +stdout '"Test":"TestWeirdTiming","Output":"[^"]* logging to outer again\\n"' + +-- go.mod -- +module example.com +go 1.15 +-- main_test.go -- +package main + +import ( + "testing" +) + +func TestWeirdTiming(outer *testing.T) { + outer.Run("pauser", func(pauser *testing.T) { + outer.Logf("logging to outer") + pauser.Parallel() + }) + + outer.Logf("logging to outer again") +} diff --git a/src/cmd/go/testdata/script/test_json_panic_exit.txt b/src/cmd/go/testdata/script/test_json_panic_exit.txt new file mode 100644 index 0000000..d0a7991 --- /dev/null +++ b/src/cmd/go/testdata/script/test_json_panic_exit.txt @@ -0,0 +1,69 @@ +# Verifies golang.org/issue/37555. + +[short] skip + +# 'go test -json' should say a test passes if it says it passes. +go test -json ./pass +stdout '"Action":"pass".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test passes if it exits 0 and prints nothing. +# TODO(golang.org/issue/29062): this should fail in the future. +go test -json ./exit0main +stdout '"Action":"pass".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test fails if it exits 1 and prints nothing. +! go test -json ./exit1main +stdout '"Action":"fail".*\n\z' +! stdout '"Test":.*\n\z' + +# 'go test -json' should say a test fails if it panics. +! go test -json ./panic +stdout '"Action":"fail".*\n\z' +! stdout '"Test":.*\n\z' + +-- go.mod -- +module example.com/test + +go 1.14 + +-- pass/pass_test.go -- +package pass_test + +import "testing" + +func TestPass(t *testing.T) {} + +-- exit0main/exit0main_test.go -- +package exit0_test + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Exit(0) +} + +-- exit1main/exit1main_test.go -- +package exit1_test + +import ( + "os" + "testing" +) + +func TestMain(m *testing.M) { + os.Exit(1) +} + +-- panic/panic_test.go -- +package panic_test + +import "testing" + +func TestPanic(t *testing.T) { + panic("oh no") +} diff --git a/src/cmd/go/testdata/script/test_main.txt b/src/cmd/go/testdata/script/test_main.txt new file mode 100644 index 0000000..25d02e4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main.txt @@ -0,0 +1,92 @@ +# Test TestMain +go test standalone_main_normal_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +# Test TestMain sees testing flags +go test standalone_testmain_flag_test.go +stdout '^ok.*\[no tests to run\]' + +# Test TestMain with wrong signature (Issue #22388) +! go test standalone_main_wrong_test.go +stderr 'wrong signature for TestMain, must be: func TestMain\(m \*testing.M\)' + +# Test TestMain does not call os.Exit (Issue #34129) +! go test standalone_testmain_not_call_os_exit_test.go +! stdout '^ok' + +-- standalone_main_normal_test.go -- +// Copyright 2017 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 standalone_main_normal_test + +import "testing" + +func TestMain(t *testing.T) { +} +-- standalone_main_wrong_test.go -- +// Copyright 2017 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 standalone_main_wrong_test + +import "testing" + +func TestMain(m *testing.Main) { +} +-- standalone_testmain_flag_test.go -- +// Copyright 2019 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 standalone_testmain_flag_test + +import ( + "flag" + "fmt" + "os" + "testing" +) + +func TestMain(m *testing.M) { + // A TestMain should be able to access testing flags if it calls + // flag.Parse without needing to use testing.Init. + flag.Parse() + found := false + flag.VisitAll(func(f *flag.Flag) { + if f.Name == "test.count" { + found = true + } + }) + if !found { + fmt.Println("testing flags not registered") + os.Exit(1) + } + os.Exit(m.Run()) +} +-- standalone_testmain_not_call_os_exit_test.go -- +// Copyright 2020 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 standalone_testmain_not_call_os_exit_test + +import ( + "testing" +) + +func TestWillFail(t *testing.T) { + t.Error("this test will fail.") +} + +func TestMain(m *testing.M) { + defer func() { + recover() + }() + exit := m.Run() + panic(exit) +} diff --git a/src/cmd/go/testdata/script/test_main_archive.txt b/src/cmd/go/testdata/script/test_main_archive.txt new file mode 100644 index 0000000..410d923 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_archive.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +# Test that a main_test of 'package main' imports the package, +# not the installed binary. + +[short] skip + +env GOBIN=$WORK/bin +go test main_test +go install main_test + +go list -f '{{.Stale}}' main_test +stdout false + +go test main_test + +-- main_test/m.go -- +package main + +func F() {} +func main() {} +-- main_test/m_test.go -- +package main_test + +import ( + . "main_test" + "testing" +) + +func Test1(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/test_main_panic.txt b/src/cmd/go/testdata/script/test_main_panic.txt new file mode 100644 index 0000000..45887c5 --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_panic.txt @@ -0,0 +1,30 @@ +[short] skip +[!race] skip + +! go test -v -race main_panic/testmain_parallel_sub_panic_test.go +! stdout 'DATA RACE' +-- main_panic/testmain_parallel_sub_panic_test.go -- +package testmain_parallel_sub_panic_test + +import "testing" + +func setup() { println("setup()") } +func teardown() { println("teardown()") } +func TestA(t *testing.T) { + t.Run("1", func(t *testing.T) { + t.Run("1", func(t *testing.T) { + t.Parallel() + panic("A/1/1 panics") + }) + t.Run("2", func(t *testing.T) { + t.Parallel() + println("A/1/2 is ok") + }) + }) +} + +func TestMain(m *testing.M) { + setup() + defer teardown() + m.Run() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_main_twice.txt b/src/cmd/go/testdata/script/test_main_twice.txt new file mode 100644 index 0000000..f32d4fc --- /dev/null +++ b/src/cmd/go/testdata/script/test_main_twice.txt @@ -0,0 +1,27 @@ +[short] skip + +env GOCACHE=$WORK/tmp +go test -v multimain +stdout -count=2 notwithstanding # check tests ran twice + +-- go.mod -- +module multimain + +go 1.16 +-- multimain_test.go -- +package multimain_test + +import "testing" + +func TestMain(m *testing.M) { + // Some users run m.Run multiple times, changing + // some kind of global state between runs. + // This used to work so I guess now it has to keep working. + // See golang.org/issue/23129. + m.Run() + m.Run() +} + +func Test(t *testing.T) { + t.Log("notwithstanding") +} diff --git a/src/cmd/go/testdata/script/test_match_benchmark_labels.txt b/src/cmd/go/testdata/script/test_match_benchmark_labels.txt new file mode 100644 index 0000000..13c4007 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_benchmark_labels.txt @@ -0,0 +1,18 @@ +# Benchmark labels, file outside gopath +# TODO(matloob): This test was called TestBenchmarkLabelsOutsideGOPATH +# why "OutsideGOPATH"? Does the go command need to be run outside GOPATH? +# Do the files need to exist outside GOPATH? +cp $GOPATH/src/standalone_benchmark_test.go $WORK/tmp/standalone_benchmark_test.go +go test -run '^$' -bench . $WORK/tmp/standalone_benchmark_test.go +stdout '^goos: '$GOOS +stdout '^goarch: '$GOARCH +! stdout '^pkg:' +! stderr '^pkg:' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_benchmarks.txt b/src/cmd/go/testdata/script/test_match_no_benchmarks.txt new file mode 100644 index 0000000..30f4be8 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_benchmarks.txt @@ -0,0 +1,13 @@ +# Matches no benchmarks +go test -run '^$' -bench ThisWillNotMatch standalone_benchmark_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests.txt b/src/cmd/go/testdata/script/test_match_no_subtests.txt new file mode 100644 index 0000000..7abb1eb --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests.txt @@ -0,0 +1,12 @@ +# The subtests don't match +go test -run Test/ThisWillNotMatch standalone_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt b/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt new file mode 100644 index 0000000..b3c5b92 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests_failure.txt @@ -0,0 +1,15 @@ +# Matches no subtests, but parent test still fails +! go test -run TestThatFails/ThisWillNotMatch standalone_fail_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout 'FAIL' + +-- standalone_fail_sub_test.go -- +package standalone_fail_sub_test + +import "testing" + +func TestThatFails(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) + t.Fail() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt b/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt new file mode 100644 index 0000000..11c734c --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_subtests_parallel.txt @@ -0,0 +1,19 @@ +# Matches no subtests, parallel +go test -run Test/Sub/ThisWillNotMatch standalone_parallel_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_match_no_tests.txt b/src/cmd/go/testdata/script/test_match_no_tests.txt new file mode 100644 index 0000000..1ad2097 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests.txt @@ -0,0 +1,11 @@ +# Matches no tests +go test -run ThisWillNotMatch standalone_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_test.go -- +package standalone_test + +import "testing" + +func Test(t *testing.T) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt new file mode 100644 index 0000000..e1c9643 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt @@ -0,0 +1,19 @@ +# Test that when there's a build failure and a -run flag that doesn't match, +# that the error for not matching tests does not override the error for +# the build failure. + +! go test -run ThisWillNotMatch syntaxerror +! stderr '(?m)^ok.*\[no tests to run\]' +stdout 'FAIL' + +-- go.mod -- +module syntaxerror + +go 1.16 +-- x.go -- +package p +-- x_test.go -- +package p + +func f() (x.y, z int) { +} diff --git a/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt b/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt new file mode 100644 index 0000000..0d94918 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_no_tests_with_subtests.txt @@ -0,0 +1,12 @@ +# Matches no tests with subtests +go test -run ThisWillNotMatch standalone_sub_test.go +stdout '^ok.*\[no tests to run\]' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_benchmarks.txt b/src/cmd/go/testdata/script/test_match_only_benchmarks.txt new file mode 100644 index 0000000..5dfb96e --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_benchmarks.txt @@ -0,0 +1,13 @@ +# Matches only benchmarks +go test -run '^$' -bench . standalone_benchmark_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_benchmark_test.go -- +package standalone_benchmark + +import "testing" + +func Benchmark(b *testing.B) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_example.txt b/src/cmd/go/testdata/script/test_match_only_example.txt new file mode 100644 index 0000000..515ccb3 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_example.txt @@ -0,0 +1,31 @@ +[short] skip + +# Check that it's okay for test pattern to match only examples. +go test -run Example example1_test.go +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- example1_test.go -- +// Copyright 2013 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. + +// Make sure that go test runs Example_Z before Example_A, preserving source order. + +package p + +import "fmt" + +var n int + +func Example_Z() { + n++ + fmt.Println(n) + // Output: 1 +} + +func Example_A() { + n++ + fmt.Println(n) + // Output: 2 +} diff --git a/src/cmd/go/testdata/script/test_match_only_subtests.txt b/src/cmd/go/testdata/script/test_match_only_subtests.txt new file mode 100644 index 0000000..beea895 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_subtests.txt @@ -0,0 +1,14 @@ +# Matches only subtests +go test -run Test/Sub standalone_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_sub_test.go -- +package standalone_sub_test + +import "testing" + +func Test(t *testing.T) { + t.Run("Sub", func(t *testing.T) {}) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt b/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt new file mode 100644 index 0000000..11872c2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_subtests_parallel.txt @@ -0,0 +1,21 @@ +# Matches only subtests, parallel +go test -run Test/Sub/Nested standalone_parallel_sub_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_match_only_tests.txt b/src/cmd/go/testdata/script/test_match_only_tests.txt new file mode 100644 index 0000000..9185793 --- /dev/null +++ b/src/cmd/go/testdata/script/test_match_only_tests.txt @@ -0,0 +1,13 @@ +# Matches only tests +go test -run Test standalone_test.go +! stdout '^ok.*\[no tests to run\]' +! stderr '^ok.*\[no tests to run\]' +stdout '^ok' + +-- standalone_test.go -- +package standalone_test + +import "testing" + +func Test(t *testing.T) { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/test_minus_n.txt b/src/cmd/go/testdata/script/test_minus_n.txt new file mode 100644 index 0000000..9900dbc --- /dev/null +++ b/src/cmd/go/testdata/script/test_minus_n.txt @@ -0,0 +1,14 @@ +# The intent here is to verify that 'go test -n' works without crashing. +# Any test will do. + +go test -n x_test.go + +-- x_test.go -- +package x_test + +import ( + "testing" +) + +func TestEmpty(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/test_no_run_example.txt b/src/cmd/go/testdata/script/test_no_run_example.txt new file mode 100644 index 0000000..53ac755 --- /dev/null +++ b/src/cmd/go/testdata/script/test_no_run_example.txt @@ -0,0 +1,30 @@ +go test -v norunexample +stdout 'File with non-runnable example was built.' + +-- go.mod -- +module norunexample + +go 1.16 +-- example_test.go -- +package pkg_test + +import "os" + +func init() { + os.Stdout.Write([]byte("File with non-runnable example was built.\n")) +} + +func Example_test() { + // This test will not be run, it has no "Output:" comment. +} +-- test_test.go -- +package pkg + +import ( + "os" + "testing" +) + +func TestBuilt(t *testing.T) { + os.Stdout.Write([]byte("A normal test was executed.\n")) +} diff --git a/src/cmd/go/testdata/script/test_no_tests.txt b/src/cmd/go/testdata/script/test_no_tests.txt new file mode 100644 index 0000000..2d624d1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_no_tests.txt @@ -0,0 +1,15 @@ +# Tests issue #26242 + +go test testnorun +stdout 'testnorun\t\[no test files\]' + +-- go.mod -- +module testnorun + +go 1.16 +-- p.go -- +package p + +func init() { + panic("go test must not link and run test binaries without tests") +} diff --git a/src/cmd/go/testdata/script/test_overlay.txt b/src/cmd/go/testdata/script/test_overlay.txt new file mode 100644 index 0000000..b6bdc11 --- /dev/null +++ b/src/cmd/go/testdata/script/test_overlay.txt @@ -0,0 +1,24 @@ +[short] skip + +cd $WORK/gopath/src/foo +go test -list=. -overlay=overlay.json . +stdout 'TestBar' + +-- go.mod -- +module test.pkg +-- foo/foo_test.go -- +package foo + +import "testing" + +func TestFoo(t *testing.T) { } +-- tmp/bar_test.go -- +package foo + +import "testing" + +func TestBar(t *testing.T) { + t.Fatal("dummy failure") +} +-- foo/overlay.json -- +{"Replace": {"foo_test.go": "../tmp/bar_test.go"}} diff --git a/src/cmd/go/testdata/script/test_parallel_number.txt b/src/cmd/go/testdata/script/test_parallel_number.txt new file mode 100644 index 0000000..4eb9794 --- /dev/null +++ b/src/cmd/go/testdata/script/test_parallel_number.txt @@ -0,0 +1,25 @@ +[short] skip + +# go test -parallel -1 shouldn't work +! go test -parallel -1 standalone_parallel_sub_test.go +stdout '-parallel can only be given' + +# go test -parallel 0 shouldn't work +! go test -parallel 0 standalone_parallel_sub_test.go +stdout '-parallel can only be given' + +-- standalone_parallel_sub_test.go -- +package standalone_parallel_sub_test + +import "testing" + +func Test(t *testing.T) { + ch := make(chan bool, 1) + t.Run("Sub", func(t *testing.T) { + t.Parallel() + <-ch + t.Run("Nested", func(t *testing.T) {}) + }) + // Ensures that Sub will finish after its t.Run call already returned. + ch <- true +} diff --git a/src/cmd/go/testdata/script/test_profile.txt b/src/cmd/go/testdata/script/test_profile.txt new file mode 100644 index 0000000..4bfa2cc --- /dev/null +++ b/src/cmd/go/testdata/script/test_profile.txt @@ -0,0 +1,19 @@ +[gccgo] skip 'gccgo has no standard packages' +[short] skip + +# Check go test -cpuprofile creates errors.test +go test -cpuprofile errors.prof errors +exists -exec errors.test$GOEXE + +# Check go test -cpuprofile -o myerrors.test creates errors.test +go test -cpuprofile errors.prof -o myerrors.test$GOEXE errors +exists -exec myerrors.test$GOEXE + +# Check go test -mutexprofile creates errors.test +go test -mutexprofile errors.prof errors +exists -exec errors.test$GOEXE + +# Check go test -mutexprofile -o myerrors.test creates errors.test +go test -mutexprofile errors.prof -o myerrors.test$GOEXE errors +exists -exec myerrors.test$GOEXE + diff --git a/src/cmd/go/testdata/script/test_race.txt b/src/cmd/go/testdata/script/test_race.txt new file mode 100644 index 0000000..2ffea46 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race.txt @@ -0,0 +1,51 @@ +[short] skip +[!race] skip + +go test testrace + +! go test -race testrace +stdout 'FAIL: TestRace' +! stdout 'PASS' +! stderr 'PASS' + +! go test -race testrace -run XXX -bench . +stdout 'FAIL: BenchmarkRace' +! stdout 'PASS' +! stderr 'PASS' + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + for i := 0; i < 10; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} + +func BenchmarkRace(b *testing.B) { + for i := 0; i < b.N; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} diff --git a/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt new file mode 100644 index 0000000..eacc882 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_cover_mode_issue20435.txt @@ -0,0 +1,48 @@ +[short] skip +[!race] skip + +# Make sure test is functional. +go test testrace + +# Now, check that -race -covermode=set is not allowed. +! go test -race -covermode=set testrace +stderr '-covermode must be "atomic", not "set", when -race is enabled' +! stdout PASS +! stderr PASS + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + for i := 0; i < 10; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} + +func BenchmarkRace(b *testing.B) { + for i := 0; i < b.N; i++ { + c := make(chan int) + x := 1 + go func() { + x = 2 + c <- 1 + }() + x = 3 + <-c + _ = x + } +} diff --git a/src/cmd/go/testdata/script/test_race_install.txt b/src/cmd/go/testdata/script/test_race_install.txt new file mode 100644 index 0000000..a1d47a7 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_install.txt @@ -0,0 +1,18 @@ +[!race] skip +[short] skip + +mkdir $WORKDIR/tmp/pkg +go install -race -pkgdir=$WORKDIR/tmp/pkg std + +# Make sure go test -i -race doesn't rebuild cached packages +go test -race -pkgdir=$WORKDIR/tmp/pkg -i -v empty/pkg +cmp stderr stderr.txt + +-- go.mod -- +module empty + +go 1.16 +-- pkg/pkg.go -- +package p +-- stderr.txt -- +go: -i flag is deprecated diff --git a/src/cmd/go/testdata/script/test_race_install_cgo.txt b/src/cmd/go/testdata/script/test_race_install_cgo.txt new file mode 100644 index 0000000..e1fe4f2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_install_cgo.txt @@ -0,0 +1,91 @@ +# Tests Issue #10500 + +[!race] skip + +env GOBIN=$WORK/bin +go install m/mtime m/sametime + +go tool -n cgo +cp stdout cgopath.txt +exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt +cp stdout cgotime_before.txt + + # For this test, we don't actually care whether 'go test -race -i' succeeds. + # It may fail if GOROOT is read-only (perhaps it was installed as root). + # We only care that it does not overwrite cmd/cgo regardless. +? go test -race -i runtime/race + +exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt +cp stdout cgotime_after.txt +exec $GOBIN/sametime cgotime_before.txt cgotime_after.txt + +-- go.mod -- +module m + +go 1.16 +-- mtime/mtime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "strings" +) + +func main() { + b, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + filename := strings.TrimSpace(string(b)) + info, err := os.Stat(filename) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.NewEncoder(os.Stdout).Encode(info.ModTime()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} +-- sametime/sametime.go -- +package main + +import ( + "encoding/json" + "fmt" + "os" + "time" +) + + +func main() { + var t1 time.Time + b1, err := os.ReadFile(os.Args[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b1, &t1); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + var t2 time.Time + b2, err := os.ReadFile(os.Args[2]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := json.Unmarshal(b2, &t2); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + if !t1.Equal(t2) { + fmt.Fprintf(os.Stderr, "time in %v (%v) is not the same as time in %v (%v)", os.Args[1], t1, os.Args[2], t2) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/test_race_tag.txt b/src/cmd/go/testdata/script/test_race_tag.txt new file mode 100644 index 0000000..4b18ebc --- /dev/null +++ b/src/cmd/go/testdata/script/test_race_tag.txt @@ -0,0 +1,29 @@ +# Tests Issue #54468 + +[short] skip 'links a test binary' +[!race] skip + +go mod tidy +go test -c -o=$devnull -race . + +! stderr 'cannot find package' + +-- go.mod -- +module testrace + +go 1.18 + +require rsc.io/sampler v1.0.0 +-- race_test.go -- +//go:build race + +package testrace + +import ( + "testing" + + _ "rsc.io/sampler" +) + +func TestRaceTag(t *testing.T) { +} diff --git a/src/cmd/go/testdata/script/test_rebuildall.txt b/src/cmd/go/testdata/script/test_rebuildall.txt new file mode 100644 index 0000000..38233c1 --- /dev/null +++ b/src/cmd/go/testdata/script/test_rebuildall.txt @@ -0,0 +1,14 @@ +env GO111MODULE=off + +# Regression test for golang.org/issue/6844: +# 'go test -a' should force dependencies in the standard library to be rebuilt. + +[short] skip + +go test -x -a -c testdata/dep_test.go +stderr '^.*[/\\]compile'$GOEXE'["]? (.* )?regexp .*[/\\]regexp\.go' + +-- testdata/dep_test.go -- +package deps + +import _ "testing" diff --git a/src/cmd/go/testdata/script/test_regexps.txt b/src/cmd/go/testdata/script/test_regexps.txt new file mode 100644 index 0000000..2f33080 --- /dev/null +++ b/src/cmd/go/testdata/script/test_regexps.txt @@ -0,0 +1,79 @@ +go test -cpu=1 -run=X/Y -bench=X/Y -count=2 -v testregexp + +# Test the following: + +# TestX is run, twice +stdout -count=2 '^=== RUN TestX$' +stdout -count=2 '^ x_test.go:6: LOG: X running$' + +# TestX/Y is run, twice +stdout -count=2 '^=== RUN TestX/Y$' +stdout -count=2 '^ x_test.go:8: LOG: Y running$' + +# TestXX is run, twice +stdout -count=2 '^=== RUN TestXX$' +stdout -count=2 '^ z_test.go:10: LOG: XX running' + +# TestZ is not run +! stdout '^=== RUN TestZ$' + +# BenchmarkX is run with N=1 once, only to discover what sub-benchmarks it has, +# and should not print a final summary line. +stdout -count=1 '^ x_test.go:13: LOG: X running N=1$' +! stdout '^\s+BenchmarkX: x_test.go:13: LOG: X running N=\d\d+' +! stdout 'BenchmarkX\s+\d+' + +# Same for BenchmarkXX. +stdout -count=1 '^ z_test.go:18: LOG: XX running N=1$' +! stdout '^ z_test.go:18: LOG: XX running N=\d\d+' +! stdout 'BenchmarkXX\s+\d+' + +# BenchmarkX/Y is run in full twice due to -count=2. +# "Run in full" means that it runs for approximately the default benchtime, +# but may cap out at N=1e9. +# We don't actually care what the final iteration count is, but it should be +# a large number, and the last iteration count prints right before the results. +stdout -count=2 '^ x_test.go:15: LOG: Y running N=[1-9]\d{4,}\nBenchmarkX/Y\s+\d+' + +-- go.mod -- +module testregexp + +go 1.16 +-- x_test.go -- +package x + +import "testing" + +func TestX(t *testing.T) { + t.Logf("LOG: X running") + t.Run("Y", func(t *testing.T) { + t.Logf("LOG: Y running") + }) +} + +func BenchmarkX(b *testing.B) { + b.Logf("LOG: X running N=%d", b.N) + b.Run("Y", func(b *testing.B) { + b.Logf("LOG: Y running N=%d", b.N) + }) +} +-- z_test.go -- +package x + +import "testing" + +func TestZ(t *testing.T) { + t.Logf("LOG: Z running") +} + +func TestXX(t *testing.T) { + t.Logf("LOG: XX running") +} + +func BenchmarkZ(b *testing.B) { + b.Logf("LOG: Z running N=%d", b.N) +} + +func BenchmarkXX(b *testing.B) { + b.Logf("LOG: XX running N=%d", b.N) +} diff --git a/src/cmd/go/testdata/script/test_relative_cmdline.txt b/src/cmd/go/testdata/script/test_relative_cmdline.txt new file mode 100644 index 0000000..96f7b87 --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_cmdline.txt @@ -0,0 +1,52 @@ +# Relative imports in command line package + +env GO111MODULE=off + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +go test ./testimport/p.go ./testimport/p_test.go ./testimport/x_test.go +stdout '^ok' + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p2/p2.go -- +package p2 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} +-- testimport/x_test.go -- +package p_test + +import ( + . "../testimport" + + "./p2" + + "testing" +) + +func TestF1(t *testing.T) { + if F() != p2.F() { + t.Fatal(F()) + } +} diff --git a/src/cmd/go/testdata/script/test_relative_import.txt b/src/cmd/go/testdata/script/test_relative_import.txt new file mode 100644 index 0000000..938a875 --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_import.txt @@ -0,0 +1,31 @@ +# Relative imports in go test +env GO111MODULE=off # relative import not supported in module mode + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +go test ./testimport +stdout '^ok' + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} diff --git a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt new file mode 100644 index 0000000..b2716d8 --- /dev/null +++ b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt @@ -0,0 +1,32 @@ +# Relative imports in go test -i +env GO111MODULE=off # relative import not supported in module mode + +# Run tests outside GOPATH. +env GOPATH=$WORK/tmp + +# Check that it's safe to pass -i (which installs dependencies in $GOPATH/pkg) to go test. +! stale runtime # don't let test -i overwrite runtime +go test -i ./testimport + +-- testimport/p.go -- +package p + +func F() int { return 1 } +-- testimport/p1/p1.go -- +package p1 + +func F() int { return 1 } +-- testimport/p_test.go -- +package p + +import ( + "./p1" + + "testing" +) + +func TestF(t *testing.T) { + if F() != p1.F() { + t.Fatal(F()) + } +} diff --git a/src/cmd/go/testdata/script/test_script_cmdcd.txt b/src/cmd/go/testdata/script/test_script_cmdcd.txt new file mode 100644 index 0000000..6e6f67e --- /dev/null +++ b/src/cmd/go/testdata/script/test_script_cmdcd.txt @@ -0,0 +1,13 @@ +# Tests that after a cd command, where usually the UNIX path separator is used, +# a match against $PWD does not fail on Windows. + +cd $WORK/a/b/c/pkg + +go list -find -f {{.Root}} +stdout $PWD + +-- $WORK/a/b/c/pkg/go.mod -- +module pkg + +-- $WORK/a/b/c/pkg/pkg.go -- +package pkg diff --git a/src/cmd/go/testdata/script/test_shuffle.txt b/src/cmd/go/testdata/script/test_shuffle.txt new file mode 100644 index 0000000..3a50605 --- /dev/null +++ b/src/cmd/go/testdata/script/test_shuffle.txt @@ -0,0 +1,148 @@ +# Shuffle order of tests and benchmarks + +# Run tests +go test -v foo_test.go +! stdout '-test.shuffle ' +stdout '(?s)TestOne(.*)TestTwo(.*)TestThree' + +go test -v -shuffle=off foo_test.go +! stdout '-test.shuffle ' +stdout '(?s)TestOne(.*)TestTwo(.*)TestThree' + +go test -v -shuffle=42 foo_test.go +stdout '^-test.shuffle 42' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo' + +go test -v -shuffle=43 foo_test.go +stdout '^-test.shuffle 43' +stdout '(?s)TestThree(.*)TestTwo(.*)TestOne' + +go test -v -shuffle=44 foo_test.go +stdout '^-test.shuffle 44' +stdout '(?s)TestOne(.*)TestThree(.*)TestTwo' + +go test -v -shuffle=0 foo_test.go +stdout '^-test.shuffle 0' +stdout '(?s)TestTwo(.*)TestOne(.*)TestThree' + +go test -v -shuffle -1 foo_test.go +stdout '^-test.shuffle -1' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo' + +go test -v -shuffle=on foo_test.go +stdout '^-test.shuffle ' +stdout '(?s)=== RUN TestOne(.*)--- PASS: TestOne' +stdout '(?s)=== RUN TestTwo(.*)--- PASS: TestTwo' +stdout '(?s)=== RUN TestThree(.*)--- PASS: TestThree' + + +# Run tests and benchmarks +go test -v -bench=. foo_test.go +! stdout '-test.shuffle ' +stdout '(?s)TestOne(.*)TestTwo(.*)TestThree(.*)BenchmarkOne(.*)BenchmarkTwo(.*)BenchmarkThree' + +go test -v -bench=. -shuffle=off foo_test.go +! stdout '-test.shuffle ' +stdout '(?s)TestOne(.*)TestTwo(.*)TestThree(.*)BenchmarkOne(.*)BenchmarkTwo(.*)BenchmarkThree' + +go test -v -bench=. -shuffle=42 foo_test.go +stdout '^-test.shuffle 42' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo' + +go test -v -bench=. -shuffle=43 foo_test.go +stdout '^-test.shuffle 43' +stdout '(?s)TestThree(.*)TestTwo(.*)TestOne(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo' + +go test -v -bench=. -shuffle=44 foo_test.go +stdout '^-test.shuffle 44' +stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree' + +go test -v -bench=. -shuffle=0 foo_test.go +stdout '^-test.shuffle 0' +stdout '(?s)TestTwo(.*)TestOne(.*)TestThree(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo' + +go test -v -bench=. -shuffle -1 foo_test.go +stdout '^-test.shuffle -1' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)BenchmarkTwo' + +go test -v -bench=. -shuffle=on foo_test.go +stdout '^-test.shuffle ' +stdout '(?s)=== RUN TestOne(.*)--- PASS: TestOne' +stdout '(?s)=== RUN TestTwo(.*)--- PASS: TestTwo' +stdout '(?s)=== RUN TestThree(.*)--- PASS: TestThree' +stdout -count=2 'BenchmarkOne' +stdout -count=2 'BenchmarkTwo' +stdout -count=2 'BenchmarkThree' + + +# When running go test -count=N, each of the N runs distinct runs should maintain the same +# shuffled order of these tests. +go test -v -shuffle=43 -count=4 foo_test.go +stdout '^-test.shuffle 43' +stdout '(?s)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne' + +go test -v -bench=. -shuffle=44 -count=2 foo_test.go +stdout '^-test.shuffle 44' +stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)' + + +# The feature should work with test binaries as well +go test -c +exec ./m.test -test.shuffle=off +! stdout '^-test.shuffle ' + +exec ./m.test -test.shuffle=on +stdout '^-test.shuffle ' + +exec ./m.test -test.v -test.bench=. -test.shuffle=0 foo_test.go +stdout '^-test.shuffle 0' +stdout '(?s)TestTwo(.*)TestOne(.*)TestThree(.*)BenchmarkThree(.*)BenchmarkOne(.*)BenchmarkTwo' + +exec ./m.test -test.v -test.bench=. -test.shuffle=123 foo_test.go +stdout '^-test.shuffle 123' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkThree(.*)BenchmarkTwo(.*)BenchmarkOne' + +exec ./m.test -test.v -test.bench=. -test.shuffle=-1 foo_test.go +stdout '^-test.shuffle -1' +stdout '(?s)TestThree(.*)TestOne(.*)TestTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)BenchmarkTwo' + +exec ./m.test -test.v -test.bench=. -test.shuffle=44 -test.count=2 foo_test.go +stdout '^-test.shuffle 44' +stdout '(?s)TestOne(.*)TestThree(.*)TestTwo(.*)TestOne(.*)TestThree(.*)TestTwo(.*)BenchmarkTwo(.*)BenchmarkOne(.*)BenchmarkThree(.*)' + + +# Negative testcases for invalid input +! go test -shuffle -count=2 +stderr 'invalid value "-count=2" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "-count=2": invalid syntax' + +! go test -shuffle= +stderr '(?s)invalid value "" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "": invalid syntax' + +! go test -shuffle=' ' +stderr '(?s)invalid value " " for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing " ": invalid syntax' + +! go test -shuffle=true +stderr 'invalid value "true" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "true": invalid syntax' + +! go test -shuffle='abc' +stderr 'invalid value "abc" for flag -shuffle: -shuffle argument must be "on", "off", or an int64: strconv.ParseInt: parsing "abc": invalid syntax' + +-- go.mod -- +module m + +go 1.16 +-- foo_test.go -- +package foo + +import "testing" + +func TestOne(t *testing.T) {} +func TestTwo(t *testing.T) {} +func TestThree(t *testing.T) {} + +func BenchmarkOne(b *testing.B) {} +func BenchmarkTwo(b *testing.B) {} +func BenchmarkThree(b *testing.B) {} + +-- foo.go -- +package foo diff --git a/src/cmd/go/testdata/script/test_source_order.txt b/src/cmd/go/testdata/script/test_source_order.txt new file mode 100644 index 0000000..2865276 --- /dev/null +++ b/src/cmd/go/testdata/script/test_source_order.txt @@ -0,0 +1,54 @@ +[short] skip + +# Control +! go test example2_test.go example1_test.go + +# This test only passes if the source order is preserved +go test example1_test.go example2_test.go + +-- example1_test.go -- +// Copyright 2013 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. + +// Make sure that go test runs Example_Z before Example_A, preserving source order. + +package p + +import "fmt" + +var n int + +func Example_Z() { + n++ + fmt.Println(n) + // Output: 1 +} + +func Example_A() { + n++ + fmt.Println(n) + // Output: 2 +} +-- example2_test.go -- +// Copyright 2013 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. + +// Make sure that go test runs Example_Y before Example_B, preserving source order. + +package p + +import "fmt" + +func Example_Y() { + n++ + fmt.Println(n) + // Output: 3 +} + +func Example_B() { + n++ + fmt.Println(n) + // Output: 4 +} diff --git a/src/cmd/go/testdata/script/test_status.txt b/src/cmd/go/testdata/script/test_status.txt new file mode 100644 index 0000000..aa6ad3c --- /dev/null +++ b/src/cmd/go/testdata/script/test_status.txt @@ -0,0 +1,18 @@ +env GO111MODULE=off + +! go test x y +stdout ^FAIL\s+x +stdout ^ok\s+y +stdout (?-m)FAIL\n$ + +-- x/x_test.go -- +package x + +import "testing" + +func TestNothingJustFail(t *testing.T) { + t.Fail() +} + +-- y/y_test.go -- +package y diff --git a/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt new file mode 100644 index 0000000..44ff6e2 --- /dev/null +++ b/src/cmd/go/testdata/script/test_syntax_error_says_fail.txt @@ -0,0 +1,25 @@ +# Test that the error message for a syntax error in a test go file +# says FAIL. + +env GO111MODULE=off +! go test syntaxerror +stderr 'x_test.go:' # check that the error is diagnosed +stdout 'FAIL' # check that go test says FAIL + +env GO111MODULE=on +cd syntaxerror +! go test syntaxerror +stderr 'x_test.go:' # check that the error is diagnosed +stdout 'FAIL' # check that go test says FAIL + +-- syntaxerror/go.mod -- +module syntaxerror + +go 1.16 +-- syntaxerror/x.go -- +package p +-- syntaxerror/x_test.go -- +package p + +func f() (x.y, z int) { +} diff --git a/src/cmd/go/testdata/script/test_timeout.txt b/src/cmd/go/testdata/script/test_timeout.txt new file mode 100644 index 0000000..4de4df4 --- /dev/null +++ b/src/cmd/go/testdata/script/test_timeout.txt @@ -0,0 +1,23 @@ +[short] skip +env GO111MODULE=off +cd a + +# If no timeout is set explicitly, 'go test' should set +# -test.timeout to its internal deadline. +go test -v . -- +stdout '10m0s' + +# An explicit -timeout argument should be propagated to -test.timeout. +go test -v -timeout 30m . -- +stdout '30m0s' + +-- a/timeout_test.go -- +package t +import ( + "flag" + "fmt" + "testing" +) +func TestTimeout(t *testing.T) { + fmt.Println(flag.Lookup("test.timeout").Value.String()) +} diff --git a/src/cmd/go/testdata/script/test_trimpath.txt b/src/cmd/go/testdata/script/test_trimpath.txt new file mode 100644 index 0000000..065f9ce --- /dev/null +++ b/src/cmd/go/testdata/script/test_trimpath.txt @@ -0,0 +1,51 @@ +[short] skip + +go test -trimpath -v . +! stdout '[/\\]pkg_test[/\\]' +stdout -count=3 '[/\\]pkg[/\\]' + +-- go.mod -- +module example.com/pkg + +go 1.17 + +-- pkg.go -- +package pkg + +import "runtime" + +func PrintFile() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +-- pkg_test.go -- +package pkg + +import "runtime" + +func PrintFileForTest() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +-- pkg_x_test.go -- +package pkg_test + +import ( + "runtime" + "testing" + + "example.com/pkg" +) + +func TestMain(m *testing.M) { + pkg.PrintFile() + pkg.PrintFileForTest() + PrintFileInXTest() +} + +func PrintFileInXTest() { + _, file, _, _ := runtime.Caller(0) + println(file) +} diff --git a/src/cmd/go/testdata/script/test_trimpath_main.txt b/src/cmd/go/testdata/script/test_trimpath_main.txt new file mode 100644 index 0000000..c076212 --- /dev/null +++ b/src/cmd/go/testdata/script/test_trimpath_main.txt @@ -0,0 +1,38 @@ +[short] skip + +go test -trimpath -v . +! stdout '[/\\]pkg_test[/\\]' +stdout -count=2 '[/\\]pkg[/\\]' + +-- go.mod -- +module example.com/pkg + +go 1.17 + +-- main.go -- +package main + +import "runtime" + +func PrintFile() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +-- main_test.go -- +package main + +import ( + "runtime" + "testing" +) + +func PrintFileForTest() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +func TestMain(m *testing.M) { + PrintFile() + PrintFileForTest() +} diff --git a/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt b/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt new file mode 100644 index 0000000..6cbad83 --- /dev/null +++ b/src/cmd/go/testdata/script/test_trimpath_test_suffix.txt @@ -0,0 +1,40 @@ +[short] skip + +go test -trimpath -v . +! stdout '[/\\]pkg_test_test[/\\]' +stdout -count=2 '[/\\]pkg_test[/\\]' + +-- go.mod -- +module example.com/pkg_test + +go 1.17 + +-- pkg.go -- +package pkg_test + +import "runtime" + +func PrintFile() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +-- pkg_x_test.go -- +package pkg_test_test + +import ( + "runtime" + "testing" + + "example.com/pkg_test" +) + +func PrintFileForTest() { + _, file, _, _ := runtime.Caller(0) + println(file) +} + +func TestMain(m *testing.M) { + pkg_test.PrintFile() + PrintFileForTest() +} diff --git a/src/cmd/go/testdata/script/test_vendor.txt b/src/cmd/go/testdata/script/test_vendor.txt new file mode 100644 index 0000000..c6a88b6 --- /dev/null +++ b/src/cmd/go/testdata/script/test_vendor.txt @@ -0,0 +1,57 @@ +# In GOPATH mode, vendored packages can replace std packages. +env GO111MODULE=off +cd vend/hello +go test -v +stdout TestMsgInternal +stdout TestMsgExternal + +# In module mode, they cannot. +env GO111MODULE=on +! go test -mod=vendor +stderr 'undefined: strings.Msg' + +-- vend/hello/go.mod -- +module vend/hello + +go 1.16 +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/hello/hellox_test.go -- +package main_test + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgExternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/test_vet.txt b/src/cmd/go/testdata/script/test_vet.txt new file mode 100644 index 0000000..6151f91 --- /dev/null +++ b/src/cmd/go/testdata/script/test_vet.txt @@ -0,0 +1,123 @@ +[short] skip + +# Test file +! go test p1_test.go +stderr 'Logf format %d' +go test -vet=off +stdout '^ok' + +# Non-test file +! go test p1.go +stderr 'Printf format %d' +go test -x -vet=shift p1.go +stderr '[\\/]vet.*-shift' +stdout '\[no test files\]' +go test -vet=off p1.go +! stderr '[\\/]vet.*-shift' +stdout '\[no test files\]' + +# ensure all runs non-default vet +! go test -vet=all ./vetall/... +stderr 'using resp before checking for errors' + +# Test issue #47309 +! go test -vet=bools,xyz ./vetall/... +stderr '-vet argument must be a supported analyzer' + +# Test with a single analyzer +! go test -vet=httpresponse ./vetall/... +stderr 'using resp before checking for errors' + +# Test with a list of analyzers +go test -vet=atomic,bools,nilfunc ./vetall/... +stdout 'm/vetall.*\[no tests to run\]' + +# Test issue #22890 +go test m/vetcycle +stdout 'm/vetcycle.*\[no test files\]' + +# Test with ... +! go test ./vetfail/... +stderr 'Printf format %d' +stdout 'ok\s+m/vetfail/p2' + +# Check there's no diagnosis of a bad build constraint in vetxonly mode. +# Use -a so that we need to recompute the vet-specific export data for +# vetfail/p1. +go test -a m/vetfail/p2 +! stderr 'invalid.*constraint' + +-- go.mod -- +module m + +go 1.16 +-- p1_test.go -- +package p + +import "testing" + +func Test(t *testing.T) { + t.Logf("%d") // oops +} +-- p1.go -- +package p + +import "fmt" + +func F() { + fmt.Printf("%d") // oops +} +-- vetall/p.go -- +package p + +import "net/http" + +func F() { + resp, err := http.Head("example.com") + defer resp.Body.Close() + if err != nil { + panic(err) + } + // (defer statement belongs here) +} +-- vetall/p_test.go -- +package p +-- vetcycle/p.go -- +package p + +type ( + _ interface{ m(B1) } + A1 interface{ a(D1) } + B1 interface{ A1 } + C1 interface { + B1 /* ERROR issue #18395 */ + } + D1 interface{ C1 } +) + +var _ A1 = C1 /* ERROR cannot use C1 */ (nil) +-- vetfail/p1/p1.go -- +// +build !foo-bar + +package p1 + +import "fmt" + +func F() { + fmt.Printf("%d", "hello") // causes vet error +} +-- vetfail/p2/p2.go -- +package p2 + +import _ "m/vetfail/p1" + +func F() { +} +-- vetfail/p2/p2_test.go -- +package p2 + +import "testing" + +func TestF(t *testing.T) { + F() +} diff --git a/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt new file mode 100644 index 0000000..0db183f --- /dev/null +++ b/src/cmd/go/testdata/script/test_write_profiles_on_timeout.txt @@ -0,0 +1,26 @@ +# Tests issue 19394 + +[short] skip + +! go test -cpuprofile cpu.pprof -memprofile mem.pprof -timeout 1ms +stdout '^panic: test timed out' +grep . cpu.pprof +grep . mem.pprof + +-- go.mod -- +module profiling + +go 1.16 +-- timeout_test.go -- +package timeouttest_test + +import ( + "testing" + "time" +) + +func TestSleep(t *testing.T) { + for { + time.Sleep(1 * time.Second) + } +} diff --git a/src/cmd/go/testdata/script/test_xtestonly_works.txt b/src/cmd/go/testdata/script/test_xtestonly_works.txt new file mode 100644 index 0000000..8e150db --- /dev/null +++ b/src/cmd/go/testdata/script/test_xtestonly_works.txt @@ -0,0 +1,27 @@ +[short] skip + +go test xtestonly +! stdout '^ok.*\[no tests to run\]' +stdout '^ok' + +-- go.mod -- +module xtestonly + +go 1.16 +-- f.go -- +package xtestonly + +func F() int { return 42 } +-- f_test.go -- +package xtestonly_test + +import ( + "testing" + "xtestonly" +) + +func TestF(t *testing.T) { + if x := xtestonly.F(); x != 42 { + t.Errorf("f.F() = %d, want 42", x) + } +} diff --git a/src/cmd/go/testdata/script/testing_issue40908.txt b/src/cmd/go/testdata/script/testing_issue40908.txt new file mode 100644 index 0000000..839320e --- /dev/null +++ b/src/cmd/go/testdata/script/testing_issue40908.txt @@ -0,0 +1,25 @@ +[short] skip +[!race] skip + +go test -race testrace + +-- go.mod -- +module testrace + +go 1.16 +-- race_test.go -- +package testrace + +import "testing" + +func TestRace(t *testing.T) { + helperDone := make(chan struct{}) + go func() { + t.Logf("Something happened before cleanup.") + close(helperDone) + }() + + t.Cleanup(func() { + <-helperDone + }) +} diff --git a/src/cmd/go/testdata/script/toolexec.txt b/src/cmd/go/testdata/script/toolexec.txt new file mode 100644 index 0000000..bb86467 --- /dev/null +++ b/src/cmd/go/testdata/script/toolexec.txt @@ -0,0 +1,128 @@ +[short] skip + +# Build our simple toolexec program. +go build ./cmd/mytool + +# Use an ephemeral build cache so that our toolexec output is not cached +# for any stale standard-library dependencies. +# +# TODO(#27628): This should not be necessary. +env GOCACHE=$WORK/gocache + +# Build the main package with our toolexec program. For each action, it will +# print the tool's name and the TOOLEXEC_IMPORTPATH value. We expect to compile +# each package once, and link the main package once. +# Don't check the entire output at once, because the order in which the tools +# are run is irrelevant here. +# Finally, note that asm and cgo are run twice. + +go build -toolexec=$PWD/mytool +[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$' +[cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$' +[cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main"$' +stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main"$' + +# Test packages are a little bit trickier. +# We have four variants of test/main, as reported by 'go list -test': +# +# test/main - the regular non-test package +# test/main.test - the generated test program +# test/main [test/main.test] - the test package for foo_test.go +# test/main_test [test/main.test] - the test package for foo_separate_test.go +# +# As such, TOOLEXEC_IMPORTPATH must see the same strings, to be able to uniquely +# identify each package being built as reported by 'go list -f {{.ImportPath}}'. +# Note that these are not really "import paths" anymore, but that naming is +# consistent with 'go list -json' at least. + +go test -toolexec=$PWD/mytool + +stderr -count=2 '^# test/main\.test$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main\.test"$' +stderr -count=1 '^link'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main\.test"$' + +stderr -count=1 '^# test/main \[test/main\.test\]$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main \[test/main\.test\]"$' + +stderr -count=1 '^# test/main_test \[test/main\.test\]$' +stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main_test \[test/main\.test\]"$' + +-- go.mod -- +module test/main +-- foo.go -- +// Simple package so we can test a program build with -toolexec. +// With a dummy import, to test different TOOLEXEC_IMPORTPATH values. +// Includes dummy uses of cgo and asm, to cover those tools as well. +package main + +import ( + _ "test/main/withasm" + _ "test/main/withcgo" +) + +func main() {} +-- foo_test.go -- +package main + +import "testing" + +func TestFoo(t *testing.T) {} +-- foo_separate_test.go -- +package main_test + +import "testing" + +func TestSeparateFoo(t *testing.T) {} +-- withcgo/withcgo.go -- +package withcgo + +// int fortytwo() +// { +// return 42; +// } +import "C" +-- withcgo/stub.go -- +package withcgo + +// Stub file to ensure we build without cgo too. +-- withasm/withasm.go -- +package withasm + +// Note that we don't need to declare the Add func at all. +-- withasm/withasm_amd64.s -- +TEXT ·Add(SB),$0-24 + MOVQ a+0(FP), AX + ADDQ b+8(FP), AX + MOVQ AX, ret+16(FP) + RET +-- cmd/mytool/main.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" +) + +func main() { + tool, args := os.Args[1], os.Args[2:] + toolName := filepath.Base(tool) + if len(args) > 0 && args[0] == "-V=full" { + // We can't alter the version output. + } else { + // Print which tool we're running, and on what package. + fmt.Fprintf(os.Stdout, "%s TOOLEXEC_IMPORTPATH=%q\n", toolName, os.Getenv("TOOLEXEC_IMPORTPATH")) + } + + // Simply run the tool. + cmd := exec.Command(tool, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/src/cmd/go/testdata/script/trampoline_reuse_test.txt b/src/cmd/go/testdata/script/trampoline_reuse_test.txt new file mode 100644 index 0000000..bca897c --- /dev/null +++ b/src/cmd/go/testdata/script/trampoline_reuse_test.txt @@ -0,0 +1,100 @@ +# Verify PPC64 does not reuse a trampoline which is too far away. +# This tests an edge case where the direct call relocation addend should +# be ignored when computing the distance from the direct call to the +# already placed trampoline +[short] skip +[!ppc64] [!ppc64le] skip +[aix] skip + +# Note, this program does not run. Presumably, 'DWORD $0' is simpler to +# assembly 2^26 or so times. +# +# We build something which should be laid out as such: +# +# bar.Bar +# main.Func1 +# bar.Bar+400-tramp0 +# main.BigAsm +# main.Func2 +# bar.Bar+400-tramp1 +# +# bar.Bar needs to be placed far enough away to generate relocations +# from main package calls. and main.Func1 and main.Func2 are placed +# a bit more than the direct call limit apart, but not more than 0x400 +# bytes beyond it (to verify the reloc calc). + +go build + +-- go.mod -- + +module foo + +go 1.19 + +-- main.go -- + +package main + +import "foo/bar" + +func Func1() + +func main() { + Func1() + bar.Bar2() +} + +-- foo.s -- + +TEXT main·Func1(SB),0,$0-0 + CALL bar·Bar+0x400(SB) + CALL main·BigAsm(SB) +// A trampoline will be placed here to bar.Bar + +// This creates a gap sufficiently large to prevent trampoline reuse +#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; +#define NOP256 NOP64 NOP64 NOP64 NOP64 +#define NOP2S10 NOP256 NOP256 NOP256 NOP256 +#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10 +#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12 +#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14 +#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16 +#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18 +#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20 +#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22 +#define BIGNOP NOP2S24 NOP2S24 +TEXT main·BigAsm(SB),0,$0-0 + // Fill to the direct call limit so Func2 must generate a new trampoline. + // As the implicit trampoline above is just barely unreachable. + BIGNOP + MOVD $main·Func2(SB), R3 + +TEXT main·Func2(SB),0,$0-0 + CALL bar·Bar+0x400(SB) +// Another trampoline should be placed here. + +-- bar/bar.s -- + +#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; +#define NOP256 NOP64 NOP64 NOP64 NOP64 +#define NOP2S10 NOP256 NOP256 NOP256 NOP256 +#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10 +#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12 +#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14 +#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16 +#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18 +#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20 +#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22 +#define BIGNOP NOP2S24 NOP2S24 NOP2S10 +// A very big not very interesting function. +TEXT bar·Bar(SB),0,$0-0 + BIGNOP + +-- bar/bar.go -- + +package bar + +func Bar() + +func Bar2() { +} diff --git a/src/cmd/go/testdata/script/vendor_complex.txt b/src/cmd/go/testdata/script/vendor_complex.txt new file mode 100644 index 0000000..9ca94e7 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_complex.txt @@ -0,0 +1,75 @@ +env GO111MODULE=off + +# smoke test for complex build configuration +go build -o complex.exe complex +[exec:gccgo] go build -compiler=gccgo -o complex.exe complex + +-- complex/main.go -- +package main + +import ( + _ "complex/nest/sub/test12" + _ "complex/nest/sub/test23" + "complex/w" + "v" +) + +func main() { + println(v.Hello + " " + w.World) +} + +-- complex/nest/sub/test12/p.go -- +package test12 + +// Check that vendor/v1 is used but vendor/v2 is NOT used (sub/vendor/v2 wins). + +import ( + "v1" + "v2" +) + +const x = v1.ComplexNestVendorV1 +const y = v2.ComplexNestSubVendorV2 + +-- complex/nest/sub/test23/p.go -- +package test23 + +// Check that vendor/v3 is used but vendor/v2 is NOT used (sub/vendor/v2 wins). + +import ( + "v2" + "v3" +) + +const x = v3.ComplexNestVendorV3 +const y = v2.ComplexNestSubVendorV2 + +-- complex/nest/sub/vendor/v2/v2.go -- +package v2 + +const ComplexNestSubVendorV2 = true + +-- complex/nest/vendor/v1/v1.go -- +package v1 + +const ComplexNestVendorV1 = true + +-- complex/nest/vendor/v2/v2.go -- +package v2 + +const ComplexNestVendorV2 = true + +-- complex/nest/vendor/v3/v3.go -- +package v3 + +const ComplexNestVendorV3 = true + +-- complex/vendor/v/v.go -- +package v + +const Hello = "hello" + +-- complex/w/w.go -- +package w + +const World = "world" diff --git a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt new file mode 100644 index 0000000..da52f9a --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt @@ -0,0 +1,52 @@ +[!windows] [short] stop 'this test only applies to Windows' +env GO111MODULE=off + +go build run_go.go +exec ./run_go$GOEXE $GOPATH $GOPATH/src/vend/hello +stdout 'hello, world' + +-- run_go.go -- +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func changeVolume(s string, f func(s string) string) string { + vol := filepath.VolumeName(s) + return f(vol) + s[len(vol):] +} + +func main() { + gopath := changeVolume(os.Args[1], strings.ToLower) + dir := changeVolume(os.Args[2], strings.ToUpper) + cmd := exec.Command("go", "run", "hello.go") + cmd.Dir = dir + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" diff --git a/src/cmd/go/testdata/script/vendor_import.txt b/src/cmd/go/testdata/script/vendor_import.txt new file mode 100644 index 0000000..df4c27d --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import.txt @@ -0,0 +1,104 @@ +# Imports +env GO111MODULE=off +go list -f '{{.ImportPath}} {{.Imports}}' 'vend/...' 'vend/vendor/...' 'vend/x/vendor/...' +cmp stdout want_vendor_imports.txt + +-- want_vendor_imports.txt -- +vend [vend/vendor/p r] +vend/dir1 [] +vend/hello [fmt vend/vendor/strings] +vend/subdir [vend/vendor/p r] +vend/x [vend/x/vendor/p vend/vendor/q vend/x/vendor/r vend/dir1 vend/vendor/vend/dir1/dir2] +vend/x/invalid [vend/x/invalid/vendor/foo] +vend/vendor/p [] +vend/vendor/q [] +vend/vendor/strings [] +vend/vendor/vend/dir1/dir2 [] +vend/x/vendor/p [] +vend/x/vendor/p/p [notfound] +vend/x/vendor/r [] +-- vend/bad.go -- +package vend + +import _ "r" +-- vend/dir1/dir1.go -- +package dir1 +-- vend/good.go -- +package vend + +import _ "p" +-- vend/hello/hello.go -- +package main + +import ( + "fmt" + "strings" // really ../vendor/strings +) + +func main() { + fmt.Printf("%s\n", strings.Msg) +} +-- vend/hello/hello_test.go -- +package main + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgInternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/hello/hellox_test.go -- +package main_test + +import ( + "strings" // really ../vendor/strings + "testing" +) + +func TestMsgExternal(t *testing.T) { + if strings.Msg != "hello, world" { + t.Fatalf("unexpected msg: %v", strings.Msg) + } +} +-- vend/subdir/bad.go -- +package subdir + +import _ "r" +-- vend/subdir/good.go -- +package subdir + +import _ "p" +-- vend/vendor/p/p.go -- +package p +-- vend/vendor/q/q.go -- +package q +-- vend/vendor/strings/msg.go -- +package strings + +var Msg = "hello, world" +-- vend/vendor/vend/dir1/dir2/dir2.go -- +package dir2 +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" +-- vend/x/vendor/p/p.go -- +package p +-- vend/x/vendor/r/r.go -- +package r +-- vend/x/x.go -- +package x + +import _ "p" +import _ "q" +import _ "r" +import _ "vend/dir1" // not vendored +import _ "vend/dir1/dir2" // vendored diff --git a/src/cmd/go/testdata/script/vendor_import_missing.txt b/src/cmd/go/testdata/script/vendor_import_missing.txt new file mode 100644 index 0000000..8e50dfe --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import_missing.txt @@ -0,0 +1,7 @@ +# Missing package error message +! go build vend/x/vendor/p/p + +-- vend/x/vendor/p/p/p.go -- +package p + +import _ "notfound" diff --git a/src/cmd/go/testdata/script/vendor_import_wrong.txt b/src/cmd/go/testdata/script/vendor_import_wrong.txt new file mode 100644 index 0000000..73bf595 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_import_wrong.txt @@ -0,0 +1,20 @@ +# Wrong import path +env GO111MODULE=off +! go build vend/x/invalid +stderr 'must be imported as foo' + +env GO111MODULE= +cd vend/x/invalid +! go build vend/x/invalid +stderr 'must be imported as foo' + +-- vend/x/invalid/go.mod -- +module vend/x/invalid + +go 1.16 + +-- vend/x/invalid/invalid.go -- +package invalid + +import "vend/x/invalid/vendor/foo" + diff --git a/src/cmd/go/testdata/script/vendor_issue12156.txt b/src/cmd/go/testdata/script/vendor_issue12156.txt new file mode 100644 index 0000000..ac95c6d --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_issue12156.txt @@ -0,0 +1,16 @@ +# Tests issue #12156, a former index out of range panic. + +env GO111MODULE=off +env GOPATH=$WORK/gopath/src/testvendor2 # vendor/x is directly in $GOPATH, not in $GOPATH/src +cd $WORK/gopath/src/testvendor2/src/p + +! go build p.go +! stderr panic # Make sure it doesn't panic +stderr 'cannot find package "x"' + +-- testvendor2/src/p/p.go -- +package p + +import "x" +-- testvendor2/vendor/x/x.go -- +package x diff --git a/src/cmd/go/testdata/script/vendor_list_issue11977.txt b/src/cmd/go/testdata/script/vendor_list_issue11977.txt new file mode 100644 index 0000000..cdab33c --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_list_issue11977.txt @@ -0,0 +1,17 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get github.com/rsc/go-get-issue-11864 + +go list -f '{{join .TestImports "\n"}}' github.com/rsc/go-get-issue-11864/t +stdout 'go-get-issue-11864/vendor/vendor.org/p' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/tx +stdout 'go-get-issue-11864/vendor/vendor.org/p' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2 +stdout 'go-get-issue-11864/vendor/vendor.org/tx2' + +go list -f '{{join .XTestImports "\n"}}' github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx3 +stdout 'go-get-issue-11864/vendor/vendor.org/tx3' diff --git a/src/cmd/go/testdata/script/vendor_resolve.txt b/src/cmd/go/testdata/script/vendor_resolve.txt new file mode 100644 index 0000000..bc8cf0a --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_resolve.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off +! go build p +stderr 'must be imported as x' + +-- p/p.go -- +package p + +import ( + _ "q/y" + _ "q/z" +) +-- q/vendor/x/x.go -- +package x +-- q/y/y.go -- +package y + +import _ "x" +-- q/z/z.go -- +package z + +import _ "q/vendor/x" diff --git a/src/cmd/go/testdata/script/vendor_test_issue11864.txt b/src/cmd/go/testdata/script/vendor_test_issue11864.txt new file mode 100644 index 0000000..cfb43bf --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_test_issue11864.txt @@ -0,0 +1,20 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +go get github.com/rsc/go-get-issue-11864 + +# build -i should work +go build -i github.com/rsc/go-get-issue-11864 +go build -i github.com/rsc/go-get-issue-11864/t + +# test -i should work like build -i (golang.org/issue/11988) +go test -i github.com/rsc/go-get-issue-11864 +go test -i github.com/rsc/go-get-issue-11864/t + +# test should work too +go test github.com/rsc/go-get-issue-11864 +go test github.com/rsc/go-get-issue-11864/t + +# external tests should observe internal test exports (golang.org/issue/11977) +go test github.com/rsc/go-get-issue-11864/vendor/vendor.org/tx2 diff --git a/src/cmd/go/testdata/script/vendor_test_issue14613.txt b/src/cmd/go/testdata/script/vendor_test_issue14613.txt new file mode 100644 index 0000000..cfd7e58 --- /dev/null +++ b/src/cmd/go/testdata/script/vendor_test_issue14613.txt @@ -0,0 +1,22 @@ +[!net] skip +[!exec:git] skip +env GO111MODULE=off + +cd $GOPATH + +go get github.com/clsung/go-vendor-issue-14613 +go build -o $WORK/a.out -i github.com/clsung/go-vendor-issue-14613 + +# test folder should work +go test -i github.com/clsung/go-vendor-issue-14613 +go test github.com/clsung/go-vendor-issue-14613 + +# test with specified _test.go should work too +cd $GOPATH/src +go test -i github.com/clsung/go-vendor-issue-14613/vendor_test.go +go test github.com/clsung/go-vendor-issue-14613/vendor_test.go + +# test with imported and not used +go test -i github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go +! go test github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go +stderr 'imported and not used' diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt new file mode 100644 index 0000000..adca7af --- /dev/null +++ b/src/cmd/go/testdata/script/version.txt @@ -0,0 +1,70 @@ +# Without arguments, we just print Go's own version. +go version +stdout '^go version' + +# Flags without files, or paths to misisng files, should error. +! go version missing.exe +! go version -m +stderr 'with arguments' +! go version -v +stderr 'with arguments' + +# Neither of the two flags above should be an issue via GOFLAGS. +env GOFLAGS='-m -v' +go version +stdout '^go version' +env GOFLAGS= + +env GO111MODULE=on + +# Check that very basic version lookup succeeds. +go build empty.go +go version empty$GOEXE +[cgo] go build -ldflags=-linkmode=external empty.go +[cgo] go version empty$GOEXE + +# Skip the remaining builds if we are running in short mode. +[short] skip + +# Check that 'go version' and 'go version -m' work on a binary built in module mode. +go get rsc.io/fortune +go build -o fortune.exe rsc.io/fortune +go version fortune.exe +stdout '^fortune.exe: .+' +go version -m fortune.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +# Check the build info of a binary built from $GOROOT/src/cmd +go build -o test2json.exe cmd/test2json +go version -m test2json.exe +stdout '^test2json.exe: .+' +stdout '^\tpath\tcmd/test2json$' +! stdout 'mod' + +# Repeat the test with -buildmode=pie. +[!buildmode:pie] stop +go build -buildmode=pie -o external.exe rsc.io/fortune +go version external.exe +stdout '^external.exe: .+' +go version -m external.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +# Also test PIE with internal linking. +# currently only supported on linux/amd64, linux/arm64 and windows/amd64. +[!linux] [!windows] stop +[!amd64] [!arm64] stop +go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune +go version internal.exe +stdout '^internal.exe: .+' +go version -m internal.exe +stdout '^\tpath\trsc.io/fortune' +stdout '^\tmod\trsc.io/fortune\tv1.0.0' + +-- go.mod -- +module m + +-- empty.go -- +package main +func main(){} diff --git a/src/cmd/go/testdata/script/version_build_settings.txt b/src/cmd/go/testdata/script/version_build_settings.txt new file mode 100644 index 0000000..08df7e6 --- /dev/null +++ b/src/cmd/go/testdata/script/version_build_settings.txt @@ -0,0 +1,85 @@ +[short] skip + +# Compiler name is always added. +go build +go version -m m$GOEXE +stdout '^\tbuild\t-compiler=gc$' +stdout '^\tbuild\tGOOS=' +stdout '^\tbuild\tGOARCH=' +[amd64] stdout '^\tbuild\tGOAMD64=' +! stdout asmflags|gcflags|ldflags|gccgoflags + +# Toolchain flags are added if present. +# The raw flags are included, with package patterns if specified. +go build -asmflags=example.com/m=-D=FOO=bar +go version -m m$GOEXE +stdout '^\tbuild\t-asmflags=example\.com/m=-D=FOO=bar$' + +go build -gcflags=example.com/m=-N +go version -m m$GOEXE +stdout '^\tbuild\t-gcflags=example\.com/m=-N$' + +go build -ldflags=example.com/m=-w +go version -m m$GOEXE +stdout '^\tbuild\t-ldflags=example\.com/m=-w$' + +# gccgoflags are not added when gc is used, and vice versa. +# TODO: test gccgo. +go build -gccgoflags=all=UNUSED +go version -m m$GOEXE +! stdout gccgoflags + +# Build and tool tags are added but not release tags. +# "race" is included with build tags but not "cgo". +go build -tags=a,b +go version -m m$GOEXE +stdout '^\tbuild\t-tags=a,b$' +[race] go build -race +[race] go version -m m$GOEXE +[race] ! stdout '^\tbuild\t-tags=' +[race] stdout '^\tbuild\t-race=true$' + +# CGO flags are separate settings. +# CGO_ENABLED is always present. +# Other flags are added if CGO_ENABLED is true. +env CGO_ENABLED=0 +go build +go version -m m$GOEXE +stdout '^\tbuild\tCGO_ENABLED=0$' +! stdout CGO_CPPFLAGS|CGO_CFLAGS|CGO_CXXFLAGS|CGO_LDFLAGS + +[cgo] env CGO_ENABLED=1 +[cgo] env CGO_CPPFLAGS=-DFROM_CPPFLAGS=1 +[cgo] env CGO_CFLAGS=-DFROM_CFLAGS=1 +[cgo] env CGO_CXXFLAGS=-DFROM_CXXFLAGS=1 +[cgo] env CGO_LDFLAGS=-L/extra/dir/does/not/exist +[cgo] go build '-ldflags=all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist' +[cgo] go version -m m$GOEXE +[cgo] stdout '^\tbuild\t-ldflags="all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist"$' +[cgo] stdout '^\tbuild\tCGO_ENABLED=1$' +[cgo] stdout '^\tbuild\tCGO_CPPFLAGS=-DFROM_CPPFLAGS=1$' +[cgo] stdout '^\tbuild\tCGO_CFLAGS=-DFROM_CFLAGS=1$' +[cgo] stdout '^\tbuild\tCGO_CXXFLAGS=-DFROM_CXXFLAGS=1$' +[cgo] stdout '^\tbuild\tCGO_LDFLAGS=-L/extra/dir/does/not/exist$' + +# https://go.dev/issue/52372: a cgo-enabled binary should not be stamped with +# CGO_ flags that contain paths. +[cgo] env CGO_ENABLED=1 +[cgo] env CGO_CPPFLAGS=-DFROM_CPPFLAGS=1 +[cgo] env CGO_CFLAGS=-DFROM_CFLAGS=1 +[cgo] env CGO_CXXFLAGS=-DFROM_CXXFLAGS=1 +[cgo] env CGO_LDFLAGS=-L/extra/dir/does/not/exist +[cgo] go build -trimpath '-ldflags=all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist' +[cgo] go version -m m$GOEXE +[cgo] ! stdout '/extra/dir/does/not/exist' +[cgo] ! stdout '/bonus/dir/does/not/exist' +[cgo] stdout '^\tbuild\tCGO_ENABLED=1$' + +-- go.mod -- +module example.com/m + +go 1.18 +-- m.go -- +package main + +func main() {} diff --git a/src/cmd/go/testdata/script/version_buildvcs_bzr.txt b/src/cmd/go/testdata/script/version_buildvcs_bzr.txt new file mode 100644 index 0000000..85db9ba --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_bzr.txt @@ -0,0 +1,107 @@ +# This test checks that VCS information is stamped into Go binaries by default, +# controlled with -buildvcs. This test focuses on Bazaar specifics. +# The Git test covers common functionality. + +[!exec:bzr] skip +[short] skip +env GOBIN=$WORK/gopath/bin +env oldpath=$PATH +env HOME=$WORK +cd repo/a +exec bzr whoami 'J.R. Gopher <gopher@golang.org>' + +# If there's no local repository, there's no VCS info. +go install +go version -m $GOBIN/a$GOEXE +! stdout bzrrevision +rm $GOBIN/a$GOEXE + +# If there is a repository, but it can't be used for some reason, +# there should be an error. It should hint about -buildvcs=false. +cd .. +mkdir .bzr +env PATH=$WORK${/}fakebin${:}$oldpath +chmod 0755 $WORK/fakebin/bzr +! exec bzr help +cd a +! go install +stderr '^error obtaining VCS status: exit status 1\n\tUse -buildvcs=false to disable VCS stamping.$' +rm $GOBIN/a$GOEXE +cd .. +env PATH=$oldpath +rm .bzr + +# If there is an empty repository in a parent directory, only "modified" is tagged. +exec bzr init +cd a +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=bzr$' +! stdout vcs.revision +! stdout vcs.time +stdout '^\tbuild\tvcs.modified=true$' +cd .. + +# Revision and commit time are tagged for repositories with commits. +exec bzr add a README +exec bzr commit -m 'initial commit' +cd a +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=bzr$' +stdout '^\tbuild\tvcs.revision=' +stdout '^\tbuild\tvcs.time=' +stdout '^\tbuild\tvcs.modified=false$' +rm $GOBIN/a$GOEXE + +# Building an earlier commit should still build clean. +cp ../../outside/empty.txt ../NEWS +exec bzr add ../NEWS +exec bzr commit -m 'add NEWS' +exec bzr update -r1 +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=bzr$' +stdout '^\tbuild\tvcs.revision=' +stdout '^\tbuild\tvcs.time=' +stdout '^\tbuild\tvcs.modified=false$' + +# Building with -buildvcs=false suppresses the info. +go install -buildvcs=false +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +# An untracked file is shown as modified, even if it isn't part of the build. +cp ../../outside/empty.txt . +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +rm empty.txt +rm $GOBIN/a$GOEXE + +# An edited file is shown as modified, even if it isn't part of the build. +cp ../../outside/empty.txt ../README +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +exec bzr revert ../README +rm $GOBIN/a$GOEXE + +-- $WORK/fakebin/bzr -- +#!/bin/sh +exit 1 +-- $WORK/fakebin/bzr.bat -- +exit 1 +-- repo/README -- +Far out in the uncharted backwaters of the unfashionable end of the western +spiral arm of the Galaxy lies a small, unregarded yellow sun. +-- repo/a/go.mod -- +module example.com/a + +go 1.18 +-- repo/a/a.go -- +package main + +func main() {} +-- outside/empty.txt -- diff --git a/src/cmd/go/testdata/script/version_buildvcs_fossil.txt b/src/cmd/go/testdata/script/version_buildvcs_fossil.txt new file mode 100644 index 0000000..7203068 --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_fossil.txt @@ -0,0 +1,93 @@ +# This test checks that VCS information is stamped into Go binaries by default, +# controlled with -buildvcs. This test focuses on Fossil specifics. +# The Git test covers common functionality. + +# "fossil" is the Fossil file server on Plan 9. +[plan9] skip +[!exec:fossil] skip +[short] skip +env GOBIN=$WORK/gopath/bin +env oldpath=$PATH +env HOME=$WORK +env USER=gopher +[!windows] env fslckout=.fslckout +[windows] env fslckout=_FOSSIL_ +exec pwd +exec fossil init repo.fossil +cd repo/a + +# If there's no local repository, there's no VCS info. +go install +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +# If there is a repository, but it can't be used for some reason, +# there should be an error. It should hint about -buildvcs=false. +cd .. +mkdir $fslckout +env PATH=$WORK${/}fakebin${:}$oldpath +chmod 0755 $WORK/fakebin/fossil +! exec fossil help +cd a +! go install +stderr '^error obtaining VCS status: exit status 1\n\tUse -buildvcs=false to disable VCS stamping.$' +rm $GOBIN/a$GOEXE +cd .. +env PATH=$oldpath +rm $fslckout + +# Revision and commit time are tagged for repositories with commits. +exec fossil open ../repo.fossil -f +exec fossil add a README +exec fossil commit -m 'initial commit' +cd a +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=fossil\n' +stdout '^\tbuild\tvcs.revision=' +stdout '^\tbuild\tvcs.time=' +stdout '^\tbuild\tvcs.modified=false$' +rm $GOBIN/a$GOEXE + +# Building with -buildvcs=false suppresses the info. +go install -buildvcs=false +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +# An untracked file is shown as modified, even if it isn't part of the build. +cp ../../outside/empty.txt . +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=fossil\n' +stdout '^\tbuild\tvcs.modified=true$' +rm empty.txt +rm $GOBIN/a$GOEXE + +# An edited file is shown as modified, even if it isn't part of the build. +cp ../../outside/empty.txt ../README +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=fossil\n' +stdout '^\tbuild\tvcs.modified=true$' +exec fossil revert ../README +rm $GOBIN/a$GOEXE + +-- $WORK/fakebin/fossil -- +#!/bin/sh +exit 1 +-- $WORK/fakebin/fossil.bat -- +exit 1 +-- repo/README -- +Far out in the uncharted backwaters of the unfashionable end of the western +spiral arm of the Galaxy lies a small, unregarded yellow sun. +-- repo/a/go.mod -- +module example.com/a + +go 1.18 +-- repo/a/a.go -- +package main + +func main() {} +-- outside/empty.txt -- diff --git a/src/cmd/go/testdata/script/version_buildvcs_git.txt b/src/cmd/go/testdata/script/version_buildvcs_git.txt new file mode 100644 index 0000000..4470687 --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_git.txt @@ -0,0 +1,164 @@ +# This test checks that VCS information is stamped into Go binaries by default, +# controlled with -buildvcs. This test focuses on Git. Other tests focus on +# other VCS tools but may not cover common functionality. + +[!exec:git] skip +[short] skip +env GOBIN=$WORK/gopath/bin +env oldpath=$PATH +cd repo/a + +# If there's no local repository, there's no VCS info. +go install +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +# If there is a repository, but it can't be used for some reason, +# there should be an error. It should hint about -buildvcs=false. +# Also ensure that multiple errors are collected by "go list -e". +cd .. +mkdir .git +env PATH=$WORK${/}fakebin${:}$oldpath +chmod 0755 $WORK/fakebin/git +! exec git help +cd a +! go install +stderr '^error obtaining VCS status: exit status 1\n\tUse -buildvcs=false to disable VCS stamping.$' +go list -e -f '{{.ImportPath}}: {{.Error}}' ./... +stdout -count=1 '^example\.com/a: error obtaining VCS status' +stdout -count=1 '^example\.com/a/library: <nil>' +stdout -count=1 '^example\.com/a/othermain: error obtaining VCS status' +cd .. +env PATH=$oldpath +rm .git + +# If there is an empty repository in a parent directory, only "uncommitted" is tagged. +exec git init +exec git config user.email gopher@golang.org +exec git config user.name 'J.R. Gopher' +cd a +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs=git$' +stdout '^\tbuild\tvcs.modified=true$' +! stdout vcs.revision +! stdout vcs.time +rm $GOBIN/a$GOEXE + +# Revision and commit time are tagged for repositories with commits. +exec git add -A +exec git commit -m 'initial commit' +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.revision=' +stdout '^\tbuild\tvcs.time=' +stdout '^\tbuild\tvcs.modified=false$' +rm $GOBIN/a$GOEXE + +# Building with -buildvcs=false suppresses the info. +go install -buildvcs=false +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +# An untracked file is shown as uncommitted, even if it isn't part of the build. +cp ../../outside/empty.txt . +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +rm empty.txt +rm $GOBIN/a$GOEXE + +# An edited file is shown as uncommitted, even if it isn't part of the build. +cp ../../outside/empty.txt ../README +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +exec git checkout ../README +rm $GOBIN/a$GOEXE + +# If the build doesn't include any packages from the repository, +# there should be no VCS info. +go install example.com/cmd/a@v1.0.0 +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +rm $GOBIN/a$GOEXE + +go mod edit -require=example.com/c@v0.0.0 +go mod edit -replace=example.com/c@v0.0.0=../../outside/c +go install example.com/c +go version -m $GOBIN/c$GOEXE +! stdout vcs.revision +rm $GOBIN/c$GOEXE +exec git checkout go.mod + +# If the build depends on a package in the repository, but it's not in the +# main module, there should be no VCS info. +go mod edit -require=example.com/b@v0.0.0 +go mod edit -replace=example.com/b@v0.0.0=../b +go mod edit -require=example.com/d@v0.0.0 +go mod edit -replace=example.com/d@v0.0.0=../../outside/d +go install example.com/d +go version -m $GOBIN/d$GOEXE +! stdout vcs.revision +exec git checkout go.mod +rm $GOBIN/d$GOEXE + +# If we're loading multiple main packages, +# but they share the same VCS repository, +# we only need to execute VCS status commands once. +go list -x ./... +stdout -count=3 '^example.com' +stderr -count=1 '^git status' +stderr -count=1 '^git -c log.showsignature=false show' + +-- $WORK/fakebin/git -- +#!/bin/sh +exit 1 +-- $WORK/fakebin/git.bat -- +exit 1 +-- repo/README -- +Far out in the uncharted backwaters of the unfashionable end of the western +spiral arm of the Galaxy lies a small, unregarded yellow sun. +-- repo/a/go.mod -- +module example.com/a + +go 1.18 +-- repo/a/a.go -- +package main + +func main() {} +-- repo/a/library/f.go -- +package library +-- repo/a/othermain/f.go -- +package main + +func main() {} +-- repo/b/go.mod -- +module example.com/b + +go 1.18 +-- repo/b/b.go -- +package b +-- outside/empty.txt -- +-- outside/c/go.mod -- +module example.com/c + +go 1.18 +-- outside/c/main.go -- +package main + +func main() {} +-- outside/d/go.mod -- +module example.com/d + +go 1.18 + +require example.com/b v0.0.0 +-- outside/d/main.go -- +package main + +import _ "example.com/b" + +func main() {} diff --git a/src/cmd/go/testdata/script/version_buildvcs_hg.txt b/src/cmd/go/testdata/script/version_buildvcs_hg.txt new file mode 100644 index 0000000..fbbd886 --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_hg.txt @@ -0,0 +1,91 @@ +# This test checks that VCS information is stamped into Go binaries by default, +# controlled with -buildvcs. This test focuses on Mercurial specifics. +# The Git test covers common functionality. + +[!exec:hg] skip +[short] skip +env GOBIN=$WORK/gopath/bin +env oldpath=$PATH +cd repo/a + +# If there's no local repository, there's no VCS info. +go install +go version -m $GOBIN/a$GOEXE +! stdout hgrevision +rm $GOBIN/a$GOEXE + +# If there is a repository, but it can't be used for some reason, +# there should be an error. It should hint about -buildvcs=false. +cd .. +mkdir .hg +env PATH=$WORK${/}fakebin${:}$oldpath +chmod 0755 $WORK/fakebin/hg +! exec hg help +cd a +! go install +stderr '^error obtaining VCS status: exit status 1\n\tUse -buildvcs=false to disable VCS stamping.$' +rm $GOBIN/a$GOEXE +cd .. +env PATH=$oldpath +rm .hg + +# If there is an empty repository in a parent directory, only "uncommitted" is tagged. +exec hg init +cd a +go install +go version -m $GOBIN/a$GOEXE +! stdout vcs.revision +! stdout vcs.time +stdout '^\tbuild\tvcs.modified=true$' +cd .. + +# Revision and commit time are tagged for repositories with commits. +exec hg add a README +exec hg commit -m 'initial commit' +cd a +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.revision=' +stdout '^\tbuild\tvcs.time=' +stdout '^\tbuild\tvcs.modified=false$' +rm $GOBIN/a$GOEXE + +# Building with -buildvcs=false suppresses the info. +go install -buildvcs=false +go version -m $GOBIN/a$GOEXE +! stdout hgrevision +rm $GOBIN/a$GOEXE + +# An untracked file is shown as uncommitted, even if it isn't part of the build. +cp ../../outside/empty.txt . +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +rm empty.txt +rm $GOBIN/a$GOEXE + +# An edited file is shown as uncommitted, even if it isn't part of the build. +cp ../../outside/empty.txt ../README +go install +go version -m $GOBIN/a$GOEXE +stdout '^\tbuild\tvcs.modified=true$' +exec hg revert ../README +rm $GOBIN/a$GOEXE + +-- $WORK/fakebin/hg -- +#!/bin/sh +exit 1 +-- $WORK/fakebin/hg.bat -- +exit 1 +-- repo/README -- +Far out in the uncharted backwaters of the unfashionable end of the western +spiral arm of the Galaxy lies a small, unregarded yellow sun. +-- repo/a/go.mod -- +module example.com/a + +go 1.18 +-- repo/a/a.go -- +package main + +func main() {} +-- outside/empty.txt -- diff --git a/src/cmd/go/testdata/script/version_buildvcs_nested.txt b/src/cmd/go/testdata/script/version_buildvcs_nested.txt new file mode 100644 index 0000000..a0c69f9 --- /dev/null +++ b/src/cmd/go/testdata/script/version_buildvcs_nested.txt @@ -0,0 +1,51 @@ +[!exec:git] skip +[!exec:hg] skip +[short] skip +env GOFLAGS='-n -buildvcs' + +# Create a root module in a root Git repository. +mkdir root +cd root +go mod init example.com/root +exec git init + +# Nesting repositories in parent directories are ignored, as the current +# directory main package, and containing main module are in the same repository. +# This is an error in GOPATH mode (to prevent VCS injection), but for modules, +# we assume users have control over repositories they've checked out. +mkdir hgsub +cd hgsub +exec hg init +cp ../../main.go main.go +! go build +stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*hgsub"$' +stderr '^\tUse -buildvcs=false to disable VCS stamping.$' +go build -buildvcs=false +go mod init example.com/root/hgsub +go build +cd .. + +# It's an error to build a package from a nested Git repository if the package +# is in a separate repository from the current directory or from the module +# root directory. +mkdir gitsub +cd gitsub +exec git init +exec git config user.name 'J.R.Gopher' +exec git config user.email 'gopher@golang.org' +cp ../../main.go main.go +! go build +stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*gitsub"$' +go build -buildvcs=false +go mod init example.com/root/gitsub +exec git commit --allow-empty -m empty # status commands fail without this +go build +rm go.mod +cd .. +! go build ./gitsub +stderr '^error obtaining VCS status: main package is in repository ".*gitsub" but current directory is in repository ".*root"$' +go build -buildvcs=false -o=gitsub${/} ./gitsub + +-- main.go -- +package main +func main() {} diff --git a/src/cmd/go/testdata/script/version_goexperiment.txt b/src/cmd/go/testdata/script/version_goexperiment.txt new file mode 100644 index 0000000..4b165eb --- /dev/null +++ b/src/cmd/go/testdata/script/version_goexperiment.txt @@ -0,0 +1,16 @@ +# Test that experiments appear in "go version <binary>" + +# This test requires rebuilding the runtime, which takes a while. +[short] skip + +env GOEXPERIMENT=fieldtrack +go build -o main$GOEXE version.go +go version main$GOEXE +stdout 'X:fieldtrack$' +exec ./main$GOEXE +stderr 'X:fieldtrack$' + +-- version.go -- +package main +import "runtime" +func main() { println(runtime.Version()) } diff --git a/src/cmd/go/testdata/script/version_replace.txt b/src/cmd/go/testdata/script/version_replace.txt new file mode 100644 index 0000000..82b8504 --- /dev/null +++ b/src/cmd/go/testdata/script/version_replace.txt @@ -0,0 +1,33 @@ +[short] skip + +go mod download example.com/printversion@v0.1.0 example.com/printversion@v1.0.0 +go get example.com/printversion@v0.1.0 +go install example.com/printversion + +go run example.com/printversion +cmp stdout out.txt + +go version -m $GOPATH/bin/printversion$GOEXE +stdout '^.*[/\\]bin[/\\]printversion'$GOEXE': .*$' +stdout '^ path example.com/printversion$' +stdout '^ mod example.com/printversion v0.1.0$' +stdout '^ => example.com/printversion v1.0.0 h1:.*$' +stdout '^ dep example.com/version v1.0.0$' +stdout '^ => example.com/version v1.0.1 h1:.*$' + +-- go.mod -- +module golang.org/issue/37392 +go 1.14 +require ( + example.com/printversion v0.1.0 +) +replace ( + example.com/printversion => example.com/printversion v1.0.0 + example.com/version v1.0.0 => example.com/version v1.0.1 +) +-- out.txt -- +path is example.com/printversion +main is example.com/printversion v0.1.0 + (replaced by example.com/printversion v1.0.0) +using example.com/version v1.0.0 + (replaced by example.com/version v1.0.1) diff --git a/src/cmd/go/testdata/script/vet.txt b/src/cmd/go/testdata/script/vet.txt new file mode 100644 index 0000000..6573ae3 --- /dev/null +++ b/src/cmd/go/testdata/script/vet.txt @@ -0,0 +1,62 @@ +# Package with external tests +! go vet m/vetpkg +stderr 'Printf' + +# With tags +! go vet -tags tagtest m/vetpkg +stderr 'c\.go.*Printf' + +# With flags on +! go vet -printf m/vetpkg +stderr 'Printf' + +# With flags off +go vet -printf=false m/vetpkg +! stderr . + +# With only test files (tests issue #23395) +go vet m/onlytest +! stderr . + +# With only cgo files (tests issue #24193) +[!cgo] skip +[short] skip +go vet m/onlycgo +! stderr . + +-- go.mod -- +module m + +go 1.16 +-- vetpkg/a_test.go -- +package p_test +-- vetpkg/b.go -- +package p + +import "fmt" + +func f() { + fmt.Printf("%d") +} +-- vetpkg/c.go -- +// +build tagtest + +package p + +import "fmt" + +func g() { + fmt.Printf("%d", 3, 4) +} +-- onlytest/p_test.go -- +package p + +import "testing" + +func TestMe(*testing.T) {} +-- onlycgo/p.go -- +package p + +import "C" + +func F() {} diff --git a/src/cmd/go/testdata/script/vet_asm.txt b/src/cmd/go/testdata/script/vet_asm.txt new file mode 100644 index 0000000..59b35ec --- /dev/null +++ b/src/cmd/go/testdata/script/vet_asm.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +# Issue 27665. Verify that "go vet" analyzes non-Go files. + +[!amd64] skip +! go vet -asmdecl a +stderr 'f: invalid MOVW of x' + +# -c flag shows context +! go vet -c=2 -asmdecl a +stderr '...invalid MOVW...' +stderr '1 .*TEXT' +stderr '2 MOVW' +stderr '3 RET' +stderr '4' + +# -json causes success, even with diagnostics and errors. +go vet -json -asmdecl a +stderr '"a": {' +stderr '"asmdecl":' +stderr '"posn": ".*asm.s:2:1",' +stderr '"message": ".*invalid MOVW.*"' + +-- a/a.go -- +package a + +func f(x int8) + +-- a/asm.s -- +TEXT ·f(SB),0,$0-1 + MOVW x+0(FP), AX + RET diff --git a/src/cmd/go/testdata/script/vet_deps.txt b/src/cmd/go/testdata/script/vet_deps.txt new file mode 100644 index 0000000..b2a8f16 --- /dev/null +++ b/src/cmd/go/testdata/script/vet_deps.txt @@ -0,0 +1,34 @@ +env GO111MODULE=off + +# Issue 30296. Verify that "go vet" uses only immediate dependencies. + +# First run fills the cache. +go vet a + +go vet -x a +! stderr 'transitive' + +-- a/a.go -- +package a + +import "b" + +func F() { + b.F() +} + +-- b/b.go -- +package b + +import "transitive" + +func F() { + transitive.F() +} + +-- transitive/c.go -- +package transitive + +func F() { +} + diff --git a/src/cmd/go/testdata/script/vet_flags.txt b/src/cmd/go/testdata/script/vet_flags.txt new file mode 100644 index 0000000..e2e3f5b --- /dev/null +++ b/src/cmd/go/testdata/script/vet_flags.txt @@ -0,0 +1,93 @@ +env GO111MODULE=on + +# Issue 35837: "go vet -<analyzer> <std package>" should use the requested +# analyzers, not the default analyzers for 'go test'. +go vet -n -buildtags=false runtime +stderr '-buildtags=false' +! stderr '-unsafeptr=false' + +# Issue 37030: "go vet <std package>" without other flags should disable the +# unsafeptr check by default. +go vet -n runtime +stderr '-unsafeptr=false' +! stderr '-unreachable=false' + +# However, it should be enabled if requested explicitly. +go vet -n -unsafeptr runtime +stderr '-unsafeptr' +! stderr '-unsafeptr=false' + +# -unreachable is disabled during test but on during plain vet. +go test -n runtime +stderr '-unreachable=false' + +# A flag terminator should be allowed before the package list. +go vet -n -- . + +[short] stop + +# Analyzer flags should be included from GOFLAGS, and should override +# the defaults. +go vet . +env GOFLAGS='-tags=buggy' +! go vet . +stderr 'possible formatting directive' + +# Enabling one analyzer in GOFLAGS should disable the rest implicitly... +env GOFLAGS='-tags=buggy -unsafeptr' +go vet . + +# ...but enabling one on the command line should not disable the analyzers +# enabled via GOFLAGS. +env GOFLAGS='-tags=buggy -printf' +! go vet -unsafeptr +stderr 'possible formatting directive' + +# Analyzer flags don't exist unless we're running 'go vet', +# and we shouldn't run the vet tool to discover them otherwise. +# (Maybe someday we'll hard-code the analyzer flags for the default vet +# tool to make this work, but not right now.) +env GOFLAGS='-unsafeptr' +! go list . +stderr 'go: parsing \$GOFLAGS: unknown flag -unsafeptr' +env GOFLAGS= + +env GOCACHE=$WORK/gocache + +# "go test" on a user package should by default enable an explicit list of analyzers. +go test -x -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# An explicitly-empty -vet argument should imply the default analyzers. +go test -x -vet= -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# "go test" on a standard package should by default disable an explicit list. +go test -x -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +go test -x -vet= -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# Both should allow users to override via the -vet flag. +go test -x -vet=unreachable -run=none . +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +go test -x -vet=unreachable -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +-- go.mod -- +module example.com/x +-- x.go -- +package x +-- x_test.go -- +package x +-- x_tagged.go -- +// +build buggy + +package x + +import "fmt" + +func init() { + fmt.Sprint("%s") // oops! +} diff --git a/src/cmd/go/testdata/script/vet_internal.txt b/src/cmd/go/testdata/script/vet_internal.txt new file mode 100644 index 0000000..85f7093 --- /dev/null +++ b/src/cmd/go/testdata/script/vet_internal.txt @@ -0,0 +1,71 @@ +env GO111MODULE=off + +# Issue 36173. Verify that "go vet" prints line numbers on load errors. + +! go vet a/a.go +stderr '^package command-line-arguments\n\ta[/\\]a.go:5:3: use of internal package' + +! go vet a/a_test.go +stderr '^package command-line-arguments \(test\)\n\ta[/\\]a_test.go:4:3: use of internal package' + +! go vet a +stderr '^package a\n\ta[/\\]a.go:5:3: use of internal package' + +go vet b/b.go +! stderr 'use of internal package' + +! go vet b/b_test.go +stderr '^package command-line-arguments \(test\)\n\tb[/\\]b_test.go:4:3: use of internal package' + +! go vet depends-on-a/depends-on-a.go +stderr '^package command-line-arguments\n\timports a\n\ta[/\\]a.go:5:3: use of internal package' + +! go vet depends-on-a/depends-on-a_test.go +stderr '^package command-line-arguments \(test\)\n\timports a\n\ta[/\\]a.go:5:3: use of internal package a/x/internal/y not allowed' + +! go vet depends-on-a +stderr '^package depends-on-a\n\timports a\n\ta[/\\]a.go:5:3: use of internal package' + +-- a/a.go -- +// A package with bad imports in both src and test +package a + +import ( + _ "a/x/internal/y" +) + +-- a/a_test.go -- +package a + +import ( + _ "a/x/internal/y" +) + +-- b/b.go -- +// A package with a bad import in test only +package b + +-- b/b_test.go -- +package b + +import ( + _ "a/x/internal/y" +) + +-- depends-on-a/depends-on-a.go -- +// A package that depends on a package with a bad import +package depends + +import ( + _ "a" +) + +-- depends-on-a/depends-on-a_test.go -- +package depends + +import ( + _ "a" +) + +-- a/x/internal/y/y.go -- +package y diff --git a/src/cmd/go/testdata/script/work.txt b/src/cmd/go/testdata/script/work.txt new file mode 100644 index 0000000..fa1558f --- /dev/null +++ b/src/cmd/go/testdata/script/work.txt @@ -0,0 +1,151 @@ +! go work init doesnotexist +stderr 'go: creating workspace file: no go.mod file exists in directory doesnotexist' +go env GOWORK +! stdout . + +go work init ./a ./b +cmpenv go.work go.work.want +go env GOWORK +stdout '^'$WORK'(\\|/)gopath(\\|/)src(\\|/)go.work$' + +! go run example.com/b +stderr 'a(\\|/)a.go:4:8: no required module provides package rsc.io/quote; to add it:\n\tcd '$WORK(\\|/)gopath(\\|/)src(\\|/)a'\n\tgo get rsc.io/quote' +cd a +go get rsc.io/quote +go env GOMOD # go env GOMOD reports the module in a single module context +stdout $GOPATH(\\|/)src(\\|/)a(\\|/)go.mod +cd .. +go run example.com/b +stdout 'Hello, world.' + +# And try from a different directory +cd c +go run example.com/b +stdout 'Hello, world.' +cd $GOPATH/src + +go list all # all includes both modules +stdout 'example.com/a' +stdout 'example.com/b' + +# -mod can only be set to readonly in workspace mode +go list -mod=readonly all +! go list -mod=mod all +stderr '^go: -mod may only be set to readonly when in workspace mode' +env GOWORK=off +go list -mod=mod all +env GOWORK= + +# Test that duplicates in the use list return an error +cp go.work go.work.backup +cp go.work.dup go.work +! go run example.com/b +stderr 'reading go.work: path .* appears multiple times in workspace' +cp go.work.backup go.work + +cp go.work.d go.work +go run example.com/d + +# Test that we don't run into "newRequirements called with unsorted roots" +# panic with unsorted main modules. +cp go.work.backwards go.work +go run example.com/d + +# Test that command-line-arguments work inside and outside modules. +# This exercises the code that determines which module command-line-arguments +# belongs to. +go list ./b/main.go +env GOWORK=off +go build -n -o foo foo.go +env GOWORK= +go build -n -o foo foo.go + +-- go.work.dup -- +go 1.18 + +use ( + a + b + ../src/a +) +-- go.work.want -- +go $goversion + +use ( + ./a + ./b +) +-- go.work.d -- +go 1.18 + +use ( + a + b + d +) +-- a/go.mod -- + +module example.com/a + +-- a/a.go -- +package a + +import "fmt" +import "rsc.io/quote" + +func HelloFromA() { + fmt.Println(quote.Hello()) +} + +-- b/go.mod -- + +module example.com/b + +-- b/main.go -- +package main + +import "example.com/a" + +func main() { + a.HelloFromA() +} +-- b/lib/hello.go -- +package lib + +import "example.com/a" + +func Hello() { + a.HelloFromA() +} + +-- c/README -- +Create this directory so we can cd to +it and make sure paths are interpreted +relative to the go.work, not the cwd. +-- d/go.mod -- +module example.com/d + +-- d/main.go -- +package main + +import "example.com/b/lib" + +func main() { + lib.Hello() +} + +-- go.work.backwards -- +go 1.18 + +use ( + d + b + a +) + +-- foo.go -- +package main +import "fmt" +func main() { + fmt.Println("Hello, World") +} diff --git a/src/cmd/go/testdata/script/work_build_no_modules.txt b/src/cmd/go/testdata/script/work_build_no_modules.txt new file mode 100644 index 0000000..c9859b4 --- /dev/null +++ b/src/cmd/go/testdata/script/work_build_no_modules.txt @@ -0,0 +1,13 @@ +! go build . +stderr 'go: no modules were found in the current workspace; see ''go help work''' + +-- go.work -- +go 1.18 +-- go.mod -- +go 1.18 + +module foo +-- foo.go -- +package main + +func main() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_edit.txt b/src/cmd/go/testdata/script/work_edit.txt new file mode 100644 index 0000000..278afb7 --- /dev/null +++ b/src/cmd/go/testdata/script/work_edit.txt @@ -0,0 +1,162 @@ +# Test editing go.work files. + +go work init m +cmpenv go.work go.work.want_initial + +go work edit -use n +cmpenv go.work go.work.want_use_n + +go work edit -go 1.18 +cmp go.work go.work.want_go_118 + +go work edit -dropuse m +cmp go.work go.work.want_dropuse_m + +go work edit -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' +cmp go.work go.work.want_add_replaces + +go work edit -use n -use ../a -use /b -use c -use c +cmp go.work go.work.want_multiuse + +go work edit -dropuse /b -dropuse n +cmp go.work go.work.want_multidropuse + +go work edit -dropreplace='x.1@v1.4.0' +cmp go.work go.work.want_dropreplace + +go work edit -print -go 1.19 -use b -dropuse c -replace 'x.1@v1.4.0 = ../z' -dropreplace x.1 -dropreplace x.1@v1.3.0 +cmp stdout go.work.want_print + +go work edit -json -go 1.19 -use b -dropuse c -replace 'x.1@v1.4.0 = ../z' -dropreplace x.1 -dropreplace x.1@v1.3.0 +cmp stdout go.work.want_json + +env GOWORK=$GOPATH/src/unformatted +go work edit -print -fmt +cmp stdout formatted + +-- m/go.mod -- +module m + +go 1.18 +-- go.work.want_initial -- +go $goversion + +use ./m +-- go.work.want_use_n -- +go $goversion + +use ( + ./m + ./n +) +-- go.work.want_go_118 -- +go 1.18 + +use ( + ./m + ./n +) +-- go.work.want_dropuse_m -- +go 1.18 + +use ./n +-- go.work.want_add_replaces -- +go 1.18 + +use ./n + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +) +-- go.work.want_multiuse -- +go 1.18 + +use ( + ../a + ./c + ./n + /b +) + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +) +-- go.work.want_multidropuse -- +go 1.18 + +use ( + ../a + ./c +) + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +) +-- go.work.want_dropreplace -- +go 1.18 + +use ( + ../a + ./c +) + +replace x.1 v1.3.0 => y.1 v1.4.0 +-- go.work.want_print -- +go 1.19 + +use ( + ../a + ./b +) + +replace x.1 v1.4.0 => ../z +-- go.work.want_json -- +{ + "Go": "1.19", + "Use": [ + { + "DiskPath": "../a" + }, + { + "DiskPath": "./b" + } + ], + "Replace": [ + { + "Old": { + "Path": "x.1", + "Version": "v1.4.0" + }, + "New": { + "Path": "../z" + } + } + ] +} +-- unformatted -- +go 1.18 + use ( + a + b + c + ) + replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z + ) +-- formatted -- +go 1.18 + +use ( + a + b + c +) + +replace ( + x.1 v1.3.0 => y.1 v1.4.0 + x.1 v1.4.0 => ../z +)
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_env.txt b/src/cmd/go/testdata/script/work_env.txt new file mode 100644 index 0000000..511bb4e --- /dev/null +++ b/src/cmd/go/testdata/script/work_env.txt @@ -0,0 +1,28 @@ +go env GOWORK +stdout '^'$GOPATH'[\\/]src[\\/]go.work$' +go env +stdout '^(set )?GOWORK="?'$GOPATH'[\\/]src[\\/]go.work"?$' + +cd .. +go env GOWORK +! stdout . +go env +stdout 'GOWORK=("")?' + +cd src +go env GOWORK +stdout 'go.work' + +env GOWORK='off' +go env GOWORK +stdout 'off' + +! go env -w GOWORK=off +stderr '^go: GOWORK cannot be modified$' + +-- go.work -- +go 1.18 + +use a +-- a/go.mod -- +module example.com/a diff --git a/src/cmd/go/testdata/script/work_goproxy_off.txt b/src/cmd/go/testdata/script/work_goproxy_off.txt new file mode 100644 index 0000000..767040d --- /dev/null +++ b/src/cmd/go/testdata/script/work_goproxy_off.txt @@ -0,0 +1,59 @@ +go work init +go work use . ./sub + +# Verify that the go.mod files for both modules in the workspace are tidy, +# and add missing go.sum entries as needed. + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +cd sub +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig +cd .. + +go list -m all +stdout '^rsc\.io/quote v1\.5\.1$' +stdout '^rsc\.io/sampler v1\.3\.1$' + +# Now remove the module dependencies from the module cache. +# Because one module upgrades a transitive dependency needed by another, +# listing the modules in the workspace should error out. + +go clean -modcache +env GOPROXY=off +! go list -m all +stderr '^go: rsc.io/sampler@v1.3.0: module lookup disabled by GOPROXY=off$' + +-- example.go -- +package example + +import _ "rsc.io/sampler" +-- go.mod -- +module example + +go 1.18 + +require rsc.io/sampler v1.3.0 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- sub/go.mod -- +module example/sub + +go 1.18 + +require rsc.io/quote v1.5.1 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/sampler v1.3.1 // indirect +) +-- sub/sub.go -- +package example + +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/work_gowork.txt b/src/cmd/go/testdata/script/work_gowork.txt new file mode 100644 index 0000000..1cfbf0c --- /dev/null +++ b/src/cmd/go/testdata/script/work_gowork.txt @@ -0,0 +1,24 @@ +env GOWORK=stop.work +! go list a # require absolute path +! stderr panic +env GOWORK=doesnotexist +! go list a +! stderr panic + +env GOWORK=$GOPATH/src/stop.work +go list -n a +go build -n a +go test -n a + +-- stop.work -- +go 1.18 + +use ./a +-- a/a.go -- +package a +-- a/a_test.go -- +package a +-- a/go.mod -- +module a + +go 1.18
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_init_gowork.txt b/src/cmd/go/testdata/script/work_init_gowork.txt new file mode 100644 index 0000000..55ac99b --- /dev/null +++ b/src/cmd/go/testdata/script/work_init_gowork.txt @@ -0,0 +1,19 @@ +# Test that the GOWORK environment variable flag is used by go work init. + +! exists go.work +go work init +exists go.work + +env GOWORK=$GOPATH/src/foo/foo.work +! exists foo/foo.work +go work init +exists foo/foo.work + +env GOWORK= +cd foo/bar +! go work init +stderr 'already exists' + +# Create directories to make go.work files in. +-- foo/dummy.txt -- +-- foo/bar/dummy.txt -- diff --git a/src/cmd/go/testdata/script/work_init_path.txt b/src/cmd/go/testdata/script/work_init_path.txt new file mode 100644 index 0000000..e397788 --- /dev/null +++ b/src/cmd/go/testdata/script/work_init_path.txt @@ -0,0 +1,17 @@ +# Regression test for https://go.dev/issue/51448. +# 'go work init . foo/bar' should produce a go.work file +# with the same paths as 'go work init; go work use -r .'. + +go work init . foo/bar +mv go.work go.work.init + +go work init +go work use -r . +cmp go.work go.work.init + +-- go.mod -- +module example +go 1.18 +-- foo/bar/go.mod -- +module example +go 1.18 diff --git a/src/cmd/go/testdata/script/work_install_submodule.txt b/src/cmd/go/testdata/script/work_install_submodule.txt new file mode 100644 index 0000000..3d11717 --- /dev/null +++ b/src/cmd/go/testdata/script/work_install_submodule.txt @@ -0,0 +1,36 @@ +# This is a regression test for golang.org/issue/50036 +# Don't check sums for other modules in the workspace. + +cd m/sub +go install -n + +-- go.work -- +go 1.18 + +use ( + ./m + ./m/sub +) +-- m/go.mod -- +module example.com/m + +go 1.18 + +-- m/m.go -- +package m + +func M() {} +-- m/sub/go.mod -- +module example.com/m/sub + +go 1.18 + +require example.com/m v1.0.0 +-- m/sub/main.go -- +package main + +import "example.com/m" + +func main() { + m.M() +} diff --git a/src/cmd/go/testdata/script/work_issue51204.txt b/src/cmd/go/testdata/script/work_issue51204.txt new file mode 100644 index 0000000..d483002 --- /dev/null +++ b/src/cmd/go/testdata/script/work_issue51204.txt @@ -0,0 +1,57 @@ +go work sync + +go list -f '{{.Dir}}' example.com/test +stdout '^'$PWD${/}test'$' + +-- go.work -- +go 1.18 + +use ( + ./test2 + ./test2/sub +) +-- test/go.mod -- +module example.com/test + +go 1.18 +-- test/file.go -- +package test + +func DoSomething() { +} +-- test2/go.mod -- +module example.com/test2 + +go 1.18 + +replace example.com/test => ../test + +require example.com/test v0.0.0-00010101000000-000000000000 +-- test2/file.go -- +package test2 + +import ( + "example.com/test" +) + +func DoSomething() { + test.DoSomething() +} +-- test2/sub/go.mod -- +module example.com/test2/sub + +go 1.18 + +replace example.com/test => ../../test + +require example.com/test v0.0.0 +-- test2/sub/file.go -- +package test2 + +import ( + "example.com/test" +) + +func DoSomething() { + test.DoSomething() +} diff --git a/src/cmd/go/testdata/script/work_module_not_in_go_work.txt b/src/cmd/go/testdata/script/work_module_not_in_go_work.txt new file mode 100644 index 0000000..23d908c --- /dev/null +++ b/src/cmd/go/testdata/script/work_module_not_in_go_work.txt @@ -0,0 +1,25 @@ +# This is a regression test for issue #49632. +# The Go command should mention go.work if the user +# tries to load a local package that's in a module +# that's not in go.work and can't be resolved. + +! go list ./... +stderr 'pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies' + +! go list ./a +stderr 'directory a outside modules listed in go.work' + +-- go.work -- +go 1.18 + +use ./b +-- a/go.mod -- +module example.com/a + +go 1.18 +-- a/a.go -- +package a +-- b/go.mod -- +module example.com/b + +go 1.18 diff --git a/src/cmd/go/testdata/script/work_nowork.txt b/src/cmd/go/testdata/script/work_nowork.txt new file mode 100644 index 0000000..b4c9b1d --- /dev/null +++ b/src/cmd/go/testdata/script/work_nowork.txt @@ -0,0 +1,20 @@ +! go work use +stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$' + +! go work use . +stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$' + +! go work edit +stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$' + +! go work edit -go=1.18 +stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$' + +! go work sync +stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$' + +-- go.mod -- +module example +go 1.18 +-- README.txt -- +There is no go.work file here. diff --git a/src/cmd/go/testdata/script/work_prune.txt b/src/cmd/go/testdata/script/work_prune.txt new file mode 100644 index 0000000..7e2ae4e --- /dev/null +++ b/src/cmd/go/testdata/script/work_prune.txt @@ -0,0 +1,104 @@ +# This test makes sure workspace mode's handling of the module graph +# is compatible with module pruning. The graph we load from either of +# the workspace modules should be the same, even if their graphs +# don't overlap. +# +# This is the module graph in the test: +# +# example.com/a -> example.com/b v1.0.0 -> example.com/q v1.1.0 +# example.com/p -> example.com/q v1.0.0 +# +# If we didn't load the whole graph and didn't load the dependencies of b +# when loading p, we would end up loading q v1.0.0, rather than v1.1.0, +# which is selected by MVS. +# TODO(#48331): We currently load the wrong version of q. Fix this. + +go list -m -f '{{.Version}}' example.com/q +stdout '^v1.1.0$' + +-- go.work -- +go 1.18 + +use ( + ./a + ./p +) +-- a/go.mod -- +module example.com/a + +go 1.18 + +require example.com/b v1.0.0 + +replace example.com/b v1.0.0 => ../b +-- a/foo.go -- +package main + +import "example.com/b" + +func main() { + b.B() +} +-- b/go.mod -- +module example.com/b + +go 1.18 + +require example.com/q v1.1.0 + +replace example.com/q v1.0.0 => ../q1_0_0 +replace example.com/q v1.1.0 => ../q1_1_0 +-- b/b.go -- +package b + +func B() { +} +-- b/b_test.go -- +package b + +import "example.com/q" + +func TestB() { + q.PrintVersion() +} +-- p/go.mod -- +module example.com/p + +go 1.18 + +require example.com/q v1.0.0 + +replace example.com/q v1.0.0 => ../q1_0_0 +replace example.com/q v1.1.0 => ../q1_1_0 +-- p/main.go -- +package main + +import "example.com/q" + +func main() { + q.PrintVersion() +} +-- q1_0_0/go.mod -- +module example.com/q + +go 1.18 +-- q1_0_0/q.go -- +package q + +import "fmt" + +func PrintVersion() { + fmt.Println("version 1.0.0") +} +-- q1_1_0/go.mod -- +module example.com/q + +go 1.18 +-- q1_1_0/q.go -- +package q + +import "fmt" + +func PrintVersion() { + fmt.Println("version 1.1.0") +} diff --git a/src/cmd/go/testdata/script/work_prune_all.txt b/src/cmd/go/testdata/script/work_prune_all.txt new file mode 100644 index 0000000..a7ad9c0 --- /dev/null +++ b/src/cmd/go/testdata/script/work_prune_all.txt @@ -0,0 +1,176 @@ +# This test makes sure workspace mode's handling of the module graph +# is compatible with module pruning. The graph we load from either of +# the workspace modules should be the same, even if their graphs +# don't overlap. +# +# This is the module graph in the test: +# +# example.com/p -> example.com/q v1.0.0 +# example.com/a -> example.com/b v1.0.0 -> example.com/q v1.1.0 -> example.com/w v1.0.0 -> example.com/x v1.0.0 -> example.com/y v1.0.0 +# |-> example.com/z v1.0.0 |-> example.com/z v1.1.0 +# |-> example.com/q v1.0.5 -> example.com/r v1.0.0 +# If we didn't load the whole graph and didn't load the dependencies of b +# when loading p, we would end up loading q v1.0.0, rather than v1.1.0, +# which is selected by MVS. + +go list -m all +stdout 'example.com/w v1.0.0' +stdout 'example.com/q v1.1.0' +stdout 'example.com/z v1.1.0' +stdout 'example.com/x v1.0.0' +! stdout 'example.com/r' +! stdout 'example.com/y' + +-- go.work -- +go 1.18 + +use ( + ./a + ./p +) + +replace example.com/b v1.0.0 => ./b +replace example.com/q v1.0.0 => ./q1_0_0 +replace example.com/q v1.0.5 => ./q1_0_5 +replace example.com/q v1.1.0 => ./q1_1_0 +replace example.com/r v1.0.0 => ./r +replace example.com/w v1.0.0 => ./w +replace example.com/x v1.0.0 => ./x +replace example.com/y v1.0.0 => ./y +replace example.com/z v1.0.0 => ./z1_0_0 +replace example.com/z v1.1.0 => ./z1_1_0 + +-- a/go.mod -- +module example.com/a + +go 1.18 + +require example.com/b v1.0.0 +require example.com/z v1.0.0 +-- a/foo.go -- +package main + +import "example.com/b" + +func main() { + b.B() +} +-- b/go.mod -- +module example.com/b + +go 1.18 + +require example.com/q v1.1.0 +-- b/b.go -- +package b + +func B() { +} +-- p/go.mod -- +module example.com/p + +go 1.18 + +require example.com/q v1.0.0 + +replace example.com/q v1.0.0 => ../q1_0_0 +replace example.com/q v1.1.0 => ../q1_1_0 +-- p/main.go -- +package main + +import "example.com/q" + +func main() { + q.PrintVersion() +} +-- q1_0_0/go.mod -- +module example.com/q + +go 1.18 +-- q1_0_0/q.go -- +package q + +import "fmt" + +func PrintVersion() { + fmt.Println("version 1.0.0") +} +-- q1_0_5/go.mod -- +module example.com/q + +go 1.18 + +require example.com/r v1.0.0 +-- q1_0_5/q.go -- +package q + +import _ "example.com/r" +-- q1_1_0/go.mod -- +module example.com/q + +require example.com/w v1.0.0 +require example.com/z v1.1.0 + +go 1.18 +-- q1_1_0/q.go -- +package q + +import _ "example.com/w" +import _ "example.com/z" + +import "fmt" + +func PrintVersion() { + fmt.Println("version 1.1.0") +} +-- r/go.mod -- +module example.com/r + +go 1.18 + +require example.com/r v1.0.0 +-- r/r.go -- +package r +-- w/go.mod -- +module example.com/w + +go 1.18 + +require example.com/x v1.0.0 +-- w/w.go -- +package w +-- w/w_test.go -- +package w + +import _ "example.com/x" +-- x/go.mod -- +module example.com/x + +go 1.18 +-- x/x.go -- +package x +-- x/x_test.go -- +package x +import _ "example.com/y" +-- y/go.mod -- +module example.com/y + +go 1.18 +-- y/y.go -- +package y +-- z1_0_0/go.mod -- +module example.com/z + +go 1.18 + +require example.com/q v1.0.5 +-- z1_0_0/z.go -- +package z + +import _ "example.com/q" +-- z1_1_0/go.mod -- +module example.com/z + +go 1.18 +-- z1_1_0/z.go -- +package z diff --git a/src/cmd/go/testdata/script/work_regression_hang.txt b/src/cmd/go/testdata/script/work_regression_hang.txt new file mode 100644 index 0000000..a7661b6 --- /dev/null +++ b/src/cmd/go/testdata/script/work_regression_hang.txt @@ -0,0 +1,71 @@ +# This test makes checks against a regression of a bug in the Go command +# where the module loader hung forever because all main module dependencies +# kept workspace pruning instead of adopting the pruning in their go.mod +# files, and the loader kept adding dependencies on the queue until they +# were either pruned or unpruned, never breaking a module dependency cycle. +# +# This is the module graph in the test: +# +# /-------------------------\ +# | | +# V | +# example.com/a -> example.com/b v1.0.0 -> example.com/c v1.1.0 + +go list -m -f '{{.Version}}' example.com/c + +-- go.work -- +go 1.16 + +use ( + ./a +) +-- a/go.mod -- +module example.com/a + +go 1.18 + +require example.com/b v1.0.0 + +replace example.com/b v1.0.0 => ../b +replace example.com/c v1.0.0 => ../c +-- a/foo.go -- +package main + +import "example.com/b" + +func main() { + b.B() +} +-- b/go.mod -- +module example.com/b + +go 1.18 + +require example.com/c v1.0.0 +-- b/b.go -- +package b + +func B() { +} +-- b/cmd/main.go -- +package main + +import "example.com/c" + +func main() { + c.C() +} +-- c/go.mod -- +module example.com/c + +go 1.18 + +require example.com/b v1.0.0 +-- c/c.go -- +package c + +import "example.com/b" + +func C() { + b.B() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_replace.txt b/src/cmd/go/testdata/script/work_replace.txt new file mode 100644 index 0000000..81268e5 --- /dev/null +++ b/src/cmd/go/testdata/script/work_replace.txt @@ -0,0 +1,55 @@ +# Support replace statement in go.work file + +# Replacement in go.work file, and none in go.mod file. +go list -m example.com/dep +stdout 'example.com/dep v1.0.0 => ./dep' + +# Wildcard replacement in go.work file overrides version replacement in go.mod +# file. +go list -m example.com/other +stdout 'example.com/other v1.0.0 => ./other2' + +-- go.work -- +use m + +replace example.com/dep => ./dep +replace example.com/other => ./other2 + +-- m/go.mod -- +module example.com/m + +require example.com/dep v1.0.0 +require example.com/other v1.0.0 + +replace example.com/other v1.0.0 => ./other +-- m/m.go -- +package m + +import "example.com/dep" +import "example.com/other" + +func F() { + dep.G() + other.H() +} +-- dep/go.mod -- +module example.com/dep +-- dep/dep.go -- +package dep + +func G() { +} +-- other/go.mod -- +module example.com/other +-- other/dep.go -- +package other + +func G() { +} +-- other2/go.mod -- +module example.com/other +-- other2/dep.go -- +package other + +func G() { +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_replace_conflict.txt b/src/cmd/go/testdata/script/work_replace_conflict.txt new file mode 100644 index 0000000..7b71b0f --- /dev/null +++ b/src/cmd/go/testdata/script/work_replace_conflict.txt @@ -0,0 +1,53 @@ +# Conflicting replaces in workspace modules returns error that suggests +# overriding it in the go.work file. + +! go list -m example.com/dep +stderr 'go: conflicting replacements for example.com/dep@v1.0.0:\n\t'$PWD${/}'dep1\n\t'$PWD${/}'dep2\nuse "go work edit -replace example.com/dep@v1.0.0=\[override\]" to resolve' +go work edit -replace example.com/dep@v1.0.0=./dep1 +go list -m example.com/dep +stdout 'example.com/dep v1.0.0 => ./dep1' + +-- foo -- +-- go.work -- +use m +use n +-- m/go.mod -- +module example.com/m + +require example.com/dep v1.0.0 +replace example.com/dep v1.0.0 => ../dep1 +-- m/m.go -- +package m + +import "example.com/dep" + +func F() { + dep.G() +} +-- n/go.mod -- +module example.com/n + +require example.com/dep v1.0.0 +replace example.com/dep v1.0.0 => ../dep2 +-- n/n.go -- +package n + +import "example.com/dep" + +func F() { + dep.G() +} +-- dep1/go.mod -- +module example.com/dep +-- dep1/dep.go -- +package dep + +func G() { +} +-- dep2/go.mod -- +module example.com/dep +-- dep2/dep.go -- +package dep + +func G() { +} diff --git a/src/cmd/go/testdata/script/work_replace_conflict_override.txt b/src/cmd/go/testdata/script/work_replace_conflict_override.txt new file mode 100644 index 0000000..c62084b --- /dev/null +++ b/src/cmd/go/testdata/script/work_replace_conflict_override.txt @@ -0,0 +1,57 @@ +# Conflicting workspace module replaces can be overridden by a replace in the +# go.work file. + +go list -m example.com/dep +stdout 'example.com/dep v1.0.0 => ./dep3' + +-- go.work -- +use m +use n +replace example.com/dep => ./dep3 +-- m/go.mod -- +module example.com/m + +require example.com/dep v1.0.0 +replace example.com/dep => ./dep1 +-- m/m.go -- +package m + +import "example.com/dep" + +func F() { + dep.G() +} +-- n/go.mod -- +module example.com/n + +require example.com/dep v1.0.0 +replace example.com/dep => ./dep2 +-- n/n.go -- +package n + +import "example.com/dep" + +func F() { + dep.G() +} +-- dep1/go.mod -- +module example.com/dep +-- dep1/dep.go -- +package dep + +func G() { +} +-- dep2/go.mod -- +module example.com/dep +-- dep2/dep.go -- +package dep + +func G() { +} +-- dep3/go.mod -- +module example.com/dep +-- dep3/dep.go -- +package dep + +func G() { +} diff --git a/src/cmd/go/testdata/script/work_replace_main_module.txt b/src/cmd/go/testdata/script/work_replace_main_module.txt new file mode 100644 index 0000000..b213764 --- /dev/null +++ b/src/cmd/go/testdata/script/work_replace_main_module.txt @@ -0,0 +1,45 @@ +# Ensure that replaces of the main module in workspace modules +# are ignored, and replaces in the go.work file are disallowed. +# This tests against an issue where requirements of the +# main module were being ignored because the main module +# was replaced in a transitive dependency with another +# version. + +go list example.com/dep + +cp replace_main_module.go.work go.work +! go list example.com/dep +stderr 'go: workspace module example.com/mainmoda is replaced at all versions in the go.work file. To fix, remove the replacement from the go.work file or specify the version at which to replace the module.' + +-- replace_main_module.go.work -- +go 1.18 +use ( + ./mainmoda + ./mainmodb +) +replace example.com/mainmoda => ../mainmodareplacement +-- go.work -- +go 1.18 +use ( + ./mainmoda + ./mainmodb +) +-- mainmoda/go.mod -- +module example.com/mainmoda + +go 1.18 + +require example.com/dep v1.0.0 +replace example.com/dep => ../dep + +-- dep/go.mod -- +module example.com/dep +-- dep/dep.go -- +package dep +-- mainmodb/go.mod -- +module example.com/mainmodb +go 1.18 +replace example.com/mainmoda => ../mainmodareplacement +-- mainmodareplacement/go.mod -- +module example.com/mainmoda +go 1.18
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_sum.txt b/src/cmd/go/testdata/script/work_sum.txt new file mode 100644 index 0000000..19dbb90 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sum.txt @@ -0,0 +1,34 @@ +# Test adding sums to go.work.sum when sum isn't in go.mod. + +go run . +cmp go.work.sum want.sum + +-- want.sum -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:3fEykkD9k7lYzXqCYrwGAf7iNhbk4yCjHmKBN9td4L0= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +-- go.work -- +go 1.18 + +use . +-- go.mod -- +go 1.18 + +module example.com/hi + +require "rsc.io/quote" v1.5.2 +-- go.sum -- +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- main.go -- +package main + +import ( + "fmt" + "rsc.io/quote" +) + +func main() { + fmt.Println(quote.Hello()) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_sum_mismatch.txt b/src/cmd/go/testdata/script/work_sum_mismatch.txt new file mode 100644 index 0000000..9e94743 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sum_mismatch.txt @@ -0,0 +1,61 @@ +# Test mismatched sums in go.sum files + +! go run ./a +cmpenv stderr want-error + +-- want-error -- +verifying rsc.io/sampler@v1.3.0/go.mod: checksum mismatch + downloaded: h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= + $WORK${/}gopath${/}src${/}a${/}go.sum: h1:U1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= + +SECURITY ERROR +This download does NOT match an earlier download recorded in go.sum. +The bits may have been replaced on the origin server, or an attacker may +have intercepted the download attempt. + +For more information, see 'go help module-auth'. +-- go.work -- +go 1.18 + +use ./a +use ./b +-- a/go.mod -- +go 1.18 + +module example.com/hi + +require "rsc.io/quote" v1.5.2 +-- a/go.sum -- +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:U1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- a/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote" +) + +func main() { + fmt.Println(quote.Hello()) +} +-- b/go.mod -- +go 1.18 + +module example.com/hi + +require "rsc.io/quote" v1.5.2 +-- b/go.sum -- +rsc.io/sampler v1.3.0 h1:HLGR/BgEtI3r0uymSP/nl2uPLsUnNJX8toRyhfpBTII= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +-- b/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote" +) + +func main() { + fmt.Println(quote.Hello()) +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_sync.txt b/src/cmd/go/testdata/script/work_sync.txt new file mode 100644 index 0000000..69167d4 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sync.txt @@ -0,0 +1,119 @@ +go work sync +cmp a/go.mod a/want_go.mod +cmp b/go.mod b/want_go.mod + +-- go.work -- +go 1.18 + +use ( + ./a + ./b +) + +-- a/go.mod -- +go 1.18 + +module example.com/a + +require ( + example.com/p v1.0.0 + example.com/q v1.1.0 + example.com/r v1.0.0 +) + +replace ( + example.com/p => ../p + example.com/q => ../q + example.com/r => ../r +) +-- a/want_go.mod -- +go 1.18 + +module example.com/a + +require ( + example.com/p v1.1.0 + example.com/q v1.1.0 +) + +replace ( + example.com/p => ../p + example.com/q => ../q + example.com/r => ../r +) +-- a/a.go -- +package a + +import ( + "example.com/p" + "example.com/q" +) + +func Foo() { + p.P() + q.Q() +} +-- b/go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/p v1.1.0 + example.com/q v1.0.0 +) + +replace ( + example.com/p => ../p + example.com/q => ../q +) +-- b/want_go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/p v1.1.0 + example.com/q v1.1.0 +) + +replace ( + example.com/p => ../p + example.com/q => ../q +) +-- b/b.go -- +package b + +import ( + "example.com/p" + "example.com/q" +) + +func Foo() { + p.P() + q.Q() +} +-- p/go.mod -- +go 1.18 + +module example.com/p +-- p/p.go -- +package p + +func P() {} +-- q/go.mod -- +go 1.18 + +module example.com/q +-- q/q.go -- +package q + +func Q() {} +-- r/go.mod -- +go 1.18 + +module example.com/r +-- r/q.go -- +package r + +func R() {}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_sync_irrelevant_dependency.txt b/src/cmd/go/testdata/script/work_sync_irrelevant_dependency.txt new file mode 100644 index 0000000..072323d --- /dev/null +++ b/src/cmd/go/testdata/script/work_sync_irrelevant_dependency.txt @@ -0,0 +1,119 @@ +# Test of go work sync in a workspace in which some dependency needed by `a` +# appears at a lower version in the build list of `b`, but is not needed at all +# by `b` (so it should not be upgraded within b). +# +# a -> p 1.1 +# b -> q 1.0 -(through a test dependency)-> p 1.0 +go work sync +cmp a/go.mod a/want_go.mod +cmp b/go.mod b/want_go.mod + +-- go.work -- +go 1.18 + +use ( + ./a + ./b +) + +-- a/go.mod -- +go 1.18 + +module example.com/a + +require ( + example.com/p v1.1.0 +) + +replace ( + example.com/p => ../p +) +-- a/want_go.mod -- +go 1.18 + +module example.com/a + +require ( + example.com/p v1.1.0 +) + +replace ( + example.com/p => ../p +) +-- a/a.go -- +package a + +import ( + "example.com/p" +) + +func Foo() { + p.P() +} +-- b/go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/q v1.0.0 +) + +replace ( + example.com/q => ../q +) +-- b/want_go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/q v1.0.0 +) + +replace ( + example.com/q => ../q +) +-- b/b.go -- +package b + +import ( + "example.com/q" +) + +func Foo() { + q.Q() +} +-- p/go.mod -- +go 1.18 + +module example.com/p +-- p/p.go -- +package p + +func P() {} +-- q/go.mod -- +go 1.18 + +module example.com/q + +require ( + example.com/p v1.0.0 +) + +replace ( + example.com/p => ../p +) +-- q/q.go -- +package q + +func Q() { +} +-- q/q_test.go -- +package q + +import example.com/p + +func TestQ(t *testing.T) { + p.P() +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_sync_missing_module.txt b/src/cmd/go/testdata/script/work_sync_missing_module.txt new file mode 100644 index 0000000..0018c73 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sync_missing_module.txt @@ -0,0 +1,12 @@ +# Ensure go work sync works without any modules in go.work. +go work sync + +# Ensure go work sync works even without a go.mod file. +rm go.mod +go work sync + +-- go.work -- +go 1.18 +-- go.mod -- +go 1.18 +module foo diff --git a/src/cmd/go/testdata/script/work_sync_relevant_dependency.txt b/src/cmd/go/testdata/script/work_sync_relevant_dependency.txt new file mode 100644 index 0000000..d799702 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sync_relevant_dependency.txt @@ -0,0 +1,106 @@ +# Test of go work sync in a workspace in which some dependency in the build +# list of 'b' (but not otherwise needed by `b`, so not seen when lazy loading +# occurs) actually is relevant to `a`. +# +# a -> p 1.0 +# b -> q 1.1 -> p 1.1 +go work sync +cmp a/go.mod a/want_go.mod +cmp b/go.mod b/want_go.mod + +-- go.work -- +go 1.18 + +use ( + ./a + ./b +) + +-- a/go.mod -- +go 1.18 + +module example.com/a + +require ( + example.com/p v1.0.0 +) + +replace ( + example.com/p => ../p +) +-- a/want_go.mod -- +go 1.18 + +module example.com/a + +require example.com/p v1.1.0 + +replace example.com/p => ../p +-- a/a.go -- +package a + +import ( + "example.com/p" +) + +func Foo() { + p.P() +} +-- b/go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/q v1.1.0 +) + +replace ( + example.com/q => ../q +) +-- b/want_go.mod -- +go 1.18 + +module example.com/b + +require ( + example.com/q v1.1.0 +) + +replace ( + example.com/q => ../q +) +-- b/b.go -- +package b + +import ( + "example.com/q" +) + +func Foo() { + q.Q() +} +-- p/go.mod -- +go 1.18 + +module example.com/p +-- p/p.go -- +package p + +func P() {} +-- q/go.mod -- +go 1.18 + +module example.com/q + +require example.com/p v1.1.0 + +replace example.com/p => ../p +-- q/q.go -- +package q + +import example.com/p + +func Q() { + p.P() +} diff --git a/src/cmd/go/testdata/script/work_sync_sum.txt b/src/cmd/go/testdata/script/work_sync_sum.txt new file mode 100644 index 0000000..656fd31 --- /dev/null +++ b/src/cmd/go/testdata/script/work_sync_sum.txt @@ -0,0 +1,40 @@ +# Test that the sum file data state is properly reset between modules in +# go work sync so that the sum file that's written is correct. +# Exercises the fix to #50038. + +cp b/go.sum b/go.sum.want + +# As a sanity check, verify b/go.sum is tidy. +cd b +go mod tidy +cd .. +cmp b/go.sum b/go.sum.want + +# Run go work sync and verify it doesn't change b/go.sum. +go work sync +cmp b/go.sum b/go.sum.want + +-- b/go.sum -- +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= +-- go.work -- +go 1.18 +use ( + ./a + ./b +) +replace example.com/c => ./c +-- a/go.mod -- +module example.com/a +go 1.18 +require rsc.io/fortune v1.0.0 +-- a/a.go -- +package a +import "rsc.io/fortune" +-- b/go.mod -- +module example.com/b +go 1.18 +require rsc.io/quote v1.0.0 +-- b/b.go -- +package b +import _ "rsc.io/quote" diff --git a/src/cmd/go/testdata/script/work_use.txt b/src/cmd/go/testdata/script/work_use.txt new file mode 100644 index 0000000..12c8cec --- /dev/null +++ b/src/cmd/go/testdata/script/work_use.txt @@ -0,0 +1,32 @@ +go work use -r foo +cmp go.work go.want_work_r + +go work use other +cmp go.work go.want_work_other +-- go.work -- +go 1.18 + +use ( + foo + foo/bar // doesn't exist +) +-- go.want_work_r -- +go 1.18 + +use ( + ./foo + ./foo/bar/baz +) +-- go.want_work_other -- +go 1.18 + +use ( + ./foo + ./foo/bar/baz + ./other +) +-- foo/go.mod -- +module foo +-- foo/bar/baz/go.mod -- +module baz +-- other/go.mod -- diff --git a/src/cmd/go/testdata/script/work_use_deleted.txt b/src/cmd/go/testdata/script/work_use_deleted.txt new file mode 100644 index 0000000..b379cbc --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_deleted.txt @@ -0,0 +1,22 @@ +go work use -r . +cmp go.work go.work.want + +-- go.work -- +go 1.18 + +use ( + . + ./sub + ./sub/dir/deleted +) +-- go.work.want -- +go 1.18 + +use ./sub/dir +-- sub/README.txt -- +A go.mod file has been deleted from this directory. +In addition, the entire subdirectory sub/dir/deleted +has been deleted, along with sub/dir/deleted/go.mod. +-- sub/dir/go.mod -- +module example/sub/dir +go 1.18 diff --git a/src/cmd/go/testdata/script/work_use_dot.txt b/src/cmd/go/testdata/script/work_use_dot.txt new file mode 100644 index 0000000..8f21042 --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_dot.txt @@ -0,0 +1,49 @@ +cp go.work go.work.orig + +# If the current directory contains a go.mod file, +# 'go work use .' should add an entry for it. +cd bar/baz +go work use . +cmp ../../go.work ../../go.work.rel + +# If the current directory lacks a go.mod file, 'go work use .' +# should remove its entry. +mv go.mod go.mod.bak +go work use . +cmp ../../go.work ../../go.work.orig + +# If the path is absolute, it should remain absolute. +mv go.mod.bak go.mod +go work use $PWD +grep -count=1 '^use ' ../../go.work +grep '^use ["]?'$PWD'["]?$' ../../go.work + +# An absolute path should replace an entry for the corresponding relative path +# and vice-versa. +go work use . +cmp ../../go.work ../../go.work.rel +go work use $PWD +grep -count=1 '^use ' ../../go.work +grep '^use ["]?'$PWD'["]?$' ../../go.work + +# If both the absolute and relative paths are named, 'go work use' should error +# out: we don't know which one to use, and shouldn't add both because the +# resulting workspace would contain a duplicate module. +cp ../../go.work.orig ../../go.work +! go work use $PWD . +stderr '^go: already added "\./bar/baz" as "'$PWD'"$' +cmp ../../go.work ../../go.work.orig + + +-- go.mod -- +module example +go 1.18 +-- go.work -- +go 1.18 +-- go.work.rel -- +go 1.18 + +use ./bar/baz +-- bar/baz/go.mod -- +module example/bar/baz +go 1.18 diff --git a/src/cmd/go/testdata/script/work_use_issue50958.txt b/src/cmd/go/testdata/script/work_use_issue50958.txt new file mode 100644 index 0000000..7a25531 --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_issue50958.txt @@ -0,0 +1,17 @@ +go work use -r . +cmp go.work go.work.want + +-- go.mod -- +module example +go 1.18 +-- go.work -- +go 1.18 + +use sub +-- go.work.want -- +go 1.18 + +use . +-- sub/README.txt -- +This directory no longer contains a go.mod file. + diff --git a/src/cmd/go/testdata/script/work_use_noargs.txt b/src/cmd/go/testdata/script/work_use_noargs.txt new file mode 100644 index 0000000..ca05434 --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_noargs.txt @@ -0,0 +1,11 @@ +# For now, 'go work use' requires arguments. +# (Eventually, we may may it implicitly behave like 'go work use .'. + +! go work use +stderr '^go: ''go work use'' requires one or more directory arguments' + +! go work use -r +stderr '^go: ''go work use'' requires one or more directory arguments' + +-- go.work -- +go 1.18 diff --git a/src/cmd/go/testdata/script/work_use_only_dirs.txt b/src/cmd/go/testdata/script/work_use_only_dirs.txt new file mode 100644 index 0000000..aa6dd78 --- /dev/null +++ b/src/cmd/go/testdata/script/work_use_only_dirs.txt @@ -0,0 +1,17 @@ +! go work use foo bar baz + +stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]foo is not a directory' +stderr '^go: directory '$WORK'[/\\]gopath[/\\]src[/\\]baz does not exist' +cmp go.work go.work_want + +! go work use -r qux +stderr '^go: '$WORK'[/\\]gopath[/\\]src[/\\]qux is not a directory' + +-- go.work -- +go 1.18 +-- go.work_want -- +go 1.18 +-- foo -- +-- qux -- +-- bar/go.mod -- +module bar
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_vet.txt b/src/cmd/go/testdata/script/work_vet.txt new file mode 100644 index 0000000..e258fc0 --- /dev/null +++ b/src/cmd/go/testdata/script/work_vet.txt @@ -0,0 +1,19 @@ +! go vet ./a +stderr 'fmt.Println call has possible formatting directive' + +-- go.work -- +go 1.18 + +use ./a +-- a/go.mod -- +module example.com/a + +go 1.18 +-- a/a.go -- +package a + +import "fmt" + +func A() { + fmt.Println("%s") +}
\ No newline at end of file diff --git a/src/cmd/go/testdata/script/work_why_download_graph.txt b/src/cmd/go/testdata/script/work_why_download_graph.txt new file mode 100644 index 0000000..7964c91 --- /dev/null +++ b/src/cmd/go/testdata/script/work_why_download_graph.txt @@ -0,0 +1,59 @@ +# Test go mod download, why, and graph work in workspace mode. +# TODO(bcmills): clarify the interaction with #44435 + +go mod download rsc.io/quote +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod + +go mod download +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod + +go mod why rsc.io/quote +stdout '# rsc.io/quote\nexample.com/a\nrsc.io/quote' + +go mod graph +stdout 'example.com/a rsc.io/quote@v1.5.2\nexample.com/b example.com/c@v1.0.0\nrsc.io/quote@v1.5.2 rsc.io/sampler@v1.3.0\nrsc.io/sampler@v1.3.0 golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c' + +-- go.work -- +go 1.18 + +use ( + ./a + ./b +) +-- a/go.mod -- +go 1.18 + +module example.com/a + +require "rsc.io/quote" v1.5.2 +-- a/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote" +) + +func main() { + fmt.Println(quote.Hello()) +} +-- b/go.mod -- +go 1.18 + +module example.com/b + +require example.com/c v1.0.0 +replace example.com/c => ../c +-- c/go.mod -- +go 1.18 + +module example.com/c + diff --git a/src/cmd/go/testdata/testterminal18153/terminal_test.go b/src/cmd/go/testdata/testterminal18153/terminal_test.go new file mode 100644 index 0000000..34ee580 --- /dev/null +++ b/src/cmd/go/testdata/testterminal18153/terminal_test.go @@ -0,0 +1,40 @@ +// Copyright 2016 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. + +//go:build linux +// +build linux + +// This test is run by src/cmd/dist/test.go (cmd_go_test_terminal), +// and not by cmd/go's tests. This is because this test requires +// that it be called with its stdout and stderr being a terminal. +// dist doesn't run `cmd/go test` against this test directory if +// dist's stdout/stderr aren't terminals. +// +// See issue 18153. + +package p + +import ( + "syscall" + "testing" + "unsafe" +) + +const ioctlReadTermios = syscall.TCGETS + +// isTerminal reports whether fd is a terminal. +func isTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} + +func TestIsTerminal(t *testing.T) { + if !isTerminal(1) { + t.Errorf("stdout is not a terminal") + } + if !isTerminal(2) { + t.Errorf("stderr is not a terminal") + } +} diff --git a/src/cmd/go/testdata/vendormod.txt b/src/cmd/go/testdata/vendormod.txt new file mode 100644 index 0000000..1bdaf2a --- /dev/null +++ b/src/cmd/go/testdata/vendormod.txt @@ -0,0 +1,160 @@ +generated by: go run savedir.go vendormod + +-- a/foo/AUTHORS.txt -- +-- a/foo/CONTRIBUTORS -- +-- a/foo/LICENSE -- +-- a/foo/PATENTS -- +-- a/foo/COPYING -- +-- a/foo/COPYLEFT -- +-- a/foo/licensed-to-kill -- +-- w/LICENSE -- +-- x/NOTICE! -- +-- x/x2/LICENSE -- +-- mypkg/LICENSE.txt -- +-- a/foo/bar/b/main.go -- +package b +-- a/foo/bar/b/main_test.go -- +package b + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/main.go -- +package c +-- a/foo/bar/c/main_test.go -- +package c + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("../../../testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/foo/bar/c/testdata/1 -- +-- a/foo/bar/testdata/1 -- +-- a/go.mod -- +module a +-- a/main.go -- +package a +-- a/main_test.go -- +package a + +import ( + "os" + "testing" +) + +func TestDir(t *testing.T) { + if _, err := os.Stat("./testdata/1"); err != nil { + t.Fatalf("testdata: %v", err) + } +} +-- a/testdata/1 -- +-- appengine.go -- +// +build appengine + +package m + +import _ "appengine" +import _ "appengine/datastore" +-- go.mod -- +module m + +require ( + a v1.0.0 + mysite/myname/mypkg v1.0.0 + w v1.0.0 // indirect + x v1.0.0 + y v1.0.0 + z v1.0.0 +) + +replace ( + a v1.0.0 => ./a + mysite/myname/mypkg v1.0.0 => ./mypkg + w v1.0.0 => ./w + x v1.0.0 => ./x + y v1.0.0 => ./y + z v1.0.0 => ./z +) +-- mypkg/go.mod -- +module me +-- mypkg/mydir/d.go -- +package mydir +-- subdir/v1_test.go -- +package m + +import _ "mysite/myname/mypkg/mydir" +-- testdata1.go -- +package m + +import _ "a" +-- testdata2.go -- +package m + +import _ "a/foo/bar/b" +import _ "a/foo/bar/c" +-- v1.go -- +package m + +import _ "x" +-- v2.go -- +// +build abc + +package mMmMmMm + +import _ "y" +-- v3.go -- +// +build !abc + +package m + +import _ "z" +-- v4.go -- +// +build notmytag + +package m + +import _ "x/x1" +-- w/go.mod -- +module w +-- w/w.go -- +package w +-- x/go.mod -- +module x +-- x/testdata/x.txt -- +placeholder - want directory with no go files +-- x/x.go -- +package x +-- x/x1/x1.go -- +// +build notmytag + +package x1 +-- x/x2/dummy.txt -- +dummy +-- x/x_test.go -- +package x + +import _ "w" +-- y/go.mod -- +module y +-- y/y.go -- +package y +-- z/go.mod -- +module z +-- z/z.go -- +package z |