tests: Refactors container image usage

Currently, the cri-integration tests do not work on Windows due to various reasons.
One of the reasons is because all the tests are using Linux-specific images. This
commit refactors the image pulling / usage in the cri-integration tests, making it
easier to update, and easier to configure the a custom registry to pull those images
from.

For Windows runs, custom registries can be created, which will also contain Windows
images, and the cri-integration tests can be configured to use those registries by
specifying the "--image-list" argument, a TOML file which will contain an alternative
mapping of the default images.

Signed-off-by: Claudiu Belu <cbelu@cloudbasesolutions.com>
This commit is contained in:
Claudiu Belu 2021-02-16 12:45:45 +00:00
parent b0fb8a5a04
commit 5847340a7d
17 changed files with 139 additions and 31 deletions

View File

@ -18,6 +18,7 @@ ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
# Base path used to install.
DESTDIR ?= /usr/local
TEST_IMAGE_LIST ?=
# Used to populate variables in version package.
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always)

View File

@ -45,8 +45,8 @@ func TestAdditionalGids(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)
@ -59,7 +59,7 @@ func TestAdditionalGids(t *testing.T) {
t.Log("Create a container to print id")
cnConfig := ContainerConfig(
containerName,
"busybox",
testImage,
WithCommand("id"),
WithLogPath(containerName),
WithSupplementalGroups([]int64{1 /*daemon*/, 1234 /*new group*/}),

101
integration/common.go Normal file
View File

@ -0,0 +1,101 @@
// +build linux
/*
Copyright The containerd 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.
*/
package integration
import (
"fmt"
"io/ioutil"
"github.com/pelletier/go-toml"
"github.com/sirupsen/logrus"
cri "k8s.io/cri-api/pkg/apis"
)
// ImageList holds public image references
type ImageList struct {
Alpine string
BusyBox string
Pause string
VolumeCopyUp string
VolumeOwnership string
}
var (
imageService cri.ImageManagerService
imageMap map[int]string
imageList ImageList
pauseImage string // This is the same with default sandbox image
)
func initImages(imageListFile string) {
imageList = ImageList{
Alpine: "docker.io/library/alpine:latest",
BusyBox: "docker.io/library/busybox:latest",
Pause: "k8s.gcr.io/pause:3.5",
VolumeCopyUp: "gcr.io/k8s-cri-containerd/volume-copy-up:2.0",
VolumeOwnership: "gcr.io/k8s-cri-containerd/volume-ownership:2.0",
}
if imageListFile != "" {
fileContent, err := ioutil.ReadFile(imageListFile)
if err != nil {
panic(fmt.Errorf("Error reading '%v' file contents: %v", imageList, err))
}
err = toml.Unmarshal(fileContent, &imageList)
if err != nil {
panic(fmt.Errorf("Error unmarshalling '%v' TOML file: %v", imageList, err))
}
}
logrus.Infof("Using the following image list: %+v", imageList)
imageMap = initImageMap(imageList)
pauseImage = GetImage(Pause)
}
const (
// None is to be used for unset/default images
None = iota
// Alpine image
Alpine
// BusyBox image
BusyBox
// Pause image
Pause
// VolumeCopyUp image
VolumeCopyUp
// VolumeOwnership image
VolumeOwnership
)
func initImageMap(imageList ImageList) map[int]string {
images := map[int]string{}
images[Alpine] = imageList.Alpine
images[BusyBox] = imageList.BusyBox
images[Pause] = imageList.Pause
images[VolumeCopyUp] = imageList.VolumeCopyUp
images[VolumeOwnership] = imageList.VolumeOwnership
return images
}
// GetImage returns the fully qualified URI to an image (including version)
func GetImage(image int) string {
return imageMap[image]
}

View File

@ -48,8 +48,8 @@ func TestContainerLogWithoutTailingNewLine(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)
@ -108,8 +108,8 @@ func TestLongContainerLog(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)

View File

@ -42,8 +42,8 @@ func TestSharedPidMultiProcessContainerStop(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)
@ -86,8 +86,8 @@ func TestContainerStopCancellation(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)

View File

@ -37,8 +37,8 @@ func TestContainerLifecycleWithoutImageRef(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Log("Pull test image")

View File

@ -35,7 +35,7 @@ import (
// Test to test the CRI plugin should see image pulled into containerd directly.
func TestContainerdImage(t *testing.T) {
const testImage = "docker.io/library/busybox:latest"
var testImage = GetImage(BusyBox)
ctx := context.Background()
t.Logf("make sure the test image doesn't exist in the cri plugin")
@ -153,7 +153,7 @@ func TestContainerdImage(t *testing.T) {
// Test image managed by CRI plugin shouldn't be affected by images in other namespaces.
func TestContainerdImageInOtherNamespaces(t *testing.T) {
const testImage = "docker.io/library/busybox:latest"
var testImage = GetImage(BusyBox)
ctx := context.Background()
t.Logf("make sure the test image doesn't exist in the cri plugin")

View File

@ -0,0 +1,5 @@
alpine = "docker.io/library/alpine:latest"
busybox = "docker.io/library/busybox:latest"
pause = "k8s.gcr.io/pause:3.5"
VolumeCopyUp = "gcr.io/k8s-cri-containerd/volume-copy-up:2.0"
VolumeOwnership = "gcr.io/k8s-cri-containerd/volume-ownership:2.0"

View File

@ -32,8 +32,8 @@ import (
// Test to load an image from tarball.
func TestImageLoad(t *testing.T) {
testImage := "busybox:latest"
loadedImage := "docker.io/library/" + testImage
testImage := GetImage(BusyBox)
loadedImage := testImage
_, err := exec.LookPath("docker")
if err != nil {
t.Skipf("Docker is not available: %v", err)

View File

@ -33,7 +33,7 @@ func TestImageFSInfo(t *testing.T) {
config := PodSandboxConfig("running-pod", "imagefs")
t.Logf("Pull an image to make sure image fs is not empty")
img, err := imageService.PullImage(&runtime.ImageSpec{Image: "busybox"}, nil, config)
img, err := imageService.PullImage(&runtime.ImageSpec{Image: GetImage(BusyBox)}, nil, config)
require.NoError(t, err)
defer func() {
err := imageService.RemoveImage(&runtime.ImageSpec{Image: img})

View File

@ -49,13 +49,11 @@ import (
const (
timeout = 1 * time.Minute
pauseImage = "k8s.gcr.io/pause:3.5" // This is the same with default sandbox image.
k8sNamespace = constants.K8sContainerdNamespace
)
var (
runtimeService cri.RuntimeService
imageService cri.ImageManagerService
containerdClient *containerd.Client
containerdEndpoint string
)
@ -64,9 +62,11 @@ var criEndpoint = flag.String("cri-endpoint", "unix:///run/containerd/containerd
var criRoot = flag.String("cri-root", "/var/lib/containerd/io.containerd.grpc.v1.cri", "The root directory of cri plugin.")
var runtimeHandler = flag.String("runtime-handler", "", "The runtime handler to use in the test.")
var containerdBin = flag.String("containerd-bin", "containerd", "The containerd binary name. The name is used to restart containerd during test.")
var imageListFile = flag.String("image-list", "", "The TOML file containing the non-default images to be used in tests.")
func TestMain(m *testing.M) {
flag.Parse()
initImages(*imageListFile)
if err := ConnectDaemons(); err != nil {
logrus.WithError(err).Fatalf("Failed to connect daemons")
}

View File

@ -46,8 +46,8 @@ func TestPodDualStack(t *testing.T) {
assert.NoError(t, runtimeService.RemovePodSandbox(sb))
}()
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)

View File

@ -82,8 +82,8 @@ func TestPodHostname(t *testing.T) {
t.Fatalf("Expected RunPodSandbox to return error")
}
const (
testImage = "busybox"
var (
testImage = GetImage(BusyBox)
containerName = "test-container"
)
t.Logf("Pull test image %q", testImage)

View File

@ -134,7 +134,7 @@ func TestContainerdRestart(t *testing.T) {
}
t.Logf("Pull test images")
for _, image := range []string{"busybox", "alpine"} {
for _, image := range []string{GetImage(BusyBox), GetImage(Alpine)} {
img, err := imageService.PullImage(&runtime.ImageSpec{Image: image}, nil, nil)
require.NoError(t, err)
defer func() {

View File

@ -34,7 +34,7 @@ func TestTruncIndex(t *testing.T) {
sbConfig := PodSandboxConfig("sandbox", "truncindex")
t.Logf("Pull an image")
const appImage = "busybox"
var appImage = GetImage(BusyBox)
imgID, err := imageService.PullImage(&runtimeapi.ImageSpec{Image: appImage}, nil, sbConfig)
require.NoError(t, err)
imgTruncID := genTruncIndex(imgID)

View File

@ -30,8 +30,8 @@ import (
)
func TestVolumeCopyUp(t *testing.T) {
const (
testImage = "gcr.io/k8s-cri-containerd/volume-copy-up:2.0"
var (
testImage = GetImage(VolumeCopyUp)
execTimeout = time.Minute
)
@ -92,8 +92,8 @@ func TestVolumeCopyUp(t *testing.T) {
}
func TestVolumeOwnership(t *testing.T) {
const (
testImage = "gcr.io/k8s-cri-containerd/volume-ownership:2.0"
var (
testImage = GetImage(VolumeOwnership)
execTimeout = time.Minute
)

View File

@ -37,7 +37,8 @@ sudo PATH=${PATH} bin/cri-integration.test --test.run="${FOCUS}" --test.v \
--cri-endpoint=${CONTAINERD_SOCK} \
--cri-root=${CRI_ROOT} \
--runtime-handler=${RUNTIME} \
--containerd-bin=${CONTAINERD_BIN}
--containerd-bin=${CONTAINERD_BIN} \
--image-list="${TEST_IMAGE_LIST:-}"
test_exit_code=$?