// Copyright 2015 The Vanadium 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 gosh_test

// TODO(sadovsky): Add more tests:
// - effects of Shell.Cleanup
// - Shell.{Vars,Args,Rename,MakeTempFile,MakeTempDir}
// - Shell.Opts.{PropagateChildOutput,ChildOutputDir,BinDir}
// - Cmd.Clone
// - Cmd.Opts.{IgnoreParentExit,ExitAfter,PropagateOutput}

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/signal"
	"path/filepath"
	"reflect"
	"runtime/debug"
	"strings"
	"testing"
	"time"

	"v.io/x/lib/gosh"
	lib "v.io/x/lib/gosh/internal/gosh_example_lib"
)

var fakeError = errors.New("fake error")

func fatal(t *testing.T, v ...interface{}) {
	debug.PrintStack()
	t.Fatal(v...)
}

func fatalf(t *testing.T, format string, v ...interface{}) {
	debug.PrintStack()
	t.Fatalf(format, v...)
}

func ok(t *testing.T, err error) {
	if err != nil {
		fatal(t, err)
	}
}

func nok(t *testing.T, err error) {
	if err == nil {
		fatal(t, "nil err")
	}
}

func eq(t *testing.T, got, want interface{}) {
	if !reflect.DeepEqual(got, want) {
		fatalf(t, "got %v, want %v", got, want)
	}
}

func neq(t *testing.T, got, notWant interface{}) {
	if reflect.DeepEqual(got, notWant) {
		fatalf(t, "got %v", got)
	}
}

func toString(t *testing.T, r io.Reader) string {
	b, err := ioutil.ReadAll(r)
	ok(t, err)
	return string(b)
}

func makeFatalf(t *testing.T) func(string, ...interface{}) {
	return func(format string, v ...interface{}) {
		debug.PrintStack()
		t.Fatalf(format, v...)
	}
}

func setsErr(t *testing.T, sh *gosh.Shell, f func()) {
	calledFatalf := false
	sh.Opts.Fatalf = func(string, ...interface{}) { calledFatalf = true }
	f()
	nok(t, sh.Err)
	eq(t, calledFatalf, true)
	sh.Err = nil
	sh.Opts.Fatalf = makeFatalf(t)
}

////////////////////////////////////////
// Simple functions

// Simplified versions of various Unix commands.
var (
	catFunc = gosh.RegisterFunc("catFunc", func() error {
		_, err := io.Copy(os.Stdout, os.Stdin)
		return err
	})
	echoFunc = gosh.RegisterFunc("echoFunc", func() error {
		_, err := fmt.Println(os.Args[1])
		return err
	})
	readFunc = gosh.RegisterFunc("readFunc", func() {
		bufio.NewReader(os.Stdin).ReadString('\n')
	})
)

// Functions with parameters.
var (
	exitFunc = gosh.RegisterFunc("exitFunc", func(code int) {
		os.Exit(code)
	})
	sleepFunc = gosh.RegisterFunc("sleepFunc", func(d time.Duration, code int) {
		// For TestSignal and TestTerminate.
		ch := make(chan os.Signal, 1)
		signal.Notify(ch, os.Interrupt)
		go func() {
			<-ch
			os.Exit(0)
		}()
		// The parent waits for this "ready" notification to avoid the race where a
		// signal is sent before the handler is installed.
		gosh.SendVars(map[string]string{"ready": ""})
		time.Sleep(d)
		os.Exit(code)
	})
	printFunc = gosh.RegisterFunc("printFunc", func(v ...interface{}) {
		fmt.Print(v...)
	})
	printfFunc = gosh.RegisterFunc("printfFunc", func(format string, v ...interface{}) {
		fmt.Printf(format, v...)
	})
)

////////////////////////////////////////
// Tests

func TestCustomFatalf(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	var calledFatalf bool
	sh.Opts.Fatalf = func(string, ...interface{}) { calledFatalf = true }
	sh.HandleError(fakeError)
	// Note, our deferred sh.Cleanup() should succeed despite this error.
	nok(t, sh.Err)
	eq(t, calledFatalf, true)
}

