Skip to content

Commit 24443b6

Browse files
committed
Expand PLEG SetWatchCondition unit test coverage
1 parent 7fce6f2 commit 24443b6

File tree

1 file changed

+153
-46
lines changed

1 file changed

+153
-46
lines changed

pkg/kubelet/pleg/generic_test.go

Lines changed: 153 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/google/go-cmp/cmp"
3030
"github.com/stretchr/testify/assert"
31+
"github.com/stretchr/testify/mock"
3132
"github.com/stretchr/testify/require"
3233

3334
"k8s.io/apimachinery/pkg/types"
@@ -82,9 +83,10 @@ func getEventsFromChannel(ch <-chan *PodLifecycleEvent) []*PodLifecycleEvent {
8283
return events
8384
}
8485

85-
func createTestContainer(ID string, state kubecontainer.State) *kubecontainer.Container {
86+
func createTestContainer(id string, state kubecontainer.State) *kubecontainer.Container {
8687
return &kubecontainer.Container{
87-
ID: kubecontainer.ContainerID{Type: testContainerRuntimeType, ID: ID},
88+
ID: kubecontainer.ContainerID{Type: testContainerRuntimeType, ID: id},
89+
Name: id,
8890
State: state,
8991
}
9092
}
@@ -317,14 +319,14 @@ func testReportMissingPods(t *testing.T, numRelists int) {
317319
}
318320

319321
func newTestGenericPLEGWithRuntimeMock(runtimeMock kubecontainer.Runtime) *GenericPLEG {
320-
pleg := &GenericPLEG{
321-
relistDuration: &RelistDuration{RelistPeriod: time.Hour, RelistThreshold: 2 * time.Hour},
322-
runtime: runtimeMock,
323-
eventChannel: make(chan *PodLifecycleEvent, 1000),
324-
podRecords: make(podRecords),
325-
cache: kubecontainer.NewCache(),
326-
clock: clock.RealClock{},
327-
}
322+
pleg := NewGenericPLEG(
323+
klog.Logger{},
324+
runtimeMock,
325+
make(chan *PodLifecycleEvent, 1000),
326+
&RelistDuration{RelistPeriod: time.Hour, RelistThreshold: 2 * time.Hour},
327+
kubecontainer.NewCache(),
328+
clock.RealClock{},
329+
).(*GenericPLEG)
328330
return pleg
329331
}
330332

@@ -738,42 +740,46 @@ kubelet_running_pods 2
738740
}
739741

