mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-20 07:56:02 +00:00
unit test: Set image volume digest as part of container statuses
Signed-off-by: Itamar Holder <iholder@redhat.com>
This commit is contained in:
@@ -41,6 +41,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/version"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
core "k8s.io/client-go/testing"
|
||||
@@ -4092,6 +4093,185 @@ func TestConvertToAPIContainerStatuses(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// imageDigestRuntime is a simple wrapper that returns a fixed digest for image volumes
|
||||
type imageDigestRuntime struct {
|
||||
*containertest.FakeRuntime
|
||||
digest string
|
||||
}
|
||||
|
||||
func (r *imageDigestRuntime) GetImageRef(ctx context.Context, image kubecontainer.ImageSpec) (string, error) {
|
||||
return r.digest, nil
|
||||
}
|
||||
|
||||
func TestConvertToAPIContainerStatusesWithImageVolumeDigest(t *testing.T) {
|
||||
const (
|
||||
imageVolumeName = "image-volume"
|
||||
imageVolumeMountPath = "/mock/path"
|
||||
imageVolumeRef = "registry.k8s.io/example:1.2.3"
|
||||
imageDigest = "sha256:abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd"
|
||||
)
|
||||
|
||||
now := metav1.Now()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
currentStatus *kubecontainer.PodStatus
|
||||
previousStatus []v1.ContainerStatus
|
||||
expected []v1.ContainerStatus
|
||||
}{
|
||||
{
|
||||
name: "with image volume - should include digest in status",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "node123",
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "containerA",
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
Name: imageVolumeName,
|
||||
MountPath: imageVolumeMountPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: imageVolumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
Image: &v1.ImageVolumeSource{
|
||||
Reference: imageVolumeRef,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
},
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "my-pod", DeletionTimestamp: &now},
|
||||
},
|
||||
currentStatus: &kubecontainer.PodStatus{
|
||||
ContainerStatuses: []*kubecontainer.Status{
|
||||
{
|
||||
ID: kubecontainer.ContainerID{Type: "test", ID: "containerA-id"},
|
||||
Name: "containerA",
|
||||
State: kubecontainer.ContainerStateRunning,
|
||||
Image: imageVolumeRef,
|
||||
Mounts: []kubecontainer.Mount{
|
||||
{
|
||||
Name: imageVolumeName,
|
||||
ContainerPath: imageVolumeMountPath,
|
||||
Image: &runtimeapi.ImageSpec{Image: imageVolumeRef},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
previousStatus: []v1.ContainerStatus{
|
||||
func() v1.ContainerStatus {
|
||||
previousContainerA := runningState("containerA")
|
||||
previousContainerA.VolumeMounts = []v1.VolumeMountStatus{
|
||||
{
|
||||
Name: imageVolumeName,
|
||||
MountPath: imageVolumeMountPath,
|
||||
},
|
||||
}
|
||||
return previousContainerA
|
||||
}(),
|
||||
},
|
||||
expected: []v1.ContainerStatus{
|
||||
func() v1.ContainerStatus {
|
||||
containerStatus := runningState("containerA")
|
||||
containerStatus.Image = imageVolumeRef
|
||||
containerStatus.ContainerID = "test://containerA-id"
|
||||
containerStatus.Resources = &v1.ResourceRequirements{}
|
||||
containerStatus.VolumeMounts = []v1.VolumeMountStatus{
|
||||
{
|
||||
Name: imageVolumeName,
|
||||
MountPath: imageVolumeMountPath,
|
||||
VolumeStatus: v1.VolumeStatus{Image: &v1.ImageVolumeStatus{ImageRef: imageDigest}},
|
||||
},
|
||||
}
|
||||
return containerStatus
|
||||
}(),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with no image volume - should not include digest in status",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "node123",
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "containerA",
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
},
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "my-pod", DeletionTimestamp: &now},
|
||||
},
|
||||
currentStatus: &kubecontainer.PodStatus{
|
||||
ContainerStatuses: []*kubecontainer.Status{
|
||||
{
|
||||
ID: kubecontainer.ContainerID{Type: "test", ID: "containerA-id"},
|
||||
Name: "containerA",
|
||||
State: kubecontainer.ContainerStateRunning,
|
||||
},
|
||||
},
|
||||
},
|
||||
previousStatus: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
},
|
||||
expected: []v1.ContainerStatus{
|
||||
func() v1.ContainerStatus {
|
||||
containerStatus := runningState("containerA")
|
||||
containerStatus.ContainerID = "test://containerA-id"
|
||||
containerStatus.Resources = &v1.ResourceRequirements{}
|
||||
return containerStatus
|
||||
}(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ImageVolume, true)
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ImageVolumeWithDigest, true)
|
||||
|
||||
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
|
||||
defer testKubelet.Cleanup()
|
||||
kl := testKubelet.kubelet
|
||||
|
||||
// Mock the container runtime to return the expected image digest
|
||||
kl.containerRuntime = &imageDigestRuntime{
|
||||
FakeRuntime: &containertest.FakeRuntime{},
|
||||
digest: imageDigest,
|
||||
}
|
||||
|
||||
containerStatuses := kl.convertToAPIContainerStatuses(
|
||||
test.pod,
|
||||
test.currentStatus,
|
||||
test.previousStatus,
|
||||
test.pod.Spec.Containers,
|
||||
sets.New(imageVolumeName),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
for i, status := range containerStatuses {
|
||||
assert.Equal(t, test.expected[i], status, "[test %s]", test.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_generateAPIPodStatus(t *testing.T) {
|
||||
desiredState := v1.PodSpec{
|
||||
NodeName: "machine",
|
||||
@@ -5400,11 +5580,7 @@ func TestConvertToAPIContainerStatusesDataRace(t *testing.T) {
|
||||
// detection, so would catch a race condition consistently, despite only spawning 2 goroutines
|
||||
for i := 0; i < 2; i++ {
|
||||
go func() {
|
||||
<<<<<<< HEAD
|
||||
kl.convertToAPIContainerStatuses(pod, criStatus, []v1.ContainerStatus{}, []v1.Container{}, false, false, false)
|
||||
=======
|
||||
kl.convertToAPIContainerStatuses(pod, criStatus, []v1.ContainerStatus{}, []v1.Container{}, nil, false, false)
|
||||
>>>>>>> 3102f167ced (Set image volume digest as part of container statuses)
|
||||
kl.convertToAPIContainerStatuses(pod, criStatus, []v1.ContainerStatus{}, []v1.Container{}, nil, false, false, false)
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -5873,12 +6049,7 @@ func TestConvertToAPIContainerStatusesForResources(t *testing.T) {
|
||||
state = tc.State
|
||||
}
|
||||
podStatus := testPodStatus(state, resources)
|
||||
|
||||
<<<<<<< HEAD
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, podStatus, []v1.ContainerStatus{tc.OldStatus}, tPod.Spec.Containers, false, false, false)
|
||||
=======
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, podStatus, []v1.ContainerStatus{tc.OldStatus}, tPod.Spec.Containers, nil, false, false)
|
||||
>>>>>>> 3102f167ced (Set image volume digest as part of container statuses)
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, podStatus, []v1.ContainerStatus{tc.OldStatus}, tPod.Spec.Containers, nil, false, false, false)
|
||||
actual := cStatuses[0]
|
||||
// Explicitly test AllocatedResources and Resources separately for debuggability.
|
||||
assert.Equal(t, tc.Expected.AllocatedResources, actual.AllocatedResources, "AllocatedResources")
|
||||
@@ -6004,11 +6175,9 @@ func TestConvertToAPIContainerStatusesForUser(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SupplementalGroupsPolicy, tc.featureEnabled)
|
||||
tPod := testPod.DeepCopy()
|
||||
t.Logf("TestCase: %q", tdesc)
|
||||
<<<<<<< HEAD
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, tc.testPodStatus, tPod.Status.ContainerStatuses, tPod.Spec.Containers, false, false, false)
|
||||
=======
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, tc.testPodStatus, tPod.Status.ContainerStatuses, tPod.Spec.Containers, nil, false, false)
|
||||
>>>>>>> 3102f167ced (Set image volume digest as part of container statuses)
|
||||
|
||||
cStatuses := kubelet.convertToAPIContainerStatuses(tPod, tc.testPodStatus, tPod.Status.ContainerStatuses, tPod.Spec.Containers, nil, false, false, false)
|
||||
|
||||
assert.Equal(t, tc.expectedContainerStatus, cStatuses)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user