func TestPushdPopd(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	startDir, err := os.Getwd()
	ok(t, err)
	parentDir := filepath.Dir(startDir)
	neq(t, startDir, parentDir)
	sh.Pushd(parentDir)
	cwd, err := os.Getwd()
	ok(t, err)
	eq(t, cwd, parentDir)
	sh.Pushd(startDir)
	cwd, err = os.Getwd()
	ok(t, err)
	eq(t, cwd, startDir)
	sh.Popd()
	cwd, err = os.Getwd()
	ok(t, err)
	eq(t, cwd, parentDir)
	sh.Popd()
	cwd, err = os.Getwd()
	ok(t, err)
	eq(t, cwd, startDir)
	// The next sh.Popd() will fail.
	setsErr(t, sh, func() { sh.Popd() })
}

func evalSymlinks(t *testing.T, dir string) string {
	var err error
	dir, err = filepath.EvalSymlinks(dir)
	ok(t, err)
	return dir
}

func getwdEvalSymlinks(t *testing.T) string {
	dir, err := os.Getwd()
	ok(t, err)
	return evalSymlinks(t, dir)
}

func TestPushdNoPopdCleanup(t *testing.T) {
	startDir := getwdEvalSymlinks(t)
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	tmpDir := sh.MakeTempDir()
	sh.Pushd(tmpDir)
	eq(t, getwdEvalSymlinks(t), evalSymlinks(t, tmpDir))
	// There is no matching popd; the cwd is tmpDir, which is deleted by Cleanup.
	// Cleanup needs to put us back in startDir, otherwise all subsequent Pushd
	// calls will fail.
	sh.Cleanup()
	eq(t, getwdEvalSymlinks(t), startDir)
}

// Mirrors ExampleCmd in internal/gosh_example/main.go.
func TestCmd(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Start server.
	binPath := sh.BuildGoPkg("v.io/x/lib/gosh/internal/gosh_example_server")
	c := sh.Cmd(binPath)
	c.Start()
	addr := c.AwaitVars("addr")["addr"]
	neq(t, addr, "")

	// Run client.
	binPath = sh.BuildGoPkg("v.io/x/lib/gosh/internal/gosh_example_client")
	c = sh.Cmd(binPath, "-addr="+addr)
	eq(t, c.Stdout(), "Hello, world!\n")
}

var (
	getFunc   = gosh.RegisterFunc("getFunc", lib.Get)
	serveFunc = gosh.RegisterFunc("serveFunc", lib.Serve)
)

// Mirrors ExampleFuncCmd in internal/gosh_example/main.go.
func TestFuncCmd(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Start server.
	c := sh.FuncCmd(serveFunc)
	c.Start()
	addr := c.AwaitVars("addr")["addr"]
	neq(t, addr, "")

	// Run client.
	c = sh.FuncCmd(getFunc, addr)
	eq(t, c.Stdout(), "Hello, world!\n")
}

// Tests that BuildGoPkg works even when the -o flag is passed.
// TODO(sadovsky): Add tests for (1) missing name after -o, (2) multiple
// instances of -o, (3) using --o instead of -o, and perhaps other cases as
// well.
func TestBuildGoPkg(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	tempDir := sh.MakeTempDir()
	absName := filepath.Join(tempDir, "hw")
	sh.BuildGoPkg("v.io/x/lib/gosh/internal/hello_world", "-o", absName)
	c := sh.Cmd(absName)
	eq(t, c.Stdout(), "Hello, world!\n")

	absName = filepath.Join(sh.Opts.BinDir, "hw")
	sh.BuildGoPkg("v.io/x/lib/gosh/internal/hello_world", "-o", "hw")
	c = sh.Cmd(absName)
	eq(t, c.Stdout(), "Hello, world!\n")
}

// Tests that Shell.Cmd uses Shell.Vars["PATH"] to locate executables with
// relative names.
func TestLookPath(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	tempDir := sh.MakeTempDir()
	sh.Vars["PATH"] += ":" + tempDir
	absName, relName := filepath.Join(tempDir, "hw"), "hw"
	sh.BuildGoPkg("v.io/x/lib/gosh/internal/hello_world", "-o", absName)
	c := sh.Cmd(relName)
	eq(t, c.Stdout(), "Hello, world!\n")

	// Test the case where we cannot find the executable.
	sh.Vars["PATH"] = ""
	setsErr(t, sh, func() { sh.Cmd("yes") })
}

