Skip to content

Commit

Permalink
test: add code coverage support
Browse files Browse the repository at this point in the history
Signed-off-by: Ramkumar Chinchani <[email protected]>
  • Loading branch information
rchincha committed Dec 20, 2022
1 parent e54a685 commit e258ecc
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: install dependencies
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -yy lxc-utils lxc-dev libacl1-dev jq libcap-dev libseccomp-dev libpam-dev bats parallel libzstd-dev
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@ jobs:
["1.19.x"]
privilege-level: >-
["unpriv", "priv"]
coverage:
uses: ./.github/workflows/coverage.yaml
with:
# note >-, args needs to be strings to be used as inputs
# for the reusable build.yaml workflow
go-version: >-
["1.19.x"]
privilege-level: >-
["unpriv", "priv"]
51 changes: 51 additions & 0 deletions .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Reusable stacker build for coverage
on:
workflow_call:
inputs:
go-version:
required: true
type: string
description: 'Stringified JSON object listing go versions'
privilege-level:
required: true
type: string
description: 'Stringified JSON object listing stacker privilege-level'
jobs:
build:
runs-on: ubuntu-22.04
services:
registry:
image: registry:2
ports:
- 5000:5000
strategy:
matrix:
go-version: ${{fromJson(inputs.go-version)}}
privilege-level: ${{fromJson(inputs.privilege-level)}}
name: "golang ${{ matrix.go-version }} privilege ${{ matrix.privilege-level }}"
steps:
- uses: actions/checkout@v3
- uses: benjlevesque/[email protected]
id: short-sha
- name: Set up golang ${{ matrix.go-version }}
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -yy lxc-utils lxc-dev libacl1-dev jq libcap-dev libseccomp-dev libpam-dev bats parallel libzstd-dev
GO111MODULE=off go get github.com/opencontainers/umoci/cmd/umoci
sudo cp ~/go/bin/umoci /usr/bin
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
sudo apt-get install -yy autoconf automake make autogen autoconf libtool binutils git squashfs-tools libcryptsetup-dev libdevmapper-dev cryptsetup-bin squashfuse
(cd /tmp && git clone https://github.com/AgentD/squashfs-tools-ng && cd squashfs-tools-ng && ./autogen.sh && ./configure --prefix=/usr && make -j2 && sudo make -j2 install && sudo ldconfig -v)
(cd /tmp && git clone https://github.com/anuvu/squashfs && cd squashfs && make && sudo cp squashtool/squashtool /usr/bin)
- if: github.event_name != 'release' || github.event.action != 'published'
name: Build and test
run: |
make check-cov PRIVILEGE_LEVEL=${{ matrix.privilege-level }}
env:
REGISTRY_URL: localhost:5000
- name: Upload code coverage
uses: codecov/codecov-action@v3
26 changes: 22 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ BUILD_TAGS = exclude_graphdriver_btrfs exclude_graphdriver_devicemapper containe

STACKER_OPTS=--oci-dir=.build/oci --roots-dir=.build/roots --stacker-dir=.build/stacker --storage-type=overlay

build_stacker = go build -tags "$(BUILD_TAGS) $1" -ldflags "-X main.version=$(VERSION_FULL) -X main.lxc_version=$(LXC_VERSION) $2" -o $3 ./cmd/stacker
build_stacker = go $1 -tags "$(BUILD_TAGS) $2" -ldflags "-X main.version=$(VERSION_FULL) -X main.lxc_version=$(LXC_VERSION) $3" -o $4 ./cmd/stacker

STACKER_DOCKER_BASE?=docker://
STACKER_BUILD_BASE_IMAGE?=$(STACKER_DOCKER_BASE)alpine:edge
Expand All @@ -23,15 +23,28 @@ stacker: stacker-dynamic
--substitute STACKER_BUILD_BASE_IMAGE=$(STACKER_BUILD_BASE_IMAGE) \
--substitute LXC_CLONE_URL=$(LXC_CLONE_URL) \
--substitute LXC_BRANCH=$(LXC_BRANCH) \
--substitute VERSION_FULL=$(VERSION_FULL)
--substitute VERSION_FULL=$(VERSION_FULL) \
--substitute WITH_COV=no

stacker-cov: stacker-dynamic
./stacker-dynamic --debug $(STACKER_OPTS) build \
-f build.yaml --shell-fail \
--substitute STACKER_BUILD_BASE_IMAGE=$(STACKER_BUILD_BASE_IMAGE) \
--substitute LXC_CLONE_URL=$(LXC_CLONE_URL) \
--substitute LXC_BRANCH=$(LXC_BRANCH) \
--substitute VERSION_FULL=$(VERSION_FULL) \
--substitute WITH_COV=yes

stacker-static: $(GO_SRC) go.mod go.sum cmd/stacker/lxc-wrapper/lxc-wrapper
$(call build_stacker,static_build,-extldflags '-static',stacker)
$(call build_stacker,build,static_build,-extldflags '-static',stacker)

stacker-static-cov: $(GO_SRC) go.mod go.sum cmd/stacker/lxc-wrapper/lxc-wrapper
$(call build_stacker,test -c -race -cover -covermode=atomic -coverpkg="./...",static_build testrunmain,-extldflags '-static',stacker)

# TODO: because we clean lxc-wrapper in the nested build, this always rebuilds.
# Could find a better way to do this.
stacker-dynamic: $(GO_SRC) go.mod go.sum cmd/stacker/lxc-wrapper/lxc-wrapper
$(call build_stacker,,,stacker-dynamic)
$(call build_stacker,build,,,stacker-dynamic)

cmd/stacker/lxc-wrapper/lxc-wrapper: cmd/stacker/lxc-wrapper/lxc-wrapper.c
make -C cmd/stacker/lxc-wrapper LDFLAGS=-static LDLIBS="$(shell pkg-config --static --libs lxc) -lpthread -ldl" lxc-wrapper
Expand Down Expand Up @@ -61,6 +74,11 @@ check: stacker lint
$(shell [ -z $(PRIVILEGE_LEVEL) ] || echo --privilege-level=$(PRIVILEGE_LEVEL)) \
$(patsubst %,test/%.bats,$(TEST))

check-cov: stacker-cov lint
sudo -E PATH="$$PATH" LXC_BRANCH="$(LXC_BRANCH)" LXC_CLONE_URL="$(LXC_CLONE_URL)" ./test/main.py \
$(shell [ -z $(PRIVILEGE_LEVEL) ] || echo --privilege-level=$(PRIVILEGE_LEVEL)) \
$(patsubst %,test/%.bats,$(TEST))

.PHONY: vendorup
vendorup:
go get -u
Expand Down
6 changes: 5 additions & 1 deletion build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,8 @@ build:
export VERSION_FULL=${{VERSION_FULL}}
make -C /stacker-tree/cmd/stacker/lxc-wrapper clean
make -C /stacker-tree stacker-static
if [ x${{WITH_COV}} = x"yes" ]; then
make -C /stacker-tree stacker-static-cov
else
make -C /stacker-tree stacker-static
fi
39 changes: 39 additions & 0 deletions cmd/stacker/cov_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//go:build testrunmain
// +build testrunmain

package main

import (
"fmt"
"os"
"os/signal"
"stackerbuild.io/stacker/pkg/log"
"syscall"
"testing"
"time"
)

func init() {
log.Infof("stacker[%d]: Running with sanity coverage enabled\n", os.Getpid())
os.Args = append([]string{os.Args[0]}, "-test.coverprofile", fmt.Sprintf("coverage-%d.txt", time.Now().Unix()), "--")
os.Args = append(os.Args, os.Args[1:]...)
}

func TestRunMain(t *testing.T) {
/*
https://golang.org/pkg/os/signal/#Notify
It is allowed to call Notify multiple times with different channels and the
same signals: each channel receives copies of incoming signals
independently.
*/
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM)
done := make(chan struct{})
go func() {
<-sigs
done <- struct{}{}
}()

go func() { main() }()
<-done
}
14 changes: 13 additions & 1 deletion cmd/stacker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,5 +301,17 @@ func main() {
return nil
}

stackerResult(app.Run(os.Args))
args := os.Args

// check if run under code coverage
for i, arg := range os.Args {
if arg == "-test.coverprofile" {
args = append(os.Args[:i], os.Args[i+3:]...)
break
}
}

log.Infof("cmdline args: %v", args)

stackerResult(app.Run(args))
}
1 change: 1 addition & 0 deletions cmd/stacker/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main

0 comments on commit e258ecc

Please sign in to comment.