Skip to content

Commit d257068

Browse files
JustinKulidhaiducek
authored andcommitted
Implement test coverage
Refs: - stolostron/backlog#24298 Co-authored-by: Dale Haiducek <[email protected]> Signed-off-by: Justin Kulikauskas <[email protected]>
1 parent f99ae0c commit d257068

File tree

4 files changed

+111
-11
lines changed

4 files changed

+111
-11
lines changed

.github/workflows/kind.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
kind-tests:
1818
runs-on: ubuntu-latest
1919
strategy:
20+
fail-fast: false
2021
matrix:
2122
# KinD tags: https://hub.docker.com/r/kindest/node/tags
2223
# (OCP 4.6 runs Kubernetes v1.19)
@@ -51,7 +52,7 @@ jobs:
5152
run: |
5253
export GOPATH=$(go env GOPATH)
5354
make wait-for-work-agent
54-
make e2e-test
55+
make e2e-test-coverage
5556
5657
- if: matrix.hosted_mode == 'true'
5758
name: E2E tests hosted mode
@@ -60,6 +61,14 @@ jobs:
6061
make wait-for-work-agent
6162
make e2e-test-hosted-mode
6263
64+
- name: Test Coverage Verification
65+
if: |
66+
github.event_name == 'pull_request' &&
67+
matrix.hosted_mode == 'false'
68+
run: |
69+
make test-coverage
70+
make coverage-verify
71+
6372
- name: Clean up clusters
6473
run: |
6574
RUN_MODE="delete" ./build/manage-clusters.sh

Makefile

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ vet: ## Run go vet against code.
8282

8383
.PHONY: test
8484
test: manifests generate fmt vet envtest ## Run tests.
85-
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test `go list ./... | grep -v test/e2e` -coverprofile coverage.out
85+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test $(TESTARGS) `go list ./... | grep -v test/e2e`
86+
87+
.PHONY: test-coverage
88+
test-coverage: TESTARGS = -json -cover -covermode=atomic -coverprofile=coverage_unit.out
89+
test-coverage: test
8690

8791
GOSEC = $(LOCAL_BIN)/gosec
8892
GOSEC_VERSION = 2.9.6
@@ -159,6 +163,7 @@ HUB_KUBECONFIG ?= $(PWD)/policy-addon-ctrl1.kubeconfig
159163
HUB_KUBECONFIG_INTERNAL ?= $(PWD)/policy-addon-ctrl1.kubeconfig-internal
160164
HUB_CLUSTER_NAME ?= policy-addon-ctrl1
161165
MANAGED_CLUSTER_NAME ?= cluster1
166+
KIND_VERSION ?= latest
162167
ifneq ($(KIND_VERSION), latest)
163168
KIND_ARGS = --image kindest/node:$(KIND_VERSION)
164169
else
@@ -220,7 +225,7 @@ CONTROLLER_NAMESPACE ?= governance-policy-addon-controller-system
220225

221226
.PHONY: kind-run-local
222227
kind-run-local: manifests generate fmt vet $(KIND_KUBECONFIG) ## Run the policy-addon-controller locally against the kind cluster.
223-
KUBECONFIG=$(KIND_KUBECONFIG) kubectl get ns $(CONTROLLER_NAMESPACE); if [ $$? -ne 0 ] ; then kubectl create ns $(CONTROLLER_NAMESPACE); fi
228+
-KUBECONFIG=$(KIND_KUBECONFIG) kubectl create ns $(CONTROLLER_NAMESPACE)
224229
go run ./main.go controller --kubeconfig=$(KIND_KUBECONFIG) --namespace $(CONTROLLER_NAMESPACE)
225230

226231
.PHONY: kind-load-image
@@ -235,24 +240,52 @@ kind-regenerate-controller: manifests generate kustomize $(KIND_KUBECONFIG) ## R
235240
mv config/default/kustomization.yaml.tmp config/default/kustomization.yaml
236241
KUBECONFIG=$(KIND_KUBECONFIG) kubectl delete -n $(CONTROLLER_NAMESPACE) pods -l=app=governance-policy-addon-controller
237242

