Skip to content

Commit

Permalink
Add support for specifying custom test container images.
Browse files Browse the repository at this point in the history
This patch adds an optional `--test-images-file` argument for specifying
the path to a YAML file containing custom container image references
to be used in tests.

Initial user-overridable image keys being `defaultTestContainerImage`
(the image used in the majority of tests), and `webServerTestImage`
(which is used in Networking-related tests)

Signed-off-by: Nashwan Azhari <[email protected]>
  • Loading branch information
aznashwan committed Dec 29, 2021
1 parent b0c7dbf commit 4026dfb
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 31 deletions.
1 change: 1 addition & 0 deletions docs/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ critest connects to Unix: `unix:///var/run/dockershim.sock` or Windows: `tcp://l

- `-ginkgo.focus`: Only run the tests that match the regular expression.
- `-image-endpoint`: Set the endpoint of image service. Same with runtime-endpoint if not specified.
- `-test-images-file`: Optional path to a YAML file containing references to custom container images to be used in tests.
- `-runtime-endpoint`: Set the endpoint of runtime service. Default to `unix:///var/run/dockershim.sock` or Windows: `tcp://localhost:3735`.
- `-ginkgo.skip`: Skip the tests that match the regular expression.
- `-parallel`: The number of parallel test nodes to run (default 1). [ginkgo](https://github.com/onsi/ginkgo) must be installed to run parallel tests.
Expand Down
32 changes: 32 additions & 0 deletions pkg/framework/test_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@ package framework

import (
"flag"
"fmt"
"os"
"path/filepath"
"runtime"
"time"

"github.com/onsi/ginkgo/config"
"gopkg.in/yaml.v3"
)

// TestImageList aggregates references to the images used in tests.
type TestImageList struct {
DefaultTestContainerImage string `yaml:"defaultTestContainerImage"`
WebServerTestImage string `yaml:"webServerTestImage"`
}

// TestContextType is the type of test context.
type TestContextType struct {
// Report related settings.
Expand All @@ -40,6 +48,10 @@ type TestContextType struct {
RuntimeServiceTimeout time.Duration
RuntimeHandler string

// Test images-related settings.
TestImagesFilePath string
TestImageList TestImageList

// Benchmark setting.
Number int

Expand Down Expand Up @@ -69,6 +81,7 @@ func RegisterFlags() {
flag.StringVar(&TestContext.ReportPrefix, "report-prefix", "", "Optional prefix for JUnit XML reports. Default is empty, which doesn't prepend anything to the default name.")
flag.StringVar(&TestContext.ReportDir, "report-dir", "", "Path to the directory where the JUnit XML reports should be saved. Default is empty, which doesn't generate these reports.")
flag.StringVar(&TestContext.ImageServiceAddr, "image-endpoint", "", "Image service socket for client to connect.")
flag.StringVar(&TestContext.TestImagesFilePath, "test-images-file", "", "Optional path to a YAML file containing references to custom container images to be used in tests.")
flag.DurationVar(&TestContext.ImageServiceTimeout, "image-service-timeout", 300*time.Second, "Timeout when trying to connect to image service.")

svcaddr := "unix:///var/run/dockershim.sock"
Expand All @@ -90,3 +103,22 @@ func RegisterFlags() {
}
flag.StringVar(&TestContext.RegistryPrefix, "registry-prefix", DefaultRegistryPrefix, "A possible registry prefix added to all images, like 'localhost:5000/'")
}

// Loads the custom images mapping file (if defined) into the TestContextType.
func (tc TestContextType) LoadCustomImagesFileIntoTestingContext() error {
Logf("Testing context container image list file: %s", TestContext.TestImagesFilePath)
if TestContext.TestImagesFilePath != "" {
fileContent, err := os.ReadFile(TestContext.TestImagesFilePath)
if err != nil {
return fmt.Errorf("error reading '%v' file contents: %v", TestContext.TestImagesFilePath, err)
}

err = yaml.Unmarshal(fileContent, &TestContext.TestImageList)
if err != nil {
return fmt.Errorf("error unmarshalling '%v' YAML file: %v", TestContext.TestImagesFilePath, err)
}
}

Logf("Testing context container image list: %+v", TestContext.TestImageList)
return nil
}
17 changes: 10 additions & 7 deletions pkg/framework/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ var (
// DefaultPodLabels are labels used by default in pods
DefaultPodLabels map[string]string

// DefaultContainerImage is the default image used for containers
DefaultContainerImage string

// DefaultContainerCommand is the default command used for containers
DefaultContainerCommand []string

Expand Down Expand Up @@ -103,18 +100,24 @@ const (
var _ = BeforeSuite(func() {
if runtime.GOOS != "windows" || TestContext.IsLcow {
DefaultPodLabels = DefaultLinuxPodLabels
DefaultContainerImage = DefaultLinuxContainerImage
DefaultContainerCommand = DefaultLinuxContainerCommand
DefaultPauseCommand = DefaultLinuxPauseCommand
TestContext.TestImageList.DefaultTestContainerImage = DefaultLinuxContainerImage

if TestContext.IsLcow {
DefaultPodLabels = DefaultLcowPodLabels
}
} else {
DefaultPodLabels = DefaultWindowsPodLabels
DefaultContainerImage = DefaultWindowsContainerImage
DefaultContainerCommand = DefaultWindowsContainerCommand
DefaultPauseCommand = DefaultWindowsPauseCommand
TestContext.TestImageList.DefaultTestContainerImage = DefaultWindowsContainerImage
}

// Load any custom image definitions:
err := TestContext.LoadCustomImagesFileIntoTestingContext()
if err != nil {
panic(err)
}

for _, callback := range beforeSuiteCallbacks {
Expand Down Expand Up @@ -254,7 +257,7 @@ func CreateDefaultContainer(rc internalapi.RuntimeService, ic internalapi.ImageM
containerName := prefix + NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: BuildContainerMetadata(containerName, DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: TestContext.TestImageList.DefaultTestContainerImage},
Command: DefaultContainerCommand,
Linux: &runtimeapi.LinuxContainerConfig{},
}
Expand All @@ -267,7 +270,7 @@ func CreatePauseContainer(rc internalapi.RuntimeService, ic internalapi.ImageMan
containerName := prefix + NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: BuildContainerMetadata(containerName, DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: TestContext.TestImageList.DefaultTestContainerImage},
Command: DefaultPauseCommand,
Linux: &runtimeapi.LinuxContainerConfig{},
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/validate/apparmor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func createContainerWithAppArmor(rc internalapi.RuntimeService, ic internalapi.I
containerName := "apparmor-test-" + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"touch", "/tmp/foo"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down
5 changes: 5 additions & 0 deletions pkg/validate/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@ var _ = framework.AddBeforeSuiteCallback(func() {
getDNSConfigContent = getDNSConfigWindowsContent
getHostnameCmd = getHostnameWindowsCmd
}

// Override the web server test image if an explicit one is provided:
if framework.TestContext.TestImageList.WebServerTestImage != "" {
webServerImage = framework.TestContext.TestImageList.WebServerTestImage
}
})

// Streaming test constants
Expand Down
8 changes: 4 additions & 4 deletions pkg/validate/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func createShellContainer(rc internalapi.RuntimeService, ic internalapi.ImageMan
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: shellCmd,
Linux: &runtimeapi.LinuxContainerConfig{},
Stdin: true,
Expand Down Expand Up @@ -455,7 +455,7 @@ func createVolumeContainer(rc internalapi.RuntimeService, ic internalapi.ImageMa
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
// mount host path to the same directory in container, and will check if hostPath isn't empty
Mounts: []*runtimeapi.Mount{
Expand All @@ -477,7 +477,7 @@ func createLogContainer(rc internalapi.RuntimeService, ic internalapi.ImageManag
path := fmt.Sprintf("%s.log", containerName)
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: logDefaultCmd,
LogPath: path,
}
Expand All @@ -491,7 +491,7 @@ func createKeepLoggingContainer(rc internalapi.RuntimeService, ic internalapi.Im
path := fmt.Sprintf("%s.log", containerName)
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: loopLogDefaultCmd,
LogPath: path,
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/validate/container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func createMountPropagationContainer(rc internalapi.RuntimeService, ic internala
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
// Set Privileged in order to executing mount command in container
Linux: &runtimeapi.LinuxContainerConfig{
Expand Down
2 changes: 1 addition & 1 deletion pkg/validate/multi_container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func createMultiContainerTestBusyboxContainer(rc internalapi.RuntimeService, ic
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"sh", "-c", "echo " + defaultLog + "; sleep 1000"},
LogPath: fmt.Sprintf("%s.log", containerName),
}
Expand Down
32 changes: 16 additions & 16 deletions pkg/validate/security_context_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
command = []string{"sh", "-c", "sleep 1000"}
prefix = "container-with-HostPID-test-"
containerName = prefix + framework.NewUUID()
containerID, _, _ = createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.DefaultContainerImage, namespaceOption, command, "")
containerID, _, _ = createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.TestContext.TestImageList.DefaultTestContainerImage, namespaceOption, command, "")

By("start container")
startContainer(rc, containerID)
Expand Down Expand Up @@ -145,7 +145,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
By("create a default container with namespace")
prefix := "namespace-container-"
containerName := prefix + framework.NewUUID()
containerID, _, _ := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.DefaultContainerImage, namespaceOption, pauseCmd, "")
containerID, _, _ := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.TestContext.TestImageList.DefaultTestContainerImage, namespaceOption, pauseCmd, "")

By("start container")
startContainer(rc, containerID)
Expand Down Expand Up @@ -177,7 +177,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
By("create a default container with namespace")
prefix := "namespace-container-"
containerName := prefix + framework.NewUUID()
containerID, _, _ := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.DefaultContainerImage, namespaceOption, pauseCmd, "")
containerID, _, _ := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.TestContext.TestImageList.DefaultTestContainerImage, namespaceOption, pauseCmd, "")

By("start container")
startContainer(rc, containerID)
Expand Down Expand Up @@ -294,7 +294,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
containerName := "container-with-SupplementalGroups-test-" + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -549,7 +549,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
containerName := "container-with-maskedpaths" + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -578,7 +578,7 @@ var _ = framework.KubeDescribe("Security Context", func() {
containerName := "container-with-readonlypaths" + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -846,7 +846,7 @@ func createRunAsUserContainer(rc internalapi.RuntimeService, ic internalapi.Imag
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand All @@ -868,7 +868,7 @@ func createRunAsUserNameContainer(rc internalapi.RuntimeService, ic internalapi.
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand All @@ -890,7 +890,7 @@ func createRunAsGroupContainer(rc internalapi.RuntimeService, ic internalapi.Ima
By("create a container with RunAsUser and RunAsGroup")
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"sh", "-c", "echo $(id -u):$(id -g)"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand All @@ -913,7 +913,7 @@ func createInvalidRunAsGroupContainer(rc internalapi.RuntimeService, ic internal
By("create a container with RunAsGroup without RunAsUser")
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"sh", "-c", "echo $(id -u):$(id -g)"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -970,7 +970,7 @@ func createReadOnlyRootfsContainer(rc internalapi.RuntimeService, ic internalapi
path := fmt.Sprintf("%s.log", containerName)
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"sh", "-c", "touch test.go && [ -f test.go ] && echo 'Found'"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -1021,7 +1021,7 @@ func createPrivilegedContainer(rc internalapi.RuntimeService, ic internalapi.Ima
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -1053,7 +1053,7 @@ func createCapabilityContainer(rc internalapi.RuntimeService, ic internalapi.Ima
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -1086,7 +1086,7 @@ func createAndCheckHostNetwork(rc internalapi.RuntimeService, ic internalapi.Ima
command := []string{"sh", "-c", "netstat -ln"}
containerName := "container-with-HostNetwork-test-" + framework.NewUUID()
path := fmt.Sprintf("%s.log", containerName)
containerID, _, logPath := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.DefaultContainerImage, namespaceOptions, command, path)
containerID, _, logPath := createNamespaceContainer(rc, ic, podID, podConfig, containerName, framework.TestContext.TestImageList.DefaultTestContainerImage, namespaceOptions, command, path)

By("start container")
startContainer(rc, containerID)
Expand Down Expand Up @@ -1154,7 +1154,7 @@ func seccompTestContainer(rc internalapi.RuntimeService, ic internalapi.ImageMan
containerName := containerNamePrefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: pauseCmd,
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down Expand Up @@ -1200,7 +1200,7 @@ func createSeccompContainer(rc internalapi.RuntimeService,
containerName := prefix + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.DefaultContainerImage},
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"sleep", "60"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
Expand Down
Loading

0 comments on commit 4026dfb

Please sign in to comment.