Skip to content

Commit ba6fa06

Browse files
authored
Merge pull request #2489 from iwankgb/perf_integration_tests
Integration test for Docker and perf stats
2 parents 713e6af + 4a2441a commit ba6fa06

File tree

8 files changed

+184
-34
lines changed

8 files changed

+184
-34
lines changed

.github/workflows/test.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
matrix:
2727
go-versions: [1.13.x, 1.14.x]
2828
platform: [ubuntu-latest]
29+
environment-variables: [build/config/plain.sh, build/config/libpfm4.sh]
2930
runs-on: ${{ matrix.platform }}
3031
timeout-minutes: 30
3132
steps:
@@ -40,4 +41,11 @@ jobs:
4041
path: go/src/github.com/google/cadvisor
4142
- name: Run integration tests
4243
run: |
43-
cd $GITHUB_WORKSPACE/go/src/github.com/google/cadvisor && make docker-test-integration
44+
cd $GITHUB_WORKSPACE/go/src/github.com/google/cadvisor && source ${{ matrix.environment-variables }} && make docker-test-integration
45+
- name: Upload cAdvisor log file
46+
uses: actions/upload-artifact@v1
47+
if: failure()
48+
with:
49+
name: cadvisor.log
50+
path: ${{ github.workspace }}/go/src/github.com/google/cadvisor/cadvisor.log
51+

build/config/libpfm4.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2020 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
export GO_FLAGS="-tags=libpfm,netgo -race"
16+
export PACKAGES="sudo libpfm4"
17+
export BUILD_PACKAGES="libpfm4 libpfm4-dev"
18+
export CADVISOR_ARGS="-perf_events_config=perf/testing/perf-non-hardware.json"

build/config/plain.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2020 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Nothing happens here, this is just default config.

build/integration-in-docker.sh

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,50 @@ set -e
1919
ROOT="$(cd "$(dirname "${BASH_SOURCE}")/.." && pwd -P)"
2020
TMPDIR=$(mktemp -d)
2121
function delete() {
22-
echo "Deleting ${TMPDIR}..."
23-
if [[ $EUID -ne 0 ]]; then
24-
sudo rm -rf "${TMPDIR}"
25-
else
26-
rm -rf "${TMPDIR}"
27-
fi
22+
echo "Deleting ${TMPDIR}..."
23+
if [[ $EUID -ne 0 ]]; then
24+
sudo rm -rf "${TMPDIR}"
25+
else
26+
rm -rf "${TMPDIR}"
27+
fi
2828
}
2929
trap delete EXIT INT
3030

31-
docker run --rm \
32-
-w /go/src/github.com/google/cadvisor \
33-
-v ${PWD}:/go/src/github.com/google/cadvisor \
34-
golang:1.13 \
35-
bash -c "env GOOS=linux GO_FLAGS='-race' ./build/build.sh amd64 && \
36-
env GOOS=linux go test -c github.com/google/cadvisor/integration/tests/api && \
37-
env GOOS=linux go test -c github.com/google/cadvisor/integration/tests/healthz"
38-
39-
EXTRA_DOCKER_OPTS="-e DOCKER_IN_DOCKER_ENABLED=true"
40-
if [[ "${OSTYPE}" == "linux"* ]]; then
41-
EXTRA_DOCKER_OPTS+=" -v ${TMPDIR}/docker-graph:/docker-graph"
42-
fi
43-
44-
mkdir ${TMPDIR}/docker-graph
45-
docker run --rm \
46-
-w /go/src/github.com/google/cadvisor \
47-
-v ${ROOT}:/go/src/github.com/google/cadvisor \
48-
${EXTRA_DOCKER_OPTS} \
49-
--privileged \
50-
--entrypoint="" \
51-
gcr.io/k8s-testimages/bootstrap \
52-
bash -c "apt update && apt install sudo && \
53-
/usr/local/bin/runner.sh build/integration.sh"
31+
function run_tests() {
32+
BUILD_CMD="env GOOS=linux GO_FLAGS='$GO_FLAGS' ./build/build.sh amd64 && \
33+
env GOOS=linux GOFLAGS='$GO_FLAGS' go test -c github.com/google/cadvisor/integration/tests/api && \
34+
env GOOS=linux GOFLAGS='$GO_FLAGS' go test -c github.com/google/cadvisor/integration/tests/healthz"
35+
36+
if [ "$BUILD_PACKAGES" != "" ]; then
37+
BUILD_CMD="apt-get update && apt-get install $BUILD_PACKAGES && \
38+
$BUILD_CMD"
39+
fi
40+
docker run --rm \
41+
-w /go/src/github.com/google/cadvisor \
42+
-v ${PWD}:/go/src/github.com/google/cadvisor \
43+
golang:1.13 \
44+
bash -c "$BUILD_CMD"
45+
46+
EXTRA_DOCKER_OPTS="-e DOCKER_IN_DOCKER_ENABLED=true"
47+
if [[ "${OSTYPE}" == "linux"* ]]; then
48+
EXTRA_DOCKER_OPTS+=" -v ${TMPDIR}/docker-graph:/docker-graph"
49+
fi
50+
51+
mkdir ${TMPDIR}/docker-graph
52+
docker run --rm \
53+
-w /go/src/github.com/google/cadvisor \
54+
-v ${ROOT}:/go/src/github.com/google/cadvisor \
55+
${EXTRA_DOCKER_OPTS} \
56+
--privileged \
57+
--cap-add="sys_admin" \
58+
--entrypoint="" \
59+
gcr.io/k8s-testimages/bootstrap \
60+
bash -c "apt update && apt install $PACKAGES && \
61+
CADVISOR_ARGS="$CADVISOR_ARGS" /usr/local/bin/runner.sh build/integration.sh"
62+
}
63+
64+
GO_FLAGS=${GO_FLAGS:-"-tags=netgo -race"}
65+
PACKAGES=${PACKAGES:-"sudo"}
66+
BUILD_PACKAGES=${BUILD_PACKAGES:-}
67+
CADVISOR_ARGS=${CADVISOR_ARGS:-}
68+
run_tests "$GO_FLAGS" "$PACKAGES" "$BUILD_PACKAGES" "$CADVISOR_ARGS"

