sigs.k8s.io/cluster-api-provider-azure@v1.17.0/azure/services/networkinterfaces/networkinterfaces_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 networkinterfaces
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"io"
    23  	"net/http"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
    28  	"github.com/google/go-cmp/cmp"
    29  	. "github.com/onsi/gomega"
    30  	"go.uber.org/mock/gomock"
    31  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    32  	"sigs.k8s.io/cluster-api-provider-azure/azure"
    33  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/async/mock_async"
    34  	"sigs.k8s.io/cluster-api-provider-azure/azure/services/networkinterfaces/mock_networkinterfaces"
    35  	gomockinternal "sigs.k8s.io/cluster-api-provider-azure/internal/test/matchers/gomock"
    36  	"sigs.k8s.io/cluster-api-provider-azure/util/reconciler"
    37  )
    38  
    39  var (
    40  	fakeNICSpec1 = NICSpec{
    41  		Name:                  "nic-1",
    42  		ResourceGroup:         "my-rg",
    43  		Location:              "fake-location",
    44  		SubscriptionID:        "123",
    45  		MachineName:           "azure-test1",
    46  		SubnetName:            "my-subnet",
    47  		VNetName:              "my-vnet",
    48  		VNetResourceGroup:     "my-rg",
    49  		AcceleratedNetworking: nil,
    50  		SKU:                   &fakeSku,
    51  	}
    52  	fakeNICSpec2 = NICSpec{
    53  		Name:                  "nic-2",
    54  		ResourceGroup:         "my-rg",
    55  		Location:              "fake-location",
    56  		SubscriptionID:        "123",
    57  		MachineName:           "azure-test1",
    58  		SubnetName:            "my-subnet",
    59  		VNetName:              "my-vnet",
    60  		VNetResourceGroup:     "my-rg",
    61  		AcceleratedNetworking: nil,
    62  		SKU:                   &fakeSku,
    63  	}
    64  	fakeNICSpec3 = NICSpec{
    65  		Name:                  "nic-3",
    66  		ResourceGroup:         "my-rg",
    67  		Location:              "fake-location",
    68  		SubscriptionID:        "123",
    69  		MachineName:           "azure-test1",
    70  		VNetName:              "my-vnet",
    71  		VNetResourceGroup:     "my-rg",
    72  		AcceleratedNetworking: nil,
    73  		SKU:                   &fakeSku,
    74  		IPConfigs:             []IPConfig{{}, {}},
    75  	}
    76  	internalError = &azcore.ResponseError{
    77  		RawResponse: &http.Response{
    78  			Body:       io.NopCloser(strings.NewReader("#: Internal Server Error: StatusCode=500")),
    79  			StatusCode: http.StatusInternalServerError,
    80  		},
    81  	}
    82  )
    83  
    84  func TestReconcileNetworkInterface(t *testing.T) {
    85  	testcases := []struct {
    86  		name          string
    87  		expectedError string
    88  		expect        func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder)
    89  	}{
    90  		{
    91  			name:          "noop if no network interface specs are found",
    92  			expectedError: "",
    93  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
    94  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
    95  				s.NICSpecs().Return([]azure.ResourceSpecGetter{})
    96  			},
    97  		},
    98  		{
    99  			name:          "successfully create a network interface",
   100  			expectedError: "",
   101  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   102  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   103  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1})
   104  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil, nil)
   105  				s.UpdatePutStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, nil)
   106  			},
   107  		},
   108  		{
   109  			name:          "successfully create a network interface with multiple IPConfigs",
   110  			expectedError: "",
   111  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   112  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   113  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec3})
   114  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec3, serviceName).Return(nil, nil)
   115  				s.UpdatePutStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, nil)
   116  			},
   117  		},
   118  		{
   119  			name:          "successfully create multiple network interfaces",
   120  			expectedError: "",
   121  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   122  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   123  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1, &fakeNICSpec2})
   124  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil, nil)
   125  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec2, serviceName).Return(nil, nil)
   126  				s.UpdatePutStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, nil)
   127  			},
   128  		},
   129  		{
   130  			name:          "network interface create fails",
   131  			expectedError: internalError.Error(),
   132  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   133  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   134  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1, &fakeNICSpec2})
   135  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil, internalError)
   136  				r.CreateOrUpdateResource(gomockinternal.AContext(), &fakeNICSpec2, serviceName).Return(nil, nil)
   137  				s.UpdatePutStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, internalError)
   138  			},
   139  		},
   140  	}
   141  
   142  	for _, tc := range testcases {
   143  		tc := tc
   144  		t.Run(tc.name, func(t *testing.T) {
   145  			g := NewWithT(t)
   146  			t.Parallel()
   147  			mockCtrl := gomock.NewController(t)
   148  			defer mockCtrl.Finish()
   149  			scopeMock := mock_networkinterfaces.NewMockNICScope(mockCtrl)
   150  			asyncMock := mock_async.NewMockReconciler(mockCtrl)
   151  
   152  			tc.expect(scopeMock.EXPECT(), asyncMock.EXPECT())
   153  
   154  			s := &Service{
   155  				Scope:      scopeMock,
   156  				Reconciler: asyncMock,
   157  			}
   158  
   159  			err := s.Reconcile(context.TODO())
   160  			if tc.expectedError != "" {
   161  				g.Expect(err).To(HaveOccurred())
   162  				fmt.Print(cmp.Diff(err.Error(), tc.expectedError))
   163  
   164  				g.Expect(err.Error()).To(Equal(tc.expectedError))
   165  			} else {
   166  				g.Expect(err).NotTo(HaveOccurred())
   167  			}
   168  		})
   169  	}
   170  }
   171  
   172  func TestDeleteNetworkInterface(t *testing.T) {
   173  	testcases := []struct {
   174  		name          string
   175  		expectedError string
   176  		expect        func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder)
   177  	}{
   178  		{
   179  			name:          "noop if no network interface specs are found",
   180  			expectedError: "",
   181  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   182  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   183  				s.NICSpecs().Return([]azure.ResourceSpecGetter{})
   184  			},
   185  		},
   186  		{
   187  			name:          "successfully delete an existing network interface",
   188  			expectedError: "",
   189  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   190  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   191  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1})
   192  				r.DeleteResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil)
   193  				s.UpdateDeleteStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, nil)
   194  			},
   195  		},
   196  		{
   197  			name:          "successfully delete multiple existing network interfaces",
   198  			expectedError: "",
   199  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   200  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   201  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1, &fakeNICSpec2})
   202  				r.DeleteResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil)
   203  				r.DeleteResource(gomockinternal.AContext(), &fakeNICSpec2, serviceName).Return(nil)
   204  				s.UpdateDeleteStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, nil)
   205  			},
   206  		},
   207  		{
   208  			name:          "network interface deletion fails",
   209  			expectedError: internalError.Error(),
   210  			expect: func(s *mock_networkinterfaces.MockNICScopeMockRecorder, r *mock_async.MockReconcilerMockRecorder) {
   211  				s.DefaultedAzureServiceReconcileTimeout().Return(reconciler.DefaultAzureServiceReconcileTimeout)
   212  				s.NICSpecs().Return([]azure.ResourceSpecGetter{&fakeNICSpec1, &fakeNICSpec2})
   213  				r.DeleteResource(gomockinternal.AContext(), &fakeNICSpec1, serviceName).Return(nil)
   214  				r.DeleteResource(gomockinternal.AContext(), &fakeNICSpec2, serviceName).Return(internalError)
   215  				s.UpdateDeleteStatus(infrav1.NetworkInterfaceReadyCondition, serviceName, internalError)
   216  			},
   217  		},
   218  	}
   219  
   220  	for _, tc := range testcases {
   221  		tc := tc
   222  		t.Run(tc.name, func(t *testing.T) {
   223  			g := NewWithT(t)
   224  			t.Parallel()
   225  			mockCtrl := gomock.NewController(t)
   226  			defer mockCtrl.Finish()
   227  			scopeMock := mock_networkinterfaces.NewMockNICScope(mockCtrl)
   228  			asyncMock := mock_async.NewMockReconciler(mockCtrl)
   229  
   230  			tc.expect(scopeMock.EXPECT(), asyncMock.EXPECT())
   231  
   232  			s := &Service{
   233  				Scope:      scopeMock,
   234  				Reconciler: asyncMock,
   235  			}
   236  
   237  			err := s.Delete(context.TODO())
   238  			if tc.expectedError != "" {
   239  				g.Expect(err).To(HaveOccurred())
   240  				g.Expect(err).To(MatchError(tc.expectedError))
   241  			} else {
   242  				g.Expect(err).NotTo(HaveOccurred())
   243  			}
   244  		})
   245  	}
   246  }