var (
	sendVarsFunc = gosh.RegisterFunc("sendVarsFunc", func(vars map[string]string) {
		gosh.SendVars(vars)
		time.Sleep(time.Hour)
	})
	stderrFunc = gosh.RegisterFunc("stderrFunc", func(s string) {
		fmt.Fprintf(os.Stderr, s)
		time.Sleep(time.Hour)
	})
)

// Tests that AwaitVars works under various conditions.
func TestAwaitVars(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	c := sh.FuncCmd(sendVarsFunc, map[string]string{"a": "1"})
	c.Start()
	eq(t, c.AwaitVars("a")["a"], "1")

	c = sh.FuncCmd(stderrFunc, `<goshVars{"a":"1","b":"2"}goshVars>`)
	c.Start()
	vars := c.AwaitVars("a", "b")
	eq(t, vars["a"], "1")
	eq(t, vars["b"], "2")

	c = sh.FuncCmd(stderrFunc, `<goshVars{"a":"1"}goshVars><gosh`)
	c.Start()
	eq(t, c.AwaitVars("a")["a"], "1")

	c = sh.FuncCmd(stderrFunc, `<goshVars{"a":"1"}goshVars><goshVars{"b":"2"}goshVars>`)
	c.Start()
	vars = c.AwaitVars("a", "b")
	eq(t, vars["a"], "1")
	eq(t, vars["b"], "2")

	c = sh.FuncCmd(stderrFunc, `<goshVars{"a":"1","b":"2"}goshVars>`)
	c.Start()
	vars = c.AwaitVars("a")
	eq(t, vars["a"], "1")
	eq(t, vars["b"], "")
	vars = c.AwaitVars("b")
	eq(t, vars["a"], "")
	eq(t, vars["b"], "2")

	c = sh.FuncCmd(stderrFunc, `<g<goshVars{"a":"goshVars"}goshVars>s><goshVars`)
	c.Start()
	eq(t, c.AwaitVars("a")["a"], "goshVars")

	c = sh.FuncCmd(stderrFunc, `<<goshVars{"a":"1"}goshVars>><<goshVars{"b":"<goshVars"}goshVars>>`)
	c.Start()
	vars = c.AwaitVars("a", "b")
	eq(t, vars["a"], "1")
	eq(t, vars["b"], "<goshVars")
}

// Tests that AwaitVars returns immediately when the process exits.
func TestAwaitProcessExit(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	c := sh.FuncCmd(exitFunc, 0)
	c.Start()
	setsErr(t, sh, func() { c.AwaitVars("foo") })
}

// Functions designed for TestRegistry.
var (
	printIntsFunc = gosh.RegisterFunc("printIntsFunc", func(v ...int) {
		var vi []interface{}
		for _, x := range v {
			vi = append(vi, x)
		}
		fmt.Print(vi...)
	})
	printfIntsFunc = gosh.RegisterFunc("printfIntsFunc", func(format string, v ...int) {
		var vi []interface{}
		for _, x := range v {
			vi = append(vi, x)
		}
		fmt.Printf(format, vi...)
	})
)

