Add TestVolumeUnmount
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
@@ -94,7 +95,7 @@ func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName stri
|
|||||||
id := runContainer(t, cli, &containerConfig)
|
id := runContainer(t, cli, &containerConfig)
|
||||||
defer cleanContainer(t, cli, id)
|
defer cleanContainer(t, cli, id)
|
||||||
waitForReady(t, cli, id)
|
waitForReady(t, cli, id)
|
||||||
_, out := execContainer(t, cli, id, []string{"dspmq"})
|
out := execContainerWithOutput(t, cli, id, "mqm", []string{"dspmq"})
|
||||||
if !strings.Contains(out, search) {
|
if !strings.Contains(out, search) {
|
||||||
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
|
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
|
||||||
}
|
}
|
||||||
@@ -219,3 +220,46 @@ func TestStartQueueManagerFail(t *testing.T) {
|
|||||||
t.Errorf("Expected rc=1, got rc=%v", rc)
|
t.Errorf("Expected rc=1, got rc=%v", rc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVolumeUnmount(t *testing.T) {
|
||||||
|
cli, err := client.NewEnvClient()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
vol := createVolume(t, cli)
|
||||||
|
defer removeVolume(t, cli, vol.Name)
|
||||||
|
containerConfig := container.Config{
|
||||||
|
Image: imageName(),
|
||||||
|
Env: []string{"LICENSE=accept", "MQ_QMGR_NAME=qm1"},
|
||||||
|
}
|
||||||
|
hostConfig := container.HostConfig{
|
||||||
|
// SYS_ADMIN capability is required to unmount file systems
|
||||||
|
CapAdd: []string{
|
||||||
|
"SYS_ADMIN",
|
||||||
|
},
|
||||||
|
Binds: []string{
|
||||||
|
coverageBind(t),
|
||||||
|
vol.Name + ":/mnt/mqm",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
networkingConfig := network.NetworkingConfig{}
|
||||||
|
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
startContainer(t, cli, ctr.ID)
|
||||||
|
defer cleanContainer(t, cli, ctr.ID)
|
||||||
|
waitForReady(t, cli, ctr.ID)
|
||||||
|
// Unmount the volume as root
|
||||||
|
rc := execContainerWithExitCode(t, cli, ctr.ID, "root", []string{"umount", "-l", "-f", "/mnt/mqm"})
|
||||||
|
if rc != 0 {
|
||||||
|
t.Fatalf("Expected umount to work with rc=0, got %v", rc)
|
||||||
|
}
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
rc = execContainerWithExitCode(t, cli, ctr.ID, "mqm", []string{"chkmqhealthy"})
|
||||||
|
if rc == 0 {
|
||||||
|
t.Errorf("Expected chkmqhealthy to fail")
|
||||||
|
t.Logf(execContainerWithOutput(t, cli, ctr.ID, "mqm", []string{"df"}))
|
||||||
|
t.Logf(execContainerWithOutput(t, cli, ctr.ID, "mqm", []string{"ps", "-ef"}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -179,11 +179,45 @@ func waitForContainer(t *testing.T, cli *client.Client, ID string, timeout int64
|
|||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|
||||||
// execContainer runs the specified command inside the container, returning the
|
// execContainerWithExitCode runs a command in a running container, and returns the exit code
|
||||||
// exit code and the stdout/stderr string.
|
// Note: due to a bug in Docker/Moby code, you always get an exit code of 0 if you attach to the
|
||||||
func execContainer(t *testing.T, cli *client.Client, ID string, cmd []string) (int, string) {
|
// container to get output. This is why these are two separate commands.
|
||||||
|
func execContainerWithExitCode(t *testing.T, cli *client.Client, ID string, user string, cmd []string) int {
|
||||||
config := types.ExecConfig{
|
config := types.ExecConfig{
|
||||||
User: "mqm",
|
User: user,
|
||||||
|
Privileged: false,
|
||||||
|
Tty: false,
|
||||||
|
AttachStdin: false,
|
||||||
|
// Note that you still need to attach stdout/stderr, even though they're not wanted
|
||||||
|
AttachStdout: true,
|
||||||
|
AttachStderr: true,
|
||||||
|
Detach: false,
|
||||||
|
Cmd: cmd,
|
||||||
|
}
|
||||||
|
resp, err := cli.ContainerExecCreate(context.Background(), ID, config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cli.ContainerExecStart(context.Background(), resp.ID, types.ExecStartCheck{
|
||||||
|
Detach: false,
|
||||||
|
Tty: false,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return inspect.ExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// execContainerWithOutput runs a command in a running container, and returns the output from stdout/stderr
|
||||||
|
// Note: due to a bug in Docker/Moby code, you always get an exit code of 0 if you attach to the
|
||||||
|
// container to get output. This is why these are two separate commands.
|
||||||
|
func execContainerWithOutput(t *testing.T, cli *client.Client, ID string, user string, cmd []string) string {
|
||||||
|
config := types.ExecConfig{
|
||||||
|
User: user,
|
||||||
Privileged: false,
|
Privileged: false,
|
||||||
Tty: false,
|
Tty: false,
|
||||||
AttachStdin: false,
|
AttachStdin: false,
|
||||||
@@ -207,46 +241,19 @@ func execContainer(t *testing.T, cli *client.Client, ID string, cmd []string) (i
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
// TODO: For some reason, each line seems to start with an extra, random character
|
// TODO: For some reason, each line seems to start with an extra, random character
|
||||||
buf, err := ioutil.ReadAll(hijack.Reader)
|
buf, err := ioutil.ReadAll(hijack.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
hijack.Close()
|
hijack.Close()
|
||||||
return inspect.ExitCode, string(buf)
|
return string(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForReady(t *testing.T, cli *client.Client, ID string) {
|
func waitForReady(t *testing.T, cli *client.Client, ID string) {
|
||||||
for {
|
for {
|
||||||
resp, err := cli.ContainerExecCreate(context.Background(), ID, types.ExecConfig{
|
rc := execContainerWithExitCode(t, cli, ID, "mqm", []string{"chkmqready"})
|
||||||
User: "mqm",
|
if rc == 0 {
|
||||||
Privileged: false,
|
|
||||||
Tty: false,
|
|
||||||
AttachStdin: false,
|
|
||||||
AttachStdout: true,
|
|
||||||
AttachStderr: true,
|
|
||||||
Detach: false,
|
|
||||||
Cmd: []string{"chkmqready"},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
cli.ContainerExecStart(context.Background(), resp.ID, types.ExecStartCheck{
|
|
||||||
Detach: false,
|
|
||||||
Tty: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if inspect.ExitCode == 0 {
|
|
||||||
t.Log("MQ is ready")
|
t.Log("MQ is ready")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user