sigs.k8s.io/cluster-api@v1.7.1/controllers/noderefutil/util_test.go (about)

     1  /*
     2  Copyright 2018 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 noderefutil
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	. "github.com/onsi/gomega"
    24  	corev1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  )
    27  
    28  func TestIsNodeAvaialble(t *testing.T) {
    29  	tests := []struct {
    30  		name              string
    31  		node              *corev1.Node
    32  		minReadySeconds   int32
    33  		expectedAvailable bool
    34  	}{
    35  		{
    36  			name:              "no node",
    37  			expectedAvailable: false,
    38  		},
    39  		{
    40  			name:              "no status",
    41  			node:              &corev1.Node{},
    42  			expectedAvailable: false,
    43  		},
    44  		{
    45  			name:              "no condition",
    46  			node:              &corev1.Node{Status: corev1.NodeStatus{}},
    47  			expectedAvailable: false,
    48  		},
    49  		{
    50  			name: "no ready condition",
    51  			node: &corev1.Node{Status: corev1.NodeStatus{
    52  				Conditions: []corev1.NodeCondition{
    53  					{
    54  						Type:   corev1.NodeDiskPressure,
    55  						Status: corev1.ConditionTrue,
    56  					},
    57  				}},
    58  			},
    59  			expectedAvailable: false,
    60  		},
    61  		{
    62  			name: "ready condition true, minReadySeconds = 0, lastTransitionTime now",
    63  			node: &corev1.Node{Status: corev1.NodeStatus{
    64  				Conditions: []corev1.NodeCondition{
    65  					{
    66  						Type:               corev1.NodeReady,
    67  						Status:             corev1.ConditionTrue,
    68  						LastTransitionTime: metav1.Now(),
    69  					},
    70  				}},
    71  			},
    72  			expectedAvailable: true,
    73  		},
    74  		{
    75  			name: "ready condition true, minReadySeconds = 0, lastTransitionTime past",
    76  			node: &corev1.Node{Status: corev1.NodeStatus{
    77  				Conditions: []corev1.NodeCondition{
    78  					{
    79  						Type:               corev1.NodeReady,
    80  						Status:             corev1.ConditionTrue,
    81  						LastTransitionTime: metav1.Time{Time: time.Now().Add(time.Duration(-700) * time.Second)},
    82  					},
    83  				}},
    84  			},
    85  			expectedAvailable: true,
    86  		},
    87  		{
    88  			name: "ready condition true, minReadySeconds = 300, lastTransitionTime now",
    89  			node: &corev1.Node{Status: corev1.NodeStatus{
    90  				Conditions: []corev1.NodeCondition{
    91  					{
    92  						Type:               corev1.NodeReady,
    93  						Status:             corev1.ConditionTrue,
    94  						LastTransitionTime: metav1.Now(),
    95  					},
    96  				}},
    97  			},
    98  			minReadySeconds:   300,
    99  			expectedAvailable: false,
   100  		},
   101  		{
   102  			name: "ready condition true, minReadySeconds = 300, lastTransitionTime past",
   103  			node: &corev1.Node{Status: corev1.NodeStatus{
   104  				Conditions: []corev1.NodeCondition{
   105  					{
   106  						Type:               corev1.NodeReady,
   107  						Status:             corev1.ConditionTrue,
   108  						LastTransitionTime: metav1.Time{Time: time.Now().Add(time.Duration(-700) * time.Second)},
   109  					},
   110  				}},
   111  			},
   112  			minReadySeconds:   300,
   113  			expectedAvailable: true,
   114  		},
   115  		{
   116  			name: "ready condition false",
   117  			node: &corev1.Node{Status: corev1.NodeStatus{
   118  				Conditions: []corev1.NodeCondition{
   119  					{
   120  						Type:   corev1.NodeReady,
   121  						Status: corev1.ConditionFalse,
   122  					},
   123  				}},
   124  			},
   125  			expectedAvailable: false,
   126  		},
   127  		{
   128  			name: "ready condition unknown",
   129  			node: &corev1.Node{Status: corev1.NodeStatus{
   130  				Conditions: []corev1.NodeCondition{
   131  					{
   132  						Type:   corev1.NodeReady,
   133  						Status: corev1.ConditionUnknown,
   134  					},
   135  				}},
   136  			},
   137  			expectedAvailable: false,
   138  		},
   139  	}
   140  
   141  	for _, test := range tests {
   142  		t.Run(test.name, func(t *testing.T) {
   143  			g := NewWithT(t)
   144  
   145  			g.Expect(IsNodeAvailable(test.node, test.minReadySeconds, metav1.Now())).To(Equal(test.expectedAvailable))
   146  		})
   147  	}
   148  }
   149  
   150  func TestGetReadyCondition(t *testing.T) {
   151  	tests := []struct {
   152  		name              string
   153  		nodeStatus        *corev1.NodeStatus
   154  		expectedCondition *corev1.NodeCondition
   155  	}{
   156  		{
   157  			name: "no status",
   158  		},
   159  		{
   160  			name:       "no condition",
   161  			nodeStatus: &corev1.NodeStatus{},
   162  		},
   163  		{
   164  			name: "no ready condition",
   165  			nodeStatus: &corev1.NodeStatus{
   166  				Conditions: []corev1.NodeCondition{
   167  					{
   168  						Type:   corev1.NodeDiskPressure,
   169  						Status: corev1.ConditionTrue,
   170  					},
   171  				},
   172  			},
   173  		},
   174  		{
   175  			name: "ready condition true",
   176  			nodeStatus: &corev1.NodeStatus{
   177  				Conditions: []corev1.NodeCondition{
   178  					{
   179  						Type:   corev1.NodeReady,
   180  						Status: corev1.ConditionTrue,
   181  					},
   182  				},
   183  			},
   184  			expectedCondition: &corev1.NodeCondition{
   185  				Type:   corev1.NodeReady,
   186  				Status: corev1.ConditionTrue,
   187  			},
   188  		},
   189  		{
   190  			name: "ready condition false",
   191  			nodeStatus: &corev1.NodeStatus{
   192  				Conditions: []corev1.NodeCondition{
   193  					{
   194  						Type:   corev1.NodeReady,
   195  						Status: corev1.ConditionFalse,
   196  					},
   197  				},
   198  			},
   199  			expectedCondition: &corev1.NodeCondition{
   200  				Type:   corev1.NodeReady,
   201  				Status: corev1.ConditionFalse,
   202  			},
   203  		},
   204  		{
   205  			name: "ready condition unknown",
   206  			nodeStatus: &corev1.NodeStatus{
   207  				Conditions: []corev1.NodeCondition{
   208  					{
   209  						Type:   corev1.NodeReady,
   210  						Status: corev1.ConditionUnknown,
   211  					},
   212  				},
   213  			},
   214  			expectedCondition: &corev1.NodeCondition{
   215  				Type:   corev1.NodeReady,
   216  				Status: corev1.ConditionUnknown,
   217  			},
   218  		},
   219  	}
   220  
   221  	for _, test := range tests {
   222  		t.Run(test.name, func(t *testing.T) {
   223  			g := NewWithT(t)
   224  
   225  			g.Expect(GetReadyCondition(test.nodeStatus)).To(BeComparableTo(test.expectedCondition))
   226  		})
   227  	}
   228  }
   229  
   230  func TestIsNodeReady(t *testing.T) {
   231  	tests := []struct {
   232  		name          string
   233  		node          *corev1.Node
   234  		expectedReady bool
   235  	}{
   236  		{
   237  			name:          "no node",
   238  			expectedReady: false,
   239  		},
   240  		{
   241  			name:          "no status",
   242  			node:          &corev1.Node{},
   243  			expectedReady: false,
   244  		},
   245  		{
   246  			name:          "no condition",
   247  			node:          &corev1.Node{Status: corev1.NodeStatus{}},
   248  			expectedReady: false,
   249  		},
   250  		{
   251  			name: "no ready condition",
   252  			node: &corev1.Node{Status: corev1.NodeStatus{
   253  				Conditions: []corev1.NodeCondition{
   254  					{
   255  						Type:   corev1.NodeDiskPressure,
   256  						Status: corev1.ConditionTrue,
   257  					},
   258  				}},
   259  			},
   260  			expectedReady: false,
   261  		},
   262  		{
   263  			name: "ready condition true",
   264  			node: &corev1.Node{Status: corev1.NodeStatus{
   265  				Conditions: []corev1.NodeCondition{
   266  					{
   267  						Type:   corev1.NodeReady,
   268  						Status: corev1.ConditionTrue,
   269  					},
   270  				}},
   271  			},
   272  			expectedReady: true,
   273  		},
   274  		{
   275  			name: "ready condition false",
   276  			node: &corev1.Node{Status: corev1.NodeStatus{
   277  				Conditions: []corev1.NodeCondition{
   278  					{
   279  						Type:   corev1.NodeReady,
   280  						Status: corev1.ConditionFalse,
   281  					},
   282  				}},
   283  			},
   284  			expectedReady: false,
   285  		},
   286  		{
   287  			name: "ready condition unknown",
   288  			node: &corev1.Node{Status: corev1.NodeStatus{
   289  				Conditions: []corev1.NodeCondition{
   290  					{
   291  						Type:   corev1.NodeReady,
   292  						Status: corev1.ConditionUnknown,
   293  					},
   294  				}},
   295  			},
   296  			expectedReady: false,
   297  		},
   298  	}
   299  
   300  	for _, test := range tests {
   301  		t.Run(test.name, func(t *testing.T) {
   302  			g := NewWithT(t)
   303  
   304  			g.Expect(IsNodeReady(test.node)).To(Equal(test.expectedReady))
   305  		})
   306  	}
   307  }