mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
Merge pull request #119068 from lauchokyip/podgc-unit-test
added podgc orphaned pod unit tests
This commit is contained in:
commit
8e2b12a220
@ -18,14 +18,18 @@ package podgc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/informers"
|
||||
@ -43,6 +47,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/eviction"
|
||||
testingclock "k8s.io/utils/clock/testing"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func alwaysReady() bool { return true }
|
||||
@ -671,6 +676,128 @@ func TestGCTerminating(t *testing.T) {
|
||||
testDeletingPodsMetrics(t, 7, metrics.PodGCReasonTerminatingOutOfService)
|
||||
}
|
||||
|
||||
func TestGCInspectingPatchedPodBeforeDeletion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
expectedPatchedPod *v1.Pod
|
||||
expectedDeleteAction *clienttesting.DeleteActionImpl
|
||||
}{
|
||||
{
|
||||
name: "orphaned pod should have DisruptionTarget condition added before deletion",
|
||||
pod: &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "testPod",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "deletedNode",
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
Conditions: []v1.PodCondition{
|
||||
{
|
||||
Type: v1.PodReady,
|
||||
Status: v1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPatchedPod: &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "testPod",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "deletedNode",
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodFailed,
|
||||
Conditions: []v1.PodCondition{
|
||||
{
|
||||
Type: v1.DisruptionTarget,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "DeletionByPodGC",
|
||||
Message: "PodGC: node no longer exists",
|
||||
},
|
||||
{
|
||||
Type: v1.PodReady,
|
||||
Status: v1.ConditionTrue,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDeleteAction: &clienttesting.DeleteActionImpl{
|
||||
Name: "testPod",
|
||||
DeleteOptions: metav1.DeleteOptions{GracePeriodSeconds: pointer.Int64(0)},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, ctx := ktesting.NewTestContext(t)
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodDisruptionConditions, true)()
|
||||
|
||||
pods := []*v1.Pod{test.pod}
|
||||
|
||||
client := setupNewSimpleClient(nil, pods)
|
||||
gcc, podInformer, _ := NewFromClient(ctx, client, -1)
|
||||
gcc.quarantineTime = time.Duration(-1)
|
||||
podInformer.Informer().GetStore().Add(test.pod)
|
||||
gcc.gc(ctx)
|
||||
|
||||
actions := client.Actions()
|
||||
|
||||
var patchAction clienttesting.PatchAction
|
||||
var deleteAction clienttesting.DeleteAction
|
||||
|
||||
for _, action := range actions {
|
||||
if action.GetVerb() == "patch" {
|
||||
patchAction = action.(clienttesting.PatchAction)
|
||||
}
|
||||
|
||||
if action.GetVerb() == "delete" {
|
||||
deleteAction = action.(clienttesting.DeleteAction)
|
||||
}
|
||||
}
|
||||
|
||||
if patchAction != nil && test.expectedPatchedPod == nil {
|
||||
t.Fatalf("Pod was pactched but expectedPatchedPod is nil")
|
||||
}
|
||||
if test.expectedPatchedPod != nil {
|
||||
patchedPodBytes := patchAction.GetPatch()
|
||||
originalPod, err := json.Marshal(test.pod)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal original pod %#v: %v", originalPod, err)
|
||||
}
|
||||
updated, err := strategicpatch.StrategicMergePatch(originalPod, patchedPodBytes, v1.Pod{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to apply strategic merge patch %q on pod %#v: %v", patchedPodBytes, originalPod, err)
|
||||
}
|
||||
|
||||
updatedPod := &v1.Pod{}
|
||||
if err := json.Unmarshal(updated, updatedPod); err != nil {
|
||||
t.Fatalf("Failed to unmarshal updated pod %q: %v", updated, err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(test.expectedPatchedPod, updatedPod, cmpopts.IgnoreFields(v1.Pod{}, "TypeMeta"), cmpopts.IgnoreFields(v1.PodCondition{}, "LastTransitionTime")); diff != "" {
|
||||
t.Fatalf("Unexpected diff on pod (-want,+got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
if deleteAction != nil && test.expectedDeleteAction == nil {
|
||||
t.Fatalf("Pod was deleted but expectedDeleteAction is nil")
|
||||
}
|
||||
if test.expectedDeleteAction != nil {
|
||||
if diff := cmp.Diff(*test.expectedDeleteAction, deleteAction, cmpopts.IgnoreFields(clienttesting.DeleteActionImpl{}, "ActionImpl")); diff != "" {
|
||||
t.Fatalf("Unexpected diff on deleteAction (-want,+got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func verifyDeletedAndPatchedPods(t *testing.T, client *fake.Clientset, wantDeletedPodNames, wantPatchedPodNames sets.String) {
|
||||
t.Helper()
|
||||
deletedPodNames := getDeletedPodNames(client)
|
||||
|
Loading…
Reference in New Issue
Block a user