github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/releaseutil/kind_sorter_test.go (about) 1 /* 2 Copyright The Helm 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 releaseutil 18 19 import ( 20 "bytes" 21 "testing" 22 23 "github.com/stefanmcshane/helm/pkg/release" 24 ) 25 26 func TestKindSorter(t *testing.T) { 27 manifests := []Manifest{ 28 { 29 Name: "U", 30 Head: &SimpleHead{Kind: "IngressClass"}, 31 }, 32 { 33 Name: "E", 34 Head: &SimpleHead{Kind: "SecretList"}, 35 }, 36 { 37 Name: "i", 38 Head: &SimpleHead{Kind: "ClusterRole"}, 39 }, 40 { 41 Name: "I", 42 Head: &SimpleHead{Kind: "ClusterRoleList"}, 43 }, 44 { 45 Name: "j", 46 Head: &SimpleHead{Kind: "ClusterRoleBinding"}, 47 }, 48 { 49 Name: "J", 50 Head: &SimpleHead{Kind: "ClusterRoleBindingList"}, 51 }, 52 { 53 Name: "f", 54 Head: &SimpleHead{Kind: "ConfigMap"}, 55 }, 56 { 57 Name: "u", 58 Head: &SimpleHead{Kind: "CronJob"}, 59 }, 60 { 61 Name: "2", 62 Head: &SimpleHead{Kind: "CustomResourceDefinition"}, 63 }, 64 { 65 Name: "n", 66 Head: &SimpleHead{Kind: "DaemonSet"}, 67 }, 68 { 69 Name: "r", 70 Head: &SimpleHead{Kind: "Deployment"}, 71 }, 72 { 73 Name: "!", 74 Head: &SimpleHead{Kind: "HonkyTonkSet"}, 75 }, 76 { 77 Name: "v", 78 Head: &SimpleHead{Kind: "Ingress"}, 79 }, 80 { 81 Name: "t", 82 Head: &SimpleHead{Kind: "Job"}, 83 }, 84 { 85 Name: "c", 86 Head: &SimpleHead{Kind: "LimitRange"}, 87 }, 88 { 89 Name: "a", 90 Head: &SimpleHead{Kind: "Namespace"}, 91 }, 92 { 93 Name: "A", 94 Head: &SimpleHead{Kind: "NetworkPolicy"}, 95 }, 96 { 97 Name: "g", 98 Head: &SimpleHead{Kind: "PersistentVolume"}, 99 }, 100 { 101 Name: "h", 102 Head: &SimpleHead{Kind: "PersistentVolumeClaim"}, 103 }, 104 { 105 Name: "o", 106 Head: &SimpleHead{Kind: "Pod"}, 107 }, 108 { 109 Name: "3", 110 Head: &SimpleHead{Kind: "PodDisruptionBudget"}, 111 }, 112 { 113 Name: "C", 114 Head: &SimpleHead{Kind: "PodSecurityPolicy"}, 115 }, 116 { 117 Name: "q", 118 Head: &SimpleHead{Kind: "ReplicaSet"}, 119 }, 120 { 121 Name: "p", 122 Head: &SimpleHead{Kind: "ReplicationController"}, 123 }, 124 { 125 Name: "b", 126 Head: &SimpleHead{Kind: "ResourceQuota"}, 127 }, 128 { 129 Name: "k", 130 Head: &SimpleHead{Kind: "Role"}, 131 }, 132 { 133 Name: "K", 134 Head: &SimpleHead{Kind: "RoleList"}, 135 }, 136 { 137 Name: "l", 138 Head: &SimpleHead{Kind: "RoleBinding"}, 139 }, 140 { 141 Name: "L", 142 Head: &SimpleHead{Kind: "RoleBindingList"}, 143 }, 144 { 145 Name: "e", 146 Head: &SimpleHead{Kind: "Secret"}, 147 }, 148 { 149 Name: "m", 150 Head: &SimpleHead{Kind: "Service"}, 151 }, 152 { 153 Name: "d", 154 Head: &SimpleHead{Kind: "ServiceAccount"}, 155 }, 156 { 157 Name: "s", 158 Head: &SimpleHead{Kind: "StatefulSet"}, 159 }, 160 { 161 Name: "1", 162 Head: &SimpleHead{Kind: "StorageClass"}, 163 }, 164 { 165 Name: "w", 166 Head: &SimpleHead{Kind: "APIService"}, 167 }, 168 { 169 Name: "x", 170 Head: &SimpleHead{Kind: "HorizontalPodAutoscaler"}, 171 }, 172 } 173 174 for _, test := range []struct { 175 description string 176 order KindSortOrder 177 expected string 178 }{ 179 {"install", InstallOrder, "aAbcC3deEf1gh2iIjJkKlLmnopqrxstuUvw!"}, 180 {"uninstall", UninstallOrder, "wvUmutsxrqponLlKkJjIi2hg1fEed3CcbAa!"}, 181 } { 182 var buf bytes.Buffer 183 t.Run(test.description, func(t *testing.T) { 184 if got, want := len(test.expected), len(manifests); got != want { 185 t.Fatalf("Expected %d names in order, got %d", want, got) 186 } 187 defer buf.Reset() 188 orig := manifests 189 for _, r := range sortManifestsByKind(manifests, test.order) { 190 buf.WriteString(r.Name) 191 } 192 if got := buf.String(); got != test.expected { 193 t.Errorf("Expected %q, got %q", test.expected, got) 194 } 195 for i, manifest := range orig { 196 if manifest != manifests[i] { 197 t.Fatal("Expected input to sortManifestsByKind to stay the same") 198 } 199 } 200 }) 201 } 202 } 203 204 // TestKindSorterKeepOriginalOrder verifies manifests of same kind are kept in original order 205 func TestKindSorterKeepOriginalOrder(t *testing.T) { 206 manifests := []Manifest{ 207 { 208 Name: "a", 209 Head: &SimpleHead{Kind: "ClusterRole"}, 210 }, 211 { 212 Name: "A", 213 Head: &SimpleHead{Kind: "ClusterRole"}, 214 }, 215 { 216 Name: "0", 217 Head: &SimpleHead{Kind: "ConfigMap"}, 218 }, 219 { 220 Name: "1", 221 Head: &SimpleHead{Kind: "ConfigMap"}, 222 }, 223 { 224 Name: "z", 225 Head: &SimpleHead{Kind: "ClusterRoleBinding"}, 226 }, 227 { 228 Name: "!", 229 Head: &SimpleHead{Kind: "ClusterRoleBinding"}, 230 }, 231 { 232 Name: "u2", 233 Head: &SimpleHead{Kind: "Unknown"}, 234 }, 235 { 236 Name: "u1", 237 Head: &SimpleHead{Kind: "Unknown"}, 238 }, 239 { 240 Name: "t3", 241 Head: &SimpleHead{Kind: "Unknown2"}, 242 }, 243 } 244 for _, test := range []struct { 245 description string 246 order KindSortOrder 247 expected string 248 }{ 249 // expectation is sorted by kind (unknown is last) and within each group of same kind, the order is kept 250 {"cm,clusterRole,clusterRoleBinding,Unknown,Unknown2", InstallOrder, "01aAz!u2u1t3"}, 251 } { 252 var buf bytes.Buffer 253 t.Run(test.description, func(t *testing.T) { 254 defer buf.Reset() 255 for _, r := range sortManifestsByKind(manifests, test.order) { 256 buf.WriteString(r.Name) 257 } 258 if got := buf.String(); got != test.expected { 259 t.Errorf("Expected %q, got %q", test.expected, got) 260 } 261 }) 262 } 263 } 264 265 func TestKindSorterNamespaceAgainstUnknown(t *testing.T) { 266 unknown := Manifest{ 267 Name: "a", 268 Head: &SimpleHead{Kind: "Unknown"}, 269 } 270 namespace := Manifest{ 271 Name: "b", 272 Head: &SimpleHead{Kind: "Namespace"}, 273 } 274 275 manifests := []Manifest{unknown, namespace} 276 manifests = sortManifestsByKind(manifests, InstallOrder) 277 278 expectedOrder := []Manifest{namespace, unknown} 279 for i, manifest := range manifests { 280 if expectedOrder[i].Name != manifest.Name { 281 t.Errorf("Expected %s, got %s", expectedOrder[i].Name, manifest.Name) 282 } 283 } 284 } 285 286 // test hook sorting with a small subset of kinds, since it uses the same algorithm as sortManifestsByKind 287 func TestKindSorterForHooks(t *testing.T) { 288 hooks := []*release.Hook{ 289 { 290 Name: "i", 291 Kind: "ClusterRole", 292 }, 293 { 294 Name: "j", 295 Kind: "ClusterRoleBinding", 296 }, 297 { 298 Name: "c", 299 Kind: "LimitRange", 300 }, 301 { 302 Name: "a", 303 Kind: "Namespace", 304 }, 305 } 306 307 for _, test := range []struct { 308 description string 309 order KindSortOrder 310 expected string 311 }{ 312 {"install", InstallOrder, "acij"}, 313 {"uninstall", UninstallOrder, "jica"}, 314 } { 315 var buf bytes.Buffer 316 t.Run(test.description, func(t *testing.T) { 317 if got, want := len(test.expected), len(hooks); got != want { 318 t.Fatalf("Expected %d names in order, got %d", want, got) 319 } 320 defer buf.Reset() 321 orig := hooks 322 for _, r := range sortHooksByKind(hooks, test.order) { 323 buf.WriteString(r.Name) 324 } 325 for i, hook := range orig { 326 if hook != hooks[i] { 327 t.Fatal("Expected input to sortHooksByKind to stay the same") 328 } 329 } 330 if got := buf.String(); got != test.expected { 331 t.Errorf("Expected %q, got %q", test.expected, got) 332 } 333 }) 334 } 335 }