Skip to content

Commit 51e60c7

Browse files
committed
Improves unittest CC for azure_controller_common
1 parent 0891f69 commit 51e60c7

File tree

1 file changed

+201
-7
lines changed

1 file changed

+201
-7
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure_controller_common_test.go

Lines changed: 201 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ import (
3030
"github.com/stretchr/testify/assert"
3131

3232
"k8s.io/apimachinery/pkg/types"
33+
"k8s.io/apimachinery/pkg/util/wait"
3334
cloudprovider "k8s.io/cloud-provider"
3435
"k8s.io/legacy-cloud-providers/azure/clients/diskclient/mockdiskclient"
3536
"k8s.io/legacy-cloud-providers/azure/clients/vmclient/mockvmclient"
37+
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
38+
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
3639
"k8s.io/legacy-cloud-providers/azure/retry"
3740
"k8s.io/utils/pointer"
3841
)
@@ -41,11 +44,18 @@ func TestCommonAttachDisk(t *testing.T) {
4144
ctrl := gomock.NewController(t)
4245
defer ctrl.Finish()
4346

47+
maxShare := int32(1)
48+
goodInstanceID := fmt.Sprintf("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/%s", "vm1")
49+
diskEncryptionSetID := fmt.Sprintf("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/diskEncryptionSets/%s", "diskEncryptionSet-name")
50+
testTags := make(map[string]*string)
51+
testTags[WriteAcceleratorEnabled] = to.StringPtr("true")
4452
testCases := []struct {
4553
desc string
4654
vmList map[string]string
4755
nodeName types.NodeName
4856
isDataDisksFull bool
57+
isBadDiskURI bool
58+
isDiskUsed bool
4959
existedDisk compute.Disk
5060
expectedLun int32
5161
expectedErr bool
@@ -70,10 +80,35 @@ func TestCommonAttachDisk(t *testing.T) {
7080
desc: "correct LUN and no error shall be returned if everything is good",
7181
vmList: map[string]string{"vm1": "PowerState/Running"},
7282
nodeName: "vm1",
73-
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
83+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name"), DiskProperties: &compute.DiskProperties{Encryption: &compute.Encryption{DiskEncryptionSetID: &diskEncryptionSetID, Type: compute.EncryptionAtRestWithCustomerKey}}, Tags: testTags},
7484
expectedLun: 1,
7585
expectedErr: false,
7686
},
87+
{
88+
desc: "an error shall be returned if there's invalid disk uri",
89+
vmList: map[string]string{"vm1": "PowerState/Running"},
90+
nodeName: "vm1",
91+
isBadDiskURI: true,
92+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
93+
expectedLun: -1,
94+
expectedErr: true,
95+
},
96+
{
97+
desc: "an error shall be returned if attach an already attached disk with good ManagedBy instance id",
98+
vmList: map[string]string{"vm1": "PowerState/Running"},
99+
nodeName: "vm1",
100+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name"), ManagedBy: to.StringPtr(goodInstanceID), DiskProperties: &compute.DiskProperties{MaxShares: &maxShare}},
101+
expectedLun: -1,
102+
expectedErr: true,
103+
},
104+
{
105+
desc: "an error shall be returned if attach an already attached disk with bad ManagedBy instance id",
106+
vmList: map[string]string{"vm1": "PowerState/Running"},
107+
nodeName: "vm1",
108+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name"), ManagedBy: to.StringPtr("test"), DiskProperties: &compute.DiskProperties{MaxShares: &maxShare}},
109+
expectedLun: -1,
110+
expectedErr: true,
111+
},
77112
{
78113
desc: "an error shall be returned if there's no matching disk",
79114
vmList: map[string]string{"vm1": "PowerState/Running"},
@@ -96,7 +131,15 @@ func TestCommonAttachDisk(t *testing.T) {
96131
}
97132
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
98133
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
134+
if test.isBadDiskURI {
135+
diskURI = fmt.Sprintf("/baduri/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
136+
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
137+
}
99138
expectedVMs := setTestVirtualMachines(testCloud, test.vmList, test.isDataDisksFull)
139+
if test.isDiskUsed {
140+
vm0 := setTestVirtualMachines(testCloud, map[string]string{"vm0": "PowerState/Running"}, test.isDataDisksFull)[0]
141+
expectedVMs = append(expectedVMs, vm0)
142+
}
100143
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
101144
for _, vm := range expectedVMs {
102145
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
@@ -116,22 +159,128 @@ func TestCommonAttachDisk(t *testing.T) {
116159
}
117160
}
118161

162+
func TestCommonAttachDiskWithVMSS(t *testing.T) {
163+
ctrl := gomock.NewController(t)
164+
defer ctrl.Finish()
165+
166+
testCases := []struct {
167+
desc string
168+
vmList map[string]string
169+
vmssList []string
170+
nodeName types.NodeName
171+
isVMSS bool
172+
isManagedBy bool
173+
isManagedDisk bool
174+
isDataDisksFull bool
175+
existedDisk compute.Disk
176+
expectedLun int32
177+
expectedErr bool
178+
}{
179+
{
180+
desc: "an error shall be returned if convert vmSet to scaleSet failed",
181+
vmList: map[string]string{"vm1": "PowerState/Running"},
182+
nodeName: "vm1",
183+
isVMSS: false,
184+
isManagedBy: false,
185+
isManagedDisk: false,
186+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
187+
expectedLun: -1,
188+
expectedErr: true,
189+
},
190+
{
191+
desc: "an error shall be returned if convert vmSet to scaleSet success but node is not managed by availability set",
192+
vmssList: []string{"vmss-vm-000001"},
193+
nodeName: "vmss1",
194+
isVMSS: true,
195+
isManagedBy: false,
196+
isManagedDisk: false,
197+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
198+
expectedLun: -1,
199+
expectedErr: true,
200+
},
201+
}
202+
203+
for i, test := range testCases {
204+
testCloud := GetTestCloud(ctrl)
205+
testCloud.VMType = vmTypeVMSS
206+
if test.isVMSS {
207+
if test.isManagedBy {
208+
testCloud.DisableAvailabilitySetNodes = false
209+
testVMSSName := "vmss"
210+
expectedVMSS := compute.VirtualMachineScaleSet{Name: to.StringPtr(testVMSSName)}
211+
mockVMSSClient := testCloud.VirtualMachineScaleSetsClient.(*mockvmssclient.MockInterface)
212+
mockVMSSClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup).Return([]compute.VirtualMachineScaleSet{expectedVMSS}, nil).AnyTimes()
213+
214+
expectedVMSSVMs, _, _ := buildTestVirtualMachineEnv(testCloud, testVMSSName, "", 0, test.vmssList, "")
215+
mockVMSSVMClient := testCloud.VirtualMachineScaleSetVMsClient.(*mockvmssvmclient.MockInterface)
216+
mockVMSSVMClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup, testVMSSName, gomock.Any()).Return(expectedVMSSVMs, nil).AnyTimes()
217+
218+
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
219+
mockVMsClient.EXPECT().List(gomock.Any(), gomock.Any()).Return([]compute.VirtualMachine{}, nil).AnyTimes()
220+
} else {
221+
testCloud.DisableAvailabilitySetNodes = true
222+
}
223+
ss, err := newScaleSet(testCloud)
224+
assert.Nil(t, err)
225+
testCloud.vmSet = ss
226+
}
227+
228+
common := &controllerCommon{
229+
location: testCloud.Location,
230+
storageEndpointSuffix: testCloud.Environment.StorageEndpointSuffix,
231+
resourceGroup: testCloud.ResourceGroup,
232+
subscriptionID: testCloud.SubscriptionID,
233+
cloud: testCloud,
234+
vmLockMap: newLockMap(),
235+
}
236+
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
237+
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
238+
if !test.isVMSS {
239+
expectedVMs := setTestVirtualMachines(testCloud, test.vmList, test.isDataDisksFull)
240+
mockVMsClient := testCloud.VirtualMachinesClient.(*mockvmclient.MockInterface)
241+
for _, vm := range expectedVMs {
242+
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, *vm.Name, gomock.Any()).Return(vm, nil).AnyTimes()
243+
}
244+
if len(expectedVMs) == 0 {
245+
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
246+
}
247+
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
248+
249+
mockDisksClient := testCloud.DisksClient.(*mockdiskclient.MockInterface)
250+
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, "disk-name").Return(test.existedDisk, nil).AnyTimes()
251+
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Not("disk-name")).Return(compute.Disk{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
252+
}
253+
254+
lun, err := common.AttachDisk(test.isManagedDisk, "test", diskURI, test.nodeName, compute.CachingTypesReadOnly)
255+
assert.Equal(t, test.expectedLun, lun, "TestCase[%d]: %s", i, test.desc)
256+
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, return error: %v", i, test.desc, err)
257+
}
258+
}
259+
119260
func TestCommonDetachDisk(t *testing.T) {
120261
ctrl := gomock.NewController(t)
121262
defer ctrl.Finish()
122263

123264
testCases := []struct {
124-
desc string
125-
vmList map[string]string
126-
nodeName types.NodeName
127-
diskName string
128-
expectedErr bool
265+
desc string
266+
vmList map[string]string
267+
nodeName types.NodeName
268+
diskName string
269+
isErrorRetriable bool
270+
expectedErr bool
129271
}{
130272
{
131273
desc: "error should not be returned if there's no such instance corresponding to given nodeName",
132274
nodeName: "vm1",
133275
expectedErr: false,
134276
},
277+
{
278+
desc: "an error should be returned if vmset detach failed with isErrorRetriable error",
279+
vmList: map[string]string{"vm1": "PowerState/Running"},
280+
nodeName: "vm1",
281+
isErrorRetriable: true,
282+
expectedErr: true,
283+
},
135284
{
136285
desc: "no error shall be returned if there's no matching disk according to given diskName",
137286
vmList: map[string]string{"vm1": "PowerState/Running"},
@@ -168,7 +317,13 @@ func TestCommonDetachDisk(t *testing.T) {
168317
if len(expectedVMs) == 0 {
169318
mockVMsClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any()).Return(compute.VirtualMachine{}, &retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
170319
}
171-
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
320+
if test.isErrorRetriable {
321+
testCloud.CloudProviderBackoff = true
322+
testCloud.ResourceRequestBackoff = wait.Backoff{Steps: 1}
323+
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(&retry.Error{HTTPStatusCode: http.StatusBadRequest, Retriable: true, RawError: fmt.Errorf("Retriable: true")}).AnyTimes()
324+
} else {
325+
mockVMsClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
326+
}
172327

173328
err := common.DetachDisk(test.diskName, diskURI, test.nodeName)
174329
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, err: %v", i, test.desc, err)
@@ -594,3 +749,42 @@ func TestFilterNonExistingDisks(t *testing.T) {
594749
filteredDisks = filterDetachingDisks(disks)
595750
assert.Equal(t, 0, len(filteredDisks))
596751
}
752+
753+
func TestFilterNonExistingDisksWithSpecialHTTPStatusCode(t *testing.T) {
754+
ctrl := gomock.NewController(t)
755+
defer ctrl.Finish()
756+
757+
ctx, cancel := getContextWithCancel()
758+
defer cancel()
759+
760+
testCloud := GetTestCloud(ctrl)
761+
common := &controllerCommon{
762+
location: testCloud.Location,
763+
storageEndpointSuffix: testCloud.Environment.StorageEndpointSuffix,
764+
resourceGroup: testCloud.ResourceGroup,
765+
subscriptionID: testCloud.SubscriptionID,
766+
cloud: testCloud,
767+
vmLockMap: newLockMap(),
768+
}
769+
// create a new disk before running test
770+
diskURIPrefix := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/",
771+
testCloud.SubscriptionID, testCloud.ResourceGroup)
772+
newDiskName := "specialdisk"
773+
newDiskURI := diskURIPrefix + newDiskName
774+
775+
mockDisksClient := testCloud.DisksClient.(*mockdiskclient.MockInterface)
776+
mockDisksClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, gomock.Eq(newDiskName)).Return(compute.Disk{}, &retry.Error{HTTPStatusCode: http.StatusBadRequest, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
777+
778+
disks := []compute.DataDisk{
779+
{
780+
Name: &newDiskName,
781+
ManagedDisk: &compute.ManagedDiskParameters{
782+
ID: &newDiskURI,
783+
},
784+
},
785+
}
786+
787+
filteredDisks := common.filterNonExistingDisks(ctx, disks)
788+
assert.Equal(t, 1, len(filteredDisks))
789+
assert.Equal(t, newDiskName, *filteredDisks[0].Name)
790+
}

0 commit comments

Comments
 (0)