Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test/docker/Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

[[constraint]]
name = "github.com/docker/docker"
version = "^1.12"
version = "=v17.03.2-ce"

[[constraint]]
name = "github.com/docker/go-connections"
Expand Down
30 changes: 1 addition & 29 deletions test/docker/devconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ limitations under the License.
package main

import (
"crypto/tls"
"fmt"
"net/http"
"testing"
"time"

"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
Expand All @@ -41,31 +37,7 @@ func TestDevGoldenPath(t *testing.T) {

defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
waitForWebReady(t, cli, id)

timeout := time.Duration(30 * time.Second)
// Disable TLS verification (server uses a self-signed certificate by default,
// so verification isn't useful anyway)
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
httpClient := http.Client{
Timeout: timeout,
Transport: tr,
}

url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/admin/installation", getWebPort(t, cli, id))
req, err := http.NewRequest("GET", url, nil)
req.SetBasicAuth("admin", "passw0rd")
resp, err := httpClient.Do(req)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Expected HTTP status code %v from 'GET installation'; got %v", http.StatusOK, resp.StatusCode)
}
waitForWebReady(t, cli, id, insecureTLSConfig)

// Stop the container cleanly
stopContainer(t, cli, id)
Expand Down
42 changes: 33 additions & 9 deletions test/docker/devconfig_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,49 @@ limitations under the License.
package main

import (
"crypto/tls"
"fmt"
"testing"
"time"
"net/http"
"crypto/tls"

"github.com/docker/docker/client"
)

func waitForWebReady(t *testing.T, cli *client.Client, ID string) {
config := tls.Config{InsecureSkipVerify: true}
a := fmt.Sprintf("localhost:%s", getWebPort(t, cli, ID))

const devAdminPassword string = "passw0rd"
const devAppPassword string = "passw0rd"

// Disable TLS verification (server uses a self-signed certificate by default,
// so verification isn't useful anyway)
var insecureTLSConfig *tls.Config = &tls.Config{
InsecureSkipVerify: true,
}

func waitForWebReady(t *testing.T, cli *client.Client, ID string, tlsConfig *tls.Config) {
httpClient := http.Client{
Timeout: time.Duration(3 * time.Second),
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
url := fmt.Sprintf("https://localhost:%s/ibmmq/rest/v1/admin/installation", getWebPort(t, cli, ID))
for {
conn, err := tls.Dial("tcp", a, &config)
if err == nil {
conn.Close()
// Extra sleep to allow web apps to start
time.Sleep(3 * time.Second)
req, err := http.NewRequest("GET", url, nil)
req.SetBasicAuth("admin", devAdminPassword)
resp, err := httpClient.Do(req)
if err == nil && resp.StatusCode == http.StatusOK {
t.Log("MQ web server is ready")
return
}
// conn, err := tls.Dial("tcp", a, &config)
// if err == nil {
// conn.Close()
// // Extra sleep to allow web apps to start
// time.Sleep(5 * time.Second)
// t.Log("MQ web server is ready")
// return
// }
time.Sleep(1 * time.Second)
}
}
40 changes: 23 additions & 17 deletions test/docker/docker_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func utilTestNoQueueManagerName(t *testing.T, hostName string, expectedName stri
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
out := execContainerWithOutput(t, cli, id, "mqm", []string{"dspmq"})
_, out := execContainer(t, cli, id, "mqm", []string{"dspmq"})
if !strings.Contains(out, search) {
t.Errorf("Expected result of running dspmq to contain name=%v, got name=%v", search, out)
}
Expand Down Expand Up @@ -285,16 +285,18 @@ func TestVolumeUnmount(t *testing.T) {
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"})
rc, _ := execContainer(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"})
rc, _ = execContainer(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"}))
_, output := execContainer(t, cli, ctr.ID, "mqm", []string{"df"})
t.Logf(output)
_, output = execContainer(t, cli, ctr.ID, "mqm", []string{"ps", "-ef"})
t.Logf(output)
}
}

Expand All @@ -318,12 +320,12 @@ func TestZombies(t *testing.T) {
waitForReady(t, cli, id)
// Kill an MQ process with children. After it is killed, its children
// will be adopted by PID 1, and should then be reaped when they die.
out := execContainerWithOutput(t, cli, id, "mqm", []string{"pkill", "--signal", "kill", "-c", "amqzxma0"})
_, out := execContainer(t, cli, id, "mqm", []string{"pkill", "--signal", "kill", "-c", "amqzxma0"})
if out == "0" {
t.Fatalf("Expected pkill to kill a process, got %v", out)
}
time.Sleep(3 * time.Second)
out = execContainerWithOutput(t, cli, id, "mqm", []string{"bash", "-c", "ps -lA | grep '^. Z'"})
_, out = execContainer(t, cli, id, "mqm", []string{"bash", "-c", "ps -lA | grep '^. Z'"})
if out != "" {
count := strings.Count(out, "\n") + 1
t.Errorf("Expected zombies=0, got %v", count)
Expand Down Expand Up @@ -356,7 +358,7 @@ func TestMQSC(t *testing.T) {
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
waitForReady(t, cli, id)
rc := execContainerWithExitCode(t, cli, id, "mqm", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test)' | runmqsc"})
rc, _ := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test)' | runmqsc"})
if rc != 0 {
t.Fatalf("Expected runmqsc to exit with rc=0, got %v", rc)
}
Expand Down Expand Up @@ -392,17 +394,19 @@ func TestReadiness(t *testing.T) {
id := runContainer(t, cli, &containerConfig)
defer cleanContainer(t, cli, id)
queueCheckCommand := fmt.Sprintf("echo 'DISPLAY QLOCAL(test%v)' | runmqsc", numQueues)
t.Log(execContainerWithOutput(t, cli, id, "root", []string{"cat", "/etc/mqm/test.mqsc"}))
_, output := execContainer(t, cli, id, "root", []string{"cat", "/etc/mqm/test.mqsc"})
t.Log(output)
for {
readyRC := execContainerWithExitCode(t, cli, id, "mqm", []string{"chkmqready"})
queueCheckRC := execContainerWithExitCode(t, cli, id, "mqm", []string{"bash", "-c", queueCheckCommand})
readyRC, _ := execContainer(t, cli, id, "mqm", []string{"chkmqready"})
queueCheckRC, _ := execContainer(t, cli, id, "mqm", []string{"bash", "-c", queueCheckCommand})
t.Logf("readyRC=%v,queueCheckRC=%v\n", readyRC, queueCheckRC)
if readyRC == 0 {
if queueCheckRC != 0 {
t.Fatalf("chkmqready returned %v when MQSC had not finished", readyRC)
} else {
// chkmqready says OK, and the last queue exists, so return
t.Log(execContainerWithOutput(t, cli, id, "root", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test1)' | runmqsc"}))
_, output = execContainer(t, cli, id, "root", []string{"bash", "-c", "echo 'DISPLAY QLOCAL(test1)' | runmqsc"})
t.Log(output)
return
}
}
Expand Down Expand Up @@ -463,11 +467,13 @@ func TestErrorLogRotation(t *testing.T) {
waitForReady(t, cli, id)
dir := "/var/mqm/qmgrs/" + qmName + "/errors"
// Generate some content for the error logs, by trying to put messages under an unauthorized user
// execContainerWithOutput(t, cli, id, "fred", []string{"bash", "-c", "for i in {1..30} ; do /opt/mqm/samp/bin/amqsput FAKE; done"})
execContainerWithOutput(t, cli, id, "root", []string{"useradd", "fred"})
// execContainer(t, cli, id, "fred", []string{"bash", "-c", "for i in {1..30} ; do /opt/mqm/samp/bin/amqsput FAKE; done"})
execContainer(t, cli, id, "root", []string{"useradd", "fred"})
for {
execContainerWithOutput(t, cli, id, "fred", []string{"bash", "-c", "/opt/mqm/samp/bin/amqsput FAKE"})
amqerr02size, err := strconv.Atoi(execContainerWithOutput(t, cli, id, "mqm", []string{"bash", "-c", "wc -c < " + filepath.Join(dir, "AMQERR02.json")}))
execContainer(t, cli, id, "fred", []string{"bash", "-c", "/opt/mqm/samp/bin/amqsput FAKE"})

_, atoiStr := execContainer(t, cli, id, "mqm", []string{"bash", "-c", "wc -c < " + filepath.Join(dir, "AMQERR02.json")})
amqerr02size, err := strconv.Atoi(atoiStr)
if err != nil {
t.Fatal(err)
}
Expand All @@ -476,7 +482,7 @@ func TestErrorLogRotation(t *testing.T) {
break
}
}
out := execContainerWithOutput(t, cli, id, "root", []string{"ls", "-l", dir})
_, out := execContainer(t, cli, id, "root", []string{"ls", "-l", dir})
t.Log(out)
stopContainer(t, cli, id)
b := copyFromContainer(t, cli, id, filepath.Join(dir, "AMQERR01.json"))
Expand Down
61 changes: 19 additions & 42 deletions test/docker/docker_api_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"strings"
"testing"
"time"
"regexp"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
Expand Down Expand Up @@ -254,10 +255,9 @@ func waitForContainer(t *testing.T, cli *client.Client, ID string, timeout int64
return rc
}

// execContainerWithExitCode runs a command in a running container, and returns the exit code
// 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 execContainerWithExitCode(t *testing.T, cli *client.Client, ID string, user string, cmd []string) int {
// execContainer runs a command in a running container, and returns the exit code and output
func execContainer(t *testing.T, cli *client.Client, ID string, user string, cmd []string) (int, string) {
rerun:
config := types.ExecConfig{
User: user,
Privileged: false,
Expand All @@ -273,56 +273,23 @@ func execContainerWithExitCode(t *testing.T, cli *client.Client, ID string, user
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,
Tty: false,
AttachStdin: false,
AttachStdout: true,
AttachStderr: true,
Detach: false,
Cmd: cmd,
}
resp, err := cli.ContainerExecCreate(context.Background(), ID, config)
if err != nil {
t.Fatal(err)
}
hijack, err := cli.ContainerExecAttach(context.Background(), resp.ID, config)
if err != nil {
t.Fatal(err)
}
err = cli.ContainerExecStart(context.Background(), resp.ID, types.ExecStartCheck{
cli.ContainerExecStart(context.Background(), resp.ID, types.ExecStartCheck{
Detach: false,
Tty: false,
})
if err != nil {
t.Fatal(err)
}
// Wait for the command to finish
var exitcode int
for {
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
if err != nil {
t.Fatal(err)
}
if !inspect.Running {
exitcode = inspect.ExitCode
break
}
}
Expand All @@ -332,12 +299,22 @@ func execContainerWithOutput(t *testing.T, cli *client.Client, ID string, user s
if err != nil {
log.Fatal(err)
}
return strings.TrimSpace(buf.String())

outputStr := strings.TrimSpace(buf.String())

// Before we go let's just double check it did actually run because sometimes we get a "Exec command already running error"
alreadyRunningErr := regexp.MustCompile("Error: Exec command .* is already running")
if alreadyRunningErr.MatchString(outputStr) {
time.Sleep(1 * time.Second)
goto rerun
}

return exitcode, outputStr
}

func waitForReady(t *testing.T, cli *client.Client, ID string) {
for {
rc := execContainerWithExitCode(t, cli, ID, "mqm", []string{"chkmqready"})
rc, _ := execContainer(t, cli, ID, "mqm", []string{"chkmqready"})
if rc == 0 {
t.Log("MQ is ready")
return
Expand Down