740742
func TestWatchConditions(t *testing.T) {
741-
pods := []*containertest.FakePod{{
742-
Pod: &kubecontainer.Pod{
743-
Name: "running-pod",
744-
ID: "running",
745-
Sandboxes: []*kubecontainer.Container{
746-
createTestContainer("s", kubecontainer.ContainerStateRunning),
747-
},
748-
Containers: []*kubecontainer.Container{
749-
createTestContainer("c", kubecontainer.ContainerStateRunning),
750-
},
743+
pods := []*kubecontainer.Pod{{
744+
Name: "running-pod",
745+
ID: "running",
746+
Sandboxes: []*kubecontainer.Container{
747+
createTestContainer("s", kubecontainer.ContainerStateRunning),
748+
},
749+
Containers: []*kubecontainer.Container{
750+
createTestContainer("c", kubecontainer.ContainerStateRunning),
751751
},
752752
}, {
753-
Pod: &kubecontainer.Pod{
754-
Name: "terminating-pod",
755-
ID: "terminating",
756-
Sandboxes: []*kubecontainer.Container{
757-
createTestContainer("s", kubecontainer.ContainerStateExited),
758-
},
753+
Name: "running-pod-2",
754+
ID: "running-2",
755+
Sandboxes: []*kubecontainer.Container{
756+
createTestContainer("s", kubecontainer.ContainerStateRunning),
757+
},
758+
Containers: []*kubecontainer.Container{
759+
createTestContainer("c-exited", kubecontainer.ContainerStateExited),
760+
createTestContainer("c-running", kubecontainer.ContainerStateRunning),
759761
},
760762
}, {
761-
Pod: &kubecontainer.Pod{
762-
Name: "reinspect-pod",
763-
ID: "reinspect",
764-
Sandboxes: []*kubecontainer.Container{
765-
createTestContainer("s", kubecontainer.ContainerStateRunning),
766-
},
763+
Name: "terminating-pod",
764+
ID: "terminating",
765+
Sandboxes: []*kubecontainer.Container{
766+
createTestContainer("s", kubecontainer.ContainerStateExited),
767+
},
768+
}, {
769+
Name: "reinspect-pod",
770+
ID: "reinspect",
771+
Sandboxes: []*kubecontainer.Container{
772+
createTestContainer("s", kubecontainer.ContainerStateRunning),
767773
},
768774
}}
769775
initialPods := pods
770-
initialPods = append(initialPods, &containertest.FakePod{Pod: &kubecontainer.Pod{
776+
initialPods = append(initialPods, &kubecontainer.Pod{
771777
Name: "terminated-pod",
772778
ID: "terminated",
773779
Sandboxes: []*kubecontainer.Container{
774780
createTestContainer("s", kubecontainer.ContainerStateExited),
775781
},
776-
}})
782+
})
777783

778784
alwaysComplete := func(_ *kubecontainer.PodStatus) bool {
779785
return true
@@ -790,13 +796,32 @@ func TestWatchConditions(t *testing.T) {
790796
return true
791797
}
792798

799+
// resettingCond decrements the version before it completes.
800+
var resettingCond = func(_ *kubecontainer.PodStatus) bool {
801+
versioned := pleg.watchConditions["running"]["resetting"]
802+
versioned.version = 0
803+
pleg.watchConditions["running"]["resetting"] = versioned
804+
return true
805+
}
806+
807+
// makeContainerCond returns a RunningContainerWatchCondition that asserts the expected container status
808+
makeContainerCond := func(expectedContainerName string, complete bool) WatchCondition {
809+
return RunningContainerWatchCondition(expectedContainerName, func(status *kubecontainer.Status) bool {
810+
if status.Name != expectedContainerName {
811+
panic(fmt.Sprintf("unexpected container name: got %q, want %q", status.Name, expectedContainerName))
812+
}
813+
return complete
814+
})
815+
}
816+
793817
testCases := []struct {
794-
name string
795-
podUID types.UID
796-
watchConditions map[string]WatchCondition
797-
expectEvaluated bool // Whether the watch conditions should be evaluated
798-
expectRemoved bool // Whether podUID should be present in the watch conditions map
799-
expectWatchConditions map[string]versionedWatchCondition // The expected watch conditions for the podUIDa (only key & version checked)
818+
name string
819+
podUID types.UID
820+
watchConditions map[string]WatchCondition
821+
incrementInitialVersion bool // Whether to call SetPodWatchCondition multiple times to increment the version
822+
expectEvaluated bool // Whether the watch conditions should be evaluated
823+
expectRemoved bool // Whether podUID should be present in the watch conditions map
824+
expectWatchConditions map[string]versionedWatchCondition // The expected watch conditions for the podUID (only key & version checked)
800825
}{{
801826
name: "no watch conditions",
802827
podUID: "running",
@@ -813,6 +838,31 @@ func TestWatchConditions(t *testing.T) {
813838
"watching": {version: 0},
814839
"updating": {version: 1},
815840
},
841+
}, {
842+
name: "conditions with incremented versions",
843+
podUID: "running",
844+
incrementInitialVersion: true,
845+
watchConditions: map[string]WatchCondition{
846+
"completing": alwaysComplete,
847+
"watching": neverComplete,
848+
"updating": updatingCond,
849+
},
850+
expectEvaluated: true,
851+
expectWatchConditions: map[string]versionedWatchCondition{
852+
"watching": {version: 1},
853+
"updating": {version: 2},
854+
},
855+
}, {
856+
name: "completed watch condition with older version",
857+
podUID: "running",
858+
incrementInitialVersion: true,
859+
watchConditions: map[string]WatchCondition{
860+
"resetting": resettingCond,
861+
},
862+
expectEvaluated: true,
863+
expectWatchConditions: map[string]versionedWatchCondition{
864+
"resetting": {version: 0},
865+
},
816866
}, {
817867
name: "non-existent pod",
818868
podUID: "non-existent",
@@ -839,22 +889,75 @@ func TestWatchConditions(t *testing.T) {
839889
expectWatchConditions: map[string]versionedWatchCondition{
840890
"watching": {version: 0},
841891
},
892+
}, {
893+
name: "single container conditions",
894+
podUID: "running",
895+
watchConditions: map[string]WatchCondition{
896+
"completing": makeContainerCond("c", true),
897+
"watching": makeContainerCond("c", false),
898+
},
899+
expectEvaluated: true,
900+
expectWatchConditions: map[string]versionedWatchCondition{
901+
"watching": {version: 0},
902+
},
903+
}, {
904+
name: "multi-container conditions",
905+
podUID: "running-2",
906+
watchConditions: map[string]WatchCondition{
907+
"completing:exited": makeContainerCond("c-exited", true),
908+
"watching:exited": makeContainerCond("c-exited", false),
909+
"completing:running": makeContainerCond("c-running", true),
910+
"watching:running": makeContainerCond("c-running", false),
911+
"completing:dne": makeContainerCond("c-dne", true),
912+
"watching:dne": makeContainerCond("c-dne", false),
913+
},
914+
expectEvaluated: true,
915+
expectWatchConditions: map[string]versionedWatchCondition{
916+
"watching:running": {version: 0},
917+
},
842918
}}
843919

844920
for _, test := range testCases {
845921
t.Run(test.name, func(t *testing.T) {
846-
testPleg := newTestGenericPLEG()
847-
pleg = testPleg.pleg
848-
runtime := testPleg.runtime
849-
runtime.AllPodList = initialPods
850-
pleg.Relist() // Setup initial pod records.
922+
runtimeMock := containertest.NewMockRuntime(t)
923+
pleg = newTestGenericPLEGWithRuntimeMock(runtimeMock)
924+
925+
// Mock pod statuses
926+
for _, pod := range initialPods {
927+
podStatus := &kubecontainer.PodStatus{
928+
ID: pod.ID,
929+
Name: pod.Name,
930+
Namespace: pod.Namespace,
931+
}
932+
for _, c := range pod.Containers {
933+
podStatus.ContainerStatuses = append(podStatus.ContainerStatuses, &kubecontainer.Status{
934+
ID: c.ID,
935+
Name: c.Name,
936+
State: c.State,
937+
})
938+
}
939+
runtimeMock.EXPECT().
940+
GetPodStatus(mock.Anything, pod.ID, pod.Name, pod.Namespace).
941+
Return(podStatus, nil).Maybe()
942+
}
851943

852-
runtime.AllPodList = pods // Doesn't have "terminated" pod.
944+
// Setup initial pod records.
945+
runtimeMock.EXPECT().GetPods(mock.Anything, true).Return(initialPods, nil).Once()
946+
pleg.Relist()
853947
pleg.podsToReinspect["reinspect"] = nil
854948

949+
// Remove "terminated" pod.
950+
runtimeMock.EXPECT().GetPods(mock.Anything, true).Return(pods, nil).Once()
951+
855952
var evaluatedConditions []string
856953
for key, condition := range test.watchConditions {
857954
wrappedCondition := func(status *kubecontainer.PodStatus) bool {
955+
defer func() {
956+
if r := recover(); r != nil {
957+
require.Fail(t, "condition error", r)
958+
}
959+
}()
960+
assert.Equal(t, test.podUID, status.ID, "podUID")
858961
if !test.expectEvaluated {
859962
assert.Fail(t, "conditions should not be evaluated")
860963
} else {
@@ -863,6 +966,10 @@ func TestWatchConditions(t *testing.T) {
863966
return condition(status)
864967
}
865968
pleg.SetPodWatchCondition(test.podUID, key, wrappedCondition)
969+
if test.incrementInitialVersion {
970+
// Set the watch condition a second time to increment the version.
971+
pleg.SetPodWatchCondition(test.podUID, key, wrappedCondition)
972+
}
866973
}
867974
pleg.Relist()
868975

0 commit comments

Comments
 (0)