k8s.io/kubernetes@v1.29.3/pkg/kubelet/cm/topologymanager/policy_options_test.go (about) 1 /* 2 Copyright 2022 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 topologymanager 18 19 import ( 20 "fmt" 21 "strings" 22 "testing" 23 24 "k8s.io/apimachinery/pkg/util/sets" 25 utilfeature "k8s.io/apiserver/pkg/util/feature" 26 "k8s.io/component-base/featuregate" 27 featuregatetesting "k8s.io/component-base/featuregate/testing" 28 pkgfeatures "k8s.io/kubernetes/pkg/features" 29 ) 30 31 var fancyBetaOption = "fancy-new-option" 32 var fancyAlphaOption = "fancy-alpha-option" 33 34 type optionAvailTest struct { 35 option string 36 featureGate featuregate.Feature 37 featureGateEnable bool 38 expectedAvailable bool 39 } 40 41 func TestNewTopologyManagerOptions(t *testing.T) { 42 testCases := []struct { 43 description string 44 policyOptions map[string]string 45 featureGate featuregate.Feature 46 featureGateEnable bool 47 expectedErr error 48 expectedOptions PolicyOptions 49 }{ 50 { 51 description: "return TopologyManagerOptions with PreferClosestNUMA set to true", 52 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 53 featureGateEnable: true, 54 expectedOptions: PolicyOptions{ 55 PreferClosestNUMA: true, 56 }, 57 policyOptions: map[string]string{ 58 PreferClosestNUMANodes: "true", 59 }, 60 }, 61 { 62 description: "fail to set option when TopologyManagerPolicyBetaOptions feature gate is not set", 63 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 64 policyOptions: map[string]string{ 65 PreferClosestNUMANodes: "true", 66 }, 67 expectedErr: fmt.Errorf("Topology Manager Policy Beta-level Options not enabled,"), 68 }, 69 { 70 description: "return empty TopologyManagerOptions", 71 }, 72 { 73 description: "fail to parse options", 74 featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, 75 featureGateEnable: true, 76 policyOptions: map[string]string{ 77 PreferClosestNUMANodes: "not a boolean", 78 }, 79 expectedErr: fmt.Errorf("bad value for option"), 80 }, 81 { 82 description: "test beta options success", 83 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 84 featureGateEnable: true, 85 policyOptions: map[string]string{ 86 fancyBetaOption: "true", 87 }, 88 }, 89 { 90 description: "test beta options fail", 91 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 92 policyOptions: map[string]string{ 93 fancyBetaOption: "true", 94 }, 95 expectedErr: fmt.Errorf("Topology Manager Policy Beta-level Options not enabled,"), 96 }, 97 { 98 description: "test alpha options success", 99 featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, 100 featureGateEnable: true, 101 policyOptions: map[string]string{ 102 fancyAlphaOption: "true", 103 }, 104 }, 105 { 106 description: "test alpha options fail", 107 policyOptions: map[string]string{ 108 fancyAlphaOption: "true", 109 }, 110 expectedErr: fmt.Errorf("Topology Manager Policy Alpha-level Options not enabled,"), 111 }, 112 } 113 114 betaOptions.Insert(fancyBetaOption) 115 alphaOptions = sets.New[string](fancyAlphaOption) 116 117 for _, tcase := range testCases { 118 t.Run(tcase.description, func(t *testing.T) { 119 if tcase.featureGate != "" { 120 defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, tcase.featureGate, tcase.featureGateEnable)() 121 } 122 opts, err := NewPolicyOptions(tcase.policyOptions) 123 if tcase.expectedErr != nil { 124 if !strings.Contains(err.Error(), tcase.expectedErr.Error()) { 125 t.Errorf("Unexpected error message. Have: %s wants %s", err.Error(), tcase.expectedErr.Error()) 126 } 127 } 128 129 if opts != tcase.expectedOptions { 130 t.Errorf("Expected TopologyManagerOptions to equal %v, not %v", tcase.expectedOptions, opts) 131 132 } 133 }) 134 } 135 } 136 137 func TestPolicyDefaultsAvailable(t *testing.T) { 138 testCases := []optionAvailTest{ 139 { 140 option: "this-option-does-not-exist", 141 expectedAvailable: false, 142 }, 143 { 144 option: PreferClosestNUMANodes, 145 expectedAvailable: true, 146 }, 147 } 148 for _, testCase := range testCases { 149 t.Run(testCase.option, func(t *testing.T) { 150 err := CheckPolicyOptionAvailable(testCase.option) 151 isEnabled := (err == nil) 152 if isEnabled != testCase.expectedAvailable { 153 t.Errorf("option %q available got=%v expected=%v", testCase.option, isEnabled, testCase.expectedAvailable) 154 } 155 }) 156 } 157 } 158 159 func TestPolicyOptionsAvailable(t *testing.T) { 160 testCases := []optionAvailTest{ 161 { 162 option: "this-option-does-not-exist", 163 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 164 featureGateEnable: false, 165 expectedAvailable: false, 166 }, 167 { 168 option: "this-option-does-not-exist", 169 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 170 featureGateEnable: true, 171 expectedAvailable: false, 172 }, 173 { 174 option: PreferClosestNUMANodes, 175 featureGate: pkgfeatures.TopologyManagerPolicyBetaOptions, 176 featureGateEnable: true, 177 expectedAvailable: true, 178 }, 179 { 180 option: PreferClosestNUMANodes, 181 featureGate: pkgfeatures.TopologyManagerPolicyAlphaOptions, 182 featureGateEnable: false, 183 expectedAvailable: true, 184 }, 185 } 186 for _, testCase := range testCases { 187 t.Run(testCase.option, func(t *testing.T) { 188 defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, testCase.featureGate, testCase.featureGateEnable)() 189 err := CheckPolicyOptionAvailable(testCase.option) 190 isEnabled := (err == nil) 191 if isEnabled != testCase.expectedAvailable { 192 t.Errorf("option %q available got=%v expected=%v", testCase.option, isEnabled, testCase.expectedAvailable) 193 } 194 }) 195 } 196 }