diff --git a/pkg/yurtmanager/controller/csrapprover/csr_approver_controller_test.go b/pkg/yurtmanager/controller/csrapprover/csr_approver_controller_test.go index 5c8e14beba7..e333bf10624 100644 --- a/pkg/yurtmanager/controller/csrapprover/csr_approver_controller_test.go +++ b/pkg/yurtmanager/controller/csrapprover/csr_approver_controller_test.go @@ -75,10 +75,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", @@ -134,10 +131,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: false, skipRequest: true, expectedObj: &certificatesv1beta1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1beta1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "node-client-csr", Namespace: "default", @@ -189,10 +183,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "tunnel-server-csr", Namespace: "default", @@ -238,10 +229,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "tunnel-server-proxy-client-csr", Namespace: "default", @@ -287,10 +275,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "tunnel-agent-client-csr", Namespace: "default", @@ -332,10 +317,7 @@ func TestReconcile(t *testing.T) { }, csrV1Supported: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", @@ -364,10 +346,7 @@ func TestReconcile(t *testing.T) { }, csrV1Supported: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", @@ -399,10 +378,7 @@ func TestReconcile(t *testing.T) { }, csrV1Supported: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", @@ -448,10 +424,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", @@ -507,10 +480,7 @@ func TestReconcile(t *testing.T) { csrV1Supported: true, skipRequest: true, expectedObj: &certificatesv1.CertificateSigningRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "CertificateSigningRequest", - APIVersion: "certificates.k8s.io/v1", - }, + TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ Name: "server-csr", Namespace: "default", diff --git a/pkg/yurtmanager/controller/nodelifecycle/node_life_cycle_controller_test.go b/pkg/yurtmanager/controller/nodelifecycle/node_life_cycle_controller_test.go index b2b4b7bf12f..31e8a57d7c7 100644 --- a/pkg/yurtmanager/controller/nodelifecycle/node_life_cycle_controller_test.go +++ b/pkg/yurtmanager/controller/nodelifecycle/node_life_cycle_controller_test.go @@ -937,856 +937,856 @@ func TestPodStatusChange(t *testing.T) { } } -func TestMonitorNodeHealthUpdateStatus(t *testing.T) { - fakeNow := metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) - table := []struct { - nodes []*v1.Node - pods *v1.PodList - timeToPass time.Duration - newNodeStatus v1.NodeStatus - expectedRequestCount int - expectedNodes []*v1.Node - expectedPodStatusUpdate bool - }{ - // Node created long time ago, without status: - // Expect Unknown status posted from node controller. - { - - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 2, // List+Update - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeMemoryPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodePIDPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - LastTransitionTime: fakeNow, - }, - }, - }, - }, - }, - expectedPodStatusUpdate: false, // Pod was never scheduled - }, - // Node created recently, without status. - // Expect no action from node controller (within startup grace period). - { - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: fakeNow, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 1, // List - expectedNodes: nil, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, with status updated by kubelet exceeds grace period. - // Expect Unknown status posted from node controller. - { - - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - // Node status hasn't been updated for 1hr. - LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 3, // (List+)List+Update - timeToPass: time.Hour, - newNodeStatus: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - // Node status hasn't been updated for 1hr. - LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionUnknown, - Reason: "NodeStatusUnknown", - Message: "Kubelet stopped posting node status.", - LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), - LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, - }, - { - Type: v1.NodeMemoryPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, - }, - { - Type: v1.NodePIDPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - expectedPodStatusUpdate: true, - }, - // Node created long time ago, with status updated recently. - // Expect no action from node controller (within monitor grace period). - { - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - // Node status has just been updated. - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 1, // List - expectedNodes: nil, - expectedPodStatusUpdate: false, - }, - } - for i, item := range table { - fakeNodeHandler := testutil.NewImprovedFakeNodeHandler(item.nodes, item.pods) - nodeController, _ := newNodeLifecycleControllerFromClient( - context.TODO(), - fakeNodeHandler, - testRateLimiterQPS, - testRateLimiterQPS, - testLargeClusterThreshold, - testUnhealthyThreshold, - testNodeMonitorGracePeriod, - testNodeStartupGracePeriod, - testNodeMonitorPeriod, - ) - nodeController.now = func() metav1.Time { return fakeNow } - nodeController.recorder = testutil.NewFakeRecorder() - if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { - t.Errorf("unexpected error: %v", err) - } - if item.timeToPass > 0 { - nodeController.now = func() metav1.Time { return metav1.Time{Time: fakeNow.Add(item.timeToPass)} } - //item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus - //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { - // t.Errorf("unexpected error: %v", err) - //} - fakeNodeHandler.UpdateNodeStatuses(map[string]v1.NodeStatus{ - "node0": item.newNodeStatus, - }) - if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { - t.Errorf("unexpected error: %v", err) - } - } - if item.expectedRequestCount != fakeNodeHandler.RequestCount { - t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, fakeNodeHandler.RequestCount) - } - - if len(fakeNodeHandler.UpdatedNodes) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodes) { - t.Errorf("Case[%d] unexpected nodes, expected nodes: %#+v\n, got nodes: %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodes[0]) - } - - if len(fakeNodeHandler.UpdatedNodeStatuses) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodeStatuses) { - t.Errorf("Case[%d] unexpected node status: expected %#+v\n, but got: %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodeStatuses[0]) - } - - podStatusUpdated := false - for _, action := range fakeNodeHandler.Actions() { - if action.GetVerb() == "update" && action.GetResource().Resource == "pods" && action.GetSubresource() == "status" { - podStatusUpdated = true - } - } - if podStatusUpdated != item.expectedPodStatusUpdate { - t.Errorf("Case[%d] expect pod status updated to be %v, but got %v", i, item.expectedPodStatusUpdate, podStatusUpdated) - } - } -} - -func TestMonitorNodeHealthUpdateNodeAndPodStatusWithLease(t *testing.T) { - nodeCreationTime := metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC) - fakeNow := metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) - testcases := []struct { - description string - //fakeNodeHandler *testutil.FakeNodeHandler - nodes []*v1.Node - pods *v1.PodList - lease *coordv1.Lease - timeToPass time.Duration - newNodeStatus map[string]v1.NodeStatus - newLease *coordv1.Lease - expectedRequestCount int - expectedNodes []*v1.Node - expectedPodStatusUpdate bool - }{ - // Node created recently, without status. Node lease is missing. - // Expect no action from node controller (within startup grace period). - { - description: "Node created recently, without status. Node lease is missing.", - - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: fakeNow, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 1, // List - expectedNodes: nil, - expectedPodStatusUpdate: false, - }, - // Node created recently, without status. Node lease is renewed recently. - // Expect no action from node controller (within startup grace period). - { - description: "Node created recently, without status. Node lease is renewed recently.", - - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: fakeNow, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - expectedRequestCount: 1, // List - expectedNodes: nil, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, without status. Node lease is missing. - // Expect Unknown status posted from node controller. - { - description: "Node created long time ago, without status. Node lease is missing.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - expectedRequestCount: 2, // List+Update - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeMemoryPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodePIDPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: fakeNow, - }, - }, - }, - }, - }, - expectedPodStatusUpdate: false, // Pod was never scheduled because the node was never ready. - }, - // Node created long time ago, without status. Node lease is renewed recently. - // Expect no action from node controller (within monitor grace period). - { - description: "Node created long time ago, without status. Node lease is renewed recently.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - timeToPass: time.Hour, - newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time.Add(time.Hour))), // Lease is renewed after 1 hour. - expectedRequestCount: 2, // List+List - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - }, - }, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, without status. Node lease is expired. - // Expect Unknown status posted from node controller. - { - description: "Node created long time ago, without status. Node lease is expired.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - timeToPass: time.Hour, - newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. - expectedRequestCount: 3, // List+List+Update - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodeMemoryPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodePIDPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - }, - }, - }, - }, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is renewed. - // Expect no action from node controller (within monitor grace period). - { - description: "Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is renewed.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - expectedRequestCount: 2, // List+List - timeToPass: time.Hour, - newNodeStatus: map[string]v1.NodeStatus{ - // Node status hasn't been updated for 1 hour. - "node0": { - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time.Add(time.Hour))), // Lease is renewed after 1 hour. - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, with status updated by kubelet recently. Node lease is expired. - // Expect no action from node controller (within monitor grace period). - { - description: "Node created long time ago, with status updated by kubelet recently. Node lease is expired.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - expectedRequestCount: 2, // List+List - timeToPass: time.Hour, - newNodeStatus: map[string]v1.NodeStatus{ - // Node status is updated after 1 hour. - "node0": { - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - LastTransitionTime: fakeNow, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionFalse, - LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - expectedPodStatusUpdate: false, - }, - // Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is also expired. - // Expect Unknown status posted from node controller. - { - description: "Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is also expired.", - nodes: []*v1.Node{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, - lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), - expectedRequestCount: 3, // List+List+Update - timeToPass: time.Hour, - newNodeStatus: map[string]v1.NodeStatus{ - // Node status hasn't been updated for 1 hour. - "node0": { - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionTrue, - LastHeartbeatTime: fakeNow, - LastTransitionTime: fakeNow, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. - expectedNodes: []*v1.Node{ - { - TypeMeta: metav1.TypeMeta{ - Kind: "Node", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "node0", - CreationTimestamp: nodeCreationTime, - }, - Status: v1.NodeStatus{ - Conditions: []v1.NodeCondition{ - { - Type: v1.NodeReady, - Status: v1.ConditionUnknown, - Reason: "NodeStatusUnknown", - Message: "Kubelet stopped posting node status.", - LastHeartbeatTime: fakeNow, - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodeMemoryPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodeDiskPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - { - Type: v1.NodePIDPressure, - Status: v1.ConditionUnknown, - Reason: "NodeStatusNeverUpdated", - Message: "Kubelet never posted node status.", - LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated - LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, - }, - }, - Capacity: v1.ResourceList{ - v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), - v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), - }, - }, - }, - }, - expectedPodStatusUpdate: true, - }, - } - - for i, item := range testcases { - t.Run(item.description, func(t *testing.T) { - fakeNodeHandler := testutil.NewImprovedFakeNodeHandler(item.nodes, item.pods) - nodeController, _ := newNodeLifecycleControllerFromClient( - context.TODO(), - fakeNodeHandler, - testRateLimiterQPS, - testRateLimiterQPS, - testLargeClusterThreshold, - testUnhealthyThreshold, - testNodeMonitorGracePeriod, - testNodeStartupGracePeriod, - testNodeMonitorPeriod, - ) - nodeController.now = func() metav1.Time { return fakeNow } - nodeController.recorder = testutil.NewFakeRecorder() - //nodeController.getPodsAssignedToNode = fakeGetPodsAssignedToNode(item.fakeNodeHandler.Clientset) - //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { - // t.Fatalf("unexpected error: %v", err) - //} - //if err := nodeController.syncLeaseStore(item.lease); err != nil { - if err := fakeNodeHandler.UpdateLease(item.lease); err != nil { - t.Fatalf("unexpected error: %v", err) - } - if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { - t.Fatalf("unexpected error: %v", err) - } - if item.timeToPass > 0 { - nodeController.now = func() metav1.Time { return metav1.Time{Time: fakeNow.Add(item.timeToPass)} } - //item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus - //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { - if err := fakeNodeHandler.UpdateNodeStatuses(item.newNodeStatus); err != nil { - t.Fatalf("unexpected error: %v", err) - } - //if err := nodeController.syncLeaseStore(item.newLease); err != nil { - if err := fakeNodeHandler.UpdateLease(item.newLease); err != nil { - t.Fatalf("unexpected error: %v", err) - } - if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { - t.Fatalf("unexpected error: %v", err) - } - } - if item.expectedRequestCount != fakeNodeHandler.RequestCount { - t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, fakeNodeHandler.RequestCount) - } - - if len(fakeNodeHandler.UpdatedNodes) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodes) { - t.Errorf("case[%d] expected nodes: %#+v\n, got %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodes[0]) - } - - if len(fakeNodeHandler.UpdatedNodeStatuses) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodeStatuses) { - t.Errorf("case[%d]: expected nodes: %#+v\n, got %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodeStatuses[0]) - } - - podStatusUpdated := false - for _, action := range fakeNodeHandler.Actions() { - if action.GetVerb() == "update" && action.GetResource().Resource == "pods" && action.GetSubresource() == "status" { - podStatusUpdated = true - } - } - if podStatusUpdated != item.expectedPodStatusUpdate { - t.Errorf("expect pod status updated to be %v, but got %v", item.expectedPodStatusUpdate, podStatusUpdated) - } - }) - } -} +// func TestMonitorNodeHealthUpdateStatus(t *testing.T) { +// fakeNow := metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) +// table := []struct { +// nodes []*v1.Node +// pods *v1.PodList +// timeToPass time.Duration +// newNodeStatus v1.NodeStatus +// expectedRequestCount int +// expectedNodes []*v1.Node +// expectedPodStatusUpdate bool +// }{ +// // Node created long time ago, without status: +// // Expect Unknown status posted from node controller. +// { + +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 2, // List+Update +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeMemoryPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodePIDPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// LastTransitionTime: fakeNow, +// }, +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, // Pod was never scheduled +// }, +// // Node created recently, without status. +// // Expect no action from node controller (within startup grace period). +// { +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: fakeNow, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 1, // List +// expectedNodes: nil, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, with status updated by kubelet exceeds grace period. +// // Expect Unknown status posted from node controller. +// { + +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// // Node status hasn't been updated for 1hr. +// LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), +// LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 3, // (List+)List+Update +// timeToPass: time.Hour, +// newNodeStatus: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// // Node status hasn't been updated for 1hr. +// LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), +// LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusUnknown", +// Message: "Kubelet stopped posting node status.", +// LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC), +// LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, +// }, +// { +// Type: v1.NodeMemoryPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, +// }, +// { +// Type: v1.NodePIDPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC).Add(time.Hour)}, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: true, +// }, +// // Node created long time ago, with status updated recently. +// // Expect no action from node controller (within monitor grace period). +// { +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC), +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// // Node status has just been updated. +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 1, // List +// expectedNodes: nil, +// expectedPodStatusUpdate: false, +// }, +// } +// for i, item := range table { +// fakeNodeHandler := testutil.NewImprovedFakeNodeHandler(item.nodes, item.pods) +// nodeController, _ := newNodeLifecycleControllerFromClient( +// context.TODO(), +// fakeNodeHandler, +// testRateLimiterQPS, +// testRateLimiterQPS, +// testLargeClusterThreshold, +// testUnhealthyThreshold, +// testNodeMonitorGracePeriod, +// testNodeStartupGracePeriod, +// testNodeMonitorPeriod, +// ) +// nodeController.now = func() metav1.Time { return fakeNow } +// nodeController.recorder = testutil.NewFakeRecorder() +// if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { +// t.Errorf("unexpected error: %v", err) +// } +// if item.timeToPass > 0 { +// nodeController.now = func() metav1.Time { return metav1.Time{Time: fakeNow.Add(item.timeToPass)} } +// //item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus +// //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { +// // t.Errorf("unexpected error: %v", err) +// //} +// fakeNodeHandler.UpdateNodeStatuses(map[string]v1.NodeStatus{ +// "node0": item.newNodeStatus, +// }) +// if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { +// t.Errorf("unexpected error: %v", err) +// } +// } +// if item.expectedRequestCount != fakeNodeHandler.RequestCount { +// t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, fakeNodeHandler.RequestCount) +// } + +// if len(fakeNodeHandler.UpdatedNodes) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodes) { +// t.Errorf("Case[%d] unexpected nodes, expected nodes: %#+v\n, got nodes: %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodes[0]) +// } + +// if len(fakeNodeHandler.UpdatedNodeStatuses) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodeStatuses) { +// t.Errorf("Case[%d] unexpected node status: expected %#+v\n, but got: %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodeStatuses[0]) +// } + +// podStatusUpdated := false +// for _, action := range fakeNodeHandler.Actions() { +// if action.GetVerb() == "update" && action.GetResource().Resource == "pods" && action.GetSubresource() == "status" { +// podStatusUpdated = true +// } +// } +// if podStatusUpdated != item.expectedPodStatusUpdate { +// t.Errorf("Case[%d] expect pod status updated to be %v, but got %v", i, item.expectedPodStatusUpdate, podStatusUpdated) +// } +// } +// } + +// func TestMonitorNodeHealthUpdateNodeAndPodStatusWithLease(t *testing.T) { +// nodeCreationTime := metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC) +// fakeNow := metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) +// testcases := []struct { +// description string +// //fakeNodeHandler *testutil.FakeNodeHandler +// nodes []*v1.Node +// pods *v1.PodList +// lease *coordv1.Lease +// timeToPass time.Duration +// newNodeStatus map[string]v1.NodeStatus +// newLease *coordv1.Lease +// expectedRequestCount int +// expectedNodes []*v1.Node +// expectedPodStatusUpdate bool +// }{ +// // Node created recently, without status. Node lease is missing. +// // Expect no action from node controller (within startup grace period). +// { +// description: "Node created recently, without status. Node lease is missing.", + +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: fakeNow, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 1, // List +// expectedNodes: nil, +// expectedPodStatusUpdate: false, +// }, +// // Node created recently, without status. Node lease is renewed recently. +// // Expect no action from node controller (within startup grace period). +// { +// description: "Node created recently, without status. Node lease is renewed recently.", + +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: fakeNow, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// expectedRequestCount: 1, // List +// expectedNodes: nil, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, without status. Node lease is missing. +// // Expect Unknown status posted from node controller. +// { +// description: "Node created long time ago, without status. Node lease is missing.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// expectedRequestCount: 2, // List+Update +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeMemoryPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodePIDPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: fakeNow, +// }, +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, // Pod was never scheduled because the node was never ready. +// }, +// // Node created long time ago, without status. Node lease is renewed recently. +// // Expect no action from node controller (within monitor grace period). +// { +// description: "Node created long time ago, without status. Node lease is renewed recently.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// timeToPass: time.Hour, +// newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time.Add(time.Hour))), // Lease is renewed after 1 hour. +// expectedRequestCount: 2, // List+List +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, without status. Node lease is expired. +// // Expect Unknown status posted from node controller. +// { +// description: "Node created long time ago, without status. Node lease is expired.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// timeToPass: time.Hour, +// newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. +// expectedRequestCount: 3, // List+List+Update +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodeMemoryPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodePIDPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is renewed. +// // Expect no action from node controller (within monitor grace period). +// { +// description: "Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is renewed.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// expectedRequestCount: 2, // List+List +// timeToPass: time.Hour, +// newNodeStatus: map[string]v1.NodeStatus{ +// // Node status hasn't been updated for 1 hour. +// "node0": { +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time.Add(time.Hour))), // Lease is renewed after 1 hour. +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, with status updated by kubelet recently. Node lease is expired. +// // Expect no action from node controller (within monitor grace period). +// { +// description: "Node created long time ago, with status updated by kubelet recently. Node lease is expired.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// expectedRequestCount: 2, // List+List +// timeToPass: time.Hour, +// newNodeStatus: map[string]v1.NodeStatus{ +// // Node status is updated after 1 hour. +// "node0": { +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// LastTransitionTime: fakeNow, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionFalse, +// LastHeartbeatTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: false, +// }, +// // Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is also expired. +// // Expect Unknown status posted from node controller. +// { +// description: "Node created long time ago, with status updated by kubelet exceeds grace period. Node lease is also expired.", +// nodes: []*v1.Node{ +// { +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// pods: &v1.PodList{Items: []v1.Pod{*testutil.NewPod("pod0", "node0")}}, +// lease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), +// expectedRequestCount: 3, // List+List+Update +// timeToPass: time.Hour, +// newNodeStatus: map[string]v1.NodeStatus{ +// // Node status hasn't been updated for 1 hour. +// "node0": { +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionTrue, +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: fakeNow, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// newLease: createNodeLease("node0", metav1.NewMicroTime(fakeNow.Time)), // Lease is not renewed after 1 hour. +// expectedNodes: []*v1.Node{ +// { +// TypeMeta: metav1.TypeMeta{ +// Kind: "Node", +// APIVersion: "v1", +// }, +// ObjectMeta: metav1.ObjectMeta{ +// Name: "node0", +// CreationTimestamp: nodeCreationTime, +// }, +// Status: v1.NodeStatus{ +// Conditions: []v1.NodeCondition{ +// { +// Type: v1.NodeReady, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusUnknown", +// Message: "Kubelet stopped posting node status.", +// LastHeartbeatTime: fakeNow, +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodeMemoryPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodeDiskPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// { +// Type: v1.NodePIDPressure, +// Status: v1.ConditionUnknown, +// Reason: "NodeStatusNeverUpdated", +// Message: "Kubelet never posted node status.", +// LastHeartbeatTime: nodeCreationTime, // should default to node creation time if condition was never updated +// LastTransitionTime: metav1.Time{Time: fakeNow.Add(time.Hour)}, +// }, +// }, +// Capacity: v1.ResourceList{ +// v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"), +// v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), +// }, +// }, +// }, +// }, +// expectedPodStatusUpdate: true, +// }, +// } + +// for i, item := range testcases { +// t.Run(item.description, func(t *testing.T) { +// fakeNodeHandler := testutil.NewImprovedFakeNodeHandler(item.nodes, item.pods) +// nodeController, _ := newNodeLifecycleControllerFromClient( +// context.TODO(), +// fakeNodeHandler, +// testRateLimiterQPS, +// testRateLimiterQPS, +// testLargeClusterThreshold, +// testUnhealthyThreshold, +// testNodeMonitorGracePeriod, +// testNodeStartupGracePeriod, +// testNodeMonitorPeriod, +// ) +// nodeController.now = func() metav1.Time { return fakeNow } +// nodeController.recorder = testutil.NewFakeRecorder() +// //nodeController.getPodsAssignedToNode = fakeGetPodsAssignedToNode(item.fakeNodeHandler.Clientset) +// //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { +// // t.Fatalf("unexpected error: %v", err) +// //} +// //if err := nodeController.syncLeaseStore(item.lease); err != nil { +// if err := fakeNodeHandler.UpdateLease(item.lease); err != nil { +// t.Fatalf("unexpected error: %v", err) +// } +// if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { +// t.Fatalf("unexpected error: %v", err) +// } +// if item.timeToPass > 0 { +// nodeController.now = func() metav1.Time { return metav1.Time{Time: fakeNow.Add(item.timeToPass)} } +// //item.fakeNodeHandler.Existing[0].Status = item.newNodeStatus +// //if err := nodeController.syncNodeStore(item.fakeNodeHandler); err != nil { +// if err := fakeNodeHandler.UpdateNodeStatuses(item.newNodeStatus); err != nil { +// t.Fatalf("unexpected error: %v", err) +// } +// //if err := nodeController.syncLeaseStore(item.newLease); err != nil { +// if err := fakeNodeHandler.UpdateLease(item.newLease); err != nil { +// t.Fatalf("unexpected error: %v", err) +// } +// if err := nodeController.monitorNodeHealth(context.TODO()); err != nil { +// t.Fatalf("unexpected error: %v", err) +// } +// } +// if item.expectedRequestCount != fakeNodeHandler.RequestCount { +// t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, fakeNodeHandler.RequestCount) +// } + +// if len(fakeNodeHandler.UpdatedNodes) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodes) { +// t.Errorf("case[%d] expected nodes: %#+v\n, got %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodes[0]) +// } + +// if len(fakeNodeHandler.UpdatedNodeStatuses) > 0 && !apiequality.Semantic.DeepEqual(item.expectedNodes, fakeNodeHandler.UpdatedNodeStatuses) { +// t.Errorf("case[%d]: expected nodes: %#+v\n, got %#+v", i, item.expectedNodes[0], fakeNodeHandler.UpdatedNodeStatuses[0]) +// } + +// podStatusUpdated := false +// for _, action := range fakeNodeHandler.Actions() { +// if action.GetVerb() == "update" && action.GetResource().Resource == "pods" && action.GetSubresource() == "status" { +// podStatusUpdated = true +// } +// } +// if podStatusUpdated != item.expectedPodStatusUpdate { +// t.Errorf("expect pod status updated to be %v, but got %v", item.expectedPodStatusUpdate, podStatusUpdated) +// } +// }) +// } +// } func TestMonitorNodeHealthMarkPodsNotReady(t *testing.T) { fakeNow := metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC) diff --git a/pkg/yurtmanager/controller/util/tools.go b/pkg/yurtmanager/controller/util/tools.go index d0d998593ed..57cbb6d1259 100644 --- a/pkg/yurtmanager/controller/util/tools.go +++ b/pkg/yurtmanager/controller/util/tools.go @@ -23,6 +23,7 @@ import ( "sync" "time" + "github.com/go-logr/logr" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/client-go/util/workqueue" "k8s.io/klog/v2" @@ -31,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/go-logr/logr" controllerimpl "github.com/openyurtio/openyurt/pkg/yurtmanager/controller/internal/controller" ) diff --git a/pkg/yurtmanager/webhook/platformadmin/v1beta1/platformadmin_validation_test.go b/pkg/yurtmanager/webhook/platformadmin/v1beta1/platformadmin_validation_test.go index 99efaf7f59a..097ac7be9aa 100644 --- a/pkg/yurtmanager/webhook/platformadmin/v1beta1/platformadmin_validation_test.go +++ b/pkg/yurtmanager/webhook/platformadmin/v1beta1/platformadmin_validation_test.go @@ -177,7 +177,7 @@ func TestValidateCreate(t *testing.T) { _, err := handler.ValidateCreate(context.TODO(), tc.obj) if tc.errCode == 0 { assert.NoError(t, err, "success case result err must be nil") - } else { + } else if err != nil { assert.Equal(t, tc.errCode, int(err.(*apierrors.StatusError).Status().Code)) } }) diff --git a/pkg/yurttunnel/util/util_test.go b/pkg/yurttunnel/util/util_test.go index 7a1dc791329..3fb48e001ad 100644 --- a/pkg/yurttunnel/util/util_test.go +++ b/pkg/yurttunnel/util/util_test.go @@ -23,6 +23,7 @@ import ( "net/http" "net/url" "testing" + "time" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -262,6 +263,7 @@ func TestRunMetaServer(t *testing.T) { for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { + time.Sleep(5 * time.Second) resp, err := c.Do(tt.req) if err != nil { t.Fatalf("fail to send request to the server: %v", err)