Skip to content
This repository was archived by the owner on Mar 9, 2022. It is now read-only.

Commit efadb8f

Browse files
committed
Add integration test framework
Signed-off-by: Lantao Liu <[email protected]>
1 parent 5d888ee commit efadb8f

File tree

8 files changed

+259
-26
lines changed

8 files changed

+259
-26
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ jobs:
6565
script:
6666
- make install.deps
6767
- make test
68+
- make test-integration
6869
- make test-cri
6970
after_script:
7071
# Abuse travis to preserve the log.
72+
- cat /tmp/test-integration/cri-containerd.log
73+
- cat /tmp/test-integration/containerd.log
7174
- cat /tmp/test-cri/cri-containerd.log
7275
- cat /tmp/test-cri/containerd.log
7376
go: 1.8.x

Makefile

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ VERSION := $(shell git describe --tags --dirty)
2525
VERSION := $(VERSION:v%=%)
2626
TARBALL ?= cri-containerd-$(VERSION).tar.gz
2727
BUILD_TAGS:= -ldflags '-X $(PROJECT)/pkg/version.criContainerdVersion=$(VERSION)'
28-
SOURCES := $(shell find . -name '*.go')
28+
SOURCES := $(shell find cmd/ pkg/ vendor/ -name '*.go')
29+
INTEGRATION_SOURCES := $(shell find integration/ -name '*.go')
2930

3031
all: binaries
3132

@@ -34,20 +35,21 @@ default: help
3435
help:
3536
@echo "Usage: make <target>"
3637
@echo
37-
@echo " * 'install' - Install binaries to system locations"
38-
@echo " * 'binaries' - Build cri-containerd"
39-
@echo " * 'static-binaries - Build static cri-containerd"
40-
@echo " * 'release' - Build release tarball"
41-
@echo " * 'push' - Push release tarball to GCS"
42-
@echo " * 'test' - Test cri-containerd"
43-
@echo " * 'test-cri' - Test cri-containerd with cri validation test"
44-
@echo " * 'test-e2e-node' - Test cri-containerd with Kubernetes node e2e test"
45-
@echo " * 'clean' - Clean artifacts"
46-
@echo " * 'verify' - Execute the source code verification tools"
47-
@echo " * 'install.tools' - Install tools used by verify"
48-
@echo " * 'install.deps' - Install dependencies of cri-containerd (containerd, runc, cni) Note: BUILDTAGS defaults to 'seccomp apparmor' for runc build"
49-
@echo " * 'uninstall' - Remove installed binaries from system locations"
50-
@echo " * 'version' - Print current cri-containerd release version"
38+
@echo " * 'install' - Install binaries to system locations"
39+
@echo " * 'binaries' - Build cri-containerd"
40+
@echo " * 'static-binaries - Build static cri-containerd"
41+
@echo " * 'release' - Build release tarball"
42+
@echo " * 'push' - Push release tarball to GCS"
43+
@echo " * 'test' - Test cri-containerd with unit test"
44+
@echo " * 'test-integration' - Test cri-containerd with integration test"
45+
@echo " * 'test-cri' - Test cri-containerd with cri validation test"
46+
@echo " * 'test-e2e-node' - Test cri-containerd with Kubernetes node e2e test"
47+
@echo " * 'clean' - Clean artifacts"
48+
@echo " * 'verify' - Execute the source code verification tools"
49+
@echo " * 'install.tools' - Install tools used by verify"
50+
@echo " * 'install.deps' - Install dependencies of cri-containerd (containerd, runc, cni) Note: BUILDTAGS defaults to 'seccomp apparmor' for runc build"
51+
@echo " * 'uninstall' - Remove installed binaries from system locations"
52+
@echo " * 'version' - Print current cri-containerd release version"
5153

5254
verify: lint gofmt boiler
5355

@@ -75,6 +77,12 @@ $(BUILD_DIR)/cri-containerd: $(SOURCES)
7577
test:
7678
go test -timeout=10m -race ./pkg/... $(BUILD_TAGS) $(GO_LDFLAGS) $(GO_GCFLAGS)
7779

80+
$(BUILD_DIR)/integration.test: $(INTEGRATION_SOURCES)
81+
go test -c $(PROJECT)/integration -o $(BUILD_DIR)/integration.test
82+
83+
test-integration: $(BUILD_DIR)/integration.test binaries
84+
@./hack/test-integration.sh
85+
7886
test-cri: binaries
7987
@./hack/test-cri.sh
8088

@@ -142,6 +150,7 @@ install.tools: .install.gitvalidation .install.gometalinter
142150
install \
143151
lint \
144152
test \
153+
test-integration \
145154
test-cri \
146155
test-e2e-node \
147156
uninstall \

hack/test-cri.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ source $(dirname "${BASH_SOURCE[0]}")/test-utils.sh
2222
FOCUS=${FOCUS:-}
2323
# SKIP skips the test to skip.
2424
SKIP=${SKIP:-""}
25+
# REPORT_DIR is the the directory to store test logs.
2526
REPORT_DIR=${REPORT_DIR:-"/tmp/test-cri"}
2627

