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  }