Skip to content

Commit b5c4cbd

Browse files
authored
[chore][codecov] Add code coverage to integration tests (#6146)
* [chore][codecov] Add code coverage to integration tests * Add env variable references to integration tests to capture coverage * Add empty newline at end of file * Move shell command to run rather than env
1 parent e342fde commit b5c4cbd

File tree

7 files changed

+103
-7
lines changed

7 files changed

+103
-7
lines changed

.github/workflows/integration-test.yml

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565
with:
6666
go-version: ${{ env.GO_VERSION }}
6767
cache-dependency-path: '**/go.sum'
68-
- run: make binaries-linux_${{ matrix.ARCH }}
68+
- run: make binaries-linux_${{ matrix.ARCH }} COVER_TESTING=true
6969
- uses: actions/upload-artifact@v4
7070
with:
7171
name: otelcol-${{ matrix.ARCH }}
@@ -237,11 +237,13 @@ jobs:
237237
if [[ "${{ matrix.PROFILE }}" = "smartagent" ]]; then
238238
target="smartagent-integration-test-with-cover"
239239
fi
240+
export CONTAINER_COVER_SRC="$(realpath .)/tests/coverage"
240241
make $target 2>&1 | tee $TEST_OUTPUT
241242
exit_status=${PIPESTATUS[0]}
242243
echo "Exit status: $exit_status"
243244
exit $exit_status
244245
env:
246+
CONTAINER_COVER_DEST: '/etc/otel/collector/coverage'
245247
SPLUNK_OTEL_COLLECTOR_IMAGE: 'otelcol:latest'
246248
# The Integration Test output is extremely large so we upload it as an artifact
247249
- name: Upload Integration Test Output as Artifact
@@ -251,6 +253,13 @@ jobs:
251253
name: ${{ env.TEST_OUTPUT }}
252254
path: ${{ env.TEST_OUTPUT }}
253255
retention-days: 5
256+
- name: Upload coverage report
257+
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # 5.4.0
258+
with:
259+
verbose: true
260+
fail_ci_if_error: true
261+
env:
262+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
254263

255264
integration-test-binary:
256265
runs-on: ${{ matrix.RUNNER }}
@@ -316,11 +325,13 @@ jobs:
316325
if [[ "${{ matrix.PROFILE }}" = "smartagent" ]]; then
317326
target="smartagent-integration-test-with-cover"
318327
fi
328+
export CONTAINER_COVER_SRC="$(realpath .)/tests/coverage"
319329
make $target 2>&1 | tee $TEST_OUTPUT
320330
exit_status=${PIPESTATUS[0]}
321331
echo "Exit status: $exit_status"
322332
exit $exit_status
323333
env:
334+
CONTAINER_COVER_DEST: '/etc/otel/collector/coverage'
324335
SPLUNK_OTEL_COLLECTOR_IMAGE: ""
325336
# The Integration Test output is extremely large so we upload it as an artifact
326337
- name: Upload Integration Test Output as Artifact
@@ -330,6 +341,13 @@ jobs:
330341
name: ${{ env.TEST_OUTPUT }}
331342
path: ${{ env.TEST_OUTPUT }}
332343
retention-days: 5
344+
- name: Upload coverage report
345+
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # 5.4.0
346+
with:
347+
verbose: true
348+
fail_ci_if_error: true
349+
env:
350+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
333351

334352
integration-test-discovery-matrix:
335353
runs-on: ubuntu-24.04
@@ -386,9 +404,19 @@ jobs:
386404
- run: ln -sf otelcol_linux_${{ matrix.ARCH }} ./bin/otelcol
387405
- run: chmod a+x ./bin/*
388406
- name: Run ${{ matrix.SERVICE }} Discovery Integration Test With Cover
389-
run: make integration-test-${{ matrix.SERVICE }}-discovery-with-cover
407+
run: |
408+
export CONTAINER_COVER_SRC="$(realpath .)/tests/coverage"
409+
make integration-test-${{ matrix.SERVICE }}-discovery-with-cover
390410
env:
411+
CONTAINER_COVER_DEST: '/etc/otel/collector/coverage'
391412
SPLUNK_OTEL_COLLECTOR_IMAGE: 'otelcol:latest'
413+
- name: Upload coverage report
414+
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # 5.4.0
415+
with:
416+
verbose: true
417+
fail_ci_if_error: true
418+
env:
419+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
392420

393421
integration-test-discovery-k8s-matrix:
394422
runs-on: ubuntu-24.04
@@ -448,9 +476,20 @@ jobs:
448476
run: |
449477
kind load docker-image otelcol:latest --name kind
450478
- name: Run ${{ matrix.SERVICE }} Discovery Kubernetes Integration Test With Cover
451-
run: KUBECONFIG=$HOME/.kube/config SKIP_TEARDOWN=true make integration-test-${{ matrix.SERVICE }}-discovery-k8s-with-cover
479+
run: |
480+
export CONTAINER_COVER_SRC="$(realpath .)/tests/coverage"
481+
KUBECONFIG=$HOME/.kube/config SKIP_TEARDOWN=true make integration-test-${{ matrix.SERVICE }}-discovery-k8s-with-cover
482+
env:
483+
CONTAINER_COVER_DEST: '/etc/otel/collector/coverage'
452484
- name: Print logs
453485
if: failure()
454486
run: |
455487
kubectl get pods -A
456488
kubectl get pod -A -l app=otelcol -o jsonpath="{range .items[*]}{.metadata.namespace} {.metadata.name}{'\n'}{end}" | xargs -r -n2 sh -c 'kubectl logs -n $0 $1'
489+
- name: Upload coverage report
490+
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # 5.4.0
491+
with:
492+
verbose: true
493+
fail_ci_if_error: true
494+
env:
495+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ SKIP_COMPILE=false
4343
ARCH?=amd64
4444
BUNDLE_SUPPORTED_ARCHS := amd64 arm64
4545
SKIP_BUNDLE=false
46+
# Used for building the collector to collect coverage information
47+
COVER_TESTING=false
4648

4749
# For integration testing against local changes you can run
4850
# SPLUNK_OTEL_COLLECTOR_IMAGE='otelcol:latest' make -e docker-otelcol integration-test
@@ -242,7 +244,11 @@ generate-metrics:
242244
.PHONY: otelcol
243245
otelcol:
244246
go generate ./...
247+
ifeq ($(COVER_TESTING), true)
248+
GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) go build $(COVER_OPTS) -trimpath -o ./bin/otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) $(BUILD_INFO) ./cmd/otelcol
249+
else
245250
GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) go build -trimpath -o ./bin/otelcol_$(GOOS)_$(GOARCH)$(EXTENSION) $(BUILD_INFO) ./cmd/otelcol
251+
endif
246252
ifeq ($(OS), Windows_NT)
247253
$(LINK_CMD) .\bin\otelcol$(EXTENSION) .\bin\otelcol_$(GOOS)_$(GOARCH)$(EXTENSION)
248254
else

tests/general/container_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package tests
1818

1919
import (
2020
"fmt"
21+
"os"
2122
"strings"
2223
"testing"
2324
"time"
@@ -33,6 +34,9 @@ import (
3334

3435
func TestDefaultContainerConfigRequiresEnvVars(t *testing.T) {
3536
image := testutils.GetCollectorImageOrSkipTest(t)
37+
coverDest := os.Getenv("CONTAINER_COVER_DEST")
38+
coverSrc := os.Getenv("CONTAINER_COVER_SRC")
39+
3640
tests := []struct {
3741
name string
3842
env map[string]string
@@ -41,18 +45,27 @@ func TestDefaultContainerConfigRequiresEnvVars(t *testing.T) {
4145
{"missing realm", map[string]string{
4246
"SPLUNK_REALM": "",
4347
"SPLUNK_ACCESS_TOKEN": "some_token",
48+
"GOCOVERDIR": coverDest,
4449
}, "SPLUNK_REALM"},
4550
{"missing token", map[string]string{
4651
"SPLUNK_REALM": "some_realm",
4752
"SPLUNK_ACCESS_TOKEN": "",
53+
"GOCOVERDIR": coverDest,
4854
}, "SPLUNK_ACCESS_TOKEN"},
4955
}
5056
for _, testcase := range tests {
5157
t.Run(testcase.name, func(tt *testing.T) {
5258
logCore, logs := observer.New(zap.DebugLevel)
5359
logger := zap.New(logCore)
5460

55-
collector, err := testutils.NewCollectorContainer().WithImage(image).WithEnv(testcase.env).WithLogger(logger).WillFail(true).Build()
61+
collector := testutils.NewCollectorContainer().WithImage(image).WithEnv(testcase.env).WithLogger(logger).WillFail(true)
62+
63+
if coverSrc != "" && coverDest != "" {
64+
collector = collector.WithMount(coverSrc, coverDest)
65+
}
66+
67+
var err error
68+
collector, err = collector.Build()
5669
require.NoError(t, err)
5770
require.NotNil(t, collector)
5871
defer collector.Shutdown()

tests/internal/discoverytest/discoverytest.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,22 @@ func Run(t *testing.T, receiverName string, configFilePath string, logMessageToA
6969
dockerGID, err := getDockerGID()
7070
require.NoError(t, err)
7171

72+
coverDest := os.Getenv("CONTAINER_COVER_DEST")
73+
coverSrc := os.Getenv("CONTAINER_COVER_SRC")
74+
var coverDirBind string
75+
if coverSrc != "" && coverDest != "" {
76+
coverDirBind = fmt.Sprintf("%s:%s", coverSrc, coverDest)
77+
}
78+
7279
req := testcontainers.ContainerRequest{
7380
Image: "otelcol:latest",
7481
HostConfigModifier: func(hc *container.HostConfig) {
75-
hc.Binds = []string{"/var/run/docker.sock:/var/run/docker.sock"}
82+
hc.Binds = []string{"/var/run/docker.sock:/var/run/docker.sock", coverDirBind}
7683
hc.NetworkMode = network.NetworkHost
7784
hc.GroupAdd = []string{dockerGID}
7885
},
7986
Env: map[string]string{
87+
"GOCOVERDIR": coverDest,
8088
"SPLUNK_REALM": "us2",
8189
"SPLUNK_ACCESS_TOKEN": "12345",
8290
"SPLUNK_DISCOVERY_LOG_LEVEL": "info",

tests/receivers/jmx/cassandra/jmx_cassandra_discovery_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ func jmxCassandraAutoDiscoveryHelper(t *testing.T, ctx context.Context, configFi
7979
dockerGID, err := getDockerGID()
8080
require.NoError(t, err)
8181

82+
coverDest := os.Getenv("CONTAINER_COVER_DEST")
83+
coverSrc := os.Getenv("CONTAINER_COVER_SRC")
84+
var coverDirBind string
85+
if coverSrc != "" && coverDest != "" {
86+
coverDirBind = fmt.Sprintf("%s:%s", coverSrc, coverDest)
87+
}
88+
8289
otelConfigPath, err := filepath.Abs(filepath.Join(".", "testdata", configFile))
8390
if err != nil {
8491
return nil, err
@@ -95,11 +102,12 @@ func jmxCassandraAutoDiscoveryHelper(t *testing.T, ctx context.Context, configFi
95102
req := testcontainers.ContainerRequest{
96103
Image: "otelcol:latest",
97104
HostConfigModifier: func(hc *container.HostConfig) {
98-
hc.Binds = []string{"/var/run/docker.sock:/var/run/docker.sock"}
105+
hc.Binds = []string{"/var/run/docker.sock:/var/run/docker.sock", coverDirBind}
99106
hc.NetworkMode = network.NetworkHost
100107
hc.GroupAdd = []string{dockerGID}
101108
},
102109
Env: map[string]string{
110+
"GOCOVERDIR": coverDest,
103111
"SPLUNK_REALM": "us2",
104112
"SPLUNK_ACCESS_TOKEN": "12345",
105113
"SPLUNK_DISCOVERY_LOG_LEVEL": "info",

tests/testutils/golden.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package testutils
1818
import (
1919
"context"
2020
"fmt"
21+
"os"
2122
"path/filepath"
2223
"runtime"
2324
"testing"
@@ -100,11 +101,18 @@ func RunMetricsCollectionTest(t *testing.T, configFile string, expectedFilePath
100101
if runtime.GOOS == "darwin" {
101102
dockerHost = "host.docker.internal"
102103
}
104+
105+
coverDest := os.Getenv("CONTAINER_COVER_DEST")
106+
coverSrc := os.Getenv("CONTAINER_COVER_SRC")
107+
103108
cc := NewCollectorContainer().
104109
WithImage(GetCollectorImageOrSkipTest(t)).
105110
WithConfigPath(filepath.Join("testdata", configFile)).
106111
WithLogger(logger).
107-
WithEnv(map[string]string{"OTLP_ENDPOINT": fmt.Sprintf("%s:%d", dockerHost, port)}).
112+
WithEnv(map[string]string{
113+
"GOCOVERDIR": coverDest,
114+
"OTLP_ENDPOINT": fmt.Sprintf("%s:%d", dockerHost, port),
115+
}).
108116
WithEnv(opts.collectorEnvVars)
109117
for k, v := range opts.fileMounts {
110118
cc.(*CollectorContainer).Container = cc.(*CollectorContainer).Container.WithFile(testcontainers.ContainerFile{
@@ -113,6 +121,11 @@ func RunMetricsCollectionTest(t *testing.T, configFile string, expectedFilePath
113121
FileMode: 0644,
114122
})
115123
}
124+
125+
if coverSrc != "" && coverDest != "" {
126+
cc = cc.WithMount(coverSrc, coverDest)
127+
}
128+
116129
p, err := cc.Build()
117130
require.NoError(t, err)
118131
require.NoError(t, p.Start())

tests/testutils/testcase.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ func (t *Testcase) splunkOtelCollector(configFilename string, builders ...Collec
133133

134134
func (t *Testcase) newCollector(initial Collector, configFilename string, builders ...CollectorBuilder) (collector Collector, shutdown func()) {
135135
collector = initial
136+
137+
coverDest := os.Getenv("CONTAINER_COVER_DEST")
138+
coverSrc := os.Getenv("CONTAINER_COVER_SRC")
139+
136140
envVars := map[string]string{
141+
"GOCOVERDIR": coverDest,
137142
"OTLP_ENDPOINT": t.OTLPEndpointForCollector,
138143
"SPLUNK_TEST_ID": t.ID,
139144
}
@@ -159,6 +164,10 @@ func (t *Testcase) newCollector(initial Collector, configFilename string, builde
159164
}
160165
collector = collector.WithEnv(splunkEnv)
161166

167+
if coverSrc != "" && coverDest != "" {
168+
collector = collector.WithMount(coverSrc, coverDest)
169+
}
170+
162171
var err error
163172
collector, err = collector.Build()
164173
require.NoError(t, err)

0 commit comments

Comments
 (0)