Fix test coverage in docker containers

This commit is contained in:
Riccardo Biraghi
2018-04-20 17:34:37 +02:00
parent 818cbaca8d
commit d7633d8313
4 changed files with 58 additions and 42 deletions

View File

@@ -156,8 +156,11 @@ test-devserver: test/docker/vendor
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_DEVSERVER) on $(shell docker --version)"$(END))) $(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_DEVSERVER) on $(shell docker --version)"$(END)))
cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER) DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) go test -parallel $(NUM_CPU) -tags mqdev $(TEST_OPTS_DOCKER) cd test/docker && TEST_IMAGE=$(MQ_IMAGE_DEVSERVER) DEV_JMS_IMAGE=$(DEV_JMS_IMAGE) go test -parallel $(NUM_CPU) -tags mqdev $(TEST_OPTS_DOCKER)
coverage:
mkdir coverage
.PHONY: test-advancedserver-cover .PHONY: test-advancedserver-cover
test-advancedserver-cover: test/docker/vendor test-advancedserver-cover: test/docker/vendor coverage
$(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER) with code coverage on $(shell docker --version)"$(END))) $(info $(SPACER)$(shell printf $(TITLE)"Test $(MQ_IMAGE_ADVANCEDSERVER) with code coverage on $(shell docker --version)"$(END)))
rm -f ./coverage/unit*.cov rm -f ./coverage/unit*.cov
# Run unit tests with coverage, for each package under 'internal' # Run unit tests with coverage, for each package under 'internal'

View File