// Tests function signature-checking and execution.
func TestRegistry(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Variadic functions. Non-variadic functions are sufficiently covered in
	// other tests.
	eq(t, sh.FuncCmd(printFunc).Stdout(), "")
	eq(t, sh.FuncCmd(printFunc, 0).Stdout(), "0")
	eq(t, sh.FuncCmd(printFunc, 0, "foo").Stdout(), "0foo")
	eq(t, sh.FuncCmd(printfFunc, "").Stdout(), "")
	eq(t, sh.FuncCmd(printfFunc, "%v", 0).Stdout(), "0")
	eq(t, sh.FuncCmd(printfFunc, "%v%v", 0, "foo").Stdout(), "0foo")
	eq(t, sh.FuncCmd(printIntsFunc, 1, 2).Stdout(), "1 2")
	eq(t, sh.FuncCmd(printfIntsFunc, "%v %v", 1, 2).Stdout(), "1 2")

	// Too few arguments.
	setsErr(t, sh, func() { sh.FuncCmd(exitFunc) })
	setsErr(t, sh, func() { sh.FuncCmd(sleepFunc, time.Second) })
	setsErr(t, sh, func() { sh.FuncCmd(printfFunc) })

	// Too many arguments.
	setsErr(t, sh, func() { sh.FuncCmd(exitFunc, 0, 0) })
	setsErr(t, sh, func() { sh.FuncCmd(sleepFunc, time.Second, 0, 0) })

	// Wrong argument types.
	setsErr(t, sh, func() { sh.FuncCmd(exitFunc, "foo") })
	setsErr(t, sh, func() { sh.FuncCmd(sleepFunc, 0, 0) })
	setsErr(t, sh, func() { sh.FuncCmd(printfFunc, 0) })
	setsErr(t, sh, func() { sh.FuncCmd(printfFunc, 0, 0) })

	// Wrong variadic argument types.
	setsErr(t, sh, func() { sh.FuncCmd(printIntsFunc, 0.5) })
	setsErr(t, sh, func() { sh.FuncCmd(printIntsFunc, 0, 0.5) })
	setsErr(t, sh, func() { sh.FuncCmd(printfIntsFunc, "%v", 0.5) })
	setsErr(t, sh, func() { sh.FuncCmd(printfIntsFunc, "%v", 0, 0.5) })

	// Unsupported argument types.
	var p *int
	setsErr(t, sh, func() { sh.FuncCmd(printFunc, p) })
	setsErr(t, sh, func() { sh.FuncCmd(printfFunc, "%v", p) })
}

func TestStdin(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// The "cat" command exits after the reader returns EOF.
	c := sh.FuncCmd(catFunc)
	c.SetStdinReader(strings.NewReader("foo\n"))
	eq(t, c.Stdout(), "foo\n")

	// The "cat" command exits after the reader returns EOF, so we must explicitly
	// close the stdin pipe.
	c = sh.FuncCmd(catFunc)
	stdin := c.StdinPipe()
	stdin.Write([]byte("foo\n"))
	stdin.Close()
	eq(t, c.Stdout(), "foo\n")

	// The "read" command exits when it sees a newline, so it is not necessary to
	// explicitly close the stdin pipe.
	c = sh.FuncCmd(readFunc)
	stdin = c.StdinPipe()
	stdin.Write([]byte("foo\n"))
	c.Run()

	// No stdin, so cat should exit immediately.
	c = sh.FuncCmd(catFunc)
	eq(t, c.Stdout(), "")

	// It's an error to call both StdinPipe and SetStdinReader.
	c = sh.FuncCmd(catFunc)
	c.StdinPipe()
	setsErr(t, sh, func() { c.StdinPipe() })

	c = sh.FuncCmd(catFunc)
	c.StdinPipe()
	setsErr(t, sh, func() { c.SetStdinReader(strings.NewReader("")) })

	c = sh.FuncCmd(catFunc)
	c.SetStdinReader(strings.NewReader(""))
	setsErr(t, sh, func() { c.StdinPipe() })

	c = sh.FuncCmd(catFunc)
	c.SetStdinReader(strings.NewReader(""))
	setsErr(t, sh, func() { c.SetStdinReader(strings.NewReader("")) })
}

func TestStdinPipeWriteUntilExit(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Ensure that Write calls on stdin fail after the process exits. Note that we
	// write to the command's stdin concurrently with the command's exit waiter
	// goroutine closing stdin. Use "go test -race" catch races.
	//
	// Set a non-zero exit code, so that os.Exit exits immediately.  See the
	// implementation of https://golang.org/pkg/os/#Exit for details.
	c := sh.FuncCmd(exitFunc, 1)
	c.ExitErrorIsOk = true
	stdin := c.StdinPipe()
	c.Start()
	for {
		if _, err := stdin.Write([]byte("a")); err != nil {
			return
		}
	}
}

