...

Source file src/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable_test.go

Documentation: k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable

     1  /*
     2  Copyright 2019 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 nodeunschedulable
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	"k8s.io/kubernetes/pkg/scheduler/framework"
    25  	"k8s.io/kubernetes/test/utils/ktesting"
    26  )
    27  
    28  func TestNodeUnschedulable(t *testing.T) {
    29  	testCases := []struct {
    30  		name       string
    31  		pod        *v1.Pod
    32  		node       *v1.Node
    33  		wantStatus *framework.Status
    34  	}{
    35  		{
    36  			name: "Does not schedule pod to unschedulable node (node.Spec.Unschedulable==true)",
    37  			pod:  &v1.Pod{},
    38  			node: &v1.Node{
    39  				Spec: v1.NodeSpec{
    40  					Unschedulable: true,
    41  				},
    42  			},
    43  			wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonUnschedulable),
    44  		},
    45  		{
    46  			name: "Schedule pod to normal node",
    47  			pod:  &v1.Pod{},
    48  			node: &v1.Node{
    49  				Spec: v1.NodeSpec{
    50  					Unschedulable: false,
    51  				},
    52  			},
    53  		},
    54  		{
    55  			name: "Schedule pod with toleration to unschedulable node (node.Spec.Unschedulable==true)",
    56  			pod: &v1.Pod{
    57  				Spec: v1.PodSpec{
    58  					Tolerations: []v1.Toleration{
    59  						{
    60  							Key:    v1.TaintNodeUnschedulable,
    61  							Effect: v1.TaintEffectNoSchedule,
    62  						},
    63  					},
    64  				},
    65  			},
    66  			node: &v1.Node{
    67  				Spec: v1.NodeSpec{
    68  					Unschedulable: true,
    69  				},
    70  			},
    71  		},
    72  	}
    73  
    74  	for _, test := range testCases {
    75  		nodeInfo := framework.NewNodeInfo()
    76  		nodeInfo.SetNode(test.node)
    77  		_, ctx := ktesting.NewTestContext(t)
    78  		p, err := New(ctx, nil, nil)
    79  		if err != nil {
    80  			t.Fatalf("creating plugin: %v", err)
    81  		}
    82  		gotStatus := p.(framework.FilterPlugin).Filter(ctx, nil, test.pod, nodeInfo)
    83  		if !reflect.DeepEqual(gotStatus, test.wantStatus) {
    84  			t.Errorf("status does not match: %v, want: %v", gotStatus, test.wantStatus)
    85  		}
    86  	}
    87  }
    88  
    89  func TestIsSchedulableAfterNodeChange(t *testing.T) {
    90  	testCases := []struct {
    91  		name           string
    92  		pod            *v1.Pod
    93  		oldObj, newObj interface{}
    94  		expectedHint   framework.QueueingHint
    95  		expectedErr    bool
    96  	}{
    97  		{
    98  			name:         "backoff-wrong-new-object",
    99  			pod:          &v1.Pod{},
   100  			newObj:       "not-a-node",
   101  			expectedHint: framework.Queue,
   102  			expectedErr:  true,
   103  		},
   104  		{
   105  			name: "backoff-wrong-old-object",
   106  			pod:  &v1.Pod{},
   107  			newObj: &v1.Node{
   108  				Spec: v1.NodeSpec{
   109  					Unschedulable: true,
   110  				},
   111  			},
   112  			oldObj:       "not-a-node",
   113  			expectedHint: framework.Queue,
   114  			expectedErr:  true,
   115  		},
   116  		{
   117  			name: "skip-queue-on-unschedulable-node-added",
   118  			pod:  &v1.Pod{},
   119  			newObj: &v1.Node{
   120  				Spec: v1.NodeSpec{
   121  					Unschedulable: true,
   122  				},
   123  			},
   124  			expectedHint: framework.QueueSkip,
   125  		},
   126  		{
   127  			name: "queue-on-schedulable-node-added",
   128  			pod:  &v1.Pod{},
   129  			newObj: &v1.Node{
   130  				Spec: v1.NodeSpec{
   131  					Unschedulable: false,
   132  				},
   133  			},
   134  			expectedHint: framework.Queue,
   135  		},
   136  		{
   137  			name: "skip-unrelated-change",
   138  			pod:  &v1.Pod{},
   139  			newObj: &v1.Node{
   140  				Spec: v1.NodeSpec{
   141  					Unschedulable: true,
   142  					Taints: []v1.Taint{
   143  						{
   144  							Key:    v1.TaintNodeNotReady,
   145  							Effect: v1.TaintEffectNoExecute,
   146  						},
   147  					},
   148  				},
   149  			},
   150  			oldObj: &v1.Node{
   151  				Spec: v1.NodeSpec{
   152  					Unschedulable: true,
   153  				},
   154  			},
   155  			expectedHint: framework.QueueSkip,
   156  		},
   157  		{
   158  			name: "queue-on-unschedulable-field-change",
   159  			pod:  &v1.Pod{},
   160  			newObj: &v1.Node{
   161  				Spec: v1.NodeSpec{
   162  					Unschedulable: false,
   163  				},
   164  			},
   165  			oldObj: &v1.Node{
   166  				Spec: v1.NodeSpec{
   167  					Unschedulable: true,
   168  				},
   169  			},
   170  			expectedHint: framework.Queue,
   171  		},
   172  	}
   173  
   174  	for _, testCase := range testCases {
   175  		t.Run(testCase.name, func(t *testing.T) {
   176  			logger, _ := ktesting.NewTestContext(t)
   177  			pl := &NodeUnschedulable{}
   178  			got, err := pl.isSchedulableAfterNodeChange(logger, testCase.pod, testCase.oldObj, testCase.newObj)
   179  			if err != nil && !testCase.expectedErr {
   180  				t.Errorf("unexpected error: %v", err)
   181  			}
   182  			if got != testCase.expectedHint {
   183  				t.Errorf("isSchedulableAfterNodeChange() = %v, want %v", got, testCase.expectedHint)
   184  			}
   185  		})
   186  	}
   187  }
   188  

View as plain text