k8s.io/kubernetes@v1.29.3/pkg/kubelet/status/generate_test.go (about)

     1  /*
     2  Copyright 2014 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 status
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  
    26  	v1 "k8s.io/api/core/v1"
    27  	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
    28  	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
    29  	"k8s.io/utils/pointer"
    30  )
    31  
    32  var (
    33  	containerRestartPolicyAlways = v1.ContainerRestartPolicyAlways
    34  )
    35  
    36  func TestGenerateContainersReadyCondition(t *testing.T) {
    37  	tests := []struct {
    38  		spec              *v1.PodSpec
    39  		containerStatuses []v1.ContainerStatus
    40  		podPhase          v1.PodPhase
    41  		expectReady       v1.PodCondition
    42  	}{
    43  		{
    44  			spec:              nil,
    45  			containerStatuses: nil,
    46  			podPhase:          v1.PodRunning,
    47  			expectReady:       getPodCondition(v1.ContainersReady, v1.ConditionFalse, UnknownContainerStatuses, ""),
    48  		},
    49  		{
    50  			spec:              &v1.PodSpec{},
    51  			containerStatuses: []v1.ContainerStatus{},
    52  			podPhase:          v1.PodRunning,
    53  			expectReady:       getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""),
    54  		},
    55  		{
    56  			spec: &v1.PodSpec{
    57  				Containers: []v1.Container{
    58  					{Name: "1234"},
    59  				},
    60  			},
    61  			containerStatuses: []v1.ContainerStatus{},
    62  			podPhase:          v1.PodRunning,
    63  			expectReady:       getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [1234]"),
    64  		},
    65  		{
    66  			spec: &v1.PodSpec{
    67  				Containers: []v1.Container{
    68  					{Name: "1234"},
    69  					{Name: "5678"},
    70  				},
    71  			},
    72  			containerStatuses: []v1.ContainerStatus{
    73  				getReadyStatus("1234"),
    74  				getReadyStatus("5678"),
    75  			},
    76  			podPhase:    v1.PodRunning,
    77  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""),
    78  		},
    79  		{
    80  			spec: &v1.PodSpec{
    81  				Containers: []v1.Container{
    82  					{Name: "1234"},
    83  					{Name: "5678"},
    84  				},
    85  			},
    86  			containerStatuses: []v1.ContainerStatus{
    87  				getReadyStatus("1234"),
    88  			},
    89  			podPhase:    v1.PodRunning,
    90  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [5678]"),
    91  		},
    92  		{
    93  			spec: &v1.PodSpec{
    94  				Containers: []v1.Container{
    95  					{Name: "1234"},
    96  					{Name: "5678"},
    97  				},
    98  			},
    99  			containerStatuses: []v1.ContainerStatus{
   100  				getReadyStatus("1234"),
   101  				getNotReadyStatus("5678"),
   102  			},
   103  			podPhase:    v1.PodRunning,
   104  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [5678]"),
   105  		},
   106  		{
   107  			spec: &v1.PodSpec{
   108  				Containers: []v1.Container{
   109  					{Name: "1234"},
   110  				},
   111  			},
   112  			containerStatuses: []v1.ContainerStatus{
   113  				getNotReadyStatus("1234"),
   114  			},
   115  			podPhase:    v1.PodSucceeded,
   116  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, PodCompleted, ""),
   117  		},
   118  		{
   119  			spec: &v1.PodSpec{
   120  				InitContainers: []v1.Container{
   121  					{Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways},
   122  				},
   123  				Containers: []v1.Container{
   124  					{Name: "regular-1"},
   125  				},
   126  			},
   127  			containerStatuses: []v1.ContainerStatus{
   128  				getReadyStatus("regular-1"),
   129  			},
   130  			podPhase:    v1.PodRunning,
   131  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [restartable-init-1]"),
   132  		},
   133  		{
   134  			spec: &v1.PodSpec{
   135  				InitContainers: []v1.Container{
   136  					{Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways},
   137  					{Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways},
   138  				},
   139  				Containers: []v1.Container{
   140  					{Name: "regular-1"},
   141  				},
   142  			},
   143  			containerStatuses: []v1.ContainerStatus{
   144  				getReadyStatus("restartable-init-1"),
   145  				getReadyStatus("restartable-init-2"),
   146  				getReadyStatus("regular-1"),
   147  			},
   148  			podPhase:    v1.PodRunning,
   149  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionTrue, "", ""),
   150  		},
   151  		{
   152  			spec: &v1.PodSpec{
   153  				InitContainers: []v1.Container{
   154  					{Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways},
   155  					{Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways},
   156  				},
   157  				Containers: []v1.Container{
   158  					{Name: "regular-1"},
   159  				},
   160  			},
   161  			containerStatuses: []v1.ContainerStatus{
   162  				getReadyStatus("restartable-init-1"),
   163  				getReadyStatus("regular-1"),
   164  			},
   165  			podPhase:    v1.PodRunning,
   166  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [restartable-init-2]"),
   167  		},
   168  		{
   169  			spec: &v1.PodSpec{
   170  				InitContainers: []v1.Container{
   171  					{Name: "restartable-init-1", RestartPolicy: &containerRestartPolicyAlways},
   172  					{Name: "restartable-init-2", RestartPolicy: &containerRestartPolicyAlways},
   173  				},
   174  				Containers: []v1.Container{
   175  					{Name: "regular-1"},
   176  				},
   177  			},
   178  			containerStatuses: []v1.ContainerStatus{
   179  				getReadyStatus("restartable-init-1"),
   180  				getNotReadyStatus("restartable-init-2"),
   181  				getReadyStatus("regular-1"),
   182  			},
   183  			podPhase:    v1.PodRunning,
   184  			expectReady: getPodCondition(v1.ContainersReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [restartable-init-2]"),
   185  		},
   186  	}
   187  
   188  	for i, test := range tests {
   189  		ready := GenerateContainersReadyCondition(test.spec, test.containerStatuses, test.podPhase)
   190  		if !reflect.DeepEqual(ready, test.expectReady) {
   191  			t.Errorf("On test case %v, expectReady:\n%+v\ngot\n%+v\n", i, test.expectReady, ready)
   192  		}
   193  	}
   194  }
   195  
   196  func TestGeneratePodReadyCondition(t *testing.T) {
   197  	tests := []struct {
   198  		spec              *v1.PodSpec
   199  		conditions        []v1.PodCondition
   200  		containerStatuses []v1.ContainerStatus
   201  		podPhase          v1.PodPhase
   202  		expectReady       v1.PodCondition
   203  	}{
   204  		{
   205  			spec:              nil,
   206  			conditions:        nil,
   207  			containerStatuses: nil,
   208  			podPhase:          v1.PodRunning,
   209  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, UnknownContainerStatuses, ""),
   210  		},
   211  		{
   212  			spec:              &v1.PodSpec{},
   213  			conditions:        nil,
   214  			containerStatuses: []v1.ContainerStatus{},
   215  			podPhase:          v1.PodRunning,
   216  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionTrue, "", ""),
   217  		},
   218  		{
   219  			spec: &v1.PodSpec{
   220  				Containers: []v1.Container{
   221  					{Name: "1234"},
   222  				},
   223  			},
   224  			conditions:        nil,
   225  			containerStatuses: []v1.ContainerStatus{},
   226  			podPhase:          v1.PodRunning,
   227  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [1234]"),
   228  		},
   229  		{
   230  			spec: &v1.PodSpec{
   231  				Containers: []v1.Container{
   232  					{Name: "1234"},
   233  					{Name: "5678"},
   234  				},
   235  			},
   236  			conditions: nil,
   237  			containerStatuses: []v1.ContainerStatus{
   238  				getReadyStatus("1234"),
   239  				getReadyStatus("5678"),
   240  			},
   241  			podPhase:    v1.PodRunning,
   242  			expectReady: getPodCondition(v1.PodReady, v1.ConditionTrue, "", ""),
   243  		},
   244  		{
   245  			spec: &v1.PodSpec{
   246  				Containers: []v1.Container{
   247  					{Name: "1234"},
   248  					{Name: "5678"},
   249  				},
   250  			},
   251  			conditions: nil,
   252  			containerStatuses: []v1.ContainerStatus{
   253  				getReadyStatus("1234"),
   254  			},
   255  			podPhase:    v1.PodRunning,
   256  			expectReady: getPodCondition(v1.PodReady, v1.ConditionFalse, ContainersNotReady, "containers with unknown status: [5678]"),
   257  		},
   258  		{
   259  			spec: &v1.PodSpec{
   260  				Containers: []v1.Container{
   261  					{Name: "1234"},
   262  					{Name: "5678"},
   263  				},
   264  			},
   265  			conditions: nil,
   266  			containerStatuses: []v1.ContainerStatus{
   267  				getReadyStatus("1234"),
   268  				getNotReadyStatus("5678"),
   269  			},
   270  			podPhase:    v1.PodRunning,
   271  			expectReady: getPodCondition(v1.PodReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [5678]"),
   272  		},
   273  		{
   274  			spec: &v1.PodSpec{
   275  				Containers: []v1.Container{
   276  					{Name: "1234"},
   277  				},
   278  			},
   279  			conditions: nil,
   280  			containerStatuses: []v1.ContainerStatus{
   281  				getNotReadyStatus("1234"),
   282  			},
   283  			podPhase:    v1.PodSucceeded,
   284  			expectReady: getPodCondition(v1.PodReady, v1.ConditionFalse, PodCompleted, ""),
   285  		},
   286  		{
   287  			spec: &v1.PodSpec{
   288  				ReadinessGates: []v1.PodReadinessGate{
   289  					{ConditionType: v1.PodConditionType("gate1")},
   290  				},
   291  			},
   292  			conditions:        nil,
   293  			containerStatuses: []v1.ContainerStatus{},
   294  			podPhase:          v1.PodRunning,
   295  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ReadinessGatesNotReady, `corresponding condition of pod readiness gate "gate1" does not exist.`),
   296  		},
   297  		{
   298  			spec: &v1.PodSpec{
   299  				ReadinessGates: []v1.PodReadinessGate{
   300  					{ConditionType: v1.PodConditionType("gate1")},
   301  				},
   302  			},
   303  			conditions: []v1.PodCondition{
   304  				getPodCondition("gate1", v1.ConditionFalse, "", ""),
   305  			},
   306  			containerStatuses: []v1.ContainerStatus{},
   307  			podPhase:          v1.PodRunning,
   308  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ReadinessGatesNotReady, `the status of pod readiness gate "gate1" is not "True", but False`),
   309  		},
   310  		{
   311  			spec: &v1.PodSpec{
   312  				ReadinessGates: []v1.PodReadinessGate{
   313  					{ConditionType: v1.PodConditionType("gate1")},
   314  				},
   315  			},
   316  			conditions: []v1.PodCondition{
   317  				getPodCondition("gate1", v1.ConditionTrue, "", ""),
   318  			},
   319  			containerStatuses: []v1.ContainerStatus{},
   320  			podPhase:          v1.PodRunning,
   321  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionTrue, "", ""),
   322  		},
   323  		{
   324  			spec: &v1.PodSpec{
   325  				ReadinessGates: []v1.PodReadinessGate{
   326  					{ConditionType: v1.PodConditionType("gate1")},
   327  					{ConditionType: v1.PodConditionType("gate2")},
   328  				},
   329  			},
   330  			conditions: []v1.PodCondition{
   331  				getPodCondition("gate1", v1.ConditionTrue, "", ""),
   332  			},
   333  			containerStatuses: []v1.ContainerStatus{},
   334  			podPhase:          v1.PodRunning,
   335  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ReadinessGatesNotReady, `corresponding condition of pod readiness gate "gate2" does not exist.`),
   336  		},
   337  		{
   338  			spec: &v1.PodSpec{
   339  				ReadinessGates: []v1.PodReadinessGate{
   340  					{ConditionType: v1.PodConditionType("gate1")},
   341  					{ConditionType: v1.PodConditionType("gate2")},
   342  				},
   343  			},
   344  			conditions: []v1.PodCondition{
   345  				getPodCondition("gate1", v1.ConditionTrue, "", ""),
   346  				getPodCondition("gate2", v1.ConditionFalse, "", ""),
   347  			},
   348  			containerStatuses: []v1.ContainerStatus{},
   349  			podPhase:          v1.PodRunning,
   350  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ReadinessGatesNotReady, `the status of pod readiness gate "gate2" is not "True", but False`),
   351  		},
   352  		{
   353  			spec: &v1.PodSpec{
   354  				ReadinessGates: []v1.PodReadinessGate{
   355  					{ConditionType: v1.PodConditionType("gate1")},
   356  					{ConditionType: v1.PodConditionType("gate2")},
   357  				},
   358  			},
   359  			conditions: []v1.PodCondition{
   360  				getPodCondition("gate1", v1.ConditionTrue, "", ""),
   361  				getPodCondition("gate2", v1.ConditionTrue, "", ""),
   362  			},
   363  			containerStatuses: []v1.ContainerStatus{},
   364  			podPhase:          v1.PodRunning,
   365  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionTrue, "", ""),
   366  		},
   367  		{
   368  			spec: &v1.PodSpec{
   369  				Containers: []v1.Container{
   370  					{Name: "1234"},
   371  				},
   372  				ReadinessGates: []v1.PodReadinessGate{
   373  					{ConditionType: v1.PodConditionType("gate1")},
   374  				},
   375  			},
   376  			conditions: []v1.PodCondition{
   377  				getPodCondition("gate1", v1.ConditionTrue, "", ""),
   378  			},
   379  			containerStatuses: []v1.ContainerStatus{getNotReadyStatus("1234")},
   380  			podPhase:          v1.PodRunning,
   381  			expectReady:       getPodCondition(v1.PodReady, v1.ConditionFalse, ContainersNotReady, "containers with unready status: [1234]"),
   382  		},
   383  	}
   384  
   385  	for i, test := range tests {
   386  		ready := GeneratePodReadyCondition(test.spec, test.conditions, test.containerStatuses, test.podPhase)
   387  		if !reflect.DeepEqual(ready, test.expectReady) {
   388  			t.Errorf("On test case %v, expectReady:\n%+v\ngot\n%+v\n", i, test.expectReady, ready)
   389  		}
   390  	}
   391  }
   392  
   393  func TestGeneratePodInitializedCondition(t *testing.T) {
   394  	noInitContainer := &v1.PodSpec{}
   395  	oneInitContainer := &v1.PodSpec{
   396  		InitContainers: []v1.Container{
   397  			{Name: "1234"},
   398  		},
   399  		Containers: []v1.Container{
   400  			{Name: "regular"},
   401  		},
   402  	}
   403  	twoInitContainer := &v1.PodSpec{
   404  		InitContainers: []v1.Container{
   405  			{Name: "1234"},
   406  			{Name: "5678"},
   407  		},
   408  		Containers: []v1.Container{
   409  			{Name: "regular"},
   410  		},
   411  	}
   412  	oneRestartableInitContainer := &v1.PodSpec{
   413  		InitContainers: []v1.Container{
   414  			{
   415  				Name: "1234",
   416  				RestartPolicy: func() *v1.ContainerRestartPolicy {
   417  					p := v1.ContainerRestartPolicyAlways
   418  					return &p
   419  				}(),
   420  			},
   421  		},
   422  		Containers: []v1.Container{
   423  			{Name: "regular"},
   424  		},
   425  	}
   426  	tests := []struct {
   427  		spec              *v1.PodSpec
   428  		containerStatuses []v1.ContainerStatus
   429  		podPhase          v1.PodPhase
   430  		expected          v1.PodCondition
   431  	}{
   432  		{
   433  			spec:              twoInitContainer,
   434  			containerStatuses: nil,
   435  			podPhase:          v1.PodRunning,
   436  			expected: v1.PodCondition{
   437  				Status: v1.ConditionFalse,
   438  				Reason: UnknownContainerStatuses,
   439  			},
   440  		},
   441  		{
   442  			spec:              noInitContainer,
   443  			containerStatuses: []v1.ContainerStatus{},
   444  			podPhase:          v1.PodRunning,
   445  			expected: v1.PodCondition{
   446  				Status: v1.ConditionTrue,
   447  				Reason: "",
   448  			},
   449  		},
   450  		{
   451  			spec:              oneInitContainer,
   452  			containerStatuses: []v1.ContainerStatus{},
   453  			podPhase:          v1.PodRunning,
   454  			expected: v1.PodCondition{
   455  				Status: v1.ConditionFalse,
   456  				Reason: ContainersNotInitialized,
   457  			},
   458  		},
   459  		{
   460  			spec: twoInitContainer,
   461  			containerStatuses: []v1.ContainerStatus{
   462  				getReadyStatus("1234"),
   463  				getReadyStatus("5678"),
   464  			},
   465  			podPhase: v1.PodRunning,
   466  			expected: v1.PodCondition{
   467  				Status: v1.ConditionTrue,
   468  				Reason: "",
   469  			},
   470  		},
   471  		{
   472  			spec: twoInitContainer,
   473  			containerStatuses: []v1.ContainerStatus{
   474  				getReadyStatus("1234"),
   475  			},
   476  			podPhase: v1.PodRunning,
   477  			expected: v1.PodCondition{
   478  				Status: v1.ConditionFalse,
   479  				Reason: ContainersNotInitialized,
   480  			},
   481  		},
   482  		{
   483  			spec: twoInitContainer,
   484  			containerStatuses: []v1.ContainerStatus{
   485  				getReadyStatus("1234"),
   486  				getNotReadyStatus("5678"),
   487  			},
   488  			podPhase: v1.PodRunning,
   489  			expected: v1.PodCondition{
   490  				Status: v1.ConditionFalse,
   491  				Reason: ContainersNotInitialized,
   492  			},
   493  		},
   494  		{
   495  			spec: oneInitContainer,
   496  			containerStatuses: []v1.ContainerStatus{
   497  				getReadyStatus("1234"),
   498  			},
   499  			podPhase: v1.PodSucceeded,
   500  			expected: v1.PodCondition{
   501  				Status: v1.ConditionTrue,
   502  				Reason: PodCompleted,
   503  			},
   504  		},
   505  		{
   506  			spec: oneRestartableInitContainer,
   507  			containerStatuses: []v1.ContainerStatus{
   508  				getNotStartedStatus("1234"),
   509  			},
   510  			podPhase: v1.PodPending,
   511  			expected: v1.PodCondition{
   512  				Status: v1.ConditionFalse,
   513  				Reason: ContainersNotInitialized,
   514  			},
   515  		},
   516  		{
   517  			spec: oneRestartableInitContainer,
   518  			containerStatuses: []v1.ContainerStatus{
   519  				getStartedStatus("1234"),
   520  			},
   521  			podPhase: v1.PodRunning,
   522  			expected: v1.PodCondition{
   523  				Status: v1.ConditionTrue,
   524  			},
   525  		},
   526  		{
   527  			spec: oneRestartableInitContainer,
   528  			containerStatuses: []v1.ContainerStatus{
   529  				getNotStartedStatus("1234"),
   530  				{
   531  					Name: "regular",
   532  					State: v1.ContainerState{
   533  						Running: &v1.ContainerStateRunning{},
   534  					},
   535  				},
   536  			},
   537  			podPhase: v1.PodRunning,
   538  			expected: v1.PodCondition{
   539  				Status: v1.ConditionTrue,
   540  			},
   541  		},
   542  	}
   543  
   544  	for _, test := range tests {
   545  		test.expected.Type = v1.PodInitialized
   546  		condition := GeneratePodInitializedCondition(test.spec, test.containerStatuses, test.podPhase)
   547  		assert.Equal(t, test.expected.Type, condition.Type)
   548  		assert.Equal(t, test.expected.Status, condition.Status)
   549  		assert.Equal(t, test.expected.Reason, condition.Reason)
   550  
   551  	}
   552  }
   553  
   554  func TestGeneratePodReadyToStartContainersCondition(t *testing.T) {
   555  	for desc, test := range map[string]struct {
   556  		pod      *v1.Pod
   557  		status   *kubecontainer.PodStatus
   558  		expected v1.PodCondition
   559  	}{
   560  		"Empty pod status": {
   561  			pod:    &v1.Pod{},
   562  			status: &kubecontainer.PodStatus{},
   563  			expected: v1.PodCondition{
   564  				Status: v1.ConditionFalse,
   565  			},
   566  		},
   567  		"Pod sandbox status not ready": {
   568  			pod: &v1.Pod{},
   569  			status: &kubecontainer.PodStatus{
   570  				SandboxStatuses: []*runtimeapi.PodSandboxStatus{
   571  					{
   572  						Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
   573  						State:    runtimeapi.PodSandboxState_SANDBOX_NOTREADY,
   574  					},
   575  				},
   576  			},
   577  			expected: v1.PodCondition{
   578  				Status: v1.ConditionFalse,
   579  			},
   580  		},
   581  		"Pod sandbox status ready but no IP configured": {
   582  			pod: &v1.Pod{},
   583  			status: &kubecontainer.PodStatus{
   584  				SandboxStatuses: []*runtimeapi.PodSandboxStatus{
   585  					{
   586  						Network: &runtimeapi.PodSandboxNetworkStatus{
   587  							Ip: "",
   588  						},
   589  						Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
   590  						State:    runtimeapi.PodSandboxState_SANDBOX_READY,
   591  					},
   592  				},
   593  			},
   594  			expected: v1.PodCondition{
   595  				Status: v1.ConditionFalse,
   596  			},
   597  		},
   598  		"Pod sandbox status ready and IP configured": {
   599  			pod: &v1.Pod{},
   600  			status: &kubecontainer.PodStatus{
   601  				SandboxStatuses: []*runtimeapi.PodSandboxStatus{
   602  					{
   603  						Network: &runtimeapi.PodSandboxNetworkStatus{
   604  							Ip: "10.0.0.10",
   605  						},
   606  						Metadata: &runtimeapi.PodSandboxMetadata{Attempt: uint32(0)},
   607  						State:    runtimeapi.PodSandboxState_SANDBOX_READY,
   608  					},
   609  				},
   610  			},
   611  			expected: v1.PodCondition{
   612  				Status: v1.ConditionTrue,
   613  			},
   614  		},
   615  	} {
   616  		t.Run(desc, func(t *testing.T) {
   617  			test.expected.Type = v1.PodReadyToStartContainers
   618  			condition := GeneratePodReadyToStartContainersCondition(test.pod, test.status)
   619  			require.Equal(t, test.expected.Type, condition.Type)
   620  			require.Equal(t, test.expected.Status, condition.Status)
   621  		})
   622  	}
   623  }
   624  
   625  func getPodCondition(conditionType v1.PodConditionType, status v1.ConditionStatus, reason, message string) v1.PodCondition {
   626  	return v1.PodCondition{
   627  		Type:    conditionType,
   628  		Status:  status,
   629  		Reason:  reason,
   630  		Message: message,
   631  	}
   632  }
   633  
   634  func getReadyStatus(cName string) v1.ContainerStatus {
   635  	return v1.ContainerStatus{
   636  		Name:  cName,
   637  		Ready: true,
   638  	}
   639  }
   640  
   641  func getNotReadyStatus(cName string) v1.ContainerStatus {
   642  	return v1.ContainerStatus{
   643  		Name:  cName,
   644  		Ready: false,
   645  	}
   646  }
   647  
   648  func getStartedStatus(cName string) v1.ContainerStatus {
   649  	return v1.ContainerStatus{
   650  		Name:    cName,
   651  		Started: pointer.Bool(true),
   652  	}
   653  }
   654  
   655  func getNotStartedStatus(cName string) v1.ContainerStatus {
   656  	return v1.ContainerStatus{
   657  		Name:    cName,
   658  		Started: pointer.Bool(false),
   659  	}
   660  }