var writeFunc = gosh.RegisterFunc("writeFunc", func(stdout, stderr bool) error {
	if stdout {
		if _, err := os.Stdout.Write([]byte("A")); err != nil {
			return err
		}
	}
	if stderr {
		if _, err := os.Stderr.Write([]byte("B")); err != nil {
			return err
		}
	}
	if stdout {
		if _, err := os.Stdout.Write([]byte("A")); err != nil {
			return err
		}
	}
	if stderr {
		if _, err := os.Stderr.Write([]byte("B")); err != nil {
			return err
		}
	}
	return nil
})

func TestStdoutStderr(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Write to stdout only.
	c := sh.FuncCmd(writeFunc, true, false)
	stdoutPipe, stderrPipe := c.StdoutPipe(), c.StderrPipe()
	stdout, stderr := c.StdoutStderr()
	eq(t, stdout, "AA")
	eq(t, stderr, "")
	eq(t, toString(t, stdoutPipe), "AA")
	eq(t, toString(t, stderrPipe), "")

	// Write to stderr only.
	c = sh.FuncCmd(writeFunc, false, true)
	stdoutPipe, stderrPipe = c.StdoutPipe(), c.StderrPipe()
	stdout, stderr = c.StdoutStderr()
	eq(t, stdout, "")
	eq(t, stderr, "BB")
	eq(t, toString(t, stdoutPipe), "")
	eq(t, toString(t, stderrPipe), "BB")

	// Write to both stdout and stderr.
	c = sh.FuncCmd(writeFunc, true, true)
	stdoutPipe, stderrPipe = c.StdoutPipe(), c.StderrPipe()
	stdout, stderr = c.StdoutStderr()
	eq(t, stdout, "AA")
	eq(t, stderr, "BB")
	eq(t, toString(t, stdoutPipe), "AA")
	eq(t, toString(t, stderrPipe), "BB")
}

var writeMoreFunc = gosh.RegisterFunc("writeMoreFunc", func() {
	sh := gosh.NewShell(gosh.Opts{})
	defer sh.Cleanup()

	c := sh.FuncCmd(writeFunc, true, true)
	c.AddStdoutWriter(os.Stdout)
	c.AddStderrWriter(os.Stderr)
	c.Run()

	fmt.Fprint(os.Stdout, " stdout done")
	fmt.Fprint(os.Stderr, " stderr done")
})

// Tests that it's safe to add os.Stdout and os.Stderr as writers.
func TestAddStdoutStderrWriter(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	stdout, stderr := sh.FuncCmd(writeMoreFunc).StdoutStderr()
	eq(t, stdout, "AA stdout done")
	eq(t, stderr, "BB stderr done")
}

func TestCombinedOutput(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	c := sh.FuncCmd(writeFunc, true, true)
	buf := &bytes.Buffer{}
	c.AddStdoutWriter(buf)
	c.AddStderrWriter(buf)
	output := c.CombinedOutput()
	// Note, we can't assume any particular ordering of stdout and stderr, so we
	// simply check the length of the combined output.
	eq(t, len(output), 4)
	// The ordering must be the same, regardless of how we captured the combined
	// output.
	eq(t, output, buf.String())
}

func TestOutputDir(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	dir := sh.MakeTempDir()
	c := sh.FuncCmd(writeFunc, true, true)
	c.OutputDir = dir
	c.Run()

	matches, err := filepath.Glob(filepath.Join(dir, "*.stdout"))
	ok(t, err)
	eq(t, len(matches), 1)
	stdout, err := ioutil.ReadFile(matches[0])
	ok(t, err)
	eq(t, string(stdout), "AA")

	matches, err = filepath.Glob(filepath.Join(dir, "*.stderr"))
	ok(t, err)
	eq(t, len(matches), 1)
	stderr, err := ioutil.ReadFile(matches[0])
	ok(t, err)
	eq(t, string(stderr), "BB")
}

var replaceFunc = gosh.RegisterFunc("replaceFunc", func(old, new byte) error {
	buf := make([]byte, 1024)
	for {
		n, err := os.Stdin.Read(buf)
		switch {
		case err == io.EOF:
			return nil
		case err != nil:
			return err
		}
		rep := bytes.Replace(buf[:n], []byte{old}, []byte{new}, -1)
		if _, err := os.Stdout.Write(rep); err != nil {
			return err
		}
	}
})

