...

Source file src/k8s.io/kubectl/pkg/cmd/create/create_pdb_test.go

Documentation: k8s.io/kubectl/pkg/cmd/create

     1  /*
     2  Copyright 2017 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 create
    18  
    19  import (
    20  	"testing"
    21  
    22  	policyv1 "k8s.io/api/policy/v1"
    23  	apiequality "k8s.io/apimachinery/pkg/api/equality"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/intstr"
    26  )
    27  
    28  func TestCreatePdbValidation(t *testing.T) {
    29  	selectorOpts := "app=nginx"
    30  	podAmountNumber := "3"
    31  	podAmountPercent := "50%"
    32  
    33  	tests := map[string]struct {
    34  		options  *PodDisruptionBudgetOpts
    35  		expected string
    36  	}{
    37  		"test-missing-name-param": {
    38  			options: &PodDisruptionBudgetOpts{
    39  				Selector:     selectorOpts,
    40  				MinAvailable: podAmountNumber,
    41  			},
    42  			expected: "name must be specified",
    43  		},
    44  		"test-missing-selector-param": {
    45  			options: &PodDisruptionBudgetOpts{
    46  				Name:         "my-pdb",
    47  				MinAvailable: podAmountNumber,
    48  			},
    49  			expected: "a selector must be specified",
    50  		},
    51  		"test-missing-max-unavailable-max-unavailable-param": {
    52  			options: &PodDisruptionBudgetOpts{
    53  				Name:     "my-pdb",
    54  				Selector: selectorOpts,
    55  			},
    56  			expected: "one of min-available or max-unavailable must be specified",
    57  		},
    58  		"test-both-min-available-max-unavailable-param": {
    59  			options: &PodDisruptionBudgetOpts{
    60  				Name:           "my-pdb",
    61  				Selector:       selectorOpts,
    62  				MinAvailable:   podAmountNumber,
    63  				MaxUnavailable: podAmountPercent,
    64  			},
    65  			expected: "min-available and max-unavailable cannot be both specified",
    66  		},
    67  		"test-invalid-min-available-format": {
    68  			options: &PodDisruptionBudgetOpts{
    69  				Name:         "my-pdb",
    70  				Selector:     selectorOpts,
    71  				MinAvailable: "10GB",
    72  			},
    73  			expected: "invalid format specified for min-available",
    74  		},
    75  		"test-invalid-max-unavailable-format": {
    76  			options: &PodDisruptionBudgetOpts{
    77  				Name:           "my-pdb",
    78  				Selector:       selectorOpts,
    79  				MaxUnavailable: "10GB",
    80  			},
    81  			expected: "invalid format specified for max-unavailable",
    82  		},
    83  		"test-valid-min-available-format": {
    84  			options: &PodDisruptionBudgetOpts{
    85  				Name:           "my-pdb",
    86  				Selector:       selectorOpts,
    87  				MaxUnavailable: podAmountNumber,
    88  			},
    89  			expected: "",
    90  		},
    91  		"test-valid-max-unavailable-format": {
    92  			options: &PodDisruptionBudgetOpts{
    93  				Name:           "my-pdb",
    94  				Selector:       selectorOpts,
    95  				MaxUnavailable: podAmountPercent,
    96  			},
    97  			expected: "",
    98  		},
    99  	}
   100  
   101  	for name, tc := range tests {
   102  		t.Run(name, func(t *testing.T) {
   103  
   104  			o := &PodDisruptionBudgetOpts{
   105  				Name:           tc.options.Name,
   106  				Selector:       tc.options.Selector,
   107  				MinAvailable:   tc.options.MinAvailable,
   108  				MaxUnavailable: tc.options.MaxUnavailable,
   109  			}
   110  
   111  			err := o.Validate()
   112  			if err != nil && err.Error() != tc.expected {
   113  				t.Errorf("unexpected error: %v", err)
   114  			}
   115  			if tc.expected != "" && err == nil {
   116  				t.Errorf("expected error, got no error")
   117  			}
   118  		})
   119  	}
   120  }
   121  
   122  func TestCreatePdb(t *testing.T) {
   123  	selectorOpts := "app=nginx"
   124  	podAmountNumber := "3"
   125  	podAmountPercent := "50%"
   126  
   127  	selector, err := metav1.ParseToLabelSelector(selectorOpts)
   128  	if err != nil {
   129  		t.Errorf("unexpected error: %v", err)
   130  	}
   131  
   132  	minAvailableNumber := intstr.Parse(podAmountNumber)
   133  	minAvailablePercent := intstr.Parse(podAmountPercent)
   134  
   135  	maxUnavailableNumber := intstr.Parse(podAmountNumber)
   136  	maxUnavailablePercent := intstr.Parse(podAmountPercent)
   137  
   138  	tests := map[string]struct {
   139  		options  *PodDisruptionBudgetOpts
   140  		expected *policyv1.PodDisruptionBudget
   141  	}{
   142  		"test-valid-min-available-pods-number": {
   143  			options: &PodDisruptionBudgetOpts{
   144  				Name:         "my-pdb",
   145  				Selector:     selectorOpts,
   146  				MinAvailable: podAmountNumber,
   147  			},
   148  			expected: &policyv1.PodDisruptionBudget{
   149  				TypeMeta: metav1.TypeMeta{
   150  					Kind:       "PodDisruptionBudget",
   151  					APIVersion: "policy/v1",
   152  				},
   153  				ObjectMeta: metav1.ObjectMeta{
   154  					Name: "my-pdb",
   155  				},
   156  				Spec: policyv1.PodDisruptionBudgetSpec{
   157  					Selector:     selector,
   158  					MinAvailable: &minAvailableNumber,
   159  				},
   160  			},
   161  		},
   162  		"test-valid-min-available-pods-percentage": {
   163  			options: &PodDisruptionBudgetOpts{
   164  				Name:         "my-pdb",
   165  				Selector:     selectorOpts,
   166  				MinAvailable: podAmountPercent,
   167  			},
   168  			expected: &policyv1.PodDisruptionBudget{
   169  				TypeMeta: metav1.TypeMeta{
   170  					Kind:       "PodDisruptionBudget",
   171  					APIVersion: "policy/v1",
   172  				},
   173  				ObjectMeta: metav1.ObjectMeta{
   174  					Name: "my-pdb",
   175  				},
   176  				Spec: policyv1.PodDisruptionBudgetSpec{
   177  					Selector:     selector,
   178  					MinAvailable: &minAvailablePercent,
   179  				},
   180  			},
   181  		},
   182  		"test-valid-max-unavailable-pods-number": {
   183  			options: &PodDisruptionBudgetOpts{
   184  				Name:           "my-pdb",
   185  				Selector:       selectorOpts,
   186  				MaxUnavailable: podAmountNumber,
   187  			},
   188  			expected: &policyv1.PodDisruptionBudget{
   189  				TypeMeta: metav1.TypeMeta{
   190  					Kind:       "PodDisruptionBudget",
   191  					APIVersion: "policy/v1",
   192  				},
   193  				ObjectMeta: metav1.ObjectMeta{
   194  					Name: "my-pdb",
   195  				},
   196  				Spec: policyv1.PodDisruptionBudgetSpec{
   197  					Selector:       selector,
   198  					MaxUnavailable: &maxUnavailableNumber,
   199  				},
   200  			},
   201  		},
   202  		"test-valid-max-unavailable-pods-percentage": {
   203  			options: &PodDisruptionBudgetOpts{
   204  				Name:           "my-pdb",
   205  				Selector:       selectorOpts,
   206  				MaxUnavailable: podAmountPercent,
   207  			},
   208  			expected: &policyv1.PodDisruptionBudget{
   209  				TypeMeta: metav1.TypeMeta{
   210  					Kind:       "PodDisruptionBudget",
   211  					APIVersion: "policy/v1",
   212  				},
   213  				ObjectMeta: metav1.ObjectMeta{
   214  					Name: "my-pdb",
   215  				},
   216  				Spec: policyv1.PodDisruptionBudgetSpec{
   217  					Selector:       selector,
   218  					MaxUnavailable: &maxUnavailablePercent,
   219  				},
   220  			},
   221  		},
   222  	}
   223  
   224  	for name, tc := range tests {
   225  		t.Run(name, func(t *testing.T) {
   226  
   227  			podDisruptionBudget, err := tc.options.createPodDisruptionBudgets()
   228  			if err != nil {
   229  				t.Errorf("unexpected error:\n%#v\n", err)
   230  				return
   231  			}
   232  			if !apiequality.Semantic.DeepEqual(podDisruptionBudget, tc.expected) {
   233  				t.Errorf("expected:\n%#v\ngot:\n%#v", tc.expected, podDisruptionBudget)
   234  			}
   235  		})
   236  	}
   237  }
   238  

View as plain text