build/integration.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ printf "" # Refresh sudo credentials if necessary.
2626
function start {
2727
set +e # We want to handle errors if cAdvisor crashes.
2828
echo ">> starting cAdvisor locally"
29-
GORACE="halt_on_error=1" ./cadvisor --docker_env_metadata_whitelist=TEST_VAR --v=4 --logtostderr &> "$log_file"
29+
GORACE="halt_on_error=1" ./cadvisor --docker_env_metadata_whitelist=TEST_VAR --v=6 --logtostderr $CADVISOR_ARGS &> "$log_file"
3030
if [ $? != 0 ]; then
3131
echo "!! cAdvisor exited unexpectedly with Exit $?"
3232
kill $TEST_PID # cAdvisor crashed: abort testing.
@@ -56,5 +56,5 @@ while [ "$(curl -Gs http://localhost:8080/healthz)" != "ok" ]; do
5656
done
5757

5858
echo ">> running integration tests against local cAdvisor"
59-
./api.test --vmodule=*=2
60-
./healthz.test --vmodule=*=2
59+
./api.test --vmodule=*=2 -test.v
60+
./healthz.test --vmodule=*=2 -test.v

docs/development/integration_testing.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,26 @@
1-
# Integration Testing cAdvisor
1+
# Integration Testing cAdvisor
2+
3+
## Docker-based tests
4+
5+
The cAdvisor integration tests are run per-pr using [Github Actions](https://help.github.com/en/actions). Workflow configuration can be found at [.github/workflows/test.yml](.github/workflows/test.yml). Tests are executed in Docker containers run on MS Azure virtual machines.
6+
7+
To run them locally Docker must be installed on your machine. Following command allows you to execute default suite of integration tests:
8+
9+
```
10+
make docker-test-integration
11+
```
12+
13+
Build scripts take care of building cAdvisor and integration tests, and executing them against running cAdvisor process.
14+
15+
In order to run non-default tests suites (e.g. such that rely on third-party C libraries) you must source one of the files available at [build/config](build/config), e.g.:
16+
17+
```
18+
source build/config/libpfm4.sh && make docker-test-integration
19+
```
20+
21+
All the necessary packages will be installed, build flags will be applied and additional parameters will be passed to cAdvisor automatically. Configuration is performed using shell environment variables.
22+
23+
## VM-base tests (legacy)
224

325
The cAdvisor integration tests are run per-pr using the [kubernetes node-e2e testing framework](https://github.com/kubernetes/community/blob/master/contributors/devel/e2e-node-tests.md) on GCE instances. To make use of this framework, complete the setup of GCP described in the node-e2e testing framework, clone `k8s.io/kubernetes`, and from that repository run:
426
```

integration/tests/api/perf_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// +build libpfm,cgo
2+
3+
// Copyright 2020 Google Inc. All Rights Reserved.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package api
18+
19+
import (
20+
"testing"
21+
"time"
22+
23+
v1 "github.com/google/cadvisor/info/v1"
24+
"github.com/google/cadvisor/integration/framework"
25+
26+
"github.com/stretchr/testify/assert"
27+
)
28+
29+
func TestPerfEvents(t *testing.T) {
30+
fm := framework.New(t)
31+
defer fm.Cleanup()
32+
33+
containerID := fm.Docker().RunPause()
34+
waitForContainerInfo(fm, containerID)
35+
36+
info, err := fm.Cadvisor().Client().DockerContainer(containerID, &v1.ContainerInfoRequest{
37+
NumStats: 1,
38+
})
39+
40+
assert.Nil(t, err)
41+
assert.Len(t, info.Stats, 1)
42+
assert.Greater(t, len(info.Stats[0].PerfStats), 0, "Length of info.Stats[0].PerfStats is not greater than zero")
43+
for k, stat := range info.Stats[0].PerfStats {
44+
//Everything beyond name is non-deterministic unfortunately.
45+
assert.Contains(t, []string{"context-switches", "cpu-migrations-custom"}, stat.Name, "Wrong metric name for key %d: %#v", k, stat)
46+
}
47+
}
48+
49+
func waitForContainerInfo(fm framework.Framework, containerID string) {
50+
framework.RetryForDuration(func() error {
51+
_, err := fm.Cadvisor().Client().DockerContainer(containerID, &v1.ContainerInfoRequest{NumStats: 1})
52+
if err != nil {
53+
return err
54+
}
55+
return nil
56+
}, 5*time.Second)
57+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"events": [
3+
["context-switches"],
4+
["cpu-migrations-custom"]
5+
],
6+
"custom_events": [
7+
{
8+
"type": 1,
9+
"config": [
10+
"0x4"
11+
],
12+
"name": "cpu-migrations-custom"
13+
}
14+
]
15+
}

0 commit comments

Comments
 (0)