@@ -19,6 +19,7 @@ import (
"flag" "flag"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strconv" "strconv"
"testing" "testing"
@@ -27,8 +28,6 @@ import (
var test *bool var test *bool
const filename = "/var/coverage/exitCode"
func init() { func init() {
test = flag.Bool("test", false, "Set to true when running tests for coverage") test = flag.Bool("test", false, "Set to true when running tests for coverage")
log, _ = logger.NewLogger(os.Stdout, true, false, "test") log, _ = logger.NewLogger(os.Stdout, true, false, "test")
@@ -41,6 +40,14 @@ func TestSystem(t *testing.T) {
defer func() { defer func() {
osExit = oldExit osExit = oldExit
}() }()
filename, ok := os.LookupEnv("EXIT_CODE_FILE")
if !ok {
filename = "/var/coverage/exitCode"
} else {
filename = filepath.Join("/var/coverage/", filename)
}
osExit = func(rc int) { osExit = func(rc int) {
// Write the exit code to a file instead // Write the exit code to a file instead
log.Printf("Writing exit code %v to file %v", strconv.Itoa(rc), filename) log.Printf("Writing exit code %v to file %v", strconv.Itoa(rc), filename)

View File

@@ -74,21 +74,7 @@ func waitForWebReady(t *testing.T, cli *client.Client, ID string, tlsConfig *tls
// tlsDir returns the host directory where the test certificate(s) are located // tlsDir returns the host directory where the test certificate(s) are located
func tlsDir(t *testing.T, unixPath bool) string { func tlsDir(t *testing.T, unixPath bool) string {
dir, err := os.Getwd() return filepath.Join(getCwd(t, unixPath), "../tls")
if err != nil {
t.Fatal(err)
}
if isWSL(t) {
// Check if the cwd is a symlink
dir, err = filepath.EvalSymlinks(dir)
if err != nil {
t.Fatal(err)
}
if !unixPath {
dir = strings.Replace(dir, getWindowsRoot(true), getWindowsRoot(false), 1)
}
}
return filepath.Join(dir, "../tls")
} }
// runJMSTests runs a container with a JMS client, which connects to the queue manager container with the specified ID // runJMSTests runs a container with a JMS client, which connects to the queue manager container with the specified ID

View File

@@ -60,28 +60,6 @@ func imageNameDevJMS() string {
return image return image
} }
func coverage() bool {
cover := os.Getenv("TEST_COVER")
if cover == "true" || cover == "1" {
return true
}
return false
}
// coverageDir returns the host directory to use for code coverage data
func coverageDir(t *testing.T) string {
dir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
return filepath.Join(dir, "coverage")
}
// coverageBind returns a string to use to add a bind-mounted directory for code coverage data
func coverageBind(t *testing.T) string {
return coverageDir(t) + ":/var/coverage"
}
// 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" {
@@ -94,6 +72,25 @@ func isWSL(t *testing.T) bool {
return false return false
} }
// getCwd returns the working directory, in an os-specific or UNIX form
func getCwd(t *testing.T, unixPath bool) string {
dir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if isWSL(t) {
// Check if the cwd is a symlink
dir, err = filepath.EvalSymlinks(dir)
if err != nil {
t.Fatal(err)
}
if !unixPath {
dir = strings.Replace(dir, getWindowsRoot(true), getWindowsRoot(false), 1)
}
}
return dir
}
// getWindowsRoot get the path of the root directory on Windows, in UNIX or OS-specific style // getWindowsRoot get the path of the root directory on Windows, in UNIX or OS-specific style
func getWindowsRoot(unixStylePath bool) string { func getWindowsRoot(unixStylePath bool) string {
if unixStylePath { if unixStylePath {
@@ -102,6 +99,24 @@ func getWindowsRoot(unixStylePath bool) string {
return "C:/" return "C:/"
} }
func coverage() bool {
cover := os.Getenv("TEST_COVER")
if cover == "true" || cover == "1" {
return true
}
return false
}
// coverageDir returns the host directory to use for code coverage data
func coverageDir(t *testing.T, unixStylePath bool) string {
return filepath.Join(getCwd(t, unixStylePath), "coverage")
}
// coverageBind returns a string to use to add a bind-mounted directory for code coverage data
func coverageBind(t *testing.T) string {
return coverageDir(t, false) + ":/var/coverage"
}
// getTempDir get the path of the tmp directory, in UNIX or OS-specific style // getTempDir get the path of the tmp directory, in UNIX or OS-specific style
func getTempDir(t *testing.T, unixStylePath bool) string { func getTempDir(t *testing.T, unixStylePath bool) string {
if isWSL(t) { if isWSL(t) {
@@ -177,7 +192,7 @@ func cleanContainer(t *testing.T, cli *client.Client, ID string) {
t.Log("Container stopped") t.Log("Container stopped")
// If a code coverage file has been generated, then rename it to match the test name // If a code coverage file has been generated, then rename it to match the test name
os.Rename(filepath.Join(coverageDir(t), "container.cov"), filepath.Join(coverageDir(t), t.Name()+".cov")) os.Rename(filepath.Join(coverageDir(t, true), "container.cov"), filepath.Join(coverageDir(t, true), t.Name()+".cov"))
// Log the container output for any container we're about to delete // Log the container output for any container we're about to delete
t.Logf("Console log from container %v:\n%v", ID, inspectTextLogs(t, cli, ID)) t.Logf("Console log from container %v:\n%v", ID, inspectTextLogs(t, cli, ID))
@@ -207,6 +222,7 @@ func runContainer(t *testing.T, cli *client.Client, containerConfig *container.C
} }
// if coverage // if coverage
containerConfig.Env = append(containerConfig.Env, "COVERAGE_FILE="+t.Name()+".cov") containerConfig.Env = append(containerConfig.Env, "COVERAGE_FILE="+t.Name()+".cov")
containerConfig.Env = append(containerConfig.Env, "EXIT_CODE_FILE="+getExitCodeFilename(t))
hostConfig := container.HostConfig{ hostConfig := container.HostConfig{
Binds: []string{ Binds: []string{
coverageBind(t), coverageBind(t),
@@ -259,8 +275,12 @@ func stopContainer(t *testing.T, cli *client.Client, ID string) {
} }
} }
func getExitCodeFilename(t *testing.T) string {
return t.Name() + "ExitCode"
}
func getCoverageExitCode(t *testing.T, orig int64) int64 { func getCoverageExitCode(t *testing.T, orig int64) int64 {
f := filepath.Join(coverageDir(t), "exitCode") f := filepath.Join(coverageDir(t, true), getExitCodeFilename(t))
_, err := os.Stat(f) _, err := os.Stat(f)
if err != nil { if err != nil {
t.Log(err) t.Log(err)