...

Source file src/k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade/policy_test.go

Documentation: k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade

     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 upgrade
    18  
    19  import (
    20  	"testing"
    21  
    22  	"k8s.io/apimachinery/pkg/util/version"
    23  )
    24  
    25  func TestEnforceVersionPolicies(t *testing.T) {
    26  	minimumKubeletVersion := version.MustParseSemantic("v1.3.0")
    27  	minimumControlPlaneVersion := version.MustParseSemantic("v1.3.0")
    28  	currentKubernetesVersion := version.MustParseSemantic("v1.4.0")
    29  	tests := []struct {
    30  		name                        string
    31  		vg                          *fakeVersionGetter
    32  		expectedMandatoryErrs       int
    33  		expectedSkippableErrs       int
    34  		allowExperimental, allowRCs bool
    35  		newK8sVersion               string
    36  	}{
    37  		{
    38  			name: "minor upgrade",
    39  			vg: &fakeVersionGetter{
    40  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    41  				kubeletVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    42  				kubeadmVersion: minimumControlPlaneVersion.WithPatch(5).String(),
    43  			},
    44  			newK8sVersion: minimumControlPlaneVersion.WithPatch(5).String(),
    45  		},
    46  		{
    47  			name: "major upgrade",
    48  			vg: &fakeVersionGetter{
    49  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    50  				kubeletVersion: minimumControlPlaneVersion.WithPatch(2).String(),
    51  				kubeadmVersion: currentKubernetesVersion.WithPatch(1).String(),
    52  			},
    53  			newK8sVersion: currentKubernetesVersion.String(),
    54  		},
    55  		{
    56  			name: "downgrade",
    57  			vg: &fakeVersionGetter{
    58  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    59  				kubeletVersion: minimumKubeletVersion.String(),
    60  				kubeadmVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    61  			},
    62  			newK8sVersion: minimumControlPlaneVersion.WithPatch(2).String(),
    63  		},
    64  		{
    65  			name: "same version upgrade",
    66  			vg: &fakeVersionGetter{
    67  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    68  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
    69  				kubeadmVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    70  			},
    71  			newK8sVersion: minimumControlPlaneVersion.WithPatch(3).String(),
    72  		},
    73  		{
    74  			name: "new version must be higher than v1.12.0",
    75  			vg: &fakeVersionGetter{
    76  				clusterVersion: "v1.12.3",
    77  				kubeletVersion: "v1.12.3",
    78  				kubeadmVersion: "v1.12.3",
    79  			},
    80  			newK8sVersion:         "v1.10.10",
    81  			expectedMandatoryErrs: 1, // version must be higher than v1.12.0
    82  			expectedSkippableErrs: 1, // can't upgrade old k8s with newer kubeadm
    83  		},
    84  		{
    85  			name: "upgrading two minor versions in one go is not supported",
    86  			vg: &fakeVersionGetter{
    87  				clusterVersion: "v1.11.3",
    88  				kubeletVersion: "v1.11.3",
    89  				kubeadmVersion: "v1.13.0",
    90  			},
    91  			newK8sVersion:         "v1.13.0",
    92  			expectedMandatoryErrs: 1, // can't upgrade two minor versions
    93  		},
    94  		{
    95  			name: "upgrading with n-3 kubelet is supported",
    96  			vg: &fakeVersionGetter{
    97  				clusterVersion: "v1.14.3",
    98  				kubeletVersion: "v1.12.3",
    99  				kubeadmVersion: "v1.15.0",
   100  			},
   101  			newK8sVersion: "v1.15.0",
   102  		},
   103  		{
   104  			name: "upgrading with n-4 kubelet is not supported",
   105  			vg: &fakeVersionGetter{
   106  				clusterVersion: "v1.14.3",
   107  				kubeletVersion: "v1.11.3",
   108  				kubeadmVersion: "v1.15.0",
   109  			},
   110  			newK8sVersion:         "v1.15.0",
   111  			expectedSkippableErrs: 1, // kubelet <-> apiserver skew too large
   112  		},
   113  		{
   114  			name: "downgrading two minor versions in one go is not supported",
   115  			vg: &fakeVersionGetter{
   116  				clusterVersion: currentKubernetesVersion.WithMinor(currentKubernetesVersion.Minor() + 2).String(),
   117  				kubeletVersion: currentKubernetesVersion.WithMinor(currentKubernetesVersion.Minor() + 2).String(),
   118  				kubeadmVersion: currentKubernetesVersion.String(),
   119  			},
   120  			newK8sVersion:         currentKubernetesVersion.String(),
   121  			expectedMandatoryErrs: 1, // can't downgrade two minor versions
   122  		},
   123  		{
   124  			name: "kubeadm version must be higher than the new kube version. However, patch version skews may be forced",
   125  			vg: &fakeVersionGetter{
   126  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   127  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   128  				kubeadmVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   129  			},
   130  			newK8sVersion:         minimumControlPlaneVersion.WithPatch(5).String(),
   131  			expectedSkippableErrs: 1,
   132  		},
   133  		{
   134  			name: "kubeadm version must be higher than the new kube version. Trying to upgrade k8s to a higher minor version than kubeadm itself should never be supported",
   135  			vg: &fakeVersionGetter{
   136  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   137  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   138  				kubeadmVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   139  			},
   140  			newK8sVersion:         currentKubernetesVersion.String(),
   141  			expectedMandatoryErrs: 1,
   142  		},
   143  		{
   144  			name: "the maximum skew between the cluster version and the kubelet versions should be three minor version.",
   145  			vg: &fakeVersionGetter{
   146  				clusterVersion: "v1.13.0",
   147  				kubeletVersion: "v1.10.8",
   148  				kubeadmVersion: "v1.13.0",
   149  			},
   150  			newK8sVersion: "v1.13.0",
   151  		},
   152  		{
   153  			name: "the maximum skew between the cluster version and the kubelet versions should be three minor version. This may be forced through though.",
   154  			vg: &fakeVersionGetter{
   155  				clusterVersion: "v1.14.0",
   156  				kubeletVersion: "v1.10.8",
   157  				kubeadmVersion: "v1.14.0",
   158  			},
   159  			newK8sVersion:         "v1.14.0",
   160  			expectedSkippableErrs: 1,
   161  		},
   162  		{
   163  			name: "experimental upgrades supported if the flag is set",
   164  			vg: &fakeVersionGetter{
   165  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   166  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   167  				kubeadmVersion: currentKubernetesVersion.WithPreRelease("beta.1").String(),
   168  			},
   169  			newK8sVersion:     currentKubernetesVersion.WithPreRelease("beta.1").String(),
   170  			allowExperimental: true,
   171  		},
   172  		{
   173  			name: "release candidate upgrades supported if the flag is set",
   174  			vg: &fakeVersionGetter{
   175  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   176  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   177  				kubeadmVersion: currentKubernetesVersion.WithPreRelease("rc.1").String(),
   178  			},
   179  			newK8sVersion: currentKubernetesVersion.WithPreRelease("rc.1").String(),
   180  			allowRCs:      true,
   181  		},
   182  		{
   183  			name: "release candidate upgrades supported if the flag is set",
   184  			vg: &fakeVersionGetter{
   185  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   186  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   187  				kubeadmVersion: currentKubernetesVersion.WithPreRelease("rc.1").String(),
   188  			},
   189  			newK8sVersion:     currentKubernetesVersion.WithPreRelease("rc.1").String(),
   190  			allowExperimental: true,
   191  		},
   192  		{
   193  			name: "the user should not be able to upgrade to an experimental version if they haven't opted into that",
   194  			vg: &fakeVersionGetter{
   195  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   196  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   197  				kubeadmVersion: currentKubernetesVersion.WithPreRelease("beta.1").String(),
   198  			},
   199  			newK8sVersion:         currentKubernetesVersion.WithPreRelease("beta.1").String(),
   200  			allowRCs:              true,
   201  			expectedSkippableErrs: 1,
   202  		},
   203  		{
   204  			name: "the user should not be able to upgrade to an release candidate version if they haven't opted into that",
   205  			vg: &fakeVersionGetter{
   206  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   207  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   208  				kubeadmVersion: currentKubernetesVersion.WithPreRelease("rc.1").String(),
   209  			},
   210  			newK8sVersion:         currentKubernetesVersion.WithPreRelease("rc.1").String(),
   211  			expectedSkippableErrs: 1,
   212  		},
   213  		{
   214  			name: "the user can't use a newer minor version of kubeadm to upgrade an older version of kubeadm",
   215  			vg: &fakeVersionGetter{
   216  				clusterVersion: minimumControlPlaneVersion.WithPatch(3).String(),
   217  				kubeletVersion: minimumKubeletVersion.WithPatch(3).String(),
   218  				kubeadmVersion: currentKubernetesVersion.String(),
   219  			},
   220  			newK8sVersion:         minimumControlPlaneVersion.WithPatch(6).String(),
   221  			expectedSkippableErrs: 1, // can't upgrade old k8s with newer kubeadm
   222  		},
   223  		{
   224  			name: "build release supported at MinimumControlPlaneVersion",
   225  			vg: &fakeVersionGetter{
   226  				clusterVersion: minimumControlPlaneVersion.String(),
   227  				kubeletVersion: minimumControlPlaneVersion.String(),
   228  				kubeadmVersion: minimumControlPlaneVersion.WithBuildMetadata("build").String(),
   229  			},
   230  			newK8sVersion: minimumControlPlaneVersion.WithBuildMetadata("build").String(),
   231  		},
   232  	}
   233  
   234  	for _, rt := range tests {
   235  		t.Run(rt.name, func(t *testing.T) {
   236  
   237  			newK8sVer, err := version.ParseSemantic(rt.newK8sVersion)
   238  			if err != nil {
   239  				t.Fatalf("couldn't parse version %s: %v", rt.newK8sVersion, err)
   240  			}
   241  
   242  			actualSkewErrs := EnforceVersionPolicies(rt.vg, rt.newK8sVersion, newK8sVer, rt.allowExperimental, rt.allowRCs)
   243  			if actualSkewErrs == nil {
   244  				// No errors were seen. Report unit test failure if we expected to see errors
   245  				if rt.expectedMandatoryErrs+rt.expectedSkippableErrs > 0 {
   246  					t.Errorf("failed TestEnforceVersionPolicies\n\texpected errors but got none")
   247  				}
   248  				// Otherwise, just move on with the next test
   249  				return
   250  			}
   251  
   252  			if len(actualSkewErrs.Skippable) != rt.expectedSkippableErrs {
   253  				t.Errorf("failed TestEnforceVersionPolicies\n\texpected skippable errors: %d\n\tgot skippable errors: %d\n%#v\n%#v", rt.expectedSkippableErrs, len(actualSkewErrs.Skippable), *rt.vg, actualSkewErrs)
   254  			}
   255  			if len(actualSkewErrs.Mandatory) != rt.expectedMandatoryErrs {
   256  				t.Errorf("failed TestEnforceVersionPolicies\n\texpected mandatory errors: %d\n\tgot mandatory errors: %d\n%#v\n%#v", rt.expectedMandatoryErrs, len(actualSkewErrs.Mandatory), *rt.vg, actualSkewErrs)
   257  			}
   258  		})
   259  	}
   260  }
   261  

View as plain text