238-
DEPLOYMENT_TARGETS := kind-deploy-registration-operator-hub kind-deploy-registration-operator-managed \
239-
kind-approve-cluster kind-load-image kind-regenerate-controller
243+
OCM_PREP_TARGETS := kind-deploy-registration-operator-hub kind-deploy-registration-operator-managed kind-approve-cluster
244+
.PHONY: kind-prep-ocm
245+
kind-prep-ocm: $(OCM_PREP_TARGETS) ## Install OCM registration pieces and connect the clusters
246+
240247
.PHONY: kind-deploy-controller
241-
kind-deploy-controller: $(DEPLOYMENT_TARGETS) ## Deploy the policy-addon-controller to the kind cluster.
248+
kind-deploy-controller: kind-prep-ocm kind-load-image kind-regenerate-controller ## Deploy the policy-addon-controller to the kind cluster.
242249

243250
GINKGO = $(LOCAL_BIN)/ginkgo
244251
.PHONY: e2e-dependencies
245252
e2e-dependencies: ## Download ginkgo locally if necessary.
246253
$(call go-get-tool,github.com/onsi/ginkgo/v2/ginkgo@$(shell awk '/github.com\/onsi\/ginkgo\/v2/ {print $$2}' go.mod))
247254

248255
.PHONY: e2e-test
249-
e2e-test: e2e-dependencies
250-
$(GINKGO) -v --label-filter="!hosted-mode" --fail-fast --slow-spec-threshold=10s test/e2e
256+
e2e-test: e2e-dependencies ## Run E2E tests.
257+
$(GINKGO) -v --label-filter="!hosted-mode" --fail-fast --slow-spec-threshold=10s $(E2E_TEST_ARGS) test/e2e
251258

252259
.PHONY: e2e-test-hosted-mode
253260
e2e-test-hosted-mode: e2e-dependencies
254261
$(GINKGO) -v --label-filter="hosted-mode" --fail-fast --slow-spec-threshold=10s test/e2e
255262

263+
.PHONY: e2e-test-coverage
264+
e2e-test-coverage: E2E_TEST_ARGS = --json-report=report_e2e.json --output-dir=.
265+
e2e-test-coverage: e2e-run-instrumented e2e-test e2e-stop-instrumented ## Run E2E tests using instrumented controller.
266+
267+
.PHONY: e2e-build-instrumented
268+
e2e-build-instrumented:
269+
go test -covermode=atomic -coverpkg=$(shell cat go.mod | head -1 | cut -d ' ' -f 2)/... -c -tags e2e ./ -o build/_output/bin/$(IMG)-instrumented
270+
271+
COVERAGE_E2E_OUT ?= coverage_e2e.out
272+
.PHONY: e2e-run-instrumented
273+
e2e-run-instrumented: e2e-build-instrumented
274+
-KUBECONFIG=$(KIND_KUBECONFIG) kubectl create ns $(CONTROLLER_NAMESPACE)
275+
CONFIG_POLICY_CONTROLLER_IMAGE="$(REGISTRY)/config-policy-controller:$(TAG)" \
276+
KUBE_RBAC_PROXY_IMAGE="registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.10" \
277+
GOVERNANCE_POLICY_SPEC_SYNC_IMAGE="$(REGISTRY)/governance-policy-spec-sync:$(TAG)" \
278+
GOVERNANCE_POLICY_STATUS_SYNC_IMAGE="$(REGISTRY)/governance-policy-status-sync:$(TAG)" \
279+
GOVERNANCE_POLICY_TEMPLATE_SYNC_IMAGE="$(REGISTRY)/governance-policy-template-sync:$(TAG)" \
280+
./build/_output/bin/$(IMG)-instrumented -test.v -test.run="^TestRunMain$$" -test.coverprofile=$(COVERAGE_E2E_OUT) \
281+
--kubeconfig="$(KIND_KUBECONFIG)" &>build/_output/controller.log &
282+
283+
.PHONY: e2e-stop-instrumented
284+
e2e-stop-instrumented:
285+
ps -ef | grep '$(IMG)' | grep -v grep | awk '{print $$2}' | xargs kill -s SIGUSR1
286+
sleep 5 # wait for tests to gracefully shut down
287+
-ps -ef | grep '$(IMG)' | grep -v grep | awk '{print $$2}' | xargs kill
288+
256289
.PHONY: e2e-debug
257290
e2e-debug: ## Collect debug logs from deployed clusters.
258291
@echo "##### Gathering information from $(KIND_NAME) #####"
@@ -262,7 +295,9 @@ e2e-debug: ## Collect debug logs from deployed clusters.
262295
-KUBECONFIG=$(KIND_KUBECONFIG) kubectl -n open-cluster-management-agent-addon get deployments
263296
-KUBECONFIG=$(KIND_KUBECONFIG) kubectl -n open-cluster-management-agent-addon get pods
264297
-KUBECONFIG=$(KIND_KUBECONFIG) kubectl get manifestwork --all-namespaces -o yaml
265-
298+
299+
@echo "* Local controller log:""
300+
-cat build/_output/controller.log
266301
@echo "* Container logs in namespace $(CONTROLLER_NAMESPACE):"
267302
-@for POD in $(shell KUBECONFIG=$(KIND_KUBECONFIG) kubectl -n $(CONTROLLER_NAMESPACE) get pods -o name); do \
268303
for CONTAINER in $$(KUBECONFIG=$(KIND_KUBECONFIG) kubectl -n $(CONTROLLER_NAMESPACE) get $${POD} -o jsonpath={.spec.containers[*].name}); do \
@@ -301,3 +336,19 @@ lint-dependencies:
301336
# eg: lint: lint-go lint-yaml
302337
.PHONY: lint
303338
lint: lint-dependencies lint-all ## Run linting against the code.
339+
340+
##@ Test Coverage
341+
GOCOVMERGE = $(LOCAL_BIN)/gocovmerge
342+
.PHONY: coverage-dependencies
343+
coverage-dependencies:
344+
$(call go-get-tool,github.com/wadey/[email protected])
345+
346+
COVERAGE_FILE = coverage.out
347+
.PHONY: coverage-merge
348+
coverage-merge: coverage-dependencies ## Merge coverage reports.
349+
@echo Merging the coverage reports into $(COVERAGE_FILE)
350+
$(GOCOVMERGE) $(PWD)/coverage_* > $(COVERAGE_FILE)
351+
352+
.PHONY: coverage-verify
353+
coverage-verify: ## Verify coverage percentage meets coverage thresholds.
354+
./build/common/scripts/coverage_calc.sh

