mirror of
https://github.com/golang/go
synced 2024-11-17 16:24:42 -07:00
cmd/go: add a "don't care about success" operator to script_test
Use that operator to make test_race_install_cgo agnostic to whether GOROOT/pkg is writable. Updates #37573 Updates #30316 Change-Id: I018c63b3c369209345069f917bbb3a52179e2b58 Reviewed-on: https://go-review.googlesource.com/c/go/+/223746 Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
0c0e8f224d
commit
42dfac6708
@ -82,9 +82,17 @@ type testScript struct {
|
|||||||
type backgroundCmd struct {
|
type backgroundCmd struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
wait <-chan struct{}
|
wait <-chan struct{}
|
||||||
neg bool // if true, cmd should fail
|
want simpleStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type simpleStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
success simpleStatus = ""
|
||||||
|
failure simpleStatus = "!"
|
||||||
|
successOrFailure simpleStatus = "?"
|
||||||
|
)
|
||||||
|
|
||||||
var extraEnvKeys = []string{
|
var extraEnvKeys = []string{
|
||||||
"SYSTEMROOT", // must be preserved on Windows to find DLLs; golang.org/issue/25210
|
"SYSTEMROOT", // must be preserved on Windows to find DLLs; golang.org/issue/25210
|
||||||
"WINDIR", // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711
|
"WINDIR", // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711
|
||||||
@ -206,7 +214,7 @@ func (ts *testScript) run() {
|
|||||||
// With -v or -testwork, start log with full environment.
|
// With -v or -testwork, start log with full environment.
|
||||||
if *testWork || testing.Verbose() {
|
if *testWork || testing.Verbose() {
|
||||||
// Display environment.
|
// Display environment.
|
||||||
ts.cmdEnv(false, nil)
|
ts.cmdEnv(success, nil)
|
||||||
fmt.Fprintf(&ts.log, "\n")
|
fmt.Fprintf(&ts.log, "\n")
|
||||||
ts.mark = ts.log.Len()
|
ts.mark = ts.log.Len()
|
||||||
}
|
}
|
||||||
@ -246,7 +254,7 @@ Script:
|
|||||||
// Parse input line. Ignore blanks entirely.
|
// Parse input line. Ignore blanks entirely.
|
||||||
parsed := ts.parse(line)
|
parsed := ts.parse(line)
|
||||||
if parsed.name == "" {
|
if parsed.name == "" {
|
||||||
if parsed.neg || len(parsed.conds) > 0 {
|
if parsed.want != "" || len(parsed.conds) > 0 {
|
||||||
ts.fatalf("missing command")
|
ts.fatalf("missing command")
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -325,7 +333,7 @@ Script:
|
|||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
ts.fatalf("unknown command %q", parsed.name)
|
ts.fatalf("unknown command %q", parsed.name)
|
||||||
}
|
}
|
||||||
cmd(ts, parsed.neg, parsed.args)
|
cmd(ts, parsed.want, parsed.args)
|
||||||
|
|
||||||
// Command can ask script to stop early.
|
// Command can ask script to stop early.
|
||||||
if ts.stopped {
|
if ts.stopped {
|
||||||
@ -338,7 +346,7 @@ Script:
|
|||||||
for _, bg := range ts.background {
|
for _, bg := range ts.background {
|
||||||
interruptProcess(bg.cmd.Process)
|
interruptProcess(bg.cmd.Process)
|
||||||
}
|
}
|
||||||
ts.cmdWait(false, nil)
|
ts.cmdWait(success, nil)
|
||||||
|
|
||||||
// Final phase ended.
|
// Final phase ended.
|
||||||
rewind()
|
rewind()
|
||||||
@ -353,7 +361,7 @@ Script:
|
|||||||
//
|
//
|
||||||
// NOTE: If you make changes here, update testdata/script/README too!
|
// NOTE: If you make changes here, update testdata/script/README too!
|
||||||
//
|
//
|
||||||
var scriptCmds = map[string]func(*testScript, bool, []string){
|
var scriptCmds = map[string]func(*testScript, simpleStatus, []string){
|
||||||
"addcrlf": (*testScript).cmdAddcrlf,
|
"addcrlf": (*testScript).cmdAddcrlf,
|
||||||
"cc": (*testScript).cmdCc,
|
"cc": (*testScript).cmdCc,
|
||||||
"cd": (*testScript).cmdCd,
|
"cd": (*testScript).cmdCd,
|
||||||
@ -386,7 +394,7 @@ var regexpCmd = map[string]bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addcrlf adds CRLF line endings to the named files.
|
// addcrlf adds CRLF line endings to the named files.
|
||||||
func (ts *testScript) cmdAddcrlf(neg bool, args []string) {
|
func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ts.fatalf("usage: addcrlf file...")
|
ts.fatalf("usage: addcrlf file...")
|
||||||
}
|
}
|
||||||
@ -400,21 +408,21 @@ func (ts *testScript) cmdAddcrlf(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cc runs the C compiler along with platform specific options.
|
// cc runs the C compiler along with platform specific options.
|
||||||
func (ts *testScript) cmdCc(neg bool, args []string) {
|
func (ts *testScript) cmdCc(want simpleStatus, args []string) {
|
||||||
if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
|
if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
|
||||||
ts.fatalf("usage: cc args... [&]")
|
ts.fatalf("usage: cc args... [&]")
|
||||||
}
|
}
|
||||||
|
|
||||||
var b work.Builder
|
var b work.Builder
|
||||||
b.Init()
|
b.Init()
|
||||||
ts.cmdExec(neg, append(b.GccCmd(".", ""), args...))
|
ts.cmdExec(want, append(b.GccCmd(".", ""), args...))
|
||||||
robustio.RemoveAll(b.WorkDir)
|
robustio.RemoveAll(b.WorkDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cd changes to a different directory.
|
// cd changes to a different directory.
|
||||||
func (ts *testScript) cmdCd(neg bool, args []string) {
|
func (ts *testScript) cmdCd(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! cd")
|
ts.fatalf("unsupported: %v cd", want)
|
||||||
}
|
}
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
ts.fatalf("usage: cd dir")
|
ts.fatalf("usage: cd dir")
|
||||||
@ -438,9 +446,9 @@ func (ts *testScript) cmdCd(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// chmod changes permissions for a file or directory.
|
// chmod changes permissions for a file or directory.
|
||||||
func (ts *testScript) cmdChmod(neg bool, args []string) {
|
func (ts *testScript) cmdChmod(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! chmod")
|
ts.fatalf("unsupported: %v chmod", want)
|
||||||
}
|
}
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ts.fatalf("usage: chmod perm paths...")
|
ts.fatalf("usage: chmod perm paths...")
|
||||||
@ -460,10 +468,10 @@ func (ts *testScript) cmdChmod(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cmp compares two files.
|
// cmp compares two files.
|
||||||
func (ts *testScript) cmdCmp(neg bool, args []string) {
|
func (ts *testScript) cmdCmp(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
// It would be strange to say "this file can have any content except this precise byte sequence".
|
// It would be strange to say "this file can have any content except this precise byte sequence".
|
||||||
ts.fatalf("unsupported: ! cmp")
|
ts.fatalf("unsupported: %v cmp", want)
|
||||||
}
|
}
|
||||||
quiet := false
|
quiet := false
|
||||||
if len(args) > 0 && args[0] == "-q" {
|
if len(args) > 0 && args[0] == "-q" {
|
||||||
@ -477,9 +485,9 @@ func (ts *testScript) cmdCmp(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cmpenv compares two files with environment variable substitution.
|
// cmpenv compares two files with environment variable substitution.
|
||||||
func (ts *testScript) cmdCmpenv(neg bool, args []string) {
|
func (ts *testScript) cmdCmpenv(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! cmpenv")
|
ts.fatalf("unsupported: %v cmpenv", want)
|
||||||
}
|
}
|
||||||
quiet := false
|
quiet := false
|
||||||
if len(args) > 0 && args[0] == "-q" {
|
if len(args) > 0 && args[0] == "-q" {
|
||||||
@ -525,7 +533,7 @@ func (ts *testScript) doCmdCmp(args []string, env, quiet bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cp copies files, maybe eventually directories.
|
// cp copies files, maybe eventually directories.
|
||||||
func (ts *testScript) cmdCp(neg bool, args []string) {
|
func (ts *testScript) cmdCp(want simpleStatus, args []string) {
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ts.fatalf("usage: cp src... dst")
|
ts.fatalf("usage: cp src... dst")
|
||||||
}
|
}
|
||||||
@ -565,20 +573,21 @@ func (ts *testScript) cmdCp(neg bool, args []string) {
|
|||||||
targ = filepath.Join(dst, filepath.Base(src))
|
targ = filepath.Join(dst, filepath.Base(src))
|
||||||
}
|
}
|
||||||
err := ioutil.WriteFile(targ, data, mode)
|
err := ioutil.WriteFile(targ, data, mode)
|
||||||
if neg {
|
switch want {
|
||||||
|
case failure:
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ts.fatalf("unexpected command success")
|
ts.fatalf("unexpected command success")
|
||||||
}
|
}
|
||||||
} else {
|
case success:
|
||||||
ts.check(err)
|
ts.check(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// env displays or adds to the environment.
|
// env displays or adds to the environment.
|
||||||
func (ts *testScript) cmdEnv(neg bool, args []string) {
|
func (ts *testScript) cmdEnv(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! env")
|
ts.fatalf("unsupported: %v env", want)
|
||||||
}
|
}
|
||||||
|
|
||||||
conv := func(s string) string { return s }
|
conv := func(s string) string { return s }
|
||||||
@ -616,7 +625,7 @@ func (ts *testScript) cmdEnv(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// exec runs the given command.
|
// exec runs the given command.
|
||||||
func (ts *testScript) cmdExec(neg bool, args []string) {
|
func (ts *testScript) cmdExec(want simpleStatus, args []string) {
|
||||||
if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
|
if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
|
||||||
ts.fatalf("usage: exec program [args...] [&]")
|
ts.fatalf("usage: exec program [args...] [&]")
|
||||||
}
|
}
|
||||||
@ -631,7 +640,7 @@ func (ts *testScript) cmdExec(neg bool, args []string) {
|
|||||||
ctxWait(testCtx, cmd)
|
ctxWait(testCtx, cmd)
|
||||||
close(wait)
|
close(wait)
|
||||||
}()
|
}()
|
||||||
ts.background = append(ts.background, backgroundCmd{cmd, wait, neg})
|
ts.background = append(ts.background, backgroundCmd{cmd, wait, want})
|
||||||
}
|
}
|
||||||
ts.stdout, ts.stderr = "", ""
|
ts.stdout, ts.stderr = "", ""
|
||||||
} else {
|
} else {
|
||||||
@ -642,7 +651,7 @@ func (ts *testScript) cmdExec(neg bool, args []string) {
|
|||||||
if ts.stderr != "" {
|
if ts.stderr != "" {
|
||||||
fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
|
fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
|
||||||
}
|
}
|
||||||
if err == nil && neg {
|
if err == nil && want == failure {
|
||||||
ts.fatalf("unexpected command success")
|
ts.fatalf("unexpected command success")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -651,14 +660,17 @@ func (ts *testScript) cmdExec(neg bool, args []string) {
|
|||||||
fmt.Fprintf(&ts.log, "[%v]\n", err)
|
fmt.Fprintf(&ts.log, "[%v]\n", err)
|
||||||
if testCtx.Err() != nil {
|
if testCtx.Err() != nil {
|
||||||
ts.fatalf("test timed out while running command")
|
ts.fatalf("test timed out while running command")
|
||||||
} else if !neg {
|
} else if want == success {
|
||||||
ts.fatalf("unexpected command failure")
|
ts.fatalf("unexpected command failure")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// exists checks that the list of files exists.
|
// exists checks that the list of files exists.
|
||||||
func (ts *testScript) cmdExists(neg bool, args []string) {
|
func (ts *testScript) cmdExists(want simpleStatus, args []string) {
|
||||||
|
if want == successOrFailure {
|
||||||
|
ts.fatalf("unsupported: %v exists", want)
|
||||||
|
}
|
||||||
var readonly, exec bool
|
var readonly, exec bool
|
||||||
loop:
|
loop:
|
||||||
for len(args) > 0 {
|
for len(args) > 0 {
|
||||||
@ -680,34 +692,34 @@ loop:
|
|||||||
for _, file := range args {
|
for _, file := range args {
|
||||||
file = ts.mkabs(file)
|
file = ts.mkabs(file)
|
||||||
info, err := os.Stat(file)
|
info, err := os.Stat(file)
|
||||||
if err == nil && neg {
|
if err == nil && want == failure {
|
||||||
what := "file"
|
what := "file"
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
what = "directory"
|
what = "directory"
|
||||||
}
|
}
|
||||||
ts.fatalf("%s %s unexpectedly exists", what, file)
|
ts.fatalf("%s %s unexpectedly exists", what, file)
|
||||||
}
|
}
|
||||||
if err != nil && !neg {
|
if err != nil && want == success {
|
||||||
ts.fatalf("%s does not exist", file)
|
ts.fatalf("%s does not exist", file)
|
||||||
}
|
}
|
||||||
if err == nil && !neg && readonly && info.Mode()&0222 != 0 {
|
if err == nil && want == success && readonly && info.Mode()&0222 != 0 {
|
||||||
ts.fatalf("%s exists but is writable", file)
|
ts.fatalf("%s exists but is writable", file)
|
||||||
}
|
}
|
||||||
if err == nil && !neg && exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
|
if err == nil && want == success && exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
|
||||||
ts.fatalf("%s exists but is not executable", file)
|
ts.fatalf("%s exists but is not executable", file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// go runs the go command.
|
// go runs the go command.
|
||||||
func (ts *testScript) cmdGo(neg bool, args []string) {
|
func (ts *testScript) cmdGo(want simpleStatus, args []string) {
|
||||||
ts.cmdExec(neg, append([]string{testGo}, args...))
|
ts.cmdExec(want, append([]string{testGo}, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdir creates directories.
|
// mkdir creates directories.
|
||||||
func (ts *testScript) cmdMkdir(neg bool, args []string) {
|
func (ts *testScript) cmdMkdir(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! mkdir")
|
ts.fatalf("unsupported: %v mkdir", want)
|
||||||
}
|
}
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
ts.fatalf("usage: mkdir dir...")
|
ts.fatalf("usage: mkdir dir...")
|
||||||
@ -718,9 +730,9 @@ func (ts *testScript) cmdMkdir(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rm removes files or directories.
|
// rm removes files or directories.
|
||||||
func (ts *testScript) cmdRm(neg bool, args []string) {
|
func (ts *testScript) cmdRm(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! rm")
|
ts.fatalf("unsupported: %v rm", want)
|
||||||
}
|
}
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
ts.fatalf("usage: rm file...")
|
ts.fatalf("usage: rm file...")
|
||||||
@ -733,12 +745,12 @@ func (ts *testScript) cmdRm(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// skip marks the test skipped.
|
// skip marks the test skipped.
|
||||||
func (ts *testScript) cmdSkip(neg bool, args []string) {
|
func (ts *testScript) cmdSkip(want simpleStatus, args []string) {
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
ts.fatalf("usage: skip [msg]")
|
ts.fatalf("usage: skip [msg]")
|
||||||
}
|
}
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! skip")
|
ts.fatalf("unsupported: %v skip", want)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before we mark the test as skipped, shut down any background processes and
|
// Before we mark the test as skipped, shut down any background processes and
|
||||||
@ -746,7 +758,7 @@ func (ts *testScript) cmdSkip(neg bool, args []string) {
|
|||||||
for _, bg := range ts.background {
|
for _, bg := range ts.background {
|
||||||
interruptProcess(bg.cmd.Process)
|
interruptProcess(bg.cmd.Process)
|
||||||
}
|
}
|
||||||
ts.cmdWait(false, nil)
|
ts.cmdWait(success, nil)
|
||||||
|
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
ts.t.Skip(args[0])
|
ts.t.Skip(args[0])
|
||||||
@ -755,15 +767,18 @@ func (ts *testScript) cmdSkip(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stale checks that the named build targets are stale.
|
// stale checks that the named build targets are stale.
|
||||||
func (ts *testScript) cmdStale(neg bool, args []string) {
|
func (ts *testScript) cmdStale(want simpleStatus, args []string) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ts.fatalf("usage: stale target...")
|
ts.fatalf("usage: stale target...")
|
||||||
}
|
}
|
||||||
tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}"
|
tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}"
|
||||||
if neg {
|
switch want {
|
||||||
|
case failure:
|
||||||
tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale{{end}}"
|
tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale{{end}}"
|
||||||
} else {
|
case success:
|
||||||
tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}"
|
tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}"
|
||||||
|
default:
|
||||||
|
ts.fatalf("unsupported: %v stale", want)
|
||||||
}
|
}
|
||||||
tmpl += "{{end}}"
|
tmpl += "{{end}}"
|
||||||
goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...)
|
goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...)
|
||||||
@ -777,26 +792,30 @@ func (ts *testScript) cmdStale(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stdout checks that the last go command standard output matches a regexp.
|
// stdout checks that the last go command standard output matches a regexp.
|
||||||
func (ts *testScript) cmdStdout(neg bool, args []string) {
|
func (ts *testScript) cmdStdout(want simpleStatus, args []string) {
|
||||||
scriptMatch(ts, neg, args, ts.stdout, "stdout")
|
scriptMatch(ts, want, args, ts.stdout, "stdout")
|
||||||
}
|
}
|
||||||
|
|
||||||
// stderr checks that the last go command standard output matches a regexp.
|
// stderr checks that the last go command standard output matches a regexp.
|
||||||
func (ts *testScript) cmdStderr(neg bool, args []string) {
|
func (ts *testScript) cmdStderr(want simpleStatus, args []string) {
|
||||||
scriptMatch(ts, neg, args, ts.stderr, "stderr")
|
scriptMatch(ts, want, args, ts.stderr, "stderr")
|
||||||
}
|
}
|
||||||
|
|
||||||
// grep checks that file content matches a regexp.
|
// grep checks that file content matches a regexp.
|
||||||
// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
|
// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
|
||||||
func (ts *testScript) cmdGrep(neg bool, args []string) {
|
func (ts *testScript) cmdGrep(want simpleStatus, args []string) {
|
||||||
scriptMatch(ts, neg, args, "", "grep")
|
scriptMatch(ts, want, args, "", "grep")
|
||||||
}
|
}
|
||||||
|
|
||||||
// scriptMatch implements both stdout and stderr.
|
// scriptMatch implements both stdout and stderr.
|
||||||
func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name string) {
|
||||||
|
if want == successOrFailure {
|
||||||
|
ts.fatalf("unsupported: %v %s", want, name)
|
||||||
|
}
|
||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
|
if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
|
||||||
if neg {
|
if want == failure {
|
||||||
ts.fatalf("cannot use -count= with negated match")
|
ts.fatalf("cannot use -count= with negated match")
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
@ -816,12 +835,12 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extraUsage := ""
|
extraUsage := ""
|
||||||
want := 1
|
wantArgs := 1
|
||||||
if name == "grep" {
|
if name == "grep" {
|
||||||
extraUsage = " file"
|
extraUsage = " file"
|
||||||
want = 2
|
wantArgs = 2
|
||||||
}
|
}
|
||||||
if len(args) != want {
|
if len(args) != wantArgs {
|
||||||
ts.fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage)
|
ts.fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,14 +861,16 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
|||||||
// Matching against workdir would be misleading.
|
// Matching against workdir would be misleading.
|
||||||
text = strings.ReplaceAll(text, ts.workdir, "$WORK")
|
text = strings.ReplaceAll(text, ts.workdir, "$WORK")
|
||||||
|
|
||||||
if neg {
|
switch want {
|
||||||
|
case failure:
|
||||||
if re.MatchString(text) {
|
if re.MatchString(text) {
|
||||||
if isGrep && !quiet {
|
if isGrep && !quiet {
|
||||||
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
||||||
}
|
}
|
||||||
ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text))
|
ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
case success:
|
||||||
if !re.MatchString(text) {
|
if !re.MatchString(text) {
|
||||||
if isGrep && !quiet {
|
if isGrep && !quiet {
|
||||||
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
|
||||||
@ -869,9 +890,9 @@ func scriptMatch(ts *testScript, neg bool, args []string, text, name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop stops execution of the test (marking it passed).
|
// stop stops execution of the test (marking it passed).
|
||||||
func (ts *testScript) cmdStop(neg bool, args []string) {
|
func (ts *testScript) cmdStop(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! stop")
|
ts.fatalf("unsupported: %v stop", want)
|
||||||
}
|
}
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
ts.fatalf("usage: stop [msg]")
|
ts.fatalf("usage: stop [msg]")
|
||||||
@ -885,9 +906,9 @@ func (ts *testScript) cmdStop(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// symlink creates a symbolic link.
|
// symlink creates a symbolic link.
|
||||||
func (ts *testScript) cmdSymlink(neg bool, args []string) {
|
func (ts *testScript) cmdSymlink(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! symlink")
|
ts.fatalf("unsupported: %v symlink", want)
|
||||||
}
|
}
|
||||||
if len(args) != 3 || args[1] != "->" {
|
if len(args) != 3 || args[1] != "->" {
|
||||||
ts.fatalf("usage: symlink file -> target")
|
ts.fatalf("usage: symlink file -> target")
|
||||||
@ -898,9 +919,9 @@ func (ts *testScript) cmdSymlink(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wait waits for background commands to exit, setting stderr and stdout to their result.
|
// wait waits for background commands to exit, setting stderr and stdout to their result.
|
||||||
func (ts *testScript) cmdWait(neg bool, args []string) {
|
func (ts *testScript) cmdWait(want simpleStatus, args []string) {
|
||||||
if neg {
|
if want != success {
|
||||||
ts.fatalf("unsupported: ! wait")
|
ts.fatalf("unsupported: %v wait", want)
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
ts.fatalf("usage: wait")
|
ts.fatalf("usage: wait")
|
||||||
@ -926,13 +947,13 @@ func (ts *testScript) cmdWait(neg bool, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if bg.cmd.ProcessState.Success() {
|
if bg.cmd.ProcessState.Success() {
|
||||||
if bg.neg {
|
if bg.want == failure {
|
||||||
ts.fatalf("unexpected command success")
|
ts.fatalf("unexpected command success")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if testCtx.Err() != nil {
|
if testCtx.Err() != nil {
|
||||||
ts.fatalf("test timed out while running command")
|
ts.fatalf("test timed out while running command")
|
||||||
} else if !bg.neg {
|
} else if bg.want == success {
|
||||||
ts.fatalf("unexpected command failure")
|
ts.fatalf("unexpected command failure")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1057,7 +1078,7 @@ type condition struct {
|
|||||||
|
|
||||||
// A command is a complete command parsed from a script.
|
// A command is a complete command parsed from a script.
|
||||||
type command struct {
|
type command struct {
|
||||||
neg bool // if true, expect the command to fail
|
want simpleStatus
|
||||||
conds []condition // all must be satisfied
|
conds []condition // all must be satisfied
|
||||||
name string // the name of the command; must be non-empty
|
name string // the name of the command; must be non-empty
|
||||||
args []string // shell-expanded arguments following name
|
args []string // shell-expanded arguments following name
|
||||||
@ -1092,11 +1113,13 @@ func (ts *testScript) parse(line string) command {
|
|||||||
|
|
||||||
// Command prefix ! means negate the expectations about this command:
|
// Command prefix ! means negate the expectations about this command:
|
||||||
// go command should fail, match should not be found, etc.
|
// go command should fail, match should not be found, etc.
|
||||||
if arg == "!" {
|
// Prefix ? means allow either success or failure.
|
||||||
if cmd.neg {
|
switch want := simpleStatus(arg); want {
|
||||||
ts.fatalf("duplicated '!' token")
|
case failure, successOrFailure:
|
||||||
|
if cmd.want != "" {
|
||||||
|
ts.fatalf("duplicated '!' or '?' token")
|
||||||
}
|
}
|
||||||
cmd.neg = true
|
cmd.want = want
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/cmd/go/testdata/script/README
vendored
12
src/cmd/go/testdata/script/README
vendored
@ -66,6 +66,10 @@ 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
|
(typically go or a matching predicate) must fail, not succeed. Only certain
|
||||||
commands support this prefix. They are indicated below by [!] in the synopsis.
|
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
|
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:
|
should only run when the condition is satisfied. The available conditions are:
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ are satisfied.
|
|||||||
|
|
||||||
The commands are:
|
The commands are:
|
||||||
|
|
||||||
- [!] cc args... [&]
|
- [! | ?] cc args... [&]
|
||||||
Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be
|
Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be
|
||||||
added automatically before args.
|
added automatically before args.
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ The commands are:
|
|||||||
Like cmp, but environment variables are substituted in the file contents
|
Like cmp, but environment variables are substituted in the file contents
|
||||||
before the comparison. For example, $GOOS is replaced by the target GOOS.
|
before the comparison. For example, $GOOS is replaced by the target GOOS.
|
||||||
|
|
||||||
- [!] cp src... dst
|
- [! | ?] cp src... dst
|
||||||
Copy the listed files to the target file or existing directory.
|
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
|
src can include "stdout" or "stderr" to use the standard output or standard error
|
||||||
from the most recent exec or go command.
|
from the most recent exec or go command.
|
||||||
@ -123,7 +127,7 @@ The commands are:
|
|||||||
The -r flag causes the values to be escaped using regexp.QuoteMeta
|
The -r flag causes the values to be escaped using regexp.QuoteMeta
|
||||||
before being recorded.
|
before being recorded.
|
||||||
|
|
||||||
- [!] exec program [args...] [&]
|
- [! | ?] exec program [args...] [&]
|
||||||
Run the given executable program with the arguments.
|
Run the given executable program with the arguments.
|
||||||
It must (or must not) succeed.
|
It must (or must not) succeed.
|
||||||
Note that 'exec' does not terminate the script (unlike in Unix shells).
|
Note that 'exec' does not terminate the script (unlike in Unix shells).
|
||||||
@ -140,7 +144,7 @@ The commands are:
|
|||||||
If -readonly is given, the files or directories must be unwritable.
|
If -readonly is given, the files or directories must be unwritable.
|
||||||
If -exec is given, the files or directories must be executable.
|
If -exec is given, the files or directories must be executable.
|
||||||
|
|
||||||
- [!] go args... [&]
|
- [! | ?] go args... [&]
|
||||||
Run the (test copy of the) go command with the given arguments.
|
Run the (test copy of the) go command with the given arguments.
|
||||||
It must (or must not) succeed.
|
It must (or must not) succeed.
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
[!race] skip
|
[!race] skip
|
||||||
|
|
||||||
|
! stale cmd/cgo
|
||||||
|
|
||||||
env GOBIN=$WORK/bin
|
env GOBIN=$WORK/bin
|
||||||
go install mtime sametime
|
go install mtime sametime
|
||||||
|
|
||||||
@ -11,11 +13,9 @@ exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopa
|
|||||||
cp stdout cgotime_before.txt
|
cp stdout cgotime_before.txt
|
||||||
|
|
||||||
# For this test, we don't actually care whether 'go test -race -i' succeeds.
|
# For this test, we don't actually care whether 'go test -race -i' succeeds.
|
||||||
# It may fail, for example, if GOROOT was installed from source as root and
|
# It may fail if GOROOT is read-only (perhaps it was installed as root).
|
||||||
# is now read-only.
|
# We only care that it does not overwrite cmd/cgo regardless.
|
||||||
# We only care that — regardless of whether it succeeds — it does not
|
? go test -race -i runtime/race
|
||||||
# overwrite cmd/cgo.
|
|
||||||
go test -race -i runtime/race
|
|
||||||
|
|
||||||
exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt
|
exec $GOBIN/mtime cgopath.txt # get the mtime of the file whose name is in cgopath.txt
|
||||||
cp stdout cgotime_after.txt
|
cp stdout cgotime_after.txt
|
||||||
@ -88,4 +88,4 @@ func main() {
|
|||||||
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)
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user