mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
[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:
parent
09268c1685
commit
20f8654259
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user