Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions test/cri-containerd/removepodsandbox_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// +build functional

package cri_containerd

import (
"context"
"testing"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
)

type TestConfig struct {
name string
containerName string
requiredFeatures []string
runtimeHandler string
sandboxImage string
containerImage string
cmd []string
}

// Utility function to test removal of a sandbox with no containers and no previous call to stop the pod
func runPodSandboxTestWithoutPodStop(t *testing.T, request *runtime.RunPodSandboxRequest) {
client := newTestRuntimeClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

podID := runPodSandbox(t, client, ctx, request)
removePodSandbox(t, client, ctx, podID)

_, err := client.PodSandboxStatus(ctx, &runtime.PodSandboxStatusRequest{
PodSandboxId: podID,
})

status, ok := status.FromError(err)
if !ok || status.Code() != codes.NotFound {
t.Fatalf("PodSandboxStatus did not return expected errorStatus: %s", err)
}
}

// Utility function to start sandbox with one container and make sure that sandbox is removed in the end
func runPodWithContainer(t *testing.T, client runtime.RuntimeServiceClient, ctx context.Context, tc *TestConfig) (string, string) {
request := getRunPodSandboxRequest(t, tc.runtimeHandler)
podID := runPodSandbox(t, client, ctx, &request)
defer removePodSandbox(t, client, ctx, podID)

containerID := createContainerInSandbox(t, client, ctx, podID, tc.containerName, tc.containerImage, tc.cmd, nil, nil, request.Config)

startContainer(t, client, ctx, containerID)

return podID, containerID
}

// Utility function to test removal of a sandbox with one container and no previous call to stop the pod or container
func runContainerInSandboxTest(t *testing.T, tc *TestConfig) {
client := newTestRuntimeClient(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

podID, containerID := runPodWithContainer(t, client, ctx, tc)

_, csErr := client.ContainerStatus(ctx, &runtime.ContainerStatusRequest{
ContainerId: containerID,
})

csStatus, csOk := status.FromError(csErr)
if !csOk || csStatus.Code() != codes.NotFound {
t.Fatalf("ContainerStatus did not return expected errorStatus: %s", csErr)
}

_, psErr := client.PodSandboxStatus(ctx, &runtime.PodSandboxStatusRequest{
PodSandboxId: podID,
})

psStatus, psOk := status.FromError(psErr)
if !psOk || psStatus.Code() != codes.NotFound {
t.Fatalf("PodSandboxStatus did not return expected errorStatus: %s", psErr)
}
}

func Test_RunPodSandbox_Without_Sandbox_Stop(t *testing.T) {
tests := []TestConfig{
{
name: "WCOW_Process",
requiredFeatures: []string{featureWCOWProcess},
runtimeHandler: wcowProcessRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
},
{
name: "WCOW_Hypervisor",
requiredFeatures: []string{featureWCOWHypervisor},
runtimeHandler: wcowHypervisorRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
},
{
name: "LCOW",
requiredFeatures: []string{featureLCOW},
runtimeHandler: lcowRuntimeHandler,
sandboxImage: imageLcowAlpine,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
requireFeatures(t, test.requiredFeatures...)

if test.runtimeHandler == lcowRuntimeHandler {
pullRequiredLcowImages(t, []string{test.sandboxImage})
} else {
pullRequiredImages(t, []string{test.sandboxImage})
}

request := getRunPodSandboxRequest(t, test.runtimeHandler)
runPodSandboxTestWithoutPodStop(t, &request)
})
}
}

func Test_RunContainer_Without_Sandbox_Stop(t *testing.T) {
tests := []TestConfig{
{
name: "WCOW_Process",
containerName: t.Name() + "-Container-WCOW_Process",
requiredFeatures: []string{featureWCOWProcess},
runtimeHandler: wcowProcessRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
containerImage: imageWindowsNanoserver,
cmd: []string{"ping", "-t", "127.0.0.1"},
},
{
name: "WCOW_Hypervisor",
containerName: t.Name() + "-Container-WCOW_Hypervisor",
requiredFeatures: []string{featureWCOWHypervisor},
runtimeHandler: wcowHypervisorRuntimeHandler,
sandboxImage: imageWindowsNanoserver,
containerImage: imageWindowsNanoserver,
cmd: []string{"ping", "-t", "127.0.0.1"},
},
{
name: "LCOW",
containerName: t.Name() + "-Container-LCOW",
requiredFeatures: []string{featureLCOW},
runtimeHandler: lcowRuntimeHandler,
sandboxImage: imageLcowK8sPause,
containerImage: imageLcowAlpine,
cmd: []string{"top"},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
requireFeatures(t, test.requiredFeatures...)

if test.runtimeHandler == lcowRuntimeHandler {
pullRequiredLcowImages(t, []string{test.sandboxImage, test.containerImage})
} else {
pullRequiredImages(t, []string{test.sandboxImage, test.containerImage})
}

runContainerInSandboxTest(t, &test)
})
}
}
12 changes: 12 additions & 0 deletions test/cri-containerd/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,15 @@ func removePodSandbox(t *testing.T, client runtime.RuntimeServiceClient, ctx con
t.Fatalf("failed RemovePodSandbox for sandbox: %s, request with: %v", podID, err)
}
}

func getRunPodSandboxRequest(t *testing.T, runtimeHandler string) runtime.RunPodSandboxRequest {
return runtime.RunPodSandboxRequest{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, might be useful to replace all of the easy (e.g. nothing other than the runtime handler needing to be filled out) RunPodSandboxRequests we have in our tests with this also. Doesn't need to be this PR though :P

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll file a separate PR for this 😄

Config: &runtime.PodSandboxConfig{
Metadata: &runtime.PodSandboxMetadata{
Name: t.Name(),
Namespace: testNamespace,
},
},
RuntimeHandler: runtimeHandler,
}
}