From 8d9c455cc265b070d5a58351a51abc92e5e61bbb Mon Sep 17 00:00:00 2001 From: Shikhar Soni <139053348+shikharish@users.noreply.github.com> Date: Fri, 17 May 2024 02:21:45 +0530 Subject: [PATCH] Replace bincover with built-in Go coverage profiling tool (#6090) We replace the deprecated bincover package with the built-in Golang coverage profiling tool. Some notable changes: * we introduce the run_cov_binary.sh script to serve as the entrypoint for the coverage-enabled Docker images. The script wraps the Antrea processes such as antrea-agent. * we are skipping e2e test `TestConnectivity/testOVSRestartSameNode` for now. It started failing in CI after this change but it doesn't seem like this change is directly responsible for this failure, as we can reproduce it locally with ToT Antrea when disabling coverage support. This needs to be investigated separately. Fixes #4962 Signed-off-by: Shikhar Soni --- Makefile | 8 +- .../antrea/templates/agent/daemonset.yaml | 11 ++- .../templates/controller/deployment.yaml | 11 ++- .../flow-aggregator/templates/deployment.yaml | 13 ++- build/images/Dockerfile.build.agent.coverage | 8 +- .../Dockerfile.build.controller.coverage | 8 +- build/images/Dockerfile.build.coverage | 52 ++++++++++ .../flow-aggregator/Dockerfile.coverage | 8 +- ci/jenkins/test-mc.sh | 6 +- ci/jenkins/test-vmc.sh | 12 ++- ci/kind/test-e2e-kind.sh | 9 ++ cmd/antctl/bincover_run_main_test.go | 28 ------ cmd/antrea-agent/bincover_run_main_test.go | 28 ------ .../bincover_run_main_test.go | 28 ------ cmd/flow-aggregator/bincover_run_main_test.go | 28 ------ go.mod | 1 - go.sum | 3 - multicluster/Makefile | 2 +- .../build/images/Dockerfile.build.coverage | 7 ++ .../bincover_run_main_test.go | 28 ------ .../manager_command_patch_coverage.yaml | 7 +- .../manager_command_patch_coverage.yaml | 7 +- .../manager_command_patch_coverage.yaml | 7 +- test/e2e/antctl_test.go | 36 +------ test/e2e/connectivity_test.go | 1 + test/e2e/coverage/agent-arg-file | 9 -- test/e2e/coverage/controller-arg-file | 9 -- test/e2e/coverage/flow-aggregator-arg-file | 8 -- test/e2e/flowaggregator_test.go | 4 +- test/e2e/framework.go | 98 +++++++++---------- test/e2e/utils/run_cov_binary.sh | 49 ++++++++++ 31 files changed, 252 insertions(+), 282 deletions(-) create mode 100644 build/images/Dockerfile.build.coverage delete mode 100644 cmd/antctl/bincover_run_main_test.go delete mode 100644 cmd/antrea-agent/bincover_run_main_test.go delete mode 100644 cmd/antrea-controller/bincover_run_main_test.go delete mode 100644 cmd/flow-aggregator/bincover_run_main_test.go delete mode 100644 multicluster/cmd/multicluster-controller/bincover_run_main_test.go delete mode 100644 test/e2e/coverage/agent-arg-file delete mode 100644 test/e2e/coverage/controller-arg-file delete mode 100644 test/e2e/coverage/flow-aggregator-arg-file create mode 100755 test/e2e/utils/run_cov_binary.sh diff --git a/Makefile b/Makefile index ea691137060..4c420f5c961 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ antrea-agent-simulator: .PHONY: antrea-agent-instr-binary antrea-agent-instr-binary: @mkdir -p $(BINDIR) - GOOS=linux $(GO) test -tags testbincover -covermode count -coverpkg=antrea.io/antrea/pkg/... -c -o $(BINDIR)/antrea-agent-coverage $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antrea-agent + GOOS=linux $(GO) build -cover -o $(BINDIR)/antrea-agent-coverage -coverpkg=antrea.io/antrea/cmd/antrea-agent,antrea.io/antrea/pkg/... $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antrea-agent .PHONY: antrea-controller antrea-controller: @@ -120,7 +120,7 @@ antrea-controller: .PHONY: antrea-controller-instr-binary antrea-controller-instr-binary: @mkdir -p $(BINDIR) - GOOS=linux $(GO) test -tags testbincover -covermode count -coverpkg=antrea.io/antrea/pkg/... -c -o $(BINDIR)/antrea-controller-coverage $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antrea-controller + GOOS=linux $(GO) build -cover -o $(BINDIR)/antrea-controller-coverage -coverpkg=antrea.io/antrea/cmd/antrea-controller,antrea.io/antrea/pkg/... $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antrea-controller .PHONY: antrea-cni antrea-cni: @@ -135,7 +135,7 @@ antrea-cni-release: .PHONY: antctl-instr-binary antctl-instr-binary: @mkdir -p $(BINDIR) - GOOS=linux $(GO) test -tags testbincover -covermode count -coverpkg=antrea.io/antrea/pkg/... -c -o $(BINDIR)/antctl-coverage $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antctl + GOOS=linux $(GO) build -cover -o $(BINDIR)/antctl-coverage -coverpkg=antrea.io/antrea/cmd/antctl,antrea.io/antrea/pkg/... $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/antctl .PHONY: windows-bin windows-bin: @@ -150,7 +150,7 @@ flow-aggregator: .PHONY: flow-aggregator-instr-binary flow-aggregator-instr-binary: @mkdir -p $(BINDIR) - GOOS=linux $(GO) test -tags testbincover -covermode count -coverpkg=antrea.io/antrea/pkg/... -c -o $(BINDIR)/flow-aggregator-coverage $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/flow-aggregator + GOOS=linux $(GO) build -cover -o $(BINDIR)/flow-aggregator-coverage -coverpkg=antrea.io/antrea/cmd/flow-aggregator,antrea.io/antrea/pkg/... $(GOFLAGS) -ldflags '$(LDFLAGS)' antrea.io/antrea/cmd/flow-aggregator .PHONY: test-unit test-integration ifeq ($(UNAME_S),Linux) diff --git a/build/charts/antrea/templates/agent/daemonset.yaml b/build/charts/antrea/templates/agent/daemonset.yaml index 3afd45aa41e..40c41c65f46 100644 --- a/build/charts/antrea/templates/agent/daemonset.yaml +++ b/build/charts/antrea/templates/agent/daemonset.yaml @@ -130,8 +130,15 @@ spec: image: {{ include "antreaAgentImage" . | quote }} imagePullPolicy: {{ include "antreaAgentImagePullPolicy" . }} {{- if ((.Values.testing).coverage) }} - command: ["/bin/sh"] - args: ["-c", "sleep 2; antrea-agent-coverage -test.run=TestBincoverRunMain -test.coverprofile=antrea-agent.cov.out -args-file=/agent-arg-file; while true; do sleep 5 & wait $!; done"] + args: + - "antrea-agent-coverage" + - "--config=/etc/antrea/antrea-agent.conf" + - "--logtostderr=false" + - "--log_dir=/var/log/antrea" + - "--alsologtostderr" + - "--log_file_max_size=100" + - "--log_file_max_num=4" + - "--v=4" {{- else}} command: ["antrea-agent"] # Log to both "/var/log/antrea/" and stderr (so "kubectl logs" can work).- diff --git a/build/charts/antrea/templates/controller/deployment.yaml b/build/charts/antrea/templates/controller/deployment.yaml index c2ec527e981..5fb81822e65 100644 --- a/build/charts/antrea/templates/controller/deployment.yaml +++ b/build/charts/antrea/templates/controller/deployment.yaml @@ -64,8 +64,15 @@ spec: imagePullPolicy: {{ include "antreaControllerImagePullPolicy" . }} resources: {{- .Values.controller.antreaController.resources | toYaml | nindent 12 }} {{- if ((.Values.testing).coverage) }} - command: ["/bin/sh"] - args: ["-c", "antrea-controller-coverage -test.run=TestBincoverRunMain -test.coverprofile=antrea-controller.cov.out -args-file=/controller-arg-file; while true; do sleep 5 & wait $!; done"] + args: + - "antrea-controller-coverage" + - "--config=/etc/antrea/antrea-controller.conf" + - "--logtostderr=false" + - "--log_dir=/var/log/antrea" + - "--alsologtostderr" + - "--log_file_max_size=100" + - "--log_file_max_num=4" + - "--v=4" {{- else }} command: ["antrea-controller"] # Log to both "/var/log/antrea/" and stderr (so "kubectl logs" can work). diff --git a/build/charts/flow-aggregator/templates/deployment.yaml b/build/charts/flow-aggregator/templates/deployment.yaml index 3c8202440db..fc231c79a4b 100644 --- a/build/charts/flow-aggregator/templates/deployment.yaml +++ b/build/charts/flow-aggregator/templates/deployment.yaml @@ -27,9 +27,16 @@ spec: - name: flow-aggregator image: {{ include "flowAggregatorImage" . | quote }} imagePullPolicy: {{ .Values.image.pullPolicy }} - {{- if .Values.testing.coverage }} - command: [ "/bin/sh" ] - args: [ "-c", "flow-aggregator-coverage -test.run=TestBincoverRunMain -test.coverprofile=flow-aggregator.cov.out -args-file=/flow-aggregator-arg-file; while true; do sleep 5 & wait $!; done" ] + {{- if ((.Values.testing).coverage) }} + args: + - flow-aggregator-coverage + - --config=/etc/flow-aggregator/flow-aggregator.conf + - --logtostderr=false + - --log_dir=/var/log/antrea/flow-aggregator + - --alsologtostderr + - --log_file_max_size=100 + - --log_file_max_num=4 + - --v=4 {{- else }} args: - --config diff --git a/build/images/Dockerfile.build.agent.coverage b/build/images/Dockerfile.build.agent.coverage index e318b41f2a6..2d19d99ba43 100644 --- a/build/images/Dockerfile.build.agent.coverage +++ b/build/images/Dockerfile.build.agent.coverage @@ -41,4 +41,10 @@ COPY --from=antrea-build /antrea/bin/antrea-agent-coverage /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antrea-cni /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antctl /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antctl-coverage /usr/local/bin/ -COPY --from=antrea-build /antrea/test/e2e/coverage/agent-arg-file / +COPY --from=antrea-build /antrea/test/e2e/utils/run_cov_binary.sh / + +# This environment variable will persist when running the container, but can also be overwritten if needed +ENV GOCOVERDIR=/tmp/coverage +RUN mkdir -p $GOCOVERDIR + +ENTRYPOINT [ "/run_cov_binary.sh" ] diff --git a/build/images/Dockerfile.build.controller.coverage b/build/images/Dockerfile.build.controller.coverage index 6e3499f76d9..bb19a038034 100644 --- a/build/images/Dockerfile.build.controller.coverage +++ b/build/images/Dockerfile.build.controller.coverage @@ -39,4 +39,10 @@ COPY --from=antrea-build /antrea/bin/antrea-controller /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antctl /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antrea-controller-coverage /usr/local/bin/ COPY --from=antrea-build /antrea/bin/antctl-coverage /usr/local/bin/ -COPY --from=antrea-build /antrea/test/e2e/coverage/controller-arg-file / +COPY --from=antrea-build /antrea/test/e2e/utils/run_cov_binary.sh / + +# This environment variable will persist when running the container, but can also be overwritten if needed +ENV GOCOVERDIR=/tmp/coverage +RUN mkdir -p $GOCOVERDIR + +ENTRYPOINT [ "/run_cov_binary.sh" ] diff --git a/build/images/Dockerfile.build.coverage b/build/images/Dockerfile.build.coverage new file mode 100644 index 00000000000..19b0123da12 --- /dev/null +++ b/build/images/Dockerfile.build.coverage @@ -0,0 +1,52 @@ +# Copyright 2022 Antrea Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG GO_VERSION +ARG BUILD_TAG +FROM golang:${GO_VERSION} as antrea-build + +WORKDIR /antrea + +COPY go.mod /antrea/go.mod + +RUN go mod download + +COPY . /antrea + +# Build antctl first in order to share an extra layer with +# build/images/Dockerfile.build.agent.coverage and build/images/Dockerfile.build.controller.coverage. +RUN make antctl-linux antctl-instr-binary && mv bin/antctl-linux bin/antctl + +# Then build antrea-agent and antrea-cni, in order to share an extra layer with +# build/images/Dockerfile.build.agent.coverage. +RUN make antrea-agent antrea-cni antrea-agent-instr-binary + +RUN make antrea-controller antrea-controller-instr-binary + +FROM antrea/base-ubuntu:${BUILD_TAG} + +LABEL maintainer="Antrea " +LABEL description="The Docker image to deploy the Antrea CNI with code coverage measurement enabled (used for testing)." + +USER root + +COPY build/images/scripts/* /usr/local/bin/ +COPY --from=antrea-build /antrea/bin/* /usr/local/bin/ +COPY --from=antrea-build /antrea/test/e2e/utils/run_cov_binary.sh / + +# This environment variable will persist when running the container, but can also be overwritten if needed +ENV GOCOVERDIR=/tmp/coverage +RUN mkdir -p $GOCOVERDIR + +ENTRYPOINT [ "/run_cov_binary.sh" ] diff --git a/build/images/flow-aggregator/Dockerfile.coverage b/build/images/flow-aggregator/Dockerfile.coverage index 031fa7c573f..02bc626ab96 100644 --- a/build/images/flow-aggregator/Dockerfile.coverage +++ b/build/images/flow-aggregator/Dockerfile.coverage @@ -30,9 +30,15 @@ LABEL description="The docker image for the flow aggregator with code coverage m USER root COPY --from=flow-aggregator-build /antrea/bin/flow-aggregator* /usr/local/bin/ -COPY --from=flow-aggregator-build /antrea/test/e2e/coverage/flow-aggregator-arg-file / COPY --from=flow-aggregator-build /antrea/bin/antctl* /usr/local/bin/ +COPY --from=flow-aggregator-build /antrea/test/e2e/utils/run_cov_binary.sh / + +# This environment variable will persist when running the container, but can also be overwritten if needed +ENV GOCOVERDIR=/tmp/coverage +RUN mkdir -p $GOCOVERDIR RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* + +ENTRYPOINT [ "/run_cov_binary.sh" ] diff --git a/ci/jenkins/test-mc.sh b/ci/jenkins/test-mc.sh index f7f1f7c7b8c..b7d005f7bb5 100755 --- a/ci/jenkins/test-mc.sh +++ b/ci/jenkins/test-mc.sh @@ -466,7 +466,11 @@ function collect_coverage { mc_controller_pod_name="$(kubectl get pods --selector=app=antrea,component=antrea-mc-controller -n ${namespace} --no-headers=true ${kubeconfig} | awk '{ print $1 }')" controller_pid="$(kubectl exec -i $mc_controller_pod_name -n ${namespace} ${kubeconfig} -- pgrep antrea)" kubectl exec -i $mc_controller_pod_name -n ${namespace} ${kubeconfig} -- kill -SIGINT $controller_pid - kubectl cp ${namespace}/$mc_controller_pod_name:antrea-mc-controller.cov.out ${COVERAGE_DIR}/$mc_controller_pod_name-$timestamp ${kubeconfig} + cov_dir="${COVERAGE_DIR}/$mc_controller_pod_name-$timestamp" + mkdir -p $cov_dir + kubectl cp ${namespace}/$mc_controller_pod_name:/tmp/coverage/* $cov_dir/ ${kubeconfig} + go tool covdata textfmt -i="${cov_dir}" -o "${cov_dir}.cov.out" + rm -rf "${cov_dir}" done } diff --git a/ci/jenkins/test-vmc.sh b/ci/jenkins/test-vmc.sh index 3d868e5094a..3b9c5f82e2b 100755 --- a/ci/jenkins/test-vmc.sh +++ b/ci/jenkins/test-vmc.sh @@ -625,7 +625,11 @@ function collect_coverage() { controller_pid="$(kubectl exec -i $antrea_controller_pod_name -n kube-system -- pgrep antrea)" kubectl exec -i $antrea_controller_pod_name -n kube-system -- kill -SIGINT $controller_pid timestamp=$(date +%Y%m%d%H%M%S) - kubectl cp kube-system/$antrea_controller_pod_name:antrea-controller.cov.out ${GIT_CHECKOUT_DIR}/conformance-coverage/$antrea_controller_pod_name-$timestamp + cov_dir="${GIT_CHECKOUT_DIR}/conformance-coverage/$antrea_controller_pod_name-$timestamp" + mkdir -p $cov_dir + kubectl cp kube-system/$antrea_controller_pod_name:/tmp/coverage/* $cov_dir/ + go tool covdata textfmt -i="${cov_dir}" -o "${cov_dir}.cov.out" + rm -rf "${cov_dir}" antrea_agent_pod_names="$(kubectl get pods --selector=app=antrea,component=antrea-agent -n kube-system --no-headers=true | awk '{ print $1 }')" for agent in ${antrea_agent_pod_names} @@ -633,7 +637,11 @@ function collect_coverage() { agent_pid="$(kubectl exec -i $agent -n kube-system -- pgrep antrea)" kubectl exec -i $agent -c antrea-agent -n kube-system -- kill -SIGINT $agent_pid timestamp=$(date +%Y%m%d%H%M%S) - kubectl cp kube-system/$agent:antrea-agent.cov.out -c antrea-agent ${GIT_CHECKOUT_DIR}/conformance-coverage/$agent-$timestamp + cov_dir="${GIT_CHECKOUT_DIR}/conformance-coverage/$agent-$timestamp" + mkdir -p $cov_dir + kubectl cp kube-system/$agent:/tmp/coverage/* -c antrea-agent $cov_dir/ + go tool covdata textfmt -i="${cov_dir}" -o "${cov_dir}.cov.out" + rm -rf "${cov_dir}" done } diff --git a/ci/kind/test-e2e-kind.sh b/ci/kind/test-e2e-kind.sh index 34c28b4821b..0585116186f 100755 --- a/ci/kind/test-e2e-kind.sh +++ b/ci/kind/test-e2e-kind.sh @@ -384,6 +384,15 @@ function run_test { EXTRA_ARGS="$vlan_args --external-server-ips $external_server_ips" go test -v -timeout=$timeout $RUN_OPT antrea.io/antrea/test/e2e $flow_visibility_args -provider=kind --logs-export-dir=$ANTREA_LOG_DIR $np_evaluation_flag --skip-cases=$skiplist $coverage_args $EXTRA_ARGS + + if $coverage; then + pushd $ANTREA_COV_DIR + for dir in */; do + go tool covdata textfmt -i="${dir}" -o "${dir%?}_$(date +%Y-%m-%d_%H-%M-%S).cov.out" + rm -rf "${dir}"; + done + popd + fi } if [[ "$mode" == "" ]] || [[ "$mode" == "encap" ]]; then diff --git a/cmd/antctl/bincover_run_main_test.go b/cmd/antctl/bincover_run_main_test.go deleted file mode 100644 index c8eb2554671..00000000000 --- a/cmd/antctl/bincover_run_main_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 Antrea Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build testbincover -// +build testbincover - -package main - -import ( - "testing" - - "github.com/confluentinc/bincover" -) - -func TestBincoverRunMain(t *testing.T) { - bincover.RunTest(main) -} diff --git a/cmd/antrea-agent/bincover_run_main_test.go b/cmd/antrea-agent/bincover_run_main_test.go deleted file mode 100644 index c8eb2554671..00000000000 --- a/cmd/antrea-agent/bincover_run_main_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 Antrea Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build testbincover -// +build testbincover - -package main - -import ( - "testing" - - "github.com/confluentinc/bincover" -) - -func TestBincoverRunMain(t *testing.T) { - bincover.RunTest(main) -} diff --git a/cmd/antrea-controller/bincover_run_main_test.go b/cmd/antrea-controller/bincover_run_main_test.go deleted file mode 100644 index c8eb2554671..00000000000 --- a/cmd/antrea-controller/bincover_run_main_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 Antrea Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build testbincover -// +build testbincover - -package main - -import ( - "testing" - - "github.com/confluentinc/bincover" -) - -func TestBincoverRunMain(t *testing.T) { - bincover.RunTest(main) -} diff --git a/cmd/flow-aggregator/bincover_run_main_test.go b/cmd/flow-aggregator/bincover_run_main_test.go deleted file mode 100644 index c8eb2554671..00000000000 --- a/cmd/flow-aggregator/bincover_run_main_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 Antrea Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build testbincover -// +build testbincover - -package main - -import ( - "testing" - - "github.com/confluentinc/bincover" -) - -func TestBincoverRunMain(t *testing.T) { - bincover.RunTest(main) -} diff --git a/go.mod b/go.mod index 0da0c46835e..26febbbf384 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/s3 v1.27.4 github.com/blang/semver v3.5.1+incompatible github.com/cheggaaa/pb/v3 v3.1.5 - github.com/confluentinc/bincover v0.1.0 github.com/containernetworking/cni v1.1.1 github.com/containernetworking/plugins v1.1.1 github.com/coreos/go-iptables v0.7.0 diff --git a/go.sum b/go.sum index 8e1de050d7b..385d2503e15 100644 --- a/go.sum +++ b/go.sum @@ -140,8 +140,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipamEh2BpGYxScCH1TOF1LL1cXc= github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/confluentinc/bincover v0.1.0 h1:M4Gfj4rCXuUQVe8TqT/VXcAMjLyvN81oDRy79fjSv3o= -github.com/confluentinc/bincover v0.1.0/go.mod h1:qeI1wx0RxdGTZtrJY0HVlgJ4NqC/X2Z+fHbvy87tgHE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs= @@ -1062,7 +1060,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/multicluster/Makefile b/multicluster/Makefile index 6fef2e7f306..c799a07aba5 100644 --- a/multicluster/Makefile +++ b/multicluster/Makefile @@ -82,7 +82,7 @@ bin: fmt vet ## Build manager binary. .PHONY: antrea-mc-instr-binary antrea-mc-instr-binary: - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go test -tags testbincover -covermode count -coverpkg=antrea.io/antrea/multicluster/... -c -o bin/antrea-mc-controller-coverage antrea.io/antrea/multicluster/cmd/... + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -cover -coverpkg=antrea.io/antrea/multicluster/...,antrea.io/antrea/multicluster/cmd/... -o bin/antrea-mc-controller-coverage antrea.io/antrea/multicluster/cmd/... run: manifests generate fmt vet ## Run a controller from your host. go run ./main.go diff --git a/multicluster/build/images/Dockerfile.build.coverage b/multicluster/build/images/Dockerfile.build.coverage index f768f70d1c9..9ab152159b1 100644 --- a/multicluster/build/images/Dockerfile.build.coverage +++ b/multicluster/build/images/Dockerfile.build.coverage @@ -33,3 +33,10 @@ LABEL description="The Docker image to deploy the Antrea Multi-cluster Controlle USER root COPY --from=antrea-build /antrea/multicluster/bin/antrea-mc-controller-coverage / +COPY --from=antrea-build /antrea/test/e2e/utils/run_cov_binary.sh / + +# This environment variable will persist when running the container, but can also be overwritten if needed +ENV GOCOVERDIR=/tmp/coverage +RUN mkdir -p $GOCOVERDIR + +ENTRYPOINT [ "/run_cov_binary.sh" ] diff --git a/multicluster/cmd/multicluster-controller/bincover_run_main_test.go b/multicluster/cmd/multicluster-controller/bincover_run_main_test.go deleted file mode 100644 index c8eb2554671..00000000000 --- a/multicluster/cmd/multicluster-controller/bincover_run_main_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2022 Antrea Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build testbincover -// +build testbincover - -package main - -import ( - "testing" - - "github.com/confluentinc/bincover" -) - -func TestBincoverRunMain(t *testing.T) { - bincover.RunTest(main) -} diff --git a/multicluster/config/overlays/leader-ns/coverage/manager_command_patch_coverage.yaml b/multicluster/config/overlays/leader-ns/coverage/manager_command_patch_coverage.yaml index e683f7ac078..0e7af4c9c4b 100644 --- a/multicluster/config/overlays/leader-ns/coverage/manager_command_patch_coverage.yaml +++ b/multicluster/config/overlays/leader-ns/coverage/manager_command_patch_coverage.yaml @@ -7,7 +7,10 @@ spec: template: spec: containers: - - command: ["/bin/sh"] - args: ["-c", "/antrea-mc-controller-coverage -test.run=TestBincoverRunMain -test.coverprofile=antrea-mc-controller.cov.out leader --config=/controller_manager_config.yaml; while true; do sleep 5 & wait $!; done"] + - command: [ "/run_cov_binary.sh" ] + args: + - /antrea-mc-controller-coverage + - leader + - --config=/controller_manager_config.yaml name: antrea-mc-controller image: antrea/antrea-mc-controller-coverage:latest diff --git a/multicluster/config/overlays/leader/coverage/manager_command_patch_coverage.yaml b/multicluster/config/overlays/leader/coverage/manager_command_patch_coverage.yaml index e683f7ac078..0e7af4c9c4b 100644 --- a/multicluster/config/overlays/leader/coverage/manager_command_patch_coverage.yaml +++ b/multicluster/config/overlays/leader/coverage/manager_command_patch_coverage.yaml @@ -7,7 +7,10 @@ spec: template: spec: containers: - - command: ["/bin/sh"] - args: ["-c", "/antrea-mc-controller-coverage -test.run=TestBincoverRunMain -test.coverprofile=antrea-mc-controller.cov.out leader --config=/controller_manager_config.yaml; while true; do sleep 5 & wait $!; done"] + - command: [ "/run_cov_binary.sh" ] + args: + - /antrea-mc-controller-coverage + - leader + - --config=/controller_manager_config.yaml name: antrea-mc-controller image: antrea/antrea-mc-controller-coverage:latest diff --git a/multicluster/config/overlays/member/coverage/manager_command_patch_coverage.yaml b/multicluster/config/overlays/member/coverage/manager_command_patch_coverage.yaml index 34fb88f28a6..c5f647f48d5 100644 --- a/multicluster/config/overlays/member/coverage/manager_command_patch_coverage.yaml +++ b/multicluster/config/overlays/member/coverage/manager_command_patch_coverage.yaml @@ -7,7 +7,10 @@ spec: template: spec: containers: - - command: ["/bin/sh"] - args: ["-c", "/antrea-mc-controller-coverage -test.run=TestBincoverRunMain -test.coverprofile=antrea-mc-controller.cov.out member --config=/controller_manager_config.yaml; while true; do sleep 5 & wait $!; done"] + - command: [ "/run_cov_binary.sh" ] + args: + - /antrea-mc-controller-coverage + - member + - --config=/controller_manager_config.yaml name: antrea-mc-controller image: antrea/antrea-mc-controller-coverage:latest diff --git a/test/e2e/antctl_test.go b/test/e2e/antctl_test.go index bb4f2dcea5e..41de9a18105 100644 --- a/test/e2e/antctl_test.go +++ b/test/e2e/antctl_test.go @@ -19,7 +19,6 @@ import ( "encoding/json" "fmt" "net" - "path" "strings" "testing" "time" @@ -116,16 +115,6 @@ func runAntctl(podName string, cmds []string, data *TestData) (string, string, e return stdout, stderr, err } -func antctlCoverageArgs(antctlPath string, covDir string) []string { - const timeFormat = "20060102T150405Z0700" - timestamp := time.Now().Format(timeFormat) - covFile := fmt.Sprintf("antctl-%s.out", timestamp) - if covDir != "" { - covFile = path.Join(covDir, covFile) - } - return []string{antctlPath, "-test.run=TestBincoverRunMain", fmt.Sprintf("-test.coverprofile=%s", covFile)} -} - // testAntctlAgentLocalAccess ensures antctl is accessible in an agent Pod. func testAntctlAgentLocalAccess(t *testing.T, data *TestData) { podName, err := data.getAntreaPodOnNode(controlPlaneNodeName()) @@ -135,25 +124,13 @@ func testAntctlAgentLocalAccess(t *testing.T, data *TestData) { antctlName := antctlName() for _, c := range antctl.CommandList.GetDebugCommands(runtime.ModeAgent) { args := []string{antctlName} - if testOptions.enableCoverage { - antctlCovArgs := antctlCoverageArgs(antctlName, "") - args = append(antctlCovArgs, c...) - } else { - args = append(args, c...) - } + args = append(args, c...) t.Logf("args: %s", args) cmd := strings.Join(args, " ") t.Run(cmd, func(t *testing.T) { stdout, stderr, err := runAntctl(podName, args, data) - // After upgrading from Go v1.19 to Go v1.21, stderr will also include the - // following warning in the error case: - // warning: GOCOVERDIR not set, no coverage data emitted - // As a result, we temporarily replace strings.HasSuffix with strings.Contains. - // We can revert this change when the following issue is addressed: - // https://github.com/antrea-io/antrea/issues/4962 - // if err != nil && !strings.HasSuffix(stderr, "not enabled\n") { - if err != nil && !strings.Contains(stderr, "not enabled\n") { + if err != nil && !strings.HasSuffix(stderr, "not enabled\n") { t.Fatalf("Error when running `antctl %s` from %s: %v\n%s", c, podName, err, antctlOutput(stdout, stderr)) } }) @@ -183,7 +160,7 @@ func runAntctlCommandFromPod(data *TestData, podName string, cmd []string) (stri // Pod. func testAntctlControllerRemoteAccess(t *testing.T, data *TestData, antctlServiceAccountName string, antctlImage string) { const podName = "antctl" - const covDir = "/coverage" + const covDir = "/tmp/coverage" antctlName := antctlName() runAntctlPod(t, data, podName, antctlServiceAccountName, antctlImage, covDir) @@ -193,12 +170,7 @@ func testAntctlControllerRemoteAccess(t *testing.T, data *TestData, antctlServic // Add all controller commands. for _, c := range antctl.CommandList.GetDebugCommands(runtime.ModeController) { cmd := []string{antctlName} - if testOptions.enableCoverage { - antctlCovArgs := antctlCoverageArgs(antctlName, covDir) - cmd = append(antctlCovArgs, c...) - } else { - cmd = append(cmd, c...) - } + cmd = append(cmd, c...) testCmds = append(testCmds, cmdAndReturnCode{args: cmd, expectedReturnCode: 0}) } testCmds = append(testCmds, diff --git a/test/e2e/connectivity_test.go b/test/e2e/connectivity_test.go index 87df12205af..64c69d4d9a8 100644 --- a/test/e2e/connectivity_test.go +++ b/test/e2e/connectivity_test.go @@ -60,6 +60,7 @@ func TestConnectivity(t *testing.T) { t.Run("testOVSRestartSameNode", func(t *testing.T) { skipIfNotIPv4Cluster(t) skipIfHasWindowsNodes(t) + t.Skip("Skipping test for now as it fails consistently") testOVSRestartSameNode(t, data, data.testNamespace) }) t.Run("testOVSFlowReplay", func(t *testing.T) { diff --git a/test/e2e/coverage/agent-arg-file b/test/e2e/coverage/agent-arg-file deleted file mode 100644 index 3b027201e37..00000000000 --- a/test/e2e/coverage/agent-arg-file +++ /dev/null @@ -1,9 +0,0 @@ ---config -/etc/antrea/antrea-agent.conf ---logtostderr=false ---log_dir=/var/log/antrea ---alsologtostderr ---log_file_max_size=100 ---log_file_max_num=4 ---v=4 - diff --git a/test/e2e/coverage/controller-arg-file b/test/e2e/coverage/controller-arg-file deleted file mode 100644 index 677653b5b7e..00000000000 --- a/test/e2e/coverage/controller-arg-file +++ /dev/null @@ -1,9 +0,0 @@ ---config -/etc/antrea/antrea-controller.conf ---logtostderr=false ---log_dir=/var/log/antrea ---alsologtostderr ---log_file_max_size=100 ---log_file_max_num=4 ---v=4 - diff --git a/test/e2e/coverage/flow-aggregator-arg-file b/test/e2e/coverage/flow-aggregator-arg-file deleted file mode 100644 index a0489d11e82..00000000000 --- a/test/e2e/coverage/flow-aggregator-arg-file +++ /dev/null @@ -1,8 +0,0 @@ ---config -/etc/flow-aggregator/flow-aggregator.conf ---logtostderr=false ---log_dir=/var/log/antrea/flow-aggregator ---alsologtostderr ---log_file_max_size=100 ---log_file_max_num=4 ---v=4 diff --git a/test/e2e/flowaggregator_test.go b/test/e2e/flowaggregator_test.go index 79531f7e640..c7978648471 100644 --- a/test/e2e/flowaggregator_test.go +++ b/test/e2e/flowaggregator_test.go @@ -897,7 +897,7 @@ func testHelper(t *testing.T, data *TestData, isIPv6 bool) { for _, args := range antctl.CommandList.GetDebugCommands(runtime.ModeFlowAggregator) { command := []string{} if testOptions.enableCoverage { - antctlCovArgs := antctlCoverageArgs("antctl-coverage", "") + antctlCovArgs := []string{"antctl-coverage"} command = append(antctlCovArgs, args...) } else { command = append([]string{"antctl", "-v"}, args...) @@ -937,7 +937,7 @@ func checkAntctlGetFlowRecordsJson(t *testing.T, data *TestData, podName string, var command []string args := []string{"get", "flowrecords", "-o", "json", "--srcip", srcIP, "--srcport", srcPort} if testOptions.enableCoverage { - antctlCovArgs := antctlCoverageArgs("antctl-coverage", "") + antctlCovArgs := []string{"antctl-coverage"} command = append(antctlCovArgs, args...) } else { command = append([]string{"antctl"}, args...) diff --git a/test/e2e/framework.go b/test/e2e/framework.go index 95d2c7829cb..d4bb6100ecd 100644 --- a/test/e2e/framework.go +++ b/test/e2e/framework.go @@ -23,6 +23,7 @@ import ( "math/rand" "net" "os" + "path" "path/filepath" "reflect" "regexp" @@ -116,9 +117,6 @@ const ( antreaControllerCovBinary = "antrea-controller-coverage" antreaAgentCovBinary = "antrea-agent-coverage" flowAggregatorCovBinary = "flow-aggregator-coverage" - antreaControllerCovFile = "antrea-controller.cov.out" - antreaAgentCovFile = "antrea-agent.cov.out" - flowAggregatorCovFile = "flow-aggregator.cov.out" cpNodeCoverageDir = "/tmp/antrea-e2e-coverage" antreaAgentConfName = "antrea-agent.conf" @@ -2654,11 +2652,7 @@ func (data *TestData) mutateAntreaConfigMap( return nil } -func (data *TestData) killProcessAndCollectCovFiles(namespace, podName, containerName, processName, covFile, covDir string) error { - if err := data.collectAntctlCovFiles(podName, containerName, namespace, covDir); err != nil { - return fmt.Errorf("error when copying antctl coverage files out: %v", err) - } - +func (data *TestData) killProcessAndCollectCovFiles(namespace, podName, containerName, processName, covDir string) error { cmds := []string{"pgrep", "-f", processName, "-P", "1"} stdout, stderr, err := data.RunCommandFromPod(namespace, podName, containerName, cmds) if err != nil { @@ -2672,14 +2666,8 @@ func (data *TestData) killProcessAndCollectCovFiles(namespace, podName, containe } log.Infof("Copying coverage files from Pod '%s'", podName) - if err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 5*time.Second, true, func(ctx context.Context) (bool, error) { - if err = data.copyPodFiles(podName, containerName, namespace, covFile, covDir); err != nil { - log.Infof("Coverage file not available yet for copy: %v", err) - return false, nil - } - return true, nil - }); err != nil { - return fmt.Errorf("timeout when waiting for coverage file") + if err := data.collectCovFiles(podName, containerName, namespace, covDir); err != nil { + return fmt.Errorf("error when copying coverage files: %v", err) } return nil @@ -2693,7 +2681,7 @@ func (data *TestData) gracefulExitAntreaController(covDir string) error { } podName := antreaController.Name - if err := data.killProcessAndCollectCovFiles(antreaNamespace, podName, "antrea-controller", antreaControllerCovBinary, antreaControllerCovFile, covDir); err != nil { + if err := data.killProcessAndCollectCovFiles(antreaNamespace, podName, "antrea-controller", antreaControllerCovBinary, covDir); err != nil { return fmt.Errorf("error when gracefully exiting Antrea Controller: %w", err) } @@ -2715,7 +2703,7 @@ func (data *TestData) gracefulExitAntreaAgent(covDir string, nodeName string) er } for _, pod := range pods.Items { podName := pod.Name - if err := data.killProcessAndCollectCovFiles(antreaNamespace, podName, "antrea-agent", antreaAgentCovBinary, antreaAgentCovFile, covDir); err != nil { + if err := data.killProcessAndCollectCovFiles(antreaNamespace, podName, "antrea-agent", antreaAgentCovBinary, covDir); err != nil { return fmt.Errorf("error when gracefully exiting Antrea Agent: %w", err) } } @@ -2730,30 +2718,39 @@ func (data *TestData) gracefulExitFlowAggregator(covDir string) error { } podName := flowAggPod.Name - if err := data.killProcessAndCollectCovFiles(flowAggregatorNamespace, podName, "flow-aggregator", flowAggregatorCovBinary, flowAggregatorCovFile, covDir); err != nil { + if err := data.killProcessAndCollectCovFiles(flowAggregatorNamespace, podName, "flow-aggregator", flowAggregatorCovBinary, covDir); err != nil { return fmt.Errorf("error when gracefully exiting Flow Aggregator: %w", err) } return nil } -// collectAntctlCovFiles collects coverage files for the antctl binary from the Pod and saves them to the coverage directory -func (data *TestData) collectAntctlCovFiles(podName string, containerName string, nsName string, covDir string) error { +// collectCovFiles collects coverage files from the Pod and saves them to the coverage directory +func (data *TestData) collectCovFiles(podName string, containerName string, nsName string, covDir string) error { // copy antctl coverage files from Pod to the coverage directory - cmds := []string{"bash", "-c", "find . -maxdepth 1 -name 'antctl*.out' -exec basename {} ';'"} + cmds := []string{"bash", "-c", "find /tmp/coverage -mindepth 1"} stdout, stderr, err := data.RunCommandFromPod(nsName, podName, containerName, cmds) if err != nil { return fmt.Errorf("error when running this find command '%s' on Pod '%s', stderr: <%v>, err: <%v>", cmds, podName, stderr, err) } + covDir = filepath.Join(covDir, podName+"-coverage") + if err := os.Mkdir(covDir, os.ModePerm); err != nil { + return fmt.Errorf("error creating coverage directory for Pod %s: %v", podName, err) + } stdout = strings.TrimSpace(stdout) files := strings.Split(stdout, "\n") for _, file := range files { if len(file) == 0 { continue } - err := data.copyPodFiles(podName, containerName, nsName, file, covDir) - if err != nil { - return fmt.Errorf("error when copying coverage files for antctl from Pod '%s' to coverage directory '%s': %v", podName, covDir, err) + if err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 5*time.Second, true, func(ctx context.Context) (bool, error) { + if err = data.copyPodFiles(podName, containerName, nsName, file, covDir); err != nil { + log.Infof("Coverage file not available yet for copy: %v", err) + return false, nil + } + return true, nil + }); err != nil { + return fmt.Errorf("timeout when waiting for coverage file") } } return nil @@ -2762,19 +2759,15 @@ func (data *TestData) collectAntctlCovFiles(podName string, containerName string // collectAntctlCovFilesFromControlPlaneNode collects coverage files for the antctl binary from the control-plane Node and saves them to the coverage directory func (data *TestData) collectAntctlCovFilesFromControlPlaneNode(covDir string) error { // copy antctl coverage files from node to the coverage directory - var cmd string - if testOptions.providerName == "kind" { - // Do not use single quotes here, as they will be interpreted literally. - // RunDockerExecCommand does not invoke a shell by default and it will split this - // string into a list of args. - cmd = fmt.Sprintf("find %s -maxdepth 1 -name antctl*.out", cpNodeCoverageDir) - } else { - cmd = fmt.Sprintf("find %s -maxdepth 1 -name 'antctl*.out'", cpNodeCoverageDir) - } + log.Infof("Copying coverage files from Node: %s", controlPlaneNodeName()) + cmd := fmt.Sprintf("find %s -mindepth 1", cpNodeCoverageDir) rc, stdout, stderr, err := data.RunCommandOnNode(controlPlaneNodeName(), cmd) if err != nil || rc != 0 { return fmt.Errorf("error when running this find command '%s' on control-plane Node '%s', stderr: <%v>, err: <%v>", cmd, controlPlaneNodeName(), stderr, err) - + } + covDir = filepath.Join(covDir, fmt.Sprintf("%s-coverage", controlPlaneNodeName())) + if err := os.Mkdir(covDir, os.ModePerm); err != nil { + return fmt.Errorf("error creating coverage directory for the control plane Node %v", err) } stdout = strings.TrimSpace(stdout) files := strings.Split(stdout, "\n") @@ -2782,7 +2775,7 @@ func (data *TestData) collectAntctlCovFilesFromControlPlaneNode(covDir string) e if len(file) == 0 { continue } - err := data.copyNodeFiles(controlPlaneNodeName(), file, covDir) + err := data.copyNodeFiles(file, covDir) if err != nil { return fmt.Errorf("error when copying coverage files for antctl from Node '%s' to coverage directory '%s': %v", controlPlaneNodeName(), covDir, err) } @@ -2795,26 +2788,24 @@ func (data *TestData) collectAntctlCovFilesFromControlPlaneNode(covDir string) e func (data *TestData) copyPodFiles(podName string, containerName string, nsName string, fileName string, destDir string) error { // getPodWriter creates the file with name podName-fileName-suffix. It returns nil if the // file cannot be created. File must be closed by the caller. - getPodWriter := func(podName, fileName, suffix string) *os.File { - destFile := filepath.Join(destDir, fmt.Sprintf("%s-%s-%s", podName, fileName, suffix)) + getPodWriter := func(fileName string) *os.File { + destFile := filepath.Join(destDir, fileName) f, err := os.Create(destFile) if err != nil { - _ = fmt.Errorf("error when creating destination file '%s': %v", destFile, err) + log.Infof("Error when creating destination file '%s': %v\n", destFile, err) return nil } return f } - // dump the file from Antrea Pods to disk. - // a filepath-friendly timestamp format. - const timeFormat = "Jan02-15-04-05" - timeStamp := time.Now().Format(timeFormat) - w := getPodWriter(podName, fileName, timeStamp) + basename := path.Base(fileName) + w := getPodWriter(basename) if w == nil { return nil } defer w.Close() cmd := []string{"cat", fileName} + log.Infof("Copying file: %s", basename) stdout, stderr, err := data.RunCommandFromPod(nsName, podName, containerName, cmd) if err != nil { return fmt.Errorf("cannot retrieve content of file '%s' from Pod '%s', stderr: <%v>, err: <%v>", fileName, podName, stderr, err) @@ -2827,29 +2818,28 @@ func (data *TestData) copyPodFiles(podName string, containerName string, nsName } // copyNodeFiles copies a file from a Node and save it to specified directory -func (data *TestData) copyNodeFiles(nodeName string, fileName string, covDir string) error { +func (data *TestData) copyNodeFiles(fileName string, destDir string) error { // getNodeWriter creates the file with name nodeName-suffix. It returns nil if the file // cannot be created. File must be closed by the caller. - getNodeWriter := func(nodeName, fileName, suffix string) *os.File { - covFile := filepath.Join(covDir, fmt.Sprintf("%s-%s-%s", nodeName, fileName, suffix)) - f, err := os.Create(covFile) + getNodeWriter := func(fileName string) *os.File { + destFile := filepath.Join(destDir, fileName) + f, err := os.Create(destFile) if err != nil { - _ = fmt.Errorf("error when creating coverage file '%s': %v", covFile, err) + log.Infof("Error when creating coverage file '%s': %v\n", destFile, err) return nil } return f } - // dump the file from Antrea Pods to disk. - // a filepath-friendly timestamp format. - const timeFormat = "Jan02-15-04-05" - timeStamp := time.Now().Format(timeFormat) - w := getNodeWriter(nodeName, fileName, timeStamp) + // dump the file from Nodes to disk. + basename := path.Base(fileName) + w := getNodeWriter(basename) if w == nil { return nil } defer w.Close() cmd := fmt.Sprintf("cat %s", fileName) + log.Infof("Copying file: %s", basename) rc, stdout, stderr, err := data.RunCommandOnNode(controlPlaneNodeName(), cmd) if err != nil || rc != 0 { return fmt.Errorf("cannot retrieve content of file '%s' from Node '%s', stderr: <%v>, err: <%v>", fileName, controlPlaneNodeName(), stderr, err) diff --git a/test/e2e/utils/run_cov_binary.sh b/test/e2e/utils/run_cov_binary.sh new file mode 100755 index 00000000000..10b76994cca --- /dev/null +++ b/test/e2e/utils/run_cov_binary.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Copyright 2024 Antrea Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script is meant to wrap a coverage instrumented binary. +# When the main process is killed, the script will start sleeping until a signal +# is received, providing the opportunity for the user to retrieve code coverage +# files. + +set -euo pipefail + +TEST_PID= + +function quit { + echo "Received signal, exiting" + # While not strictly required, it is better to try to terminate the test process gracefully if it is still running. + if [ "$TEST_PID" != "" ]; then + echo "Sending signal to test process" + kill -SIGTERM $TEST_PID > /dev/null 2>&1 || true + wait $TEST_PID + echo "Test process exited gracefully" + fi + exit 0 +} + +# This is necessary: without an explicit signal handler, the SIGTERM signal will be discarded when running +# as a process with PID 1 in a container. +trap 'quit' SIGTERM + +# Run the test process in the background, to allow exiting when a signal is received. +"$@" & +TEST_PID=$! +wait $TEST_PID +TEST_PID= + +# Sleep in the background, to allow exiting as soon as a signal is received. +sleep infinity & wait