Fix build and test in WSL
This commit is contained in:
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Fore LF line endings to prevent errors in Bash on Windows
|
||||||
|
* text=auto
|
||||||
|
*.sh text eol=lf
|
||||||
11
Makefile
11
Makefile
@@ -54,6 +54,13 @@ MQ_IMAGE_DEVSERVER_BASE=mqadvanced-server-dev-base:$(MQ_VERSION)-$(ARCH)-$(BASE_
|
|||||||
# Docker image name to use for JMS tests
|
# Docker image name to use for JMS tests
|
||||||
DEV_JMS_IMAGE=mq-dev-jms-test
|
DEV_JMS_IMAGE=mq-dev-jms-test
|
||||||
|
|
||||||
|
|
||||||
|
ifneq (,$(findstring Microsoft,$(shell uname -r)))
|
||||||
|
DOWNLOADS_DIR=$(patsubst /mnt/c%,C:%,$(realpath ./downloads/))
|
||||||
|
else
|
||||||
|
DOWNLOADS_DIR=$(realpath ./downloads/)
|
||||||
|
endif
|
||||||
|
|
||||||
# Try to figure out which archive to use from the BASE_IMAGE
|
# Try to figure out which archive to use from the BASE_IMAGE
|
||||||
ifeq "$(findstring ubuntu,$(BASE_IMAGE))" "ubuntu"
|
ifeq "$(findstring ubuntu,$(BASE_IMAGE))" "ubuntu"
|
||||||
MQ_ARCHIVE_TYPE=UBUNTU
|
MQ_ARCHIVE_TYPE=UBUNTU
|
||||||
@@ -137,7 +144,7 @@ test-unit:
|
|||||||
.PHONY: test-advancedserver
|
.PHONY: test-advancedserver
|
||||||
test-advancedserver: test/docker/vendor
|
test-advancedserver: test/docker/vendor
|
||||||
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER) on Docker"$(END)))
|
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER) on Docker"$(END)))
|
||||||
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER) go test -parallel $(NUM_CPU) $(TEST_OPTS_DOCKER)
|
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER) go test -timeout 20m -parallel $(NUM_CPU) $(TEST_OPTS_DOCKER)
|
||||||
|
|
||||||
.PHONY: build-devjmstest
|
.PHONY: build-devjmstest
|
||||||
build-devjmstest:
|
build-devjmstest:
|
||||||
@@ -181,7 +188,7 @@ define docker-build-mq
|
|||||||
--name $(BUILD_SERVER_CONTAINER) \
|
--name $(BUILD_SERVER_CONTAINER) \
|
||||||
--network build \
|
--network build \
|
||||||
--network-alias build \
|
--network-alias build \
|
||||||
--volume "$(realpath ./downloads/)":/usr/share/nginx/html:ro \
|
--volume $(DOWNLOADS_DIR):/usr/share/nginx/html:ro \
|
||||||
--detach \
|
--detach \
|
||||||
nginx:alpine
|
nginx:alpine
|
||||||
# Build the new image (use --pull to make sure we have the latest base image)
|
# Build the new image (use --pull to make sure we have the latest base image)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Testing
|
# Testing
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
You need to ensure you have the following tools installed:
|
You need to ensure you have the following tools installed:
|
||||||
@@ -8,15 +8,6 @@ You need to ensure you have the following tools installed:
|
|||||||
* [dep](https://github.com/golang/dep) (official Go dependency management tool) - needed to prepare for running the tests
|
* [dep](https://github.com/golang/dep) (official Go dependency management tool) - needed to prepare for running the tests
|
||||||
* [Helm](https://helm.sh) - only needed for running the Kubernetes tests
|
* [Helm](https://helm.sh) - only needed for running the Kubernetes tests
|
||||||
|
|
||||||
For running the Kubernetes tests, a Kubernetes environment is needed, for example [Minikube](https://github.com/kubernetes/minikube) or [IBM Cloud Private](https://www.ibm.com/cloud-computing/products/ibm-cloud-private/).
|
|
||||||
|
|
||||||
## Preparing to run the tests
|
|
||||||
The test dependencies are not included with the source code, so you need to download them before you can run them. This can be done with the following command, which uses the `dep` tool:
|
|
||||||
|
|
||||||
```
|
|
||||||
make deps
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running the tests
|
## Running the tests
|
||||||
There are two main sets of tests:
|
There are two main sets of tests:
|
||||||
|
|
||||||
@@ -57,7 +48,7 @@ make build-advancedserver-cover
|
|||||||
make test-advancedserver-cover
|
make test-advancedserver-cover
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to generate code coverage metrics from the Docker tests, the build step creates a new Docker image with an instrumented version of the code. Each test is then run individually, producing a coverage report each under `test/docker/coverage/`. These individual reports are then combined. The combined report is written to the `coverage` directory.
|
In order to generate code coverage metrics from the Docker tests, the build step creates a new Docker image with an instrumented version of the code. Each test is then run individually, producing a coverage report each under `test/docker/coverage/`. These individual reports are then combined. The combined report is written to the `coverage` directory.
|
||||||
|
|
||||||
|
|
||||||
### Running the Kubernetes tests
|
### Running the Kubernetes tests
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -79,17 +81,56 @@ func coverageBind(t *testing.T) string {
|
|||||||
return coverageDir(t) + ":/var/coverage"
|
return coverageDir(t) + ":/var/coverage"
|
||||||
}
|
}
|
||||||
|
|
||||||
// terminationLog returns the name of the file to use for the termination log message
|
// detect whether we are running in the Windows Subsystem for Linux
|
||||||
func terminationLog(t *testing.T) string {
|
func isWSL(t *testing.T) bool {
|
||||||
|
if (runtime.GOOS == "linux") {
|
||||||
|
var (
|
||||||
|
uname []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if uname, err = exec.Command("uname", "-r").Output(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Contains(string(uname), "Microsoft")
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the path of the tmp directory, in UNIX or OS-specific style
|
||||||
|
func getTempDir(t *testing.T, unixStylePath bool) string {
|
||||||
|
if (isWSL(t)) {
|
||||||
|
if (unixStylePath) {
|
||||||
|
return "/mnt/c/Temp/"
|
||||||
|
} else {
|
||||||
|
return "C:/Temp/"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "/tmp/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminationLogUnix returns the name of the file to use for the termination log message, with a UNIX path
|
||||||
|
func terminationLogUnixPath(t *testing.T) string {
|
||||||
// Warning: this directory must be accessible to the Docker daemon,
|
// Warning: this directory must be accessible to the Docker daemon,
|
||||||
// in order to enable the bind mount
|
// in order to enable the bind mount
|
||||||
return "/tmp/" + t.Name() + "-termination-log"
|
return getTempDir(t, true) + t.Name() + "-termination-log"
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminationLogWindows returns the name of the file to use for the termination log message, with an OS specific path
|
||||||
|
func terminationLogOSPath(t *testing.T) string {
|
||||||
|
// Warning: this directory must be accessible to the Docker daemon,
|
||||||
|
// in order to enable the bind mount
|
||||||
|
return getTempDir(t, false) + t.Name() + "-termination-log"
|
||||||
}
|
}
|
||||||
|
|
||||||
// terminationBind returns a string to use to bind-mount a termination log file.
|
// terminationBind returns a string to use to bind-mount a termination log file.
|
||||||
// This is done using a bind, because you can't copy files from /dev out of the container.
|
// This is done using a bind, because you can't copy files from /dev out of the container.
|
||||||
func terminationBind(t *testing.T) string {
|
func terminationBind(t *testing.T) string {
|
||||||
n := terminationLog(t)
|
n := terminationLogUnixPath(t)
|
||||||
// Remove it if it already exists
|
// Remove it if it already exists
|
||||||
os.Remove(n)
|
os.Remove(n)
|
||||||
// Create the empty file
|
// Create the empty file
|
||||||
@@ -98,12 +139,12 @@ func terminationBind(t *testing.T) string {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
f.Close()
|
f.Close()
|
||||||
return n + ":/dev/termination-log"
|
return terminationLogOSPath(t) + ":/dev/termination-log"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the termination message, or an empty string if not set
|
// Returns the termination message, or an empty string if not set
|
||||||
func terminationMessage(t *testing.T) string {
|
func terminationMessage(t *testing.T) string {
|
||||||
b, err := ioutil.ReadFile(terminationLog(t))
|
b, err := ioutil.ReadFile(terminationLogUnixPath(t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
}
|
}
|
||||||
@@ -147,7 +188,7 @@ func cleanContainer(t *testing.T, cli *client.Client, ID string) {
|
|||||||
if m != "" {
|
if m != "" {
|
||||||
t.Logf("Termination message: %v", m)
|
t.Logf("Termination message: %v", m)
|
||||||
}
|
}
|
||||||
os.Remove(terminationLog(t))
|
os.Remove(terminationLogUnixPath(t))
|
||||||
|
|
||||||
t.Logf("Removing container: %s", ID)
|
t.Logf("Removing container: %s", ID)
|
||||||
opts := types.ContainerRemoveOptions{
|
opts := types.ContainerRemoveOptions{
|
||||||
@@ -287,6 +328,9 @@ func execContainerWithExitCode(t *testing.T, cli *client.Client, ID string, user
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time.Sleep(4*time.Second)
|
||||||
|
|
||||||
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
|
inspect, err := cli.ContainerExecInspect(context.Background(), resp.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user