open-nomad/drivers/docker/docklog/docker_logger_test.go

131 lines
3.0 KiB
Go

package docklog
import (
"bytes"
"fmt"
"runtime"
"testing"
docker "github.com/fsouza/go-dockerclient"
ctu "github.com/hashicorp/nomad/client/testutil"
"github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/testutil"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func testContainerDetails() (image string, imageName string, imageTag string) {
if runtime.GOOS == "windows" {
return "dantoml/busybox-windows:08012019",
"dantoml/busybox-windows",
"08012019"
}
return "busybox:1", "busybox", "1"
}
func TestDockerLogger(t *testing.T) {
ctu.DockerCompatible(t)
t.Parallel()
require := require.New(t)
containerImage, containerImageName, containerImageTag := testContainerDetails()
client, err := docker.NewClientFromEnv()
if err != nil {
t.Skip("docker unavailable:", err)
}
if img, err := client.InspectImage(containerImage); err != nil || img == nil {
t.Log("image not found locally, downloading...")
err = client.PullImage(docker.PullImageOptions{
Repository: containerImageName,
Tag: containerImageTag,
}, docker.AuthConfiguration{})
if err != nil {
t.Fatalf("failed to pull image: %v", err)
}
}
containerConf := docker.CreateContainerOptions{
Config: &docker.Config{
Cmd: []string{
"sh", "-c", "touch ~/docklog; tail -f ~/docklog",
},
Image: containerImage,
},
Context: context.Background(),
}
container, err := client.CreateContainer(containerConf)
require.NoError(err)
defer client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
Force: true,
})
err = client.StartContainer(container.ID, nil)
require.NoError(err)
testutil.WaitForResult(func() (bool, error) {
container, err = client.InspectContainer(container.ID)
if err != nil {
return false, err
}
if !container.State.Running {
return false, fmt.Errorf("container not running")
}
return true, nil
}, func(err error) {
require.NoError(err)
})
stdout := &noopCloser{bytes.NewBuffer(nil)}
stderr := &noopCloser{bytes.NewBuffer(nil)}
dl := NewDockerLogger(testlog.HCLogger(t)).(*dockerLogger)
dl.stdout = stdout
dl.stderr = stderr
require.NoError(dl.Start(&StartOpts{
ContainerID: container.ID,
}))
echoToContainer(t, client, container.ID, "abc")
echoToContainer(t, client, container.ID, "123")
testutil.WaitForResult(func() (bool, error) {
act := stdout.String()
if "abc\n123\n" != act {
return false, fmt.Errorf("expected abc\\n123\\n for stdout but got %s", act)
}
return true, nil
}, func(err error) {
require.NoError(err)
})
}
func echoToContainer(t *testing.T, client *docker.Client, id string, line string) {
op := docker.CreateExecOptions{
Container: id,
Cmd: []string{
"ash", "-c",
fmt.Sprintf("echo %s >>~/docklog", line),
},
}
exec, err := client.CreateExec(op)
require.NoError(t, err)
require.NoError(t, client.StartExec(exec.ID, docker.StartExecOptions{Detach: true}))
}
type noopCloser struct {
*bytes.Buffer
}
func (*noopCloser) Close() error {
return nil
}