Skip to content

Commit

Permalink
Add test coverage to workflows
Browse files Browse the repository at this point in the history
This change adds code coverage to our workflows and the necessary
Makefile targets to support this.

Signed-off-by: David Son <davbson@amazon.com>
  • Loading branch information
sondavidb committed Sep 6, 2024
1 parent 0aeabca commit d473bcc
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 12 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ jobs:
if: matrix.os == 'al2-arm'
run: dnf install zlib-static.aarch64 -y
- run: make
- run: make test
- run: make test-with-coverage
- name: Show test coverage
run: make test-with-coverage

integration:
needs: setup
Expand All @@ -91,4 +93,6 @@ jobs:
- name: Install zlib static on AL2 ARM instances
if: matrix.os == 'al2-arm'
run: dnf install zlib-static.aarch64 -y
- run: make integration
- run: make integration-with-coverage
- name: Show test coverage
run: make integration-with-coverage
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/cov
/out
/release
*.db
Expand Down
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ ARG CONTAINERD_VERSION
ARG RUNC_VERSION
ARG NERDCTL_VERSION
ARG TARGETARCH
ENV GOPROXY direct
ENV GOCOVERDIR /test_coverage

COPY ./integ_entrypoint.sh /integ_entrypoint.sh
COPY . $GOPATH/src/github.com/awslabs/soci-snapshotter
ENV GOPROXY direct
RUN apk update && apk upgrade
RUN apk add --no-cache \
btrfs-progs-libs \
Expand Down
36 changes: 33 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
CMD_DESTDIR ?= /usr/local
GO111MODULE_VALUE=auto
OUTDIR ?= $(CURDIR)/out
COVDIR ?= $(CURDIR)/cov
PKG=github.com/awslabs/soci-snapshotter
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
REVISION=$(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi)
Expand Down Expand Up @@ -55,11 +56,17 @@ CMD=soci-snapshotter-grpc soci

CMD_BINARIES=$(addprefix $(OUTDIR)/,$(CMD))

PACKAGE_LIST_CMD=go list -f '{{.ImportPath}}' ./... | grep -v "benchmark" | paste -sd ","

SOCI_LIBRARY_PACKAGE_LIST=$(shell $(PACKAGE_LIST_CMD))
SOCI_CLI_PACKAGE_LIST=$(shell echo $(SOCI_LIBRARY_PACKAGE_LIST),$(shell cd $(SOCI_SNAPSHOTTER_PROJECT_ROOT)/cmd/soci && $(PACKAGE_LIST_CMD)))
SOCI_GRPC_PACKAGE_LIST=$(shell echo $(SOCI_LIBRARY_PACKAGE_LIST),$(shell cd $(SOCI_SNAPSHOTTER_PROJECT_ROOT)/cmd/soci-snapshotter-grpc && $(PACKAGE_LIST_CMD)))

GO_BENCHMARK_TESTS?=.

.PHONY: all build check flatc add-ltag install uninstall tidy vendor clean \
clean-integration test integration release benchmarks build-benchmarks \
benchmarks-perf-test benchmarks-comparison-test
clean-integration test test-coverage integration integration-coverage release \
benchmarks build-benchmarks benchmarks-perf-test benchmarks-comparison-test

all: build

Expand Down Expand Up @@ -99,6 +106,7 @@ clean: clean-integration
@echo "🧹 ... 🗑️"
@rm -rf $(OUTDIR)
@rm -rf $(CURDIR)/release/
@rm -rf $(COVDIR)
@echo "All clean!"

clean-integration:
Expand Down Expand Up @@ -127,13 +135,35 @@ vendor:

test:
@echo "$@"
@GO111MODULE=$(GO111MODULE_VALUE) go test $(GO_TEST_FLAGS) $(GO_LD_FLAGS) -race ./...
@GO111MODULE=$(GO111MODULE_VALUE) go test $(GO_TEST_FLAGS) $(GO_LD_FLAGS) -race `go list ./... | grep -v benchmark` -args $(GO_TEST_ARGS)

test-with-coverage: $(COVDIR)/unit
go tool covdata percent -i $(COVDIR)/unit

$(COVDIR):
@mkdir -p $@

$(COVDIR)/unit: $(COVDIR)
@mkdir -p $@
GO_TEST_FLAGS="$(GO_TEST_FLAGS) -cover" \
GO_TEST_ARGS="-test.gocoverdir=$(COVDIR)/unit" \
GO_BUILD_FLAGS="$(GO_BUILD_FLAGS) -coverpkg=$(SOCI_LIBRARY_PACKAGE_LIST)"\
$(MAKE) test

integration: build
@echo "$@"
@echo "SOCI_SNAPSHOTTER_PROJECT_ROOT=$(SOCI_SNAPSHOTTER_PROJECT_ROOT)"
@GO111MODULE=$(GO111MODULE_VALUE) SOCI_SNAPSHOTTER_PROJECT_ROOT=$(SOCI_SNAPSHOTTER_PROJECT_ROOT) ENABLE_INTEGRATION_TEST=true go test $(GO_TEST_FLAGS) -v -timeout=0 ./integration

integration-with-coverage: $(COVDIR)/integration
go tool covdata percent -i $(COVDIR)/integration

$(COVDIR)/integration: $(COVDIR)
@mkdir -p $@
GO_TEST_FLAGS="$(GO_TEST_FLAGS)" \
GO_BUILD_FLAGS="$(GO_BUILD_FLAGS) -coverpkg=$(SOCI_CLI_PACKAGE_LIST),$(SOCI_GRPC_PACKAGE_LIST)" \
$(MAKE) integration

