[daemonSet]: Fix unit tests

We need to ensure that `DaemonSetUpdateSurge`
featuregate is both enabled and disabled when
running tests with Rolling update strategy.
This commit is contained in:
ravisantoshgudimetla 2021-05-13 10:31:24 -04:00
parent 09268c1685
commit 20f8654259

View File

@ -440,6 +440,9 @@ func clearExpectations(t *testing.T, manager *daemonSetsController, ds *apps.Dae
}
func TestDeleteFinalStateUnknown(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -456,6 +459,7 @@ func TestDeleteFinalStateUnknown(t *testing.T) {
}
}
}
}
func TestExpectationsOnRecreate(t *testing.T) {
client := fake.NewSimpleClientset()
@ -662,6 +666,9 @@ func markPodReady(pod *v1.Pod) {
// DaemonSets without node selectors should launch pods on every node.
func TestSimpleDaemonSetLaunchesPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -678,10 +685,14 @@ func TestSimpleDaemonSetLaunchesPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 5, 0, 0)
}
}
}
// DaemonSets without node selectors should launch pods on every node by NodeAffinity.
func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) {
nodeNum := 5
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -753,12 +764,15 @@ func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) {
t.Fatalf("did not find pods on nodes %+v", nodeMap)
}
}
}
}
// Simulate a cluster with 100 nodes, but simulate a limit (like a quota limit)
// of 10 pods, and verify that the ds doesn't make 100 create calls per sync pass
func TestSimpleDaemonSetPodCreateErrors(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -784,8 +798,12 @@ func TestSimpleDaemonSetPodCreateErrors(t *testing.T) {
}
}
}
}
func TestDaemonSetPodCreateExpectationsError(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
strategies := updateStrategies()
for _, strategy := range strategies {
ds := newDaemonSet("foo")
@ -814,6 +832,7 @@ func TestDaemonSetPodCreateExpectationsError(t *testing.T) {
}
}
}
}
func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
@ -853,6 +872,9 @@ func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) {
// DaemonSets should do nothing if there aren't any nodes
func TestNoNodesDoesNothing(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController()
if err != nil {
@ -868,10 +890,14 @@ func TestNoNodesDoesNothing(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSets without node selectors should launch on a single node in a
// single node cluster.
func TestOneNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -891,9 +917,13 @@ func TestOneNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSets should place onto NotReady nodes
func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -918,6 +948,7 @@ func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
func resourcePodSpec(nodeName, memory, cpu string) v1.PodSpec {
return v1.PodSpec{
@ -956,6 +987,9 @@ func allocatableResources(memory, cpu string) v1.ResourceList {
// DaemonSets should not unschedule a daemonset pod from a node with insufficient free resource
func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
podSpec.NodeName = "too-much-mem"
@ -992,6 +1026,7 @@ func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T)
}
}
}
}
// DaemonSets should only place onto nodes with sufficient free resource and matched node selector
func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(t *testing.T) {
@ -1028,6 +1063,9 @@ func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(
// DaemonSet should launch a pod on a node with taint NetworkUnavailable condition.
func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy
@ -1052,9 +1090,13 @@ func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSets not take any actions when being deleted
func TestDontDoAnythingIfBeingDeleted(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m")
ds := newDaemonSet("foo")
@ -1085,8 +1127,12 @@ func TestDontDoAnythingIfBeingDeleted(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
// Bare client says it IS deleted.
ds := newDaemonSet("foo")
@ -1117,12 +1163,16 @@ func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// Test that if the node is already scheduled with a pod using a host port
// but belonging to the same daemonset, we don't delete that pod
//
// Issue: https://github.com/kubernetes/kubernetes/issues/22309
func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
podSpec := v1.PodSpec{
NodeName: "port-conflict",
@ -1156,9 +1206,13 @@ func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSets should place onto nodes that would not cause port conflicts
func TestNoPortConflictNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
podSpec1 := v1.PodSpec{
NodeName: "no-port-conflict",
@ -1201,6 +1255,7 @@ func TestNoPortConflictNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSetController should not sync DaemonSets with empty pod selectors.
//
@ -1215,6 +1270,9 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) {
// this case even though it's empty pod selector matches all pods. The DaemonSetController
// should detect this misconfiguration and choose not to sync the DaemonSet. We should
// not observe a deletion of the pod on node1.
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1251,9 +1309,13 @@ func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 1)
}
}
}
// Controller should not create pods on nodes which have daemon pods, and should remove excess pods from nodes that have extra pods.
func TestDealsWithExistingPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1273,9 +1335,13 @@ func TestDealsWithExistingPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 2, 5, 0)
}
}
}
// Daemon with node selector should launch pods on nodes matching selector.
func TestSelectorDaemonLaunchesPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
daemon := newDaemonSet("foo")
daemon.Spec.UpdateStrategy = *strategy
@ -1293,9 +1359,13 @@ func TestSelectorDaemonLaunchesPods(t *testing.T) {
expectSyncDaemonSets(t, manager, daemon, podControl, 3, 0, 0)
}
}
}
// Daemon with node selector should delete pods from nodes that do not satisfy selector.
func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1317,9 +1387,13 @@ func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 5, 4, 0)
}
}
}
// DaemonSet with node selector should launch pods on nodes matching selector, but also deal with existing pods on nodes.
func TestSelectorDaemonDealsWithExistingPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1345,9 +1419,13 @@ func TestSelectorDaemonDealsWithExistingPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 3, 20, 0)
}
}
}
// DaemonSet with node selector which does not match any node labels should not launch pods.
func TestBadSelectorDaemonDoesNothing(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController()
if err != nil {
@ -1365,9 +1443,13 @@ func TestBadSelectorDaemonDoesNothing(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSet with node name should launch pod on node with corresponding name.
func TestNameDaemonSetLaunchesPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1384,9 +1466,13 @@ func TestNameDaemonSetLaunchesPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet with node name that does not exist should not launch pods.
func TestBadNameDaemonSetDoesNothing(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1403,9 +1489,13 @@ func TestBadNameDaemonSetDoesNothing(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSet with node selector, and node name, matching a node, should launch a pod on the node.
func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1424,9 +1514,13 @@ func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet with node selector that matches some nodes, and node name that matches a different node, should do nothing.
func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1445,6 +1539,7 @@ func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSet with node selector, matching some nodes, should launch pods on all the nodes.
func TestSelectorDaemonSetLaunchesPods(t *testing.T) {
@ -1465,6 +1560,9 @@ func TestSelectorDaemonSetLaunchesPods(t *testing.T) {
// Daemon with node affinity should launch pods on nodes matching affinity.
func TestNodeAffinityDaemonLaunchesPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
daemon := newDaemonSet("foo")
daemon.Spec.UpdateStrategy = *strategy
@ -1499,8 +1597,12 @@ func TestNodeAffinityDaemonLaunchesPods(t *testing.T) {
expectSyncDaemonSets(t, manager, daemon, podControl, 3, 0, 0)
}
}
}
func TestNumberReadyStatus(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1544,8 +1646,12 @@ func TestNumberReadyStatus(t *testing.T) {
}
}
}
}
func TestObservedGeneration(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1578,6 +1684,7 @@ func TestObservedGeneration(t *testing.T) {
}
}
}
}
// DaemonSet controller should kill all failed pods and create at most 1 pod on every node.
func TestDaemonKillFailedPods(t *testing.T) {
@ -1615,6 +1722,9 @@ func TestDaemonKillFailedPods(t *testing.T) {
// DaemonSet controller needs to backoff when killing failed pods to avoid hot looping and fighting with kubelet.
func TestDaemonKillFailedPodsBackoff(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
t.Run(string(strategy.Type), func(t *testing.T) {
ds := newDaemonSet("foo")
@ -1681,10 +1791,14 @@ func TestDaemonKillFailedPodsBackoff(t *testing.T) {
})
}
}
}
// Daemonset should not remove a running pod from a node if the pod doesn't
// tolerate the nodes NoSchedule taint
func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy
@ -1711,10 +1825,14 @@ func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// Daemonset should remove a running pod from a node if the pod doesn't
// tolerate the nodes NoExecute taint
func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy
@ -1741,9 +1859,13 @@ func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 1, 0)
}
}
}
// DaemonSet should not launch a pod on a tainted node when the pod doesn't tolerate that taint.
func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("intolerant")
ds.Spec.UpdateStrategy = *strategy
@ -1766,9 +1888,13 @@ func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
// DaemonSet should launch a pod on a tainted node when the pod can tolerate that taint.
func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("tolerate")
ds.Spec.UpdateStrategy = *strategy
@ -1792,9 +1918,13 @@ func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy
@ -1820,9 +1950,13 @@ func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet should launch a pod on an unreachable node with taint unreachable:NoExecute.
func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("simple")
ds.Spec.UpdateStrategy = *strategy
@ -1848,9 +1982,13 @@ func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet should launch a pod on an untainted node when the pod has tolerations.
func TestNodeDaemonLaunchesToleratePod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("tolerate")
ds.Spec.UpdateStrategy = *strategy
@ -1868,9 +2006,13 @@ func TestNodeDaemonLaunchesToleratePod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
// DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
func TestDaemonSetRespectsTermination(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -1894,6 +2036,7 @@ func TestDaemonSetRespectsTermination(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 0, 0)
}
}
}
func setNodeTaint(node *v1.Node, taints []v1.Taint) {
node.Spec.Taints = taints
@ -1905,6 +2048,9 @@ func setDaemonSetToleration(ds *apps.DaemonSet, tolerations []v1.Toleration) {
// DaemonSet should launch a pod even when the node with MemoryPressure/DiskPressure/PIDPressure taints.
func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("critical")
ds.Spec.UpdateStrategy = *strategy
@ -1936,6 +2082,7 @@ func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 1, 0, 0)
}
}
}
func setDaemonSetCritical(ds *apps.DaemonSet) {
ds.Namespace = api.NamespaceSystem
@ -2218,6 +2365,9 @@ func TestNodeShouldRunDaemonPod(t *testing.T) {
}
for i, c := range cases {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
node := newNode("test-node", simpleDaemonSetLabel)
node.Status.Conditions = append(node.Status.Conditions, c.nodeCondition...)
@ -2245,6 +2395,7 @@ func TestNodeShouldRunDaemonPod(t *testing.T) {
}
}
}
}
// DaemonSets should be resynced when node labels or taints changed
func TestUpdateNode(t *testing.T) {
@ -2325,6 +2476,9 @@ func TestUpdateNode(t *testing.T) {
},
}
for _, c := range cases {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController()
if err != nil {
@ -2364,6 +2518,7 @@ func TestUpdateNode(t *testing.T) {
}
}
}
}
// DaemonSets should be resynced when non-daemon pods was deleted.
func TestDeleteNoDaemonPod(t *testing.T) {
@ -2506,6 +2661,9 @@ func TestDeleteNoDaemonPod(t *testing.T) {
}
for _, c := range cases {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, podControl, _, err := newTestController()
if err != nil {
@ -2541,8 +2699,12 @@ func TestDeleteNoDaemonPod(t *testing.T) {
}
}
}
}
func TestDeleteUnscheduledPodForNotExistingNode(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -2583,8 +2745,12 @@ func TestDeleteUnscheduledPodForNotExistingNode(t *testing.T) {
expectSyncDaemonSets(t, manager, ds, podControl, 0, 1, 0)
}
}
}
func TestGetNodesToDaemonPods(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -2655,6 +2821,7 @@ func TestGetNodesToDaemonPods(t *testing.T) {
}
}
}
}
func TestAddNode(t *testing.T) {
manager, _, _, err := newTestController()
@ -2686,6 +2853,9 @@ func TestAddNode(t *testing.T) {
}
func TestAddPod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2733,8 +2903,12 @@ func TestAddPod(t *testing.T) {
}
}
}
}
func TestAddPodOrphan(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2771,8 +2945,12 @@ func TestAddPodOrphan(t *testing.T) {
}
}
}
}
func TestUpdatePod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2824,8 +3002,12 @@ func TestUpdatePod(t *testing.T) {
}
}
}
}
func TestUpdatePodOrphanSameLabels(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2853,8 +3035,12 @@ func TestUpdatePodOrphanSameLabels(t *testing.T) {
}
}
}
}
func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2886,8 +3072,12 @@ func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
}
}
}
}
func TestUpdatePodChangeControllerRef(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy
@ -2916,8 +3106,12 @@ func TestUpdatePodChangeControllerRef(t *testing.T) {
}
}
}
}
func TestUpdatePodControllerRefRemoved(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2946,8 +3140,12 @@ func TestUpdatePodControllerRefRemoved(t *testing.T) {
}
}
}
}
func TestDeletePod(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -2995,8 +3193,12 @@ func TestDeletePod(t *testing.T) {
}
}
}
}
func TestDeletePodOrphan(t *testing.T) {
dsMaxSurgeFeatureFlags := []bool{false, true}
for _, isEnabled := range dsMaxSurgeFeatureFlags {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DaemonSetUpdateSurge, isEnabled)()
for _, strategy := range updateStrategies() {
manager, _, _, err := newTestController()
if err != nil {
@ -3029,6 +3231,7 @@ func TestDeletePodOrphan(t *testing.T) {
}
}
}
}
func bumpResourceVersion(obj metav1.Object) {
ver, _ := strconv.ParseInt(obj.GetResourceVersion(), 10, 32)