build/manage-clusters.sh

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#! /bin/bash
22

3-
RUN_MODE=${RUN_MODE:-"create"}
3+
if [[ "${HOSTED_MODE}" == "true" ]]; then
4+
RUN_MODE=${RUN_MODE:-"create"}
5+
else
6+
RUN_MODE=${RUN_MODE:-"create-dev"}
7+
fi
48

59
# Number of managed clusters
610
MANAGED_CLUSTER_COUNT=${MANAGED_CLUSTER_COUNT:-1}
@@ -32,6 +36,9 @@ case ${RUN_MODE} in
3236
create)
3337
make kind-deploy-controller
3438
;;
39+
create-dev)
40+
make kind-prep-ocm
41+
;;
3542
esac
3643

3744
# Deploy a variable number of managed clusters starting with cluster2
@@ -45,7 +52,7 @@ for i in $(seq 2 $((MANAGED_CLUSTER_COUNT+1))); do
4552
debug)
4653
make e2e-debug
4754
;;
48-
create)
55+
create | create-dev)
4956
if [[ "${HOSTED_MODE}" == "true" ]]; then
5057
make kind-deploy-registration-operator-managed-hosted
5158
else

main_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//go:build e2e
2+
// +build e2e
3+
4+
// Copyright (c) 2022 Red Hat, Inc.
5+
// Copyright Contributors to the Open Cluster Management project
6+
7+
package main
8+
9+
import (
10+
"os"
11+
"os/signal"
12+
"syscall"
13+
"testing"
14+
)
15+
16+
// TestRunMain wraps the main() function in order to build a test binary and collection coverage for
17+
// E2E/Integration tests. Controller CLI flags are also passed in here.
18+
func TestRunMain(t *testing.T) {
19+
// Modifying the args seems necessary to make the test binary and cobra happy.
20+
os.Args = append([]string{
21+
"governance-policy-addon-controller",
22+
"controller",
23+
"--namespace=governance-policy-addon-controller-system",
24+
}, os.Args[1:]...)
25+
26+
// Run main in a separate goroutine
27+
go main()
28+
29+
// The test will end (and pass) via an external signal
30+
stopHandler := make(chan os.Signal, 1)
31+
signal.Notify(stopHandler, syscall.SIGUSR1)
32+
<-stopHandler
33+
}

0 commit comments

Comments
 (0)