2728
# Check GOPATH
@@ -35,7 +36,6 @@ GOPATH=${GOPATH%%:*}
3536

3637
CRITEST=${GOPATH}/bin/critest
3738
CRITOOL_PKG=github.com/kubernetes-incubator/cri-tools
38-
CRICONTAINERD_SOCK=/var/run/cri-containerd.sock
3939

4040
# Install critest
4141
if [ ! -x "$(command -v ${CRITEST})" ]; then

hack/test-e2e-node.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ DEFAULT_SKIP+="|ImageID"
2626
export FOCUS=${FOCUS:-""}
2727
# SKIP skips the test to skip.
2828
export SKIP=${SKIP:-${DEFAULT_SKIP}}
29+
# REPORT_DIR is the the directory to store test logs.
2930
REPORT_DIR=${REPORT_DIR:-"/tmp/test-e2e-node"}
31+
# UPLOAD_LOG indicates whether to upload test log to gcs.
3032
UPLOAD_LOG=${UPLOAD_LOG:-false}
3133

3234
# Check GOPATH
@@ -71,7 +73,7 @@ start_cri_containerd ${REPORT_DIR}
7173

7274
make test-e2e-node \
7375
RUNTIME=remote \
74-
CONTAINER_RUNTIME_ENDPOINT=unix:///var/run/cri-containerd.sock \
76+
CONTAINER_RUNTIME_ENDPOINT=unix://${CRICONTAINERD_SOCK} \
7577
ARTIFACTS=${REPORT_DIR} \
7678
TEST_ARGS='--kubelet-flags=--cgroups-per-qos=true \
7779
--kubelet-flags=--cgroup-root=/ \

hack/test-integration.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
# Copyright 2017 The Kubernetes Authors.
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+
set -o nounset
17+
set -o pipefail
18+
19+
source $(dirname "${BASH_SOURCE[0]}")/test-utils.sh
20+
cd ${ROOT}
21+
22+
# FOCUS focuses the test to run.
23+
FOCUS=${FOCUS:-""}
24+
# REPORT_DIR is the the directory to store test logs.
25+
REPORT_DIR=${REPORT_DIR:-"/tmp/test-integration"}
26+
27+
mkdir -p ${REPORT_DIR}
28+
start_cri_containerd ${REPORT_DIR}
29+
30+
# Run integration test.
31+
sudo ${ROOT}/_output/integration.test --test.run="${FOCUS}" --test.v
32+
test_exit_code=$?
33+
34+
kill_cri_containerd
35+
36+
exit ${test_exit_code}

hack/test-utils.sh

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
1919
# CRI_CONTAINERD_FLAGS are the extra flags to use when start cri-containerd.
2020
CRI_CONTAINERD_FLAGS=${CRI_CONTAINERD_FLAGS:-""}
2121