func TestSignal(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	for _, d := range []time.Duration{0, time.Hour} {
		for _, s := range []os.Signal{os.Interrupt, os.Kill} {
			fmt.Println(d, s)
			c := sh.FuncCmd(sleepFunc, d, 0)
			c.Start()
			c.AwaitVars("ready")
			// Wait for a bit to allow the zero-sleep commands to exit.
			time.Sleep(100 * time.Millisecond)
			c.Signal(s)
			switch {
			case s == os.Interrupt:
				// Wait should succeed as long as the exit code was 0, regardless of
				// whether the signal arrived or the process had already exited.
				c.Wait()
			case d != 0:
				// Note: We don't call Wait in the {d: 0, s: os.Kill} case because doing
				// so makes the test flaky on slow systems.
				setsErr(t, sh, func() { c.Wait() })
			}
		}
	}

	// Signal should fail if Wait has been called.
	c := sh.FuncCmd(sleepFunc, time.Duration(0), 0)
	c.Run()
	setsErr(t, sh, func() { c.Signal(os.Interrupt) })
}

func TestTerminate(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	for _, d := range []time.Duration{0, time.Hour} {
		for _, s := range []os.Signal{os.Interrupt, os.Kill} {
			fmt.Println(d, s)
			c := sh.FuncCmd(sleepFunc, d, 0)
			c.Start()
			c.AwaitVars("ready")
			// Wait for a bit to allow the zero-sleep commands to exit.
			time.Sleep(100 * time.Millisecond)
			// Terminate should succeed regardless of the exit code, and regardless of
			// whether the signal arrived or the process had already exited.
			c.Terminate(s)
		}
	}

	// Terminate should fail if Wait has been called.
	c := sh.FuncCmd(sleepFunc, time.Duration(0), 0)
	c.Run()
	setsErr(t, sh, func() { c.Terminate(os.Interrupt) })
}

func TestShellWait(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	d0 := time.Duration(0)
	d200 := 200 * time.Millisecond

	c0 := sh.FuncCmd(sleepFunc, d0, 0)   // not started
	c1 := sh.Cmd("/#invalid#/!binary!")  // failed to start
	c2 := sh.FuncCmd(sleepFunc, d200, 0) // running and will succeed
	c3 := sh.FuncCmd(sleepFunc, d200, 1) // running and will fail
	c4 := sh.FuncCmd(sleepFunc, d0, 0)   // succeeded
	c5 := sh.FuncCmd(sleepFunc, d0, 0)   // succeeded, called wait
	c6 := sh.FuncCmd(sleepFunc, d0, 1)   // failed
	c7 := sh.FuncCmd(sleepFunc, d0, 1)   // failed, called wait

	c3.ExitErrorIsOk = true
	c6.ExitErrorIsOk = true
	c7.ExitErrorIsOk = true

	// Make sure c1 fails to start. This indirectly tests that Shell.Cleanup works
	// even if Cmd.Start failed.
	setsErr(t, sh, c1.Start)

	// Start commands, then wait for them to exit.
	for _, c := range []*gosh.Cmd{c2, c3, c4, c5, c6, c7} {
		c.Start()
	}
	// Wait for a bit to allow the zero-sleep commands to exit.
	time.Sleep(100 * time.Millisecond)
	c5.Wait()
	c7.Wait()
	sh.Wait()

	// It should be possible to run existing unstarted commands, and to create and
	// run new commands, after calling Shell.Wait.
	c0.Run()
	sh.FuncCmd(sleepFunc, d0, 0).Run()
	sh.FuncCmd(sleepFunc, d0, 0).Start()

	// Call Shell.Wait again.
	sh.Wait()
}

