sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/services/resourceskus/cache_test.go (about)

     1  /*
     2  Copyright 2020 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 resourceskus
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
    24  	"github.com/google/go-cmp/cmp"
    25  	"github.com/google/go-cmp/cmp/cmpopts"
    26  	"k8s.io/utils/ptr"
    27  )
    28  
    29  func TestCacheGet(t *testing.T) {
    30  	cases := map[string]struct {
    31  		sku          string
    32  		location     string
    33  		resourceType ResourceType
    34  		have         []armcompute.ResourceSKU
    35  		err          string
    36  	}{
    37  		"should find": {
    38  			sku:          "foo",
    39  			location:     "test",
    40  			resourceType: "bar",
    41  			have: []armcompute.ResourceSKU{
    42  				{
    43  					Name:         ptr.To("other"),
    44  					ResourceType: ptr.To("baz"),
    45  				},
    46  				{
    47  					Name:         ptr.To("foo"),
    48  					ResourceType: ptr.To("bar"),
    49  				},
    50  			},
    51  		},
    52  		"should not find": {
    53  			sku:          "foo",
    54  			location:     "test",
    55  			resourceType: "bar",
    56  			have: []armcompute.ResourceSKU{
    57  				{
    58  					Name: ptr.To("other"),
    59  				},
    60  			},
    61  			err: "reconcile error that cannot be recovered occurred: resource sku with name 'foo' and category 'bar' not found in location 'test'. Object will not be requeued",
    62  		},
    63  	}
    64  
    65  	for name, tc := range cases {
    66  		tc := tc
    67  		t.Run(name, func(t *testing.T) {
    68  			t.Parallel()
    69  
    70  			cache := &Cache{
    71  				data:     tc.have,
    72  				location: tc.location,
    73  			}
    74  
    75  			val, err := cache.Get(context.Background(), tc.sku, tc.resourceType)
    76  			if tc.err != "" {
    77  				if err == nil {
    78  					t.Fatalf("expected cache.get to fail with error %s, but actual error was nil", tc.err)
    79  					return
    80  				}
    81  				if err.Error() != tc.err {
    82  					t.Fatalf("expected cache.get to fail with error %s, but actual error was %s", tc.err, err.Error())
    83  					return
    84  				}
    85  			} else {
    86  				if val.Name == nil {
    87  					t.Fatalf("expected name to be %s, but was nil", tc.sku)
    88  					return
    89  				}
    90  				if *val.Name != tc.sku {
    91  					t.Fatalf("expected name to be %s, but was %s", tc.sku, *val.Name)
    92  				}
    93  				if val.ResourceType == nil {
    94  					t.Fatalf("expected name to be %s, but was nil", tc.sku)
    95  					return
    96  				}
    97  				if *val.ResourceType != string(tc.resourceType) {
    98  					t.Fatalf("expected kind to be %s, but was %s", tc.resourceType, *val.ResourceType)
    99  				}
   100  			}
   101  		})
   102  	}
   103  }
   104  
   105  func TestCacheGetZones(t *testing.T) {
   106  	cases := map[string]struct {
   107  		have []armcompute.ResourceSKU
   108  		want []string
   109  	}{
   110  		"should find 1 result": {
   111  			have: []armcompute.ResourceSKU{
   112  				{
   113  					Name:         ptr.To("foo"),
   114  					ResourceType: ptr.To(string(VirtualMachines)),
   115  					Locations: []*string{
   116  						ptr.To("baz"),
   117  					},
   118  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   119  						{
   120  							Location: ptr.To("baz"),
   121  							Zones:    []*string{ptr.To("1")},
   122  						},
   123  					},
   124  				},
   125  			},
   126  			want: []string{"1"},
   127  		},
   128  		"should find 2 results": {
   129  			have: []armcompute.ResourceSKU{
   130  				{
   131  					Name:         ptr.To("foo"),
   132  					ResourceType: ptr.To(string(VirtualMachines)),
   133  					Locations: []*string{
   134  						ptr.To("baz"),
   135  					},
   136  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   137  						{
   138  							Location: ptr.To("baz"),
   139  							Zones:    []*string{ptr.To("1")},
   140  						},
   141  					},
   142  				},
   143  				{
   144  					Name:         ptr.To("foo"),
   145  					ResourceType: ptr.To(string(VirtualMachines)),
   146  					Locations: []*string{
   147  						ptr.To("baz"),
   148  					},
   149  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   150  						{
   151  							Location: ptr.To("baz"),
   152  							Zones:    []*string{ptr.To("2")},
   153  						},
   154  					},
   155  				},
   156  			},
   157  			want: []string{"1", "2"},
   158  		},
   159  		"should not find due to location mismatch": {
   160  			have: []armcompute.ResourceSKU{
   161  				{
   162  					Name:         ptr.To("foo"),
   163  					ResourceType: ptr.To(string(VirtualMachines)),
   164  					Locations: []*string{
   165  						ptr.To("foobar"),
   166  					},
   167  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   168  						{
   169  							Location: ptr.To("foobar"),
   170  							Zones:    []*string{ptr.To("1")},
   171  						},
   172  					},
   173  				},
   174  			},
   175  			want: nil,
   176  		},
   177  		"should not find due to location restriction": {
   178  			have: []armcompute.ResourceSKU{
   179  				{
   180  					Name:         ptr.To("foo"),
   181  					ResourceType: ptr.To(string(VirtualMachines)),
   182  					Locations: []*string{
   183  						ptr.To("baz"),
   184  					},
   185  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   186  						{
   187  							Location: ptr.To("baz"),
   188  							Zones:    []*string{ptr.To("1")},
   189  						},
   190  					},
   191  					Restrictions: []*armcompute.ResourceSKURestrictions{
   192  						{
   193  							Type:   ptr.To(armcompute.ResourceSKURestrictionsTypeLocation),
   194  							Values: []*string{ptr.To("baz")},
   195  						},
   196  					},
   197  				},
   198  			},
   199  			want: nil,
   200  		},
   201  		"should not find due to zone restriction": {
   202  			have: []armcompute.ResourceSKU{
   203  				{
   204  					Name:         ptr.To("foo"),
   205  					ResourceType: ptr.To(string(VirtualMachines)),
   206  					Locations: []*string{
   207  						ptr.To("baz"),
   208  					},
   209  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   210  						{
   211  							Location: ptr.To("baz"),
   212  							Zones:    []*string{ptr.To("1")},
   213  						},
   214  					},
   215  					Restrictions: []*armcompute.ResourceSKURestrictions{
   216  						{
   217  							Type: ptr.To(armcompute.ResourceSKURestrictionsTypeZone),
   218  							RestrictionInfo: &armcompute.ResourceSKURestrictionInfo{
   219  								Zones: []*string{ptr.To("1")},
   220  							},
   221  						},
   222  					},
   223  				},
   224  			},
   225  			want: nil,
   226  		},
   227  	}
   228  
   229  	for name, tc := range cases {
   230  		tc := tc
   231  		t.Run(name, func(t *testing.T) {
   232  			t.Parallel()
   233  
   234  			cache := &Cache{
   235  				data: tc.have,
   236  			}
   237  
   238  			zones, err := cache.GetZones(context.Background(), "baz")
   239  			if err != nil {
   240  				t.Error(err)
   241  			}
   242  			if diff := cmp.Diff(zones, tc.want, []cmp.Option{cmpopts.EquateEmpty()}...); diff != "" {
   243  				t.Errorf(diff)
   244  			}
   245  		})
   246  	}
   247  }
   248  
   249  func TestCacheGetZonesWithVMSize(t *testing.T) {
   250  	cases := map[string]struct {
   251  		have []armcompute.ResourceSKU
   252  		want []string
   253  	}{
   254  		"should find 1 result": {
   255  			have: []armcompute.ResourceSKU{
   256  				{
   257  					Name:         ptr.To("foo"),
   258  					ResourceType: ptr.To(string(VirtualMachines)),
   259  					Locations: []*string{
   260  						ptr.To("baz"),
   261  					},
   262  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   263  						{
   264  							Location: ptr.To("baz"),
   265  							Zones:    []*string{ptr.To("1")},
   266  						},
   267  					},
   268  				},
   269  			},
   270  			want: []string{"1"},
   271  		},
   272  		"should find 2 results": {
   273  			have: []armcompute.ResourceSKU{
   274  				{
   275  					Name:         ptr.To("foo"),
   276  					ResourceType: ptr.To(string(VirtualMachines)),
   277  					Locations: []*string{
   278  						ptr.To("baz"),
   279  					},
   280  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   281  						{
   282  							Location: ptr.To("baz"),
   283  							Zones:    []*string{ptr.To("1"), ptr.To("2")},
   284  						},
   285  					},
   286  				},
   287  			},
   288  			want: []string{"1", "2"},
   289  		},
   290  		"should not find due to size mismatch": {
   291  			have: []armcompute.ResourceSKU{
   292  				{
   293  					Name:         ptr.To("foobar"),
   294  					ResourceType: ptr.To(string(VirtualMachines)),
   295  					Locations: []*string{
   296  						ptr.To("baz"),
   297  					},
   298  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   299  						{
   300  							Location: ptr.To("baz"),
   301  							Zones:    []*string{ptr.To("1")},
   302  						},
   303  					},
   304  				},
   305  			},
   306  			want: nil,
   307  		},
   308  		"should not find due to location mismatch": {
   309  			have: []armcompute.ResourceSKU{
   310  				{
   311  					Name:         ptr.To("foo"),
   312  					ResourceType: ptr.To(string(VirtualMachines)),
   313  					Locations: []*string{
   314  						ptr.To("foobar"),
   315  					},
   316  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   317  						{
   318  							Location: ptr.To("foobar"),
   319  							Zones:    []*string{ptr.To("1")},
   320  						},
   321  					},
   322  				},
   323  			},
   324  			want: nil,
   325  		},
   326  		"should not find due to location restriction": {
   327  			have: []armcompute.ResourceSKU{
   328  				{
   329  					Name:         ptr.To("foo"),
   330  					ResourceType: ptr.To(string(VirtualMachines)),
   331  					Locations: []*string{
   332  						ptr.To("baz"),
   333  					},
   334  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   335  						{
   336  							Location: ptr.To("baz"),
   337  							Zones:    []*string{ptr.To("1")},
   338  						},
   339  					},
   340  					Restrictions: []*armcompute.ResourceSKURestrictions{
   341  						{
   342  							Type:   ptr.To(armcompute.ResourceSKURestrictionsTypeLocation),
   343  							Values: []*string{ptr.To("baz")},
   344  						},
   345  					},
   346  				},
   347  			},
   348  			want: nil,
   349  		},
   350  		"should not find due to zone restriction": {
   351  			have: []armcompute.ResourceSKU{
   352  				{
   353  					Name:         ptr.To("foo"),
   354  					ResourceType: ptr.To(string(VirtualMachines)),
   355  					Locations: []*string{
   356  						ptr.To("baz"),
   357  					},
   358  					LocationInfo: []*armcompute.ResourceSKULocationInfo{
   359  						{
   360  							Location: ptr.To("baz"),
   361  							Zones:    []*string{ptr.To("1")},
   362  						},
   363  					},
   364  					Restrictions: []*armcompute.ResourceSKURestrictions{
   365  						{
   366  							Type: ptr.To(armcompute.ResourceSKURestrictionsTypeZone),
   367  							RestrictionInfo: &armcompute.ResourceSKURestrictionInfo{
   368  								Zones: []*string{ptr.To("1")},
   369  							},
   370  						},
   371  					},
   372  				},
   373  			},
   374  			want: nil,
   375  		},
   376  	}
   377  
   378  	for name, tc := range cases {
   379  		tc := tc
   380  		t.Run(name, func(t *testing.T) {
   381  			t.Parallel()
   382  
   383  			cache := &Cache{
   384  				data: tc.have,
   385  			}
   386  
   387  			zones, err := cache.GetZonesWithVMSize(context.Background(), "foo", "baz")
   388  			if err != nil {
   389  				t.Error(err)
   390  			}
   391  			if diff := cmp.Diff(zones, tc.want, []cmp.Option{cmpopts.EquateEmpty()}...); diff != "" {
   392  				t.Fatalf(diff)
   393  			}
   394  		})
   395  	}
   396  }