22+
CRICONTAINERD_SOCK=/var/run/cri-containerd.sock
23+
2224
# start_cri_containerd starts containerd and cri-containerd.
2325
start_cri_containerd() {
2426
local report_dir=$1
@@ -33,28 +35,34 @@ start_cri_containerd() {
3335
exit 1
3436
fi
3537
kill_cri_containerd
36-
sudo containerd -l debug &> ${report_dir}/containerd.log &
37-
38+
sudo containerd &> ${report_dir}/containerd.log &
3839
# Wait for containerd to be running by using the containerd client ctr to check the version
3940
# of the containerd server. Wait an increasing amount of time after each of five attempts
40-
local MAX_ATTEMPTS=5
41-
local attempt_num=1
42-
until sudo ctr version &> /dev/null || (( attempt_num == MAX_ATTEMPTS ))
43-
do
44-
echo "attempt $attempt_num to connect to containerd failed! Trying again in $attempt_num seconds..."
45-
sleep $(( attempt_num++ ))
46-
done
41+
readiness_check "sudo ctr version"
4742

4843
# Start cri-containerd
4944
sudo ${ROOT}/_output/cri-containerd --alsologtostderr --v 4 ${CRI_CONTAINERD_FLAGS} \
5045
&> ${report_dir}/cri-containerd.log &
46+
readiness_check "sudo ${GOPATH}/bin/crictl --runtime-endpoint=${CRICONTAINERD_SOCK} info"
5147
}
5248

5349
# kill_cri_containerd kills containerd and cri-containerd.
5450
kill_cri_containerd() {
5551
sudo pkill containerd
5652
}
5753

54+
# readiness_check checks readiness of a daemon with specified command.
55+
readiness_check() {
56+
local command=$1
57+
local MAX_ATTEMPTS=5
58+
local attempt_num=1
59+
until ${command} &> /dev/null || (( attempt_num == MAX_ATTEMPTS ))
60+
do
61+
echo "$attempt_num attempt \"$command\"! Trying again in $attempt_num seconds..."
62+
sleep $(( attempt_num++ ))
63+
done
64+
}
65+
5866
# upload_logs_to_gcs uploads test logs to gcs.
5967
# Var set:
6068
# 1. Bucket: gcs bucket to upload logs.

integration/imagefs_info_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package integration
18+
19+
import (
20+
"fmt"
21+
"io/ioutil"
22+
"testing"
23+
"time"
24+
25+
"github.com/stretchr/testify/assert"
26+
"github.com/stretchr/testify/require"
27+
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
28+
)
29+
30+
func TestImageFSInfo(t *testing.T) {
31+
t.Logf("Pull an image to make sure image fs is not empty")
32+
img, err := imageService.PullImage(&runtime.ImageSpec{Image: "busybox"}, nil)
33+
require.NoError(t, err)
34+
defer func() {
35+
err := imageService.RemoveImage(&runtime.ImageSpec{Image: img})
36+
assert.NoError(t, err)
37+
}()
38+
t.Logf("Create a sandbox to make sure there is an active snapshot")
39+
config := PodSandboxConfig("running-pod", "imagefs")
40+
sb, err := runtimeService.RunPodSandbox(config)
41+
require.NoError(t, err)
42+
defer func() {
43+
assert.NoError(t, runtimeService.StopPodSandbox(sb))
44+
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
45+
}()
46+
47+
// It takes time to populate imagefs stats. Use eventually
48+
// to check for a period of time.
49+
t.Logf("Check imagefs info")
50+
var info *runtime.FilesystemUsage
51+
require.NoError(t, Eventually(func() (bool, error) {
52+
stats, err := imageService.ImageFsInfo()
53+
if err != nil {
54+
return false, err
55+
}
56+
if len(stats) == 0 {
57+
return false, nil
58+
}
59+
if len(stats) >= 2 {
60+
return false, fmt.Errorf("unexpected stats length: %d", len(stats))
61+
}
62+
info = stats[0]
63+
if info.GetTimestamp() != 0 &&
64+
info.GetUsedBytes().GetValue() != 0 &&
65+
info.GetInodesUsed().GetValue() != 0 &&
66+
info.GetStorageId().GetUuid() != "" {
67+
return true, nil
68+
}
69+
return false, nil
70+
}, time.Second, 30*time.Second))
71+
72+
t.Logf("Device uuid should exist")
73+
files, err := ioutil.ReadDir("/dev/disk/by-uuid")
74+
require.NoError(t, err)
75+
var names []string
76+
for _, f := range files {
77+
names = append(names, f.Name())
78+
}
79+
assert.Contains(t, names, info.GetStorageId().GetUuid())
80+
}

integration/test_utils.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package integration
18+
19+
import (
20+
"errors"
21+
"time"
22+
23+
"github.com/golang/glog"
24+
"k8s.io/kubernetes/pkg/kubelet/apis/cri"
25+
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
26+
"k8s.io/kubernetes/pkg/kubelet/remote"
27+
28+
"github.com/kubernetes-incubator/cri-containerd/pkg/util"
29+
)
30+
31+
const (
32+
sock = "/var/run/cri-containerd.sock"
33+
timeout = 1 * time.Minute
34+
)
35+
36+
var (
37+
runtimeService cri.RuntimeService
38+
imageService cri.ImageManagerService
39+
)
40+
41+
func init() {
42+
var err error
43+
runtimeService, err = remote.NewRemoteRuntimeService(sock, timeout)
44+
if err != nil {
45+
glog.Exitf("Failed to create runtime service: %v", err)
46+
}
47+
imageService, err = remote.NewRemoteImageService(sock, timeout)
48+
if err != nil {
49+
glog.Exitf("Failed to create image service: %v", err)
50+
}
51+
}
52+
53+
// Opts sets specific information in pod sandbox config.
54+
type PodSandboxOpts func(*runtime.PodSandboxConfig)
55+
56+
// PodSandboxConfig generates a pod sandbox config for test.
57+
func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandboxConfig {
58+
config := &runtime.PodSandboxConfig{
59+
Metadata: &runtime.PodSandboxMetadata{
60+
Name: name,
61+
// Using random id as uuid is good enough for local
62+
// integration test.
63+
Uid: util.GenerateID(),
64+
Namespace: ns,
65+
},
66+
Linux: &runtime.LinuxPodSandboxConfig{},
67+
}
68+
for _, opt := range opts {
69+
opt(config)
70+
}
71+
return config
72+
}
73+
74+
// CheckFunc is the function used to check a condition is true/false.
75+
type CheckFunc func() (bool, error)
76+
77+
// Eventually waits for f to return true, it checks every period, and
78+
// returns error if timeout exceeds. If f returns error, Eventually
79+
// will return the same error immediately.
80+
func Eventually(f CheckFunc, period, timeout time.Duration) error {
81+
start := time.Now()
82+
for {
83+
done, err := f()
84+
if done {
85+
return nil
86+
}
87+
if err != nil {
88+
return err
89+
}
90+
if time.Since(start) >= timeout {
91+
return errors.New("timeout exceeded")
92+
}
93+
time.Sleep(period)
94+
}
95+
}

0 commit comments

Comments
 (0)