func TestExitErrorIsOk(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Exit code 0 is not an error.
	c := sh.FuncCmd(exitFunc, 0)
	c.Run()
	ok(t, c.Err)
	ok(t, sh.Err)

	// Exit code 1 is an error.
	c = sh.FuncCmd(exitFunc, 1)
	c.ExitErrorIsOk = true
	c.Run()
	nok(t, c.Err)
	ok(t, sh.Err)

	// If ExitErrorIsOk is false, exit code 1 triggers sh.HandleError.
	c = sh.FuncCmd(exitFunc, 1)
	setsErr(t, sh, func() { c.Run() })
	nok(t, c.Err)
}

func TestIgnoreClosedPipeError(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	defer sh.Cleanup()

	// Since writeLoopFunc will only finish if it receives a write error, it's
	// depending on the closed pipe error from closedPipeErrorWriter.
	c := sh.FuncCmd(writeLoopFunc)
	c.AddStdoutWriter(errorWriter{io.ErrClosedPipe})
	c.IgnoreClosedPipeError = true
	c.Run()
	ok(t, c.Err)
	ok(t, sh.Err)

	// Without IgnoreClosedPipeError, the command fails.
	c = sh.FuncCmd(writeLoopFunc)
	c.AddStdoutWriter(errorWriter{io.ErrClosedPipe})
	setsErr(t, sh, func() { c.Run() })
	nok(t, c.Err)
}

var writeLoopFunc = gosh.RegisterFunc("writeLoopFunc", func() error {
	for {
		if _, err := os.Stdout.Write([]byte("a\n")); err != nil {
			// Always return success; the purpose of this command is to ensure that
			// when the next command in the pipeline fails, it causes a closed pipe
			// write error here to exit the loop.
			return nil
		}
	}
})

type errorWriter struct {
	error
}

func (w errorWriter) Write(p []byte) (int, error) {
	return 0, w.error
}

// Tests that sh.Ok panics under various conditions.
func TestOkPanics(t *testing.T) {
	func() { // errDidNotCallNewShell
		sh := gosh.Shell{}
		defer func() { neq(t, recover(), nil) }()
		sh.Ok()
	}()
	func() { // errShellErrIsNotNil
		sh := gosh.NewShell(gosh.Opts{Fatalf: t.Logf})
		defer sh.Cleanup()
		sh.Err = fakeError
		defer func() { neq(t, recover(), nil) }()
		sh.Ok()
	}()
	func() { // errAlreadyCalledCleanup
		sh := gosh.NewShell(gosh.Opts{Fatalf: t.Logf})
		sh.Cleanup()
		defer func() { neq(t, recover(), nil) }()
		sh.Ok()
	}()
}

// Tests that sh.HandleError panics under various conditions.
func TestHandleErrorPanics(t *testing.T) {
	func() { // errDidNotCallNewShell
		sh := gosh.Shell{}
		defer func() { neq(t, recover(), nil) }()
		sh.HandleError(fakeError)
	}()
	func() { // errShellErrIsNotNil
		sh := gosh.NewShell(gosh.Opts{Fatalf: t.Logf})
		defer sh.Cleanup()
		sh.Err = fakeError
		defer func() { neq(t, recover(), nil) }()
		sh.HandleError(fakeError)
	}()
	func() { // errAlreadyCalledCleanup
		sh := gosh.NewShell(gosh.Opts{Fatalf: t.Logf})
		sh.Cleanup()
		defer func() { neq(t, recover(), nil) }()
		sh.HandleError(fakeError)
	}()
}

// Tests that sh.Cleanup panics under various conditions.
func TestCleanupPanics(t *testing.T) {
	func() { // errDidNotCallNewShell
		sh := gosh.Shell{}
		defer func() { neq(t, recover(), nil) }()
		sh.Cleanup()
	}()
}

// Tests that sh.Cleanup succeeds even if sh.Err is not nil.
func TestCleanupAfterError(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	sh.Err = fakeError
	sh.Cleanup()
}

// Tests that sh.Cleanup can be called multiple times.
func TestMultipleCleanup(t *testing.T) {
	sh := gosh.NewShell(gosh.Opts{Fatalf: makeFatalf(t), Logf: t.Logf})
	sh.Cleanup()
	sh.Cleanup()
}

func TestMain(m *testing.M) {
	gosh.InitMain()
	os.Exit(m.Run())
}
