diff --git a/Dockerfile-server.cover b/Dockerfile-server.cover index 621390b..0122224 100644 --- a/Dockerfile-server.cover +++ b/Dockerfile-server.cover @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +ARG BASE_IMAGE + # Build stage to build Go code FROM golang:1.9 as builder WORKDIR /go/src/github.com/ibm-messaging/mq-container/ @@ -20,7 +22,7 @@ COPY internal/ ./internal COPY vendor/ ./vendor RUN go test -c -covermode=count -coverpkg $(go list ./cmd/runmqserver ./internal/... | paste -s -d, -) ./cmd/runmqserver -FROM mq-advancedserver:latest-x86_64 +FROM $BASE_IMAGE # Copy in the version of the code instrumented for code coverage COPY --from=builder /go/src/github.com/ibm-messaging/mq-container/runmqserver.test /usr/local/bin/ diff --git a/Makefile b/Makefile index a8ffde5..1dbfe6a 100644 --- a/Makefile +++ b/Makefile @@ -30,10 +30,12 @@ TEST_OPTS_DOCKER ?= TEST_OPTS_KUBERNETES ?= # MQ_IMAGE_ADVANCEDSERVER is the name and tag of the built MQ Advanced image MQ_IMAGE_ADVANCEDSERVER ?=mqadvanced-server:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG) -# MQ_IMAGE_ADVANCEDSERVER is the name and tag of the built MQ Advanced for Developers image +# MQ_IMAGE_DEVSERVER is the name and tag of the built MQ Advanced for Developers image MQ_IMAGE_DEVSERVER ?=mqadvanced-server-dev:$(MQ_VERSION)-$(ARCH)-$(BASE_IMAGE_TAG) # DOCKER is the Docker command to run DOCKER ?= docker +# MQ_PACKAGES specifies the MQ packages (.deb or .rpm) to install. Defaults vary on base image. +MQ_PACKAGES ?= ############################################################################### # Other variables @@ -145,13 +147,15 @@ test-advancedserver-cover: test/docker/vendor rm -f ./coverage/unit*.cov # Run unit tests with coverage, for each package under 'internal' go list -f '{{.Name}}' ./internal/... | xargs -I {} go test -cover -covermode count -coverprofile ./coverage/unit-{}.cov ./internal/{} +# ls -1 ./cmd | xargs -I {} go test -cover -covermode count -coverprofile ./coverage/unit-{}.cov ./cmd/{}/... echo 'mode: count' > ./coverage/unit.cov tail -q -n +2 ./coverage/unit-*.cov >> ./coverage/unit.cov go tool cover -html=./coverage/unit.cov -o ./coverage/unit.html rm -f ./test/docker/coverage/*.cov rm -f ./coverage/docker.* - cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER)-cover go test $(TEST_OPTS_DOCKER) + mkdir -p ./test/docker/coverage/ + cd test/docker && TEST_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER)-cover TEST_COVER=true go test $(TEST_OPTS_DOCKER) echo 'mode: count' > ./coverage/docker.cov tail -q -n +2 ./test/docker/coverage/*.cov >> ./coverage/docker.cov go tool cover -html=./coverage/docker.cov -o ./coverage/docker.html @@ -214,22 +218,16 @@ docker-version: build-advancedserver: downloads/$(MQ_ARCHIVE) docker-version $(info $(SPACER)$(shell printf $(TITLE)"Build $(MQ_IMAGE_ADVANCEDSERVER)"$(END))) $(call docker-build-mq,$(MQ_IMAGE_ADVANCEDSERVER),Dockerfile-server,$(MQ_ARCHIVE),"4486e8c4cc9146fd9b3ce1f14a2dfc5b","IBM MQ Advanced",$(MQ_VERSION)) -# $(DOCKER) tag $(DOCKER_FULL_ADVANCEDSERVER) $(DOCKER_REPO_ADVANCEDSERVER):$(MQ_VERSION)-$(ARCH)-$(subst :,-,$(BASE_IMAGE)) .PHONY: build-devserver build-devserver: downloads/$(MQ_ARCHIVE_DEV) docker-version @test "$(shell uname -m)" = "x86_64" || (echo "Error: MQ Advanced for Developers is only available for x86_64 architecture" && exit 1) $(info $(shell printf $(TITLE)"Build $(MQ_IMAGE_DEVSERVER)"$(END))) $(call docker-build-mq,$(MQ_IMAGE_DEVSERVER),Dockerfile-server,$(MQ_ARCHIVE_DEV),"98102d16795c4263ad9ca075190a2d4d","IBM MQ Advanced for Developers (Non-Warranted)",$(MQ_VERSION)) -# $(DOCKER) tag $(DOCKER_FULL_DEVSERVER) $(DOCKER_REPO_DEVSERVER):$(MQ_VERSION)-$(ARCH) .PHONY: build-advancedserver-cover build-advancedserver-cover: docker-version - $(DOCKER) build -t $(MQ_IMAGE_ADVANCEDSERVER)-cover -f Dockerfile-server.cover . - -# .PHONY: build-web -# build-web: build downloads/CNJR7ML.tar.gz -# $(call docker-build-mq,mq-web:latest-$(ARCH),Dockerfile-mq-web) + $(DOCKER) build --build-arg BASE_IMAGE=$(MQ_IMAGE_ADVANCEDSERVER) -t $(MQ_IMAGE_ADVANCEDSERVER)-cover -f Dockerfile-server.cover . .PHONY: build-explorer build-explorer: downloads/$(MQ_ARCHIVE_DEV) diff --git a/cmd/runmqserver/main_test.go b/cmd/runmqserver/main_test.go index 2a78204..0643f10 100644 --- a/cmd/runmqserver/main_test.go +++ b/cmd/runmqserver/main_test.go @@ -25,6 +25,8 @@ import ( var test *bool +const filename = "/var/coverage/exitCode" + func init() { test = flag.Bool("test", false, "Set to true when running tests for coverage") } @@ -38,8 +40,11 @@ func TestSystem(t *testing.T) { }() osExit = func(rc int) { // Write the exit code to a file instead - log.Printf("Writing exit code %v to file", strconv.Itoa(rc)) - ioutil.WriteFile("/var/coverage/exitCode", []byte(strconv.Itoa(rc)), 0644) + log.Printf("Writing exit code %v to file %v", strconv.Itoa(rc), filename) + err := ioutil.WriteFile(filename, []byte(strconv.Itoa(rc)), 0644) + if err != nil { + log.Print(err) + } } main() } diff --git a/test/docker/docker_api_test_util.go b/test/docker/docker_api_test_util.go index e1ad2a7..e3e91ed 100644 --- a/test/docker/docker_api_test_util.go +++ b/test/docker/docker_api_test_util.go @@ -19,6 +19,8 @@ import ( "archive/tar" "bytes" "context" + "encoding/json" + "io" "io/ioutil" "log" "os" @@ -34,6 +36,7 @@ import ( "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" + "github.com/moby/moby/pkg/jsonmessage" ) func imageName() string { @@ -44,6 +47,14 @@ func imageName() string { 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() @@ -63,6 +74,11 @@ func cleanContainer(t *testing.T, cli *client.Client, ID string) { if err == nil { // Log the results and continue t.Logf("Inspected container %v: %#v", ID, i) + s, err := json.MarshalIndent(i, "", " ") + if err != nil { + t.Fatal(err) + } + t.Logf("Inspected container %v: %v", ID, string(s)) } t.Logf("Stopping container: %v", ID) timeout := 10 * time.Second @@ -152,7 +168,7 @@ func getCoverageExitCode(t *testing.T, orig int64) int64 { f := filepath.Join(coverageDir(t), "exitCode") _, err := os.Stat(f) if err != nil { - //t.Log(err) + t.Log(err) return orig } // Remove the file, ready for the next test @@ -177,10 +193,12 @@ func waitForContainer(t *testing.T, cli *client.Client, ID string, timeout int64 //defer cancel() rc, err := cli.ContainerWait(context.Background(), ID) - // COVERAGE: When running coverage, the exit code is written to a file, - // to allow the coverage to be generated (which doesn't happen for non-zero - // exit codes) - rc = getCoverageExitCode(t, rc) + if coverage() { + // COVERAGE: When running coverage, the exit code is written to a file, + // to allow the coverage to be generated (which doesn't happen for non-zero + // exit codes) + rc = getCoverageExitCode(t, rc) + } // err := <-errC if err != nil { @@ -378,9 +396,22 @@ func createImage(t *testing.T, cli *client.Client, files []struct{ Name, Body st if err != nil { t.Fatal(err) } - resp.Body.Close() - // Sleep for two seconds, to try and prevent "No such image" errors - time.Sleep(2 * time.Second) + // resp (ImageBuildResponse) contains a series of JSON messages + dec := json.NewDecoder(resp.Body) + for { + m := jsonmessage.JSONMessage{} + err := dec.Decode(&m) + if m.Error != nil { + t.Fatal(m.ErrorMessage) + } + t.Log(strings.TrimSpace(m.Stream)) + if err == io.EOF { + break + } + if err != nil { + t.Fatal(err) + } + } return tag }