release:
@echo "$@"
@$(SOCI_SNAPSHOTTER_PROJECT_ROOT)/scripts/create-releases.sh $(RELEASE_TAG)
Expand Down
42 changes: 37 additions & 5 deletions integration/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"encoding/csv"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"math/big"
"os"
Expand Down Expand Up @@ -148,12 +149,14 @@ services:
entrypoint: [ "/integ_entrypoint.sh" ]
environment:
- NO_PROXY=127.0.0.1,localhost
- GOCOVERDIR=/test_coverage
tmpfs:
- /tmp:exec,mode=777
- /var/lib/containerd
- /var/lib/soci-snapshotter-grpc
volumes:
- /dev/fuse:/dev/fuse
- {{.ImageContextDir}}/cov/integration:/test_coverage
`
const composeRegistryTemplate = `
version: "3.7"
Expand All @@ -165,12 +168,14 @@ services:
entrypoint: [ "/integ_entrypoint.sh" ]
environment:
- NO_PROXY=127.0.0.1,localhost,{{.RegistryHost}}:443
- GOCOVERDIR=/test_coverage
tmpfs:
- /tmp:exec,mode=777
- /var/lib/containerd
- /var/lib/soci-snapshotter-grpc
volumes:
- /dev/fuse:/dev/fuse
- {{.ImageContextDir}}/cov/integration:/test_coverage
registry:
image: {{.RegistryImageRef}}
container_name: {{.RegistryHost}}
Expand All @@ -197,12 +202,14 @@ services:
entrypoint: [ "/integ_entrypoint.sh" ]
environment:
- NO_PROXY=127.0.0.1,localhost,{{.RegistryHost}}:443
- GOCOVERDIR=/test_coverage
tmpfs:
- /tmp:exec,mode=777
- /var/lib/containerd
- /var/lib/soci-snapshotter-grpc
volumes:
- /dev/fuse:/dev/fuse
- {{.ImageContextDir}}/cov/integration:/test_coverage
registry:
image: {{.RegistryImageRef}}
container_name: {{.RegistryHost}}
Expand Down Expand Up @@ -473,6 +480,11 @@ func newShellWithRegistry(t *testing.T, r registryConfig, opts ...registryOpt) (
serviceName = "testing"
)

pRoot, err := testutil.GetProjectRoot()
if err != nil {
t.Fatal(err)
}

// Setup dummy creds for test
crt, key, err := generateRegistrySelfSignedCert(r.host)
if err != nil {
Expand Down Expand Up @@ -541,6 +553,7 @@ networks:

s, err := testutil.ApplyTextTemplate(composeRegistryTemplate, dockerComposeYaml{
ServiceName: serviceName,
ImageContextDir: pRoot,
RegistryHost: r.host,
RegistryImageRef: rOpts.registryImageRef,
HostVolumeMount: hostVolumeMount,
Expand All @@ -567,12 +580,13 @@ networks:
X("update-ca-certificates").
Retry(100, "nerdctl", "login", "-u", r.user, "-p", r.pass, r.host)
return sh, func() error {
if err := c.Cleanup(); err != nil {
return err
killErr := testutil.KillMatchingProcess(sh, "soci-snapshotter-grpc")
if err = c.Cleanup(); err != nil {
return errors.Join(killErr, err)
}
for _, f := range cleanups {
if err := f(); err != nil {
return err
return errors.Join(killErr, err)
}
}
return nil
Expand All @@ -585,7 +599,18 @@ func newSnapshotterBaseShell(t *testing.T) (*shell.Shell, func() error) {
if err != nil {
t.Fatal(err)
}
c, err := compose.Up(composeDefaultTemplate, compose.WithBuildArgs(buildArgs...), compose.WithStdio(testutil.TestingLogDest()))

pRoot, err := testutil.GetProjectRoot()
if err != nil {
t.Fatal(err)
}
s, err := testutil.ApplyTextTemplate(composeDefaultTemplate, dockerComposeYaml{
ImageContextDir: pRoot,
})
if err != nil {
t.Fatal(err)
}
c, err := compose.Up(s, compose.WithBuildArgs(buildArgs...), compose.WithStdio(testutil.TestingLogDest()))
if err != nil {
t.Fatalf("failed to prepare compose: %v", err)
}
Expand All @@ -599,7 +624,14 @@ func newSnapshotterBaseShell(t *testing.T) (*shell.Shell, func() error) {
t.Fatalf("failed to write containerd config %v: %v", defaultContainerdConfigPath, err)
}
}
return sh, c.Cleanup
cleanup := func() error {
err := testutil.KillMatchingProcess(sh, "soci-snapshotter-grpc")
if err != nil {
return fmt.Errorf("stop-soci-err: %v, compose-cleanup-err: %v", err, c.Cleanup())
}
return c.Cleanup()
}
return sh, cleanup
}

func generateRegistrySelfSignedCert(registryHost string) (crt, key []byte, _ error) {
Expand Down
3 changes: 2 additions & 1 deletion util/testutil/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,8 @@ func KillMatchingProcess(sh *shell.Shell, psLinePattern string) error {

var allErr error
for _, pid := range targets {
if err := sh.Command("kill", "-9", fmt.Sprintf("%d", pid)).Run(); err != nil {
// Send SIGTERM so the unit under test correctly writes integration coverage reports to Go coverage directory.
if err := sh.Command("kill", "-2", fmt.Sprintf("%d", pid)).Run(); err != nil {
errors.Join(allErr, fmt.Errorf("failed to kill %v: %w", pid, err))
}
}
Expand Down

0 comments on commit d473bcc

Please sign in to comment.