mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
integration: add eviction tests for UnhealthyPodEvictionPolicy
This commit is contained in:
parent
3e3912467a
commit
2fbbc473b7
@ -104,7 +104,7 @@ func TestConcurrentEvictionRequests(t *testing.T) {
|
||||
t.Errorf("Failed to create PodDisruptionBudget: %v", err)
|
||||
}
|
||||
|
||||
waitPDBStable(t, clientSet, numOfEvictions, ns.Name, pdb.Name)
|
||||
waitPDBStable(t, clientSet, ns.Name, pdb.Name, numOfEvictions)
|
||||
|
||||
var numberPodsEvicted uint32
|
||||
errCh := make(chan error, 3*numOfEvictions)
|
||||
@ -212,7 +212,7 @@ func TestTerminalPodEviction(t *testing.T) {
|
||||
t.Errorf("Failed to create PodDisruptionBudget: %v", err)
|
||||
}
|
||||
|
||||
waitPDBStable(t, clientSet, 1, ns.Name, pdb.Name)
|
||||
waitPDBStable(t, clientSet, ns.Name, pdb.Name, 1)
|
||||
|
||||
pdbList, err := clientSet.PolicyV1().PodDisruptionBudgets(ns.Name).List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
@ -394,13 +394,7 @@ func TestEvictionWithFinalizers(t *testing.T) {
|
||||
|
||||
eviction := newV1Eviction(ns.Name, pod.Name, deleteOption)
|
||||
|
||||
err := wait.PollImmediate(5*time.Second, 60*time.Second, func() (bool, error) {
|
||||
e := clientSet.PolicyV1().Evictions(ns.Name).Evict(ctx, eviction)
|
||||
if e != nil {
|
||||
return false, e
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
err := clientSet.PolicyV1().Evictions(ns.Name).Evict(ctx, eviction)
|
||||
if err != nil {
|
||||
t.Fatalf("Eviction of pod failed %v", err)
|
||||
}
|
||||
@ -419,6 +413,95 @@ func TestEvictionWithFinalizers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestEvictionWithUnhealthyPodEvictionPolicy tests eviction with a PDB that has a UnhealthyPodEvictionPolicy
|
||||
func TestEvictionWithUnhealthyPodEvictionPolicy(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
enableUnhealthyPodEvictionPolicy bool
|
||||
unhealthyPodEvictionPolicy *policyv1.UnhealthyPodEvictionPolicyType
|
||||
isPodReady bool
|
||||
}{
|
||||
"UnhealthyPodEvictionPolicy disabled and policy not set": {
|
||||
enableUnhealthyPodEvictionPolicy: false,
|
||||
unhealthyPodEvictionPolicy: nil,
|
||||
isPodReady: true,
|
||||
},
|
||||
"UnhealthyPodEvictionPolicy enabled but policy not set": {
|
||||
enableUnhealthyPodEvictionPolicy: true,
|
||||
unhealthyPodEvictionPolicy: nil,
|
||||
isPodReady: true,
|
||||
},
|
||||
"UnhealthyPodEvictionPolicy enabled but policy set to IfHealthyBudget with ready pod": {
|
||||
enableUnhealthyPodEvictionPolicy: true,
|
||||
unhealthyPodEvictionPolicy: unhealthyPolicyPtr(policyv1.IfHealthyBudget),
|
||||
isPodReady: true,
|
||||
},
|
||||
"UnhealthyPodEvictionPolicy enabled but policy set to AlwaysAllow with ready pod": {
|
||||
enableUnhealthyPodEvictionPolicy: true,
|
||||
unhealthyPodEvictionPolicy: unhealthyPolicyPtr(policyv1.AlwaysAllow),
|
||||
isPodReady: true,
|
||||
},
|
||||
"UnhealthyPodEvictionPolicy enabled but policy set to AlwaysAllow with unready pod": {
|
||||
enableUnhealthyPodEvictionPolicy: true,
|
||||
unhealthyPodEvictionPolicy: unhealthyPolicyPtr(policyv1.AlwaysAllow),
|
||||
isPodReady: false,
|
||||
},
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.PDBUnhealthyPodEvictionPolicy, tc.enableUnhealthyPodEvictionPolicy)()
|
||||
closeFn, rm, informers, _, clientSet := rmSetup(t)
|
||||
defer closeFn()
|
||||
|
||||
ns := framework.CreateNamespaceOrDie(clientSet, "eviction-with-pdb-pod-healthy-policy", t)
|
||||
defer framework.DeleteNamespaceOrDie(clientSet, ns, t)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
informers.Start(ctx.Done())
|
||||
go rm.Run(ctx)
|
||||
|
||||
pod := newPod("pod")
|
||||
if _, err := clientSet.CoreV1().Pods(ns.Name).Create(context.TODO(), pod, metav1.CreateOptions{}); err != nil {
|
||||
t.Errorf("Failed to create pod: %v", err)
|
||||
}
|
||||
|
||||
pod.Status.Phase = v1.PodRunning
|
||||
if tc.isPodReady {
|
||||
addPodConditionReady(pod)
|
||||
}
|
||||
|
||||
if _, err := clientSet.CoreV1().Pods(ns.Name).UpdateStatus(ctx, pod, metav1.UpdateOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
waitToObservePods(t, informers.Core().V1().Pods().Informer(), 1, v1.PodRunning)
|
||||
|
||||
pdb := newPDB()
|
||||
pdb.Spec.UnhealthyPodEvictionPolicy = tc.unhealthyPodEvictionPolicy
|
||||
if _, err := clientSet.PolicyV1().PodDisruptionBudgets(ns.Name).Create(context.TODO(), pdb, metav1.CreateOptions{}); err != nil {
|
||||
t.Errorf("Failed to create PodDisruptionBudget: %v", err)
|
||||
}
|
||||
|
||||
if tc.isPodReady {
|
||||
waitPDBStable(t, clientSet, ns.Name, pdb.Name, 1)
|
||||
} else {
|
||||
waitPDB(t, clientSet, ns.Name, pdb.Name, func(pdb *policyv1.PodDisruptionBudget) bool {
|
||||
return pdb.Status.ExpectedPods == 1
|
||||
})
|
||||
}
|
||||
deleteOption := metav1.DeleteOptions{}
|
||||
eviction := newV1Eviction(ns.Name, pod.Name, deleteOption)
|
||||
err := clientSet.PolicyV1().Evictions(ns.Name).Evict(ctx, eviction)
|
||||
if err != nil {
|
||||
t.Fatalf("Eviction of pod failed %v", err)
|
||||
}
|
||||
|
||||
waitToObservePods(t, informers.Core().V1().Pods().Informer(), 0, v1.PodRunning)
|
||||
waitPDBStable(t, clientSet, ns.Name, pdb.Name, 0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newPod(podName string) *v1.Pod {
|
||||
return &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@ -533,17 +616,24 @@ func waitToObservePods(t *testing.T, podInformer cache.SharedIndexInformer, podN
|
||||
}
|
||||
}
|
||||
|
||||
func waitPDBStable(t *testing.T, clientSet clientset.Interface, podNum int32, ns, pdbName string) {
|
||||
func waitPDBStable(t *testing.T, clientSet clientset.Interface, ns, pdbName string, podNum int32) {
|
||||
waitPDB(t, clientSet, ns, pdbName, func(pdb *policyv1.PodDisruptionBudget) bool {
|
||||
return pdb.Status.CurrentHealthy == podNum
|
||||
})
|
||||
}
|
||||
|
||||
func waitPDB(t *testing.T, clientSet clientset.Interface, ns, pdbName string, condition func(budget *policyv1.PodDisruptionBudget) bool) {
|
||||
if err := wait.PollImmediate(2*time.Second, 60*time.Second, func() (bool, error) {
|
||||
pdb, err := clientSet.PolicyV1().PodDisruptionBudgets(ns).Get(context.TODO(), pdbName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if pdb.Status.CurrentHealthy != podNum {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
return condition(pdb), nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func unhealthyPolicyPtr(unhealthyPodEvictionPolicy policyv1.UnhealthyPodEvictionPolicyType) *policyv1.UnhealthyPodEvictionPolicyType {
|
||||
return &unhealthyPodEvictionPolicy
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user