Fixes for tests on RHEL and test log output
This commit is contained in:
@@ -181,7 +181,7 @@ build-mqgolang-sdk: check-prereqs downloads/$(MQ_SDK_ARCHIVE)
|
|||||||
.PHONY: build-go-programs
|
.PHONY: build-go-programs
|
||||||
build-go-programs: check-prereqs downloads/$(MQ_SDK_ARCHIVE) build-mqgolang-sdk
|
build-go-programs: check-prereqs downloads/$(MQ_SDK_ARCHIVE) build-mqgolang-sdk
|
||||||
$(info $(SPACER)$(shell printf $(TITLE)"Build go programs"$(END)))
|
$(info $(SPACER)$(shell printf $(TITLE)"Build go programs"$(END)))
|
||||||
IMAGE_REVISION=$(IMAGE_REVISION) IMAGE_SOURCE=$(IMAGE_SOURCE) sudo mq-advanced-server-rhel/go-buildah.sh "$(MQ_IMAGE_GOLANG_SDK)" "$(MQDEV)"
|
IMAGE_REVISION=$(IMAGE_REVISION) IMAGE_SOURCE=$(IMAGE_SOURCE) sudo --preserve-env mq-advanced-server-rhel/go-buildah.sh "$(MQ_IMAGE_GOLANG_SDK)" "$(MQDEV)"
|
||||||
|
|
||||||
.PHONY: build-devjmstest
|
.PHONY: build-devjmstest
|
||||||
build-devjmstest: check-test-prereqs
|
build-devjmstest: check-test-prereqs
|
||||||
|
|||||||
@@ -46,12 +46,17 @@ func logContainerDetails() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
caps, err := containerruntime.GetCapabilities()
|
caps, err := containerruntime.GetCapabilities()
|
||||||
|
capLogged := false
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for k, v := range caps {
|
for k, v := range caps {
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
log.Printf("Capabilities (%s set): %v", strings.ToLower(k), strings.Join(v, ","))
|
log.Printf("Capabilities (%s set): %v", strings.ToLower(k), strings.Join(v, ","))
|
||||||
|
capLogged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !capLogged {
|
||||||
|
log.Print("Capabilities: none")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("Error getting capabilities: %v", err)
|
log.Errorf("Error getting capabilities: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,12 +50,19 @@ func logContainerDetails() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
caps, err := containerruntime.GetCapabilities()
|
caps, err := containerruntime.GetCapabilities()
|
||||||
|
capLogged := false
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for k, v := range caps {
|
for k, v := range caps {
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
log.Printf("Capabilities (%s set): %v", strings.ToLower(k), strings.Join(v, ","))
|
log.Printf("Capabilities (%s set): %v", strings.ToLower(k), strings.Join(v, ","))
|
||||||
|
capLogged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !capLogged {
|
||||||
|
log.Print("Capabilities: none")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Errorf("Error getting capabilities: %v", err)
|
||||||
}
|
}
|
||||||
sc, err := containerruntime.GetSeccomp()
|
sc, err := containerruntime.GetSeccomp()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -43,6 +43,18 @@ import (
|
|||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type containerDetails struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
Image string
|
||||||
|
Path string
|
||||||
|
Args []string
|
||||||
|
CapAdd []string
|
||||||
|
CapDrop []string
|
||||||
|
User string
|
||||||
|
Env []string
|
||||||
|
}
|
||||||
|
|
||||||
func imageName() string {
|
func imageName() string {
|
||||||
image, ok := os.LookupEnv("TEST_IMAGE")
|
image, ok := os.LookupEnv("TEST_IMAGE")
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -59,8 +71,9 @@ func imageNameDevJMS() string {
|
|||||||
return image
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// baseImage returns the ID of the underlying base image (e.g. "ubuntu" or "rhel")
|
||||||
func baseImage(t *testing.T, cli *client.Client) string {
|
func baseImage(t *testing.T, cli *client.Client) string {
|
||||||
rc, out := runContainerOneShot(t, cli, "bash", "-c", "cat /etc/*release | grep \"^ID=\"")
|
rc, out := runContainerOneShot(t, cli, "grep", "^ID=", "/etc/os-release")
|
||||||
if rc != 0 {
|
if rc != 0 {
|
||||||
t.Fatal("Couldn't determine base image")
|
t.Fatal("Couldn't determine base image")
|
||||||
}
|
}
|
||||||
@@ -71,6 +84,16 @@ func baseImage(t *testing.T, cli *client.Client) string {
|
|||||||
return s[1]
|
return s[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// devImage returns true if the image under test is a developer image,
|
||||||
|
// determined by use of the MQ_ADMIN_PASSWORD environment variable
|
||||||
|
func devImage(t *testing.T, cli *client.Client) bool {
|
||||||
|
rc, _ := runContainerOneShot(t, cli, "printenv", "MQ_ADMIN_PASSWORD")
|
||||||
|
if rc == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// isWSL return whether we are running in the Windows Subsystem for Linux
|
// isWSL return whether we are running in the Windows Subsystem for Linux
|
||||||
func isWSL(t *testing.T) bool {
|
func isWSL(t *testing.T) bool {
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
@@ -166,21 +189,49 @@ func expectTerminationMessage(t *testing.T, cli *client.Client, ID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanContainer(t *testing.T, cli *client.Client, ID string) {
|
// logContainerDetails logs selected details about the container
|
||||||
|
func logContainerDetails(t *testing.T, cli *client.Client, ID string) {
|
||||||
i, err := cli.ContainerInspect(context.Background(), ID)
|
i, err := cli.ContainerInspect(context.Background(), ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Log the results and continue
|
d := containerDetails{
|
||||||
t.Logf("Inspected container %v: %#v", ID, i)
|
ID: ID,
|
||||||
s, err := json.MarshalIndent(i, "", " ")
|
Name: i.Name,
|
||||||
if err != nil {
|
Image: i.Image,
|
||||||
t.Fatal(err)
|
Path: i.Path,
|
||||||
|
Args: i.Args,
|
||||||
|
CapAdd: i.HostConfig.CapAdd,
|
||||||
|
CapDrop: i.HostConfig.CapDrop,
|
||||||
|
User: i.Config.User,
|
||||||
|
Env: i.Config.Env,
|
||||||
}
|
}
|
||||||
t.Logf("Inspected container %v: %v", ID, string(s))
|
// If you need more details, you can always just run `json.MarshalIndent(i, "", " ")` to see everything.
|
||||||
|
t.Logf("Container details: %+v", d)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanContainerQuiet(t *testing.T, cli *client.Client, ID string) {
|
||||||
|
timeout := 10 * time.Second
|
||||||
|
err := cli.ContainerStop(context.Background(), ID, &timeout)
|
||||||
|
if err != nil {
|
||||||
|
// Just log the error and continue
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
opts := types.ContainerRemoveOptions{
|
||||||
|
RemoveVolumes: true,
|
||||||
|
Force: true,
|
||||||
|
}
|
||||||
|
err = cli.ContainerRemove(context.Background(), ID, opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanContainer(t *testing.T, cli *client.Client, ID string) {
|
||||||
|
logContainerDetails(t, cli, ID)
|
||||||
t.Logf("Stopping container: %v", ID)
|
t.Logf("Stopping container: %v", ID)
|
||||||
timeout := 10 * time.Second
|
timeout := 10 * time.Second
|
||||||
// Stop the container. This allows the coverage output to be generated.
|
// Stop the container. This allows the coverage output to be generated.
|
||||||
err = cli.ContainerStop(context.Background(), ID, &timeout)
|
err := cli.ContainerStop(context.Background(), ID, &timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Just log the error and continue
|
// Just log the error and continue
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
@@ -208,22 +259,6 @@ func cleanContainer(t *testing.T, cli *client.Client, ID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// devImage returns true if the specified image is a developer image,
|
|
||||||
// determined by use of the MQ_ADMIN_PASSWORD or MQ_APP_PASSWORD
|
|
||||||
// environment variables
|
|
||||||
func devImage(t *testing.T, cli *client.Client, imageID string) bool {
|
|
||||||
i, _, err := cli.ImageInspectWithRaw(context.Background(), imageID)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
for _, e := range i.ContainerConfig.Env {
|
|
||||||
if strings.HasPrefix(e, "MQ_ADMIN_PASSWORD") || strings.HasPrefix(e, "MQ_APP_PASSWORD") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// runContainerWithPorts creates and starts a container, exposing the specified ports on the host.
|
// runContainerWithPorts creates and starts a container, exposing the specified ports on the host.
|
||||||
// If no image is specified in the container config, then the image name is retrieved from the TEST_IMAGE
|
// If no image is specified in the container config, then the image name is retrieved from the TEST_IMAGE
|
||||||
// environment variable.
|
// environment variable.
|
||||||
@@ -247,7 +282,7 @@ func runContainerWithPorts(t *testing.T, cli *client.Client, containerConfig *co
|
|||||||
"ALL",
|
"ALL",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if devImage(t, cli, containerConfig.Image) {
|
if devImage(t, cli) {
|
||||||
t.Logf("Detected MQ Advanced for Developers image — adding extra Linux capabilities to container")
|
t.Logf("Detected MQ Advanced for Developers image — adding extra Linux capabilities to container")
|
||||||
hostConfig.CapAdd = []string{
|
hostConfig.CapAdd = []string{
|
||||||
"CHOWN",
|
"CHOWN",
|
||||||
@@ -259,6 +294,8 @@ func runContainerWithPorts(t *testing.T, cli *client.Client, containerConfig *co
|
|||||||
if baseImage(t, cli) != "ubuntu" {
|
if baseImage(t, cli) != "ubuntu" {
|
||||||
hostConfig.CapAdd = append(hostConfig.CapAdd, "DAC_OVERRIDE")
|
hostConfig.CapAdd = append(hostConfig.CapAdd, "DAC_OVERRIDE")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t.Logf("Detected MQ Advanced image - dropping all capabilities")
|
||||||
}
|
}
|
||||||
for _, p := range ports {
|
for _, p := range ports {
|
||||||
port := nat.Port(fmt.Sprintf("%v/tcp", p))
|
port := nat.Port(fmt.Sprintf("%v/tcp", p))
|
||||||
@@ -295,14 +332,21 @@ func runContainerOneShot(t *testing.T, cli *client.Client, command ...string) (i
|
|||||||
}
|
}
|
||||||
hostConfig := container.HostConfig{}
|
hostConfig := container.HostConfig{}
|
||||||
networkingConfig := network.NetworkingConfig{}
|
networkingConfig := network.NetworkingConfig{}
|
||||||
t.Logf("Running one shot container (%s)", containerConfig.Image)
|
t.Logf("Running one shot container (%s): %v", containerConfig.Image, command)
|
||||||
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
|
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name()+"OneShot")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
startContainer(t, cli, ctr.ID)
|
startOptions := types.ContainerStartOptions{}
|
||||||
defer cleanContainer(t, cli, ctr.ID)
|
err = cli.ContainerStart(context.Background(), ctr.ID, startOptions)
|
||||||
return waitForContainer(t, cli, ctr.ID, 10*time.Second), inspectLogs(t, cli, ctr.ID)
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cleanContainerQuiet(t, cli, ctr.ID)
|
||||||
|
rc := waitForContainer(t, cli, ctr.ID, 10*time.Second)
|
||||||
|
out := inspectLogs(t, cli, ctr.ID)
|
||||||
|
t.Logf("One shot container finished with rc=%v, output=%v", rc, out)
|
||||||
|
return rc, out
|
||||||
}
|
}
|
||||||
|
|
||||||
// runContainerOneShot runs a container with a custom entrypoint, as the root
|
// runContainerOneShot runs a container with a custom entrypoint, as the root
|
||||||
@@ -320,14 +364,20 @@ func runContainerOneShotWithVolume(t *testing.T, cli *client.Client, bind string
|
|||||||
}
|
}
|
||||||
networkingConfig := network.NetworkingConfig{}
|
networkingConfig := network.NetworkingConfig{}
|
||||||
t.Logf("Running one shot container with volume (%s): %v", containerConfig.Image, command)
|
t.Logf("Running one shot container with volume (%s): %v", containerConfig.Image, command)
|
||||||
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name())
|
ctr, err := cli.ContainerCreate(context.Background(), &containerConfig, &hostConfig, &networkingConfig, t.Name()+"OneShotVolume")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Logf("One shot container ID: %v", ctr.ID)
|
startOptions := types.ContainerStartOptions{}
|
||||||
startContainer(t, cli, ctr.ID)
|
err = cli.ContainerStart(context.Background(), ctr.ID, startOptions)
|
||||||
defer cleanContainer(t, cli, ctr.ID)
|
if err != nil {
|
||||||
return waitForContainer(t, cli, ctr.ID, 10*time.Second), inspectLogs(t, cli, ctr.ID)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cleanContainerQuiet(t, cli, ctr.ID)
|
||||||
|
rc := waitForContainer(t, cli, ctr.ID, 10*time.Second)
|
||||||
|
out := inspectLogs(t, cli, ctr.ID)
|
||||||
|
t.Logf("One shot container finished with rc=%v, output=%v", rc, out)
|
||||||
|
return rc, out
|
||||||
}
|
}
|
||||||
|
|
||||||
func startContainer(t *testing.T, cli *client.Client, ID string) {
|
func startContainer(t *testing.T, cli *client.Client, ID string) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# © Copyright IBM Corporation 2018
|
# © Copyright IBM Corporation 2018, 2019
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -22,24 +22,34 @@ set -e
|
|||||||
|
|
||||||
# Use a "scratch" container, so the resulting image has minimal files
|
# Use a "scratch" container, so the resulting image has minimal files
|
||||||
# Resulting image won't have yum, for example
|
# Resulting image won't have yum, for example
|
||||||
readonly ctr_mq=$(buildah from rhel7)
|
readonly ctr_mq=$(buildah from rhel7-minimal)
|
||||||
readonly mnt_mq=$(buildah mount $ctr_mq)
|
readonly mnt_mq=$(buildah mount $ctr_mq)
|
||||||
readonly imagename=$1
|
readonly imagename=$1
|
||||||
|
|
||||||
buildah run $ctr_mq -- yum install -y \
|
microdnf_opts="--nodocs"
|
||||||
java-1.7.0-openjdk-devel \
|
# Check whether the host is registered with Red Hat
|
||||||
java \
|
if subscription-manager status ; then
|
||||||
which \
|
# Host is subscribed, but the minimal image has no enabled repos
|
||||||
wget
|
# Note that the "bc" package is the only one in "extras"
|
||||||
|
microdnf_opts="${microdnf_opts} --enablerepo=rhel-7-server-rpms --enablerepo=rhel-7-server-extras-rpms"
|
||||||
|
else
|
||||||
|
# Use the Yum repositories configured on the host
|
||||||
|
cp -R /etc/yum.repos.d/* ${mnt_mq}/etc/yum.repos.d/
|
||||||
|
fi
|
||||||
|
buildah run ${ctr_mq} -- microdnf ${microdnf_opts} install \
|
||||||
|
java-1.8.0-openjdk-devel \
|
||||||
|
java \
|
||||||
|
which \
|
||||||
|
wget
|
||||||
|
|
||||||
buildah run $ctr_mq -- sh -c "cd /tmp && wget http://mirror.olnevhost.net/pub/apache/maven/binaries/apache-maven-3.2.2-bin.tar.gz"
|
buildah run $ctr_mq -- sh -c "cd /tmp && wget https://www-eu.apache.org/dist/maven/maven-3/3.6.0/binaries/apache-maven-3.6.0-bin.tar.gz"
|
||||||
tar xvf $mnt_mq/tmp/apache-maven-3.2.2-bin.tar.gz -C $mnt_mq/tmp/
|
tar xvf $mnt_mq/tmp/apache-maven-3.6.0-bin.tar.gz -C $mnt_mq/tmp/
|
||||||
|
|
||||||
mkdir -p $mnt_mq/usr/src/mymaven
|
mkdir -p $mnt_mq/usr/src/mymaven
|
||||||
cp pom.xml $mnt_mq/usr/src/mymaven/
|
cp pom.xml $mnt_mq/usr/src/mymaven/
|
||||||
cp -R src $mnt_mq/usr/src/mymaven/src
|
cp -R src $mnt_mq/usr/src/mymaven/src
|
||||||
|
|
||||||
buildah run $ctr_mq -- sh -c "cd /usr/src/mymaven && export M2_HOME=/tmp/apache-maven-3.2.2 && export M2=\$M2_HOME/bin && export PATH=\$M2:\$PATH && mvn --version && mvn dependency:go-offline install && mvn --offline install"
|
buildah run $ctr_mq -- sh -c "cd /usr/src/mymaven && export M2_HOME=/tmp/apache-maven-3.6.0 && export M2=\$M2_HOME/bin && export PATH=\$M2:\$PATH && mvn --version && mvn dependency:go-offline install && mvn --offline install"
|
||||||
|
|
||||||
mkdir -p $mnt_mq/opt/app
|
mkdir -p $mnt_mq/opt/app
|
||||||
|
|
||||||
@@ -53,13 +63,9 @@ cp $mnt_mq/usr/src/mymaven/target/lib/*.jar $mnt_mq/opt/app/
|
|||||||
rm -rf $mnt_mq/tmp/*
|
rm -rf $mnt_mq/tmp/*
|
||||||
rm -rf $mnt_mq/usr/src/mymaven
|
rm -rf $mnt_mq/usr/src/mymaven
|
||||||
|
|
||||||
# We can't uninstall tar or gzip because they are required
|
|
||||||
buildah run $ctr_mq -- yum remove -y \
|
|
||||||
wget
|
|
||||||
|
|
||||||
# Clean up cached files
|
# Clean up cached files
|
||||||
buildah run $ctr_mq -- yum clean all
|
buildah run ${ctr_mq} -- microdnf ${microdnf_opts} clean all
|
||||||
rm -rf ${mnt_mq}/var/cache/yum/*
|
rm -rf ${mnt_mq}/etc/yum.repos.d/*
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Contain image finalization
|
# Contain image finalization
|
||||||
@@ -69,6 +75,7 @@ buildah config \
|
|||||||
--os linux \
|
--os linux \
|
||||||
--label architecture=x86_64 \
|
--label architecture=x86_64 \
|
||||||
--label name="${imagename%:*}" \
|
--label name="${imagename%:*}" \
|
||||||
|
--cmd "" \
|
||||||
--entrypoint '["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]' \
|
--entrypoint '["java", "-classpath", "/opt/app/*", "org.junit.platform.console.ConsoleLauncher", "-p", "com.ibm.mqcontainer.test", "--details", "verbose"]' \
|
||||||
$ctr_mq
|
$ctr_mq
|
||||||
buildah unmount $ctr_mq
|
buildah unmount $ctr_mq
|
||||||
|
|||||||
Reference in New Issue
Block a user