containerd/cio/io_test.go
Lucas Molas eda50b1fa6 Fix race condition in IO test (TestNewAttach)
Signed-off-by: Lucas Molas <lmolas@fundacionsadosky.org.ar>
2017-12-21 13:54:22 -03:00

133 lines
3.2 KiB
Go

// +build !windows
package cio
import (
"bytes"
"context"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"syscall"
"testing"
"github.com/containerd/fifo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func assertHasPrefix(t *testing.T, s, prefix string) {
t.Helper()
if !strings.HasPrefix(s, prefix) {
t.Fatalf("expected %s to start with %s", s, prefix)
}
}
func TestNewFIFOSetInDir(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("NewFIFOSetInDir has different behaviour on windows")
}
root, err := ioutil.TempDir("", "test-new-fifo-set")
require.NoError(t, err)
defer os.RemoveAll(root)
fifos, err := NewFIFOSetInDir(root, "theid", true)
require.NoError(t, err)
assertHasPrefix(t, fifos.Stdin, root)
assertHasPrefix(t, fifos.Stdout, root)
assertHasPrefix(t, fifos.Stderr, root)
assert.Equal(t, "theid-stdin", filepath.Base(fifos.Stdin))
assert.Equal(t, "theid-stdout", filepath.Base(fifos.Stdout))
assert.Equal(t, "theid-stderr", filepath.Base(fifos.Stderr))
assert.Equal(t, true, fifos.Terminal)
files, err := ioutil.ReadDir(root)
require.NoError(t, err)
assert.Len(t, files, 1)
require.NoError(t, fifos.Close())
files, err = ioutil.ReadDir(root)
require.NoError(t, err)
assert.Len(t, files, 0)
}
func TestNewAttach(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("setupFIFOProducers not yet implemented on windows")
}
var (
expectedStdin = "this is the stdin"
expectedStdout = "this is the stdout"
expectedStderr = "this is the stderr"
stdin = bytes.NewBufferString(expectedStdin)
stdout = new(bytes.Buffer)
stderr = new(bytes.Buffer)
)
withBytesBuffers := func(streams *Streams) {
*streams = Streams{Stdin: stdin, Stdout: stdout, Stderr: stderr}
}
attacher := NewAttach(withBytesBuffers)
fifos, err := NewFIFOSetInDir("", "theid", false)
require.NoError(t, err)
io, err := attacher(fifos)
require.NoError(t, err)
defer io.Close()
producers := setupFIFOProducers(t, io.Config())
initProducers(t, producers, expectedStdout, expectedStderr)
actualStdin, err := ioutil.ReadAll(producers.Stdin)
require.NoError(t, err)
io.Wait()
io.Cancel()
assert.NoError(t, io.Close())
assert.Equal(t, expectedStdout, stdout.String())
assert.Equal(t, expectedStderr, stderr.String())
assert.Equal(t, expectedStdin, string(actualStdin))
}
type producers struct {
Stdin io.ReadCloser
Stdout io.WriteCloser
Stderr io.WriteCloser
}
func setupFIFOProducers(t *testing.T, fifos Config) producers {
var (
err error
pipes producers
ctx = context.Background()
)
pipes.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_RDONLY, 0)
require.NoError(t, err)
pipes.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_WRONLY, 0)
require.NoError(t, err)
pipes.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_WRONLY, 0)
require.NoError(t, err)
return pipes
}
func initProducers(t *testing.T, producers producers, stdout, stderr string) {
_, err := producers.Stdout.Write([]byte(stdout))
require.NoError(t, err)
require.NoError(t, producers.Stdout.Close())
_, err = producers.Stderr.Write([]byte(stderr))
require.NoError(t, err)
require.NoError(t, producers.Stderr.Close())
}