github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/cse_util_unit_test.go (about) 1 //go:build unit || ALL 2 3 /* 4 * Copyright 2024 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 5 */ 6 7 package govcd 8 9 import ( 10 semver "github.com/hashicorp/go-version" 11 "github.com/vmware/go-vcloud-director/v2/types/v56" 12 "reflect" 13 "testing" 14 ) 15 16 func Test_getCseComponentsVersions(t *testing.T) { 17 tests := []struct { 18 name string 19 cseVersion string 20 want *cseComponentsVersions 21 wantErr bool 22 }{ 23 { 24 name: "CSE 4.0 is not supported", 25 cseVersion: "4.0", 26 wantErr: true, 27 }, 28 { 29 name: "CSE 4.1 is supported", 30 cseVersion: "4.1", 31 want: &cseComponentsVersions{ 32 VcdKeConfigRdeTypeVersion: "1.1.0", 33 CapvcdRdeTypeVersion: "1.2.0", 34 CseInterfaceVersion: "1.0.0", 35 }, 36 wantErr: false, 37 }, 38 { 39 name: "CSE 4.1.1 is supported", 40 cseVersion: "4.1.1", 41 want: &cseComponentsVersions{ 42 VcdKeConfigRdeTypeVersion: "1.1.0", 43 CapvcdRdeTypeVersion: "1.2.0", 44 CseInterfaceVersion: "1.0.0", 45 }, 46 wantErr: false, 47 }, 48 { 49 name: "CSE 4.1.1a is equivalent to 4.1.1", 50 cseVersion: "4.1.1a", 51 want: &cseComponentsVersions{ 52 VcdKeConfigRdeTypeVersion: "1.1.0", 53 CapvcdRdeTypeVersion: "1.2.0", 54 CseInterfaceVersion: "1.0.0", 55 }, 56 wantErr: false, 57 }, 58 { 59 name: "CSE 4.2 is supported", 60 cseVersion: "4.2", 61 want: &cseComponentsVersions{ 62 VcdKeConfigRdeTypeVersion: "1.1.0", 63 CapvcdRdeTypeVersion: "1.3.0", 64 CseInterfaceVersion: "1.0.0", 65 }, 66 wantErr: false, 67 }, 68 { 69 name: "CSE 4.3 is not supported", 70 cseVersion: "4.3", 71 wantErr: true, 72 }, 73 } 74 for _, tt := range tests { 75 t.Run(tt.name, func(t *testing.T) { 76 version, err := semver.NewVersion(tt.cseVersion) 77 if err != nil { 78 t.Fatalf("could not parse test version: %s", err) 79 } 80 got, err := getCseComponentsVersions(*version) 81 if (err != nil) != tt.wantErr { 82 t.Errorf("getCseComponentsVersions() error = %v, wantErr %v", err, tt.wantErr) 83 return 84 } 85 if !reflect.DeepEqual(got, tt.want) { 86 t.Errorf("getCseComponentsVersions() got = %v, want %v", got, tt.want) 87 } 88 }) 89 } 90 } 91 92 // Test_getTkgVersionBundleFromVAppTemplate tests getTkgVersionBundleFromVAppTemplate function 93 func Test_getTkgVersionBundleFromVAppTemplate(t *testing.T) { 94 tests := []struct { 95 name string 96 kubernetesTemplateOva *types.VAppTemplate 97 want tkgVersionBundle 98 wantErr string 99 }{ 100 { 101 name: "ova is nil", 102 kubernetesTemplateOva: nil, 103 wantErr: "the Kubernetes Template OVA is nil", 104 }, 105 { 106 name: "ova without children", 107 kubernetesTemplateOva: &types.VAppTemplate{ 108 Name: "dummy", 109 Children: nil, 110 }, 111 wantErr: "the Kubernetes Template OVA 'dummy' doesn't have any child VM", 112 }, 113 { 114 name: "ova with nil children", 115 kubernetesTemplateOva: &types.VAppTemplate{ 116 Name: "dummy", 117 Children: &types.VAppTemplateChildren{VM: nil}, 118 }, 119 wantErr: "the Kubernetes Template OVA 'dummy' doesn't have any child VM", 120 }, 121 { 122 name: "ova with nil product section", 123 kubernetesTemplateOva: &types.VAppTemplate{ 124 Name: "dummy", 125 Children: &types.VAppTemplateChildren{VM: []*types.VAppTemplate{ 126 { 127 ProductSection: nil, 128 }, 129 }}, 130 }, 131 wantErr: "the Product section of the Kubernetes Template OVA 'dummy' is empty, can't proceed", 132 }, 133 { 134 name: "ova with no version in the product section", 135 kubernetesTemplateOva: &types.VAppTemplate{ 136 Name: "dummy", 137 Children: &types.VAppTemplateChildren{VM: []*types.VAppTemplate{ 138 { 139 ProductSection: &types.ProductSection{ 140 Property: []*types.Property{ 141 { 142 Key: "foo", 143 DefaultValue: "bar", 144 }, 145 }, 146 }, 147 }, 148 }}, 149 }, 150 wantErr: "could not find any VERSION property inside the Kubernetes Template OVA 'dummy' Product section", 151 }, 152 { 153 name: "correct ova", 154 kubernetesTemplateOva: &types.VAppTemplate{ 155 Name: "dummy", 156 Children: &types.VAppTemplateChildren{VM: []*types.VAppTemplate{ 157 { 158 ProductSection: &types.ProductSection{ 159 Property: []*types.Property{ 160 { 161 Key: "VERSION", 162 DefaultValue: "v1.25.7+vmware.2-tkg.1-8a74b9f12e488c54605b3537acb683bc", 163 }, 164 }, 165 }, 166 }, 167 }}, 168 }, 169 want: tkgVersionBundle{ 170 EtcdVersion: "v3.5.6_vmware.9", 171 CoreDnsVersion: "v1.9.3_vmware.8", 172 TkgVersion: "v2.2.0", 173 TkrVersion: "v1.25.7---vmware.2-tkg.1", 174 KubernetesVersion: "v1.25.7+vmware.2", 175 }, 176 }, 177 } 178 for _, tt := range tests { 179 t.Run(tt.name, func(t *testing.T) { 180 got, err := getTkgVersionBundleFromVAppTemplate(tt.kubernetesTemplateOva) 181 if err != nil { 182 if tt.wantErr != err.Error() { 183 t.Errorf("getTkgVersionBundleFromVAppTemplate() error = %v, wantErr = %v", err, tt.wantErr) 184 } 185 return 186 } 187 if !reflect.DeepEqual(got, tt.want) { 188 t.Errorf("getTkgVersionBundleFromVAppTemplate() got = %v, want %v", got, tt.want) 189 } 190 }) 191 } 192 } 193 194 func Test_tkgVersionBundle_compareTkgVersion(t *testing.T) { 195 tests := []struct { 196 name string 197 receiverTkgVersion string 198 comparedTkgVersion string 199 want int 200 }{ 201 { 202 name: "same TKG version", 203 receiverTkgVersion: "v1.4.3", 204 comparedTkgVersion: "v1.4.3", 205 want: 0, 206 }, 207 { 208 name: "receiver TKG version is higher", 209 receiverTkgVersion: "v1.4.4", 210 comparedTkgVersion: "v1.4.3", 211 want: 1, 212 }, 213 { 214 name: "receiver TKG version is lower", 215 receiverTkgVersion: "v1.4.2", 216 comparedTkgVersion: "v1.4.3", 217 want: -1, 218 }, 219 { 220 name: "receiver TKG version is wrong", 221 receiverTkgVersion: "foo", 222 comparedTkgVersion: "v1.4.3", 223 want: -2, 224 }, 225 { 226 name: "compared TKG version is wrong", 227 receiverTkgVersion: "v1.4.3", 228 comparedTkgVersion: "foo", 229 want: -2, 230 }, 231 } 232 for _, tt := range tests { 233 t.Run(tt.name, func(t *testing.T) { 234 tkgVersions := tkgVersionBundle{ 235 TkgVersion: tt.receiverTkgVersion, 236 } 237 if got := tkgVersions.compareTkgVersion(tt.comparedTkgVersion); got != tt.want { 238 t.Errorf("compareTkgVersion() = %v, want %v", got, tt.want) 239 } 240 }) 241 } 242 } 243 244 func Test_tkgVersionBundle_kubernetesVersionIsUpgradeableFrom(t *testing.T) { 245 tests := []struct { 246 name string 247 upgradeToVersion string 248 fromVersion string 249 want bool 250 }{ 251 { 252 name: "same Kubernetes versions", 253 upgradeToVersion: "1.20.2+vmware.1", 254 fromVersion: "1.20.2+vmware.1", 255 want: false, 256 }, 257 { 258 name: "the Kubernetes patch is higher", 259 upgradeToVersion: "1.21.9+vmware.1", 260 fromVersion: "1.21.7+vmware.1", 261 want: true, 262 }, 263 { 264 name: "one Kubernetes minor higher", 265 upgradeToVersion: "1.21.9+vmware.1", 266 fromVersion: "1.20.2+vmware.1", 267 want: true, 268 }, 269 { 270 name: "the Kubernetes patch is lower", 271 upgradeToVersion: "1.20.0+vmware.1", 272 fromVersion: "1.20.7+vmware.1", 273 want: false, 274 }, 275 { 276 name: "one Kubernetes minor lower", 277 upgradeToVersion: "1.19.9+vmware.1", 278 fromVersion: "1.20.2+vmware.1", 279 want: false, 280 }, 281 { 282 name: "several Kubernetes minors higher", 283 upgradeToVersion: "1.22.9+vmware.1", 284 fromVersion: "1.20.2+vmware.1", 285 want: false, 286 }, 287 { 288 name: "wrong receiver Kubernetes version", 289 upgradeToVersion: "foo", 290 fromVersion: "1.20.2+vmware.1", 291 want: false, 292 }, 293 { 294 name: "wrong compared Kubernetes version", 295 upgradeToVersion: "1.20.2+vmware.1", 296 fromVersion: "foo", 297 want: false, 298 }, 299 } 300 for _, tt := range tests { 301 t.Run(tt.name, func(t *testing.T) { 302 tkgVersions := tkgVersionBundle{ 303 KubernetesVersion: tt.upgradeToVersion, 304 } 305 if got := tkgVersions.kubernetesVersionIsUpgradeableFrom(tt.fromVersion); got != tt.want { 306 t.Errorf("kubernetesVersionIsUpgradeableFrom() = %v, want %v", got, tt.want) 307 } 308 }) 309 } 310 } 311 312 func Test_getCseTemplate(t *testing.T) { 313 v40, err := semver.NewVersion("4.0") 314 if err != nil { 315 t.Fatalf("could not create 4.0 version object") 316 } 317 v41, err := semver.NewVersion("4.1") 318 if err != nil { 319 t.Fatalf("could not create 4.1 version object") 320 } 321 v410, err := semver.NewVersion("4.1.0") 322 if err != nil { 323 t.Fatalf("could not create 4.1.0 version object") 324 } 325 v411, err := semver.NewVersion("4.1.1") 326 if err != nil { 327 t.Fatalf("could not create 4.1.1 version object") 328 } 329 v421, err := semver.NewVersion("4.2.1") 330 if err != nil { 331 t.Fatalf("could not create 4.2.1 version object") 332 } 333 334 tmpl41, err := getCseTemplate(*v41, "rde") 335 if err != nil { 336 t.Fatal(err) 337 } 338 tmpl410, err := getCseTemplate(*v410, "rde") 339 if err != nil { 340 t.Fatal(err) 341 } 342 tmpl411, err := getCseTemplate(*v411, "rde") 343 if err != nil { 344 t.Fatal(err) 345 } 346 if tmpl41 == "" || tmpl41 != tmpl410 || tmpl41 != tmpl411 || tmpl410 != tmpl411 { 347 t.Fatalf("templates should be the same:\n4.1: %s\n4.1.0: %s\n4.1.1: %s", tmpl41, tmpl410, tmpl411) 348 } 349 350 tmpl420, err := getCseTemplate(*v421, "rde") 351 if err != nil { 352 t.Fatal(err) 353 } 354 if tmpl420 == "" { 355 t.Fatalf("the obtained template for %s is empty", v421.String()) 356 } 357 358 _, err = getCseTemplate(*v40, "rde") 359 if err == nil && err.Error() != "the Container Service minimum version is '4.1.0'" { 360 t.Fatalf("expected an error but got %s", err) 361 } 362 }