...

Source file src/k8s.io/kubectl/pkg/util/podutils/podutils_test.go

Documentation: k8s.io/kubectl/pkg/util/podutils

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package podutils
    18  
    19  import (
    20  	"sort"
    21  	"testing"
    22  	"time"
    23  
    24  	corev1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  )
    27  
    28  func TestActivePods(t *testing.T) {
    29  	time1 := metav1.Now()
    30  	time2 := metav1.NewTime(time1.Add(1 * time.Second))
    31  	time3 := metav1.NewTime(time1.Add(2 * time.Second))
    32  
    33  	tests := []struct {
    34  		name string
    35  		pod1 *corev1.Pod
    36  		pod2 *corev1.Pod
    37  	}{
    38  		{
    39  			name: "unassigned pod should sort before assigned pod",
    40  			pod1: &corev1.Pod{
    41  				ObjectMeta: metav1.ObjectMeta{
    42  					Name:      "unassignedPod",
    43  					Namespace: "default",
    44  				},
    45  			},
    46  			pod2: &corev1.Pod{
    47  				ObjectMeta: metav1.ObjectMeta{
    48  					Name:      "assignedPod",
    49  					Namespace: "default",
    50  				},
    51  				Spec: corev1.PodSpec{
    52  					NodeName: "node1",
    53  				},
    54  			},
    55  		},
    56  		{
    57  			name: "pending pod should sort before unknown pod",
    58  			pod1: &corev1.Pod{
    59  				ObjectMeta: metav1.ObjectMeta{
    60  					Name:      "pendingPod",
    61  					Namespace: "default",
    62  				},
    63  				Spec: corev1.PodSpec{
    64  					NodeName: "node1",
    65  				},
    66  				Status: corev1.PodStatus{
    67  					Phase: corev1.PodPending,
    68  				},
    69  			},
    70  			pod2: &corev1.Pod{
    71  				ObjectMeta: metav1.ObjectMeta{
    72  					Name:              "unknownPod",
    73  					Namespace:         "default",
    74  					CreationTimestamp: time1,
    75  				},
    76  				Spec: corev1.PodSpec{
    77  					NodeName: "node1",
    78  				},
    79  				Status: corev1.PodStatus{
    80  					Phase: corev1.PodUnknown,
    81  				},
    82  			},
    83  		},
    84  		{
    85  			name: "unknown pod should sort before running pod",
    86  			pod1: &corev1.Pod{
    87  				ObjectMeta: metav1.ObjectMeta{
    88  					Name:              "unknownPod",
    89  					Namespace:         "default",
    90  					CreationTimestamp: time1,
    91  				},
    92  				Spec: corev1.PodSpec{
    93  					NodeName: "node1",
    94  				},
    95  				Status: corev1.PodStatus{
    96  					Phase: corev1.PodUnknown,
    97  				},
    98  			},
    99  			pod2: &corev1.Pod{
   100  				ObjectMeta: metav1.ObjectMeta{
   101  					Name:              "runningPod",
   102  					Namespace:         "default",
   103  					CreationTimestamp: time1,
   104  				},
   105  				Spec: corev1.PodSpec{
   106  					NodeName: "node1",
   107  				},
   108  				Status: corev1.PodStatus{
   109  					Phase: corev1.PodRunning,
   110  				},
   111  			},
   112  		},
   113  		{
   114  			name: "unready pod should sort before ready pod",
   115  			pod1: &corev1.Pod{
   116  				ObjectMeta: metav1.ObjectMeta{
   117  					Name:      "unreadyPod",
   118  					Namespace: "default",
   119  				},
   120  				Spec: corev1.PodSpec{
   121  					NodeName: "node1",
   122  				},
   123  				Status: corev1.PodStatus{
   124  					Phase: corev1.PodRunning,
   125  				},
   126  			},
   127  			pod2: &corev1.Pod{
   128  				ObjectMeta: metav1.ObjectMeta{
   129  					Name:      "readyPod",
   130  					Namespace: "default",
   131  				},
   132  				Spec: corev1.PodSpec{
   133  					NodeName: "node1",
   134  				},
   135  				Status: corev1.PodStatus{
   136  					Phase: corev1.PodRunning,
   137  					Conditions: []corev1.PodCondition{
   138  						{
   139  							Type:               corev1.PodReady,
   140  							Status:             corev1.ConditionTrue,
   141  							LastTransitionTime: time1,
   142  						},
   143  					},
   144  				},
   145  			},
   146  		},
   147  		{
   148  			name: "pod with deletion timestamp should sort before pod without deletion timestamp",
   149  			pod1: &corev1.Pod{
   150  				ObjectMeta: metav1.ObjectMeta{
   151  					Name:              "readyPodDeleting",
   152  					Namespace:         "default",
   153  					DeletionTimestamp: &time2,
   154  				},
   155  				Spec: corev1.PodSpec{
   156  					NodeName: "node1",
   157  				},
   158  				Status: corev1.PodStatus{
   159  					Phase: corev1.PodRunning,
   160  					Conditions: []corev1.PodCondition{
   161  						{
   162  							Type:               corev1.PodReady,
   163  							Status:             corev1.ConditionTrue,
   164  							LastTransitionTime: time1,
   165  						},
   166  					},
   167  				},
   168  			},
   169  			pod2: &corev1.Pod{
   170  				ObjectMeta: metav1.ObjectMeta{
   171  					Name:      "readyPod",
   172  					Namespace: "default",
   173  				},
   174  				Spec: corev1.PodSpec{
   175  					NodeName: "node1",
   176  				},
   177  				Status: corev1.PodStatus{
   178  					Phase: corev1.PodRunning,
   179  					Conditions: []corev1.PodCondition{
   180  						{
   181  							Type:               corev1.PodReady,
   182  							Status:             corev1.ConditionTrue,
   183  							LastTransitionTime: time1,
   184  						},
   185  					},
   186  				},
   187  			},
   188  		},
   189  		{
   190  			name: "older deletion timestamp should sort before newer deletion timestamp",
   191  			pod1: &corev1.Pod{
   192  				ObjectMeta: metav1.ObjectMeta{
   193  					Name:              "readyPodDeletingOlder",
   194  					Namespace:         "default",
   195  					DeletionTimestamp: &time2,
   196  				},
   197  				Spec: corev1.PodSpec{
   198  					NodeName: "node1",
   199  				},
   200  				Status: corev1.PodStatus{
   201  					Phase: corev1.PodRunning,
   202  					Conditions: []corev1.PodCondition{
   203  						{
   204  							Type:               corev1.PodReady,
   205  							Status:             corev1.ConditionTrue,
   206  							LastTransitionTime: time1,
   207  						},
   208  					},
   209  				},
   210  			},
   211  			pod2: &corev1.Pod{
   212  				ObjectMeta: metav1.ObjectMeta{
   213  					Name:              "readyPodDeletingNewer",
   214  					Namespace:         "default",
   215  					DeletionTimestamp: &time3,
   216  				},
   217  				Spec: corev1.PodSpec{
   218  					NodeName: "node1",
   219  				},
   220  				Status: corev1.PodStatus{
   221  					Phase: corev1.PodRunning,
   222  					Conditions: []corev1.PodCondition{
   223  						{
   224  							Type:               corev1.PodReady,
   225  							Status:             corev1.ConditionTrue,
   226  							LastTransitionTime: time1,
   227  						},
   228  					},
   229  				},
   230  			},
   231  		},
   232  		{
   233  			name: "newer ready timestamp should sort before older ready timestamp",
   234  			pod1: &corev1.Pod{
   235  				ObjectMeta: metav1.ObjectMeta{
   236  					Name:      "newerReadyPod",
   237  					Namespace: "default",
   238  				},
   239  				Spec: corev1.PodSpec{
   240  					NodeName: "node1",
   241  				},
   242  				Status: corev1.PodStatus{
   243  					Phase: corev1.PodRunning,
   244  					Conditions: []corev1.PodCondition{
   245  						{
   246  							Type:               corev1.PodReady,
   247  							Status:             corev1.ConditionTrue,
   248  							LastTransitionTime: time3,
   249  						},
   250  					},
   251  				},
   252  			},
   253  			pod2: &corev1.Pod{
   254  				ObjectMeta: metav1.ObjectMeta{
   255  					Name:      "olderReadyPod",
   256  					Namespace: "default",
   257  				},
   258  				Spec: corev1.PodSpec{
   259  					NodeName: "node1",
   260  				},
   261  				Status: corev1.PodStatus{
   262  					Phase: corev1.PodRunning,
   263  					Conditions: []corev1.PodCondition{
   264  						{
   265  							Type:               corev1.PodReady,
   266  							Status:             corev1.ConditionTrue,
   267  							LastTransitionTime: time2,
   268  						},
   269  					},
   270  				},
   271  			},
   272  		},
   273  		{
   274  			name: "higher restart count should sort before lower restart count",
   275  			pod1: &corev1.Pod{
   276  				ObjectMeta: metav1.ObjectMeta{
   277  					Name:      "podWithMoreRestarts",
   278  					Namespace: "default",
   279  				},
   280  				Spec: corev1.PodSpec{
   281  					NodeName: "node1",
   282  				},
   283  				Status: corev1.PodStatus{
   284  					Phase: corev1.PodRunning,
   285  					Conditions: []corev1.PodCondition{
   286  						{
   287  							Type:               corev1.PodReady,
   288  							Status:             corev1.ConditionTrue,
   289  							LastTransitionTime: time1,
   290  						},
   291  					},
   292  					ContainerStatuses: []corev1.ContainerStatus{
   293  						{
   294  							RestartCount: 3,
   295  						},
   296  					},
   297  				},
   298  			},
   299  			pod2: &corev1.Pod{
   300  				ObjectMeta: metav1.ObjectMeta{
   301  					Name:      "podWithLessRestarts",
   302  					Namespace: "default",
   303  				},
   304  				Spec: corev1.PodSpec{
   305  					NodeName: "node1",
   306  				},
   307  				Status: corev1.PodStatus{
   308  					Phase: corev1.PodRunning,
   309  					Conditions: []corev1.PodCondition{
   310  						{
   311  							Type:               corev1.PodReady,
   312  							Status:             corev1.ConditionTrue,
   313  							LastTransitionTime: time1,
   314  						},
   315  					},
   316  					ContainerStatuses: []corev1.ContainerStatus{
   317  						{
   318  							RestartCount: 2,
   319  						},
   320  					},
   321  				},
   322  			},
   323  		},
   324  		{
   325  			name: "newer creation timestamp should sort before older creation timestamp",
   326  			pod1: &corev1.Pod{
   327  				ObjectMeta: metav1.ObjectMeta{
   328  					Name:              "newerCreationPod",
   329  					Namespace:         "default",
   330  					CreationTimestamp: time3,
   331  				},
   332  				Spec: corev1.PodSpec{
   333  					NodeName: "node1",
   334  				},
   335  				Status: corev1.PodStatus{
   336  					Phase: corev1.PodRunning,
   337  					Conditions: []corev1.PodCondition{
   338  						{
   339  							Type:               corev1.PodReady,
   340  							Status:             corev1.ConditionTrue,
   341  							LastTransitionTime: time1,
   342  						},
   343  					},
   344  				},
   345  			},
   346  			pod2: &corev1.Pod{
   347  				ObjectMeta: metav1.ObjectMeta{
   348  					Name:              "olderCreationPod",
   349  					Namespace:         "default",
   350  					CreationTimestamp: time2,
   351  				},
   352  				Spec: corev1.PodSpec{
   353  					NodeName: "node1",
   354  				},
   355  				Status: corev1.PodStatus{
   356  					Phase: corev1.PodRunning,
   357  					Conditions: []corev1.PodCondition{
   358  						{
   359  							Type:               corev1.PodReady,
   360  							Status:             corev1.ConditionTrue,
   361  							LastTransitionTime: time1,
   362  						},
   363  					},
   364  				},
   365  			},
   366  		},
   367  	}
   368  	for _, tt := range tests {
   369  		t.Run(tt.name, func(t *testing.T) {
   370  			// Test that the pods are sorted in the correct order when pod1 is first and pod2 is second.
   371  			pods := ActivePods{tt.pod1, tt.pod2}
   372  			sort.Sort(pods)
   373  			if pods[0] != tt.pod1 || pods[1] != tt.pod2 {
   374  				t.Errorf("Incorrect ActivePods sorting, expected pod1 to be first")
   375  			}
   376  
   377  			// Test that the pods are sorted in the correct order when pod2 is first and pod1 is second.
   378  			pods = ActivePods{tt.pod2, tt.pod1}
   379  			sort.Sort(pods)
   380  			if pods[0] != tt.pod1 || pods[1] != tt.pod2 {
   381  				t.Errorf("Incorrect ActivePods sorting, expected pod1 to be first")
   382  			}
   383  		})
   384  	}
   385  }
   386  

View as plain text