func testShellCatStdErr(meta *metaservice.MetaService) {
	debug("### Test meta.Shell (using 'exec cat - 1>&2')")
	shell, err := meta.ExecShell(nil, false)
	nilOrPanic(err, "Failed to call meta.ExecShell()")

	input := make([]byte, 4*1024*1024+37)
	rand.Read(input)

	// Discard stderr
	go io.Copy(ioutil.Discard, shell.StdoutPipe())
	go func() {
		if goruntime.GOOS == "windows" {
			shell.StdinPipe().Write([]byte("type con 1>&2\n"))
		} else {
			shell.StdinPipe().Write([]byte("exec cat -  1>&2\n"))
		}
		// Give cat - some time to start, bash/busybox/dash won't work otherwise
		// Or they will work, but only intermittently!!!
		time.Sleep(250 * time.Millisecond)
		shell.StdinPipe().Write(input)
		shell.StdinPipe().Close()
		debug("Closed stdin")
	}()
	var output []byte
	outputDone := sync.WaitGroup{}
	outputDone.Add(1)
	go func() {
		data, rerr := ioutil.ReadAll(shell.StderrPipe())
		nilOrPanic(rerr, "Got error from stderr pipe, error: ", rerr)
		output = data
		outputDone.Done()
	}()

	success, err := shell.Wait()
	nilOrPanic(err, "Got an error from shell.Wait, error: ", err)
	assert(success, "Expected success from shell, we closed with end of stdin")
	outputDone.Wait()
	assert(bytes.Equal(output, input), "Expected data to match input, ",
		"len(input) = ", len(input), " len(output) = ", len(output))
}
func testShellHello(meta *metaservice.MetaService) {
	debug("### Test meta.Shell (using 'echo hello')")
	shell, err := meta.ExecShell(nil, false)
	nilOrPanic(err, "Failed to call meta.ExecShell()")

	readHello := sync.WaitGroup{}
	readHello.Add(1)
	// Discard stderr
	go io.Copy(ioutil.Discard, shell.StderrPipe())
	go func() {
		shell.StdinPipe().Write([]byte("echo HELLO\n"))
		readHello.Wait()
		shell.StdinPipe().Close()
	}()
	go func() {
		data := bytes.Buffer{}
		for {
			b := []byte{0}
			n, werr := shell.StdoutPipe().Read(b)
			data.Write(b[:n])
			if strings.Contains(data.String(), "HELLO") {
				readHello.Done()
				break
			}
			if werr != nil {
				assert(werr == io.EOF, "Expected EOF!")
				break
			}
		}
		// Discard the rest
		go io.Copy(ioutil.Discard, shell.StdoutPipe())
	}()

	success, err := shell.Wait()
	nilOrPanic(err, "Got an error from shell.Wait, error: ", err)
	assert(success, "Expected success from shell, we closed with end of stdin")
}