sigs.k8s.io/cluster-api-provider-azure@v1.14.3/util/azure/azure_test.go (about)

     1  /*
     2  Copyright 2023 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 azure
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	. "github.com/onsi/gomega"
    24  	utilfeature "k8s.io/component-base/featuregate/testing"
    25  	"sigs.k8s.io/cluster-api-provider-azure/feature"
    26  	expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1"
    27  	capifeature "sigs.k8s.io/cluster-api/feature"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  )
    30  
    31  func TestFindParentMachinePool(t *testing.T) {
    32  	defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, capifeature.MachinePool, true)()
    33  	client := mockClient{}
    34  
    35  	tests := []struct {
    36  		name    string
    37  		mpName  string
    38  		wantErr bool
    39  	}{
    40  		{
    41  			name:    "valid",
    42  			mpName:  "mock-machinepool-mp-0",
    43  			wantErr: false,
    44  		},
    45  		{
    46  			name:    "invalid",
    47  			mpName:  "mock-machinepool-mp-1",
    48  			wantErr: true,
    49  		},
    50  	}
    51  
    52  	for _, tc := range tests {
    53  		t.Run(tc.name, func(t *testing.T) {
    54  			g := NewWithT(t)
    55  			mp, err := FindParentMachinePool(tc.mpName, client)
    56  			if tc.wantErr {
    57  				g.Expect(err).To(HaveOccurred())
    58  			} else {
    59  				g.Expect(err).NotTo(HaveOccurred())
    60  				g.Expect(mp).NotTo(BeNil())
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func TestFindParentMachinePoolWithRetry(t *testing.T) {
    67  	defer utilfeature.SetFeatureGateDuringTest(t, feature.Gates, capifeature.MachinePool, true)()
    68  	client := mockClient{}
    69  
    70  	tests := []struct {
    71  		name        string
    72  		mpName      string
    73  		maxAttempts int
    74  		wantErr     bool
    75  	}{
    76  		{
    77  			name:        "valid",
    78  			mpName:      "mock-machinepool-mp-0",
    79  			maxAttempts: 1,
    80  			wantErr:     false,
    81  		},
    82  		{
    83  			name:        "valid with retries",
    84  			mpName:      "mock-machinepool-mp-0",
    85  			maxAttempts: 5,
    86  			wantErr:     false,
    87  		},
    88  		{
    89  			name:        "invalid",
    90  			mpName:      "mock-machinepool-mp-1",
    91  			maxAttempts: 1,
    92  			wantErr:     true,
    93  		},
    94  		{
    95  			name:        "invalid with retries",
    96  			mpName:      "mock-machinepool-mp-1",
    97  			maxAttempts: 5,
    98  			wantErr:     true,
    99  		},
   100  	}
   101  
   102  	for _, tc := range tests {
   103  		t.Run(tc.name, func(t *testing.T) {
   104  			g := NewWithT(t)
   105  			mp, err := FindParentMachinePoolWithRetry(tc.mpName, client, tc.maxAttempts)
   106  			if tc.wantErr {
   107  				g.Expect(err).To(HaveOccurred())
   108  			} else {
   109  				g.Expect(err).NotTo(HaveOccurred())
   110  				g.Expect(mp).NotTo(BeNil())
   111  			}
   112  		})
   113  	}
   114  }
   115  
   116  type mockClient struct {
   117  	client.Client
   118  }
   119  
   120  func (m mockClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
   121  	mp := &expv1.MachinePool{}
   122  	mp.Spec.Template.Spec.InfrastructureRef.Name = "mock-machinepool-mp-0"
   123  	list.(*expv1.MachinePoolList).Items = []expv1.MachinePool{*mp}
   124  
   125  	return nil
   126  }
   127  
   128  func TestParseResourceID(t *testing.T) {
   129  	tests := []struct {
   130  		name         string
   131  		id           string
   132  		expectedName string
   133  		errExpected  bool
   134  	}{
   135  		{
   136  			name:         "invalid",
   137  			id:           "invalid",
   138  			expectedName: "",
   139  			errExpected:  true,
   140  		},
   141  		{
   142  			name:         "invalid: must start with slash",
   143  			id:           "subscriptions/123/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm",
   144  			expectedName: "",
   145  			errExpected:  true,
   146  		},
   147  		{
   148  			name:         "invalid: must start with subscriptions or providers",
   149  			id:           "/prescriptions/123/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm",
   150  			expectedName: "",
   151  			errExpected:  true,
   152  		},
   153  		{
   154  			name:         "valid",
   155  			id:           "/subscriptions/123/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm",
   156  			expectedName: "vm",
   157  		},
   158  		{
   159  			name:         "valid with provider prefix",
   160  			id:           "azure:///subscriptions/123/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm",
   161  			expectedName: "vm",
   162  		},
   163  	}
   164  
   165  	for _, tt := range tests {
   166  		t.Run(tt.name, func(t *testing.T) {
   167  			g := NewWithT(t)
   168  			resourceID, err := ParseResourceID(tt.id)
   169  			if tt.errExpected {
   170  				g.Expect(err).To(HaveOccurred())
   171  			} else {
   172  				g.Expect(err).NotTo(HaveOccurred())
   173  				g.Expect(resourceID.Name).To(Equal(tt.expectedName))
   174  			}
   175  		})
   176  	}
   177  }