Skip to content

Commit 1fa2030

Browse files
authored
Merge pull request kubernetes#92129 from weijiehu/azure_controller_vmss
Improves unittest CC for azure_controller_vmss
2 parents 15e95e4 + ddbaa0c commit 1fa2030

File tree

2 files changed

+323
-0
lines changed

2 files changed

+323
-0
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ go_test(
114114
"azure_config_test.go",
115115
"azure_controller_common_test.go",
116116
"azure_controller_standard_test.go",
117+
"azure_controller_vmss_test.go",
117118
"azure_instances_test.go",
118119
"azure_loadbalancer_test.go",
119120
"azure_ratelimit_test.go",
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package azure
20+
21+
import (
22+
"fmt"
23+
"net/http"
24+
"testing"
25+
26+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
27+
"github.com/Azure/go-autorest/autorest/to"
28+
"github.com/golang/mock/gomock"
29+
"github.com/stretchr/testify/assert"
30+
31+
"k8s.io/apimachinery/pkg/types"
32+
cloudprovider "k8s.io/cloud-provider"
33+
azcache "k8s.io/legacy-cloud-providers/azure/cache"
34+
"k8s.io/legacy-cloud-providers/azure/clients/vmssclient/mockvmssclient"
35+
"k8s.io/legacy-cloud-providers/azure/clients/vmssvmclient/mockvmssvmclient"
36+
"k8s.io/legacy-cloud-providers/azure/retry"
37+
)
38+
39+
func TestAttachDiskWithVMSS(t *testing.T) {
40+
ctrl := gomock.NewController(t)
41+
defer ctrl.Finish()
42+
43+
fakeStatusNotFoundVMSSName := types.NodeName("FakeStatusNotFoundVMSSName")
44+
testCases := []struct {
45+
desc string
46+
vmList map[string]string
47+
vmssVMList []string
48+
vmssName types.NodeName
49+
vmssvmName types.NodeName
50+
isManagedDisk bool
51+
existedDisk compute.Disk
52+
expectedErr bool
53+
expectedErrMsg error
54+
}{
55+
{
56+
desc: "an error shall be returned if it is invalid vmss name",
57+
vmssVMList: []string{"vmss-vm-000001"},
58+
vmssName: "vm1",
59+
vmssvmName: "vm1",
60+
isManagedDisk: false,
61+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
62+
expectedErr: true,
63+
expectedErrMsg: fmt.Errorf("not a vmss instance"),
64+
},
65+
{
66+
desc: "no error shall be returned if everything is good with managed disk",
67+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
68+
vmssName: "vmss00",
69+
vmssvmName: "vmss00-vm-000000",
70+
isManagedDisk: true,
71+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
72+
expectedErr: false,
73+
},
74+
{
75+
desc: "no error shall be returned if everything is good with non-managed disk",
76+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
77+
vmssName: "vmss00",
78+
vmssvmName: "vmss00-vm-000000",
79+
isManagedDisk: false,
80+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
81+
expectedErr: false,
82+
},
83+
{
84+
desc: "an error shall be returned if response StatusNotFound",
85+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
86+
vmssName: fakeStatusNotFoundVMSSName,
87+
vmssvmName: "vmss00-vm-000000",
88+
isManagedDisk: false,
89+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
90+
expectedErr: true,
91+
expectedErrMsg: fmt.Errorf("Retriable: false, RetryAfter: 0s, HTTPStatusCode: 404, RawError: instance not found"),
92+
},
93+
}
94+
95+
for i, test := range testCases {
96+
scaleSetName := string(test.vmssName)
97+
ss, err := newTestScaleSet(ctrl)
98+
assert.NoError(t, err, test.desc)
99+
testCloud := ss.cloud
100+
testCloud.PrimaryScaleSetName = scaleSetName
101+
expectedVMSS := buildTestVMSS(scaleSetName, []string{testLBBackendpoolID0})
102+
mockVMSSClient := testCloud.VirtualMachineScaleSetsClient.(*mockvmssclient.MockInterface)
103+
mockVMSSClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup).Return([]compute.VirtualMachineScaleSet{expectedVMSS}, nil).AnyTimes()
104+
mockVMSSClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, scaleSetName).Return(expectedVMSS, nil).MaxTimes(1)
105+
mockVMSSClient.EXPECT().CreateOrUpdate(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(nil).MaxTimes(1)
106+
107+
expectedVMSSVMs, _, _ := buildTestVirtualMachineEnv(testCloud, scaleSetName, "", 0, test.vmssVMList, "succeeded")
108+
for _, vmssvm := range expectedVMSSVMs {
109+
vmssvm.StorageProfile = &compute.StorageProfile{
110+
OsDisk: &compute.OSDisk{
111+
Name: to.StringPtr("osdisk1"),
112+
ManagedDisk: &compute.ManagedDiskParameters{
113+
ID: to.StringPtr("ManagedID"),
114+
DiskEncryptionSet: &compute.DiskEncryptionSetParameters{
115+
ID: to.StringPtr("DiskEncryptionSetID"),
116+
},
117+
},
118+
},
119+
DataDisks: &[]compute.DataDisk{},
120+
}
121+
}
122+
mockVMSSVMClient := testCloud.VirtualMachineScaleSetVMsClient.(*mockvmssvmclient.MockInterface)
123+
mockVMSSVMClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(expectedVMSSVMs, nil).AnyTimes()
124+
if scaleSetName == string(fakeStatusNotFoundVMSSName) {
125+
mockVMSSVMClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any(), gomock.Any(), gomock.Any()).Return(&retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
126+
} else {
127+
mockVMSSVMClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
128+
}
129+
130+
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
131+
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
132+
133+
err = ss.AttachDisk(test.isManagedDisk, "disk-name", diskURI, test.vmssvmName, 0, compute.CachingTypesReadWrite, "", true)
134+
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, return error: %v", i, test.desc, err)
135+
assert.Equal(t, test.expectedErrMsg, err, "TestCase[%d]: %s, expected error: %v, return error: %v", i, test.desc, test.expectedErrMsg, err)
136+
}
137+
}
138+
139+
func TestDetachDiskWithVMSS(t *testing.T) {
140+
ctrl := gomock.NewController(t)
141+
defer ctrl.Finish()
142+
143+
fakeStatusNotFoundVMSSName := types.NodeName("FakeStatusNotFoundVMSSName")
144+
testCases := []struct {
145+
desc string
146+
vmList map[string]string
147+
vmssVMList []string
148+
vmssName types.NodeName
149+
vmssvmName types.NodeName
150+
existedDisk compute.Disk
151+
expectedErr bool
152+
expectedErrMsg error
153+
}{
154+
{
155+
desc: "an error shall be returned if it is invalid vmss name",
156+
vmssVMList: []string{"vmss-vm-000001"},
157+
vmssName: "vm1",
158+
vmssvmName: "vm1",
159+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
160+
expectedErr: true,
161+
expectedErrMsg: fmt.Errorf("not a vmss instance"),
162+
},
163+
{
164+
desc: "no error shall be returned if everything is good",
165+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
166+
vmssName: "vmss00",
167+
vmssvmName: "vmss00-vm-000000",
168+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
169+
expectedErr: false,
170+
},
171+
{
172+
desc: "an error shall be returned if response StatusNotFound",
173+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
174+
vmssName: fakeStatusNotFoundVMSSName,
175+
vmssvmName: "vmss00-vm-000000",
176+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name")},
177+
expectedErr: true,
178+
expectedErrMsg: fmt.Errorf("Retriable: false, RetryAfter: 0s, HTTPStatusCode: 404, RawError: instance not found"),
179+
},
180+
{
181+
desc: "no error shall be returned if everything is good and the attaching disk does not match data disk",
182+
vmssVMList: []string{"vmss00-vm-000000", "vmss00-vm-000001", "vmss00-vm-000002"},
183+
vmssName: "vmss00",
184+
vmssvmName: "vmss00-vm-000000",
185+
existedDisk: compute.Disk{Name: to.StringPtr("disk-name-err")},
186+
expectedErr: false,
187+
},
188+
}
189+
190+
for i, test := range testCases {
191+
scaleSetName := string(test.vmssName)
192+
ss, err := newTestScaleSet(ctrl)
193+
assert.NoError(t, err, test.desc)
194+
testCloud := ss.cloud
195+
testCloud.PrimaryScaleSetName = scaleSetName
196+
expectedVMSS := buildTestVMSS(scaleSetName, []string{testLBBackendpoolID0})
197+
mockVMSSClient := testCloud.VirtualMachineScaleSetsClient.(*mockvmssclient.MockInterface)
198+
mockVMSSClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup).Return([]compute.VirtualMachineScaleSet{expectedVMSS}, nil).AnyTimes()
199+
mockVMSSClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, scaleSetName).Return(expectedVMSS, nil).MaxTimes(1)
200+
mockVMSSClient.EXPECT().CreateOrUpdate(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(nil).MaxTimes(1)
201+
202+
expectedVMSSVMs, _, _ := buildTestVirtualMachineEnv(testCloud, scaleSetName, "", 0, test.vmssVMList, "succeeded")
203+
for _, vmssvm := range expectedVMSSVMs {
204+
vmssvm.StorageProfile = &compute.StorageProfile{
205+
OsDisk: &compute.OSDisk{
206+
Name: to.StringPtr("osdisk1"),
207+
ManagedDisk: &compute.ManagedDiskParameters{
208+
ID: to.StringPtr("ManagedID"),
209+
DiskEncryptionSet: &compute.DiskEncryptionSetParameters{
210+
ID: to.StringPtr("DiskEncryptionSetID"),
211+
},
212+
},
213+
},
214+
DataDisks: &[]compute.DataDisk{{
215+
Lun: to.Int32Ptr(0),
216+
Name: to.StringPtr("disk-name"),
217+
}},
218+
}
219+
}
220+
mockVMSSVMClient := testCloud.VirtualMachineScaleSetVMsClient.(*mockvmssvmclient.MockInterface)
221+
mockVMSSVMClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(expectedVMSSVMs, nil).AnyTimes()
222+
if scaleSetName == string(fakeStatusNotFoundVMSSName) {
223+
mockVMSSVMClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any(), gomock.Any(), gomock.Any()).Return(&retry.Error{HTTPStatusCode: http.StatusNotFound, RawError: cloudprovider.InstanceNotFound}).AnyTimes()
224+
} else {
225+
mockVMSSVMClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
226+
}
227+
228+
diskURI := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s",
229+
testCloud.SubscriptionID, testCloud.ResourceGroup, *test.existedDisk.Name)
230+
231+
err = ss.DetachDisk(*test.existedDisk.Name, diskURI, test.vmssvmName)
232+
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s, err: %v", i, test.desc, err)
233+
assert.Equal(t, test.expectedErrMsg, err, "TestCase[%d]: %s, expected error: %v, return error: %v", i, test.desc, test.expectedErrMsg, err)
234+
}
235+
}
236+
237+
func TestGetDataDisksWithVMSS(t *testing.T) {
238+
ctrl := gomock.NewController(t)
239+
defer ctrl.Finish()
240+
241+
var testCases = []struct {
242+
desc string
243+
nodeName types.NodeName
244+
isDataDiskNull bool
245+
expectedDataDisks []compute.DataDisk
246+
expectedErr bool
247+
expectedErrMsg error
248+
crt azcache.AzureCacheReadType
249+
}{
250+
{
251+
desc: "an error shall be returned if there's no corresponding vm",
252+
nodeName: "vmss00-vm-000001",
253+
expectedDataDisks: nil,
254+
expectedErr: true,
255+
expectedErrMsg: fmt.Errorf("instance not found"),
256+
crt: azcache.CacheReadTypeDefault,
257+
},
258+
{
259+
desc: "correct list of data disks shall be returned if everything is good",
260+
nodeName: "vmss00-vm-000000",
261+
expectedDataDisks: []compute.DataDisk{
262+
{
263+
Lun: to.Int32Ptr(0),
264+
Name: to.StringPtr("disk1"),
265+
},
266+
},
267+
expectedErr: false,
268+
crt: azcache.CacheReadTypeDefault,
269+
},
270+
{
271+
desc: "correct list of data disks shall be returned if everything is good",
272+
nodeName: "vmss00-vm-000000",
273+
expectedDataDisks: []compute.DataDisk{
274+
{
275+
Lun: to.Int32Ptr(0),
276+
Name: to.StringPtr("disk1"),
277+
},
278+
},
279+
expectedErr: false,
280+
crt: azcache.CacheReadTypeUnsafe,
281+
},
282+
{
283+
desc: "nil shall be returned if DataDisk is null",
284+
nodeName: "vmss00-vm-000000",
285+
isDataDiskNull: true,
286+
expectedDataDisks: nil,
287+
expectedErr: false,
288+
crt: azcache.CacheReadTypeDefault,
289+
},
290+
}
291+
for i, test := range testCases {
292+
scaleSetName := string(test.nodeName)
293+
ss, err := newTestScaleSet(ctrl)
294+
assert.NoError(t, err, test.desc)
295+
testCloud := ss.cloud
296+
testCloud.PrimaryScaleSetName = scaleSetName
297+
expectedVMSS := buildTestVMSS(scaleSetName, []string{testLBBackendpoolID0})
298+
mockVMSSClient := testCloud.VirtualMachineScaleSetsClient.(*mockvmssclient.MockInterface)
299+
mockVMSSClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup).Return([]compute.VirtualMachineScaleSet{expectedVMSS}, nil).AnyTimes()
300+
mockVMSSClient.EXPECT().Get(gomock.Any(), testCloud.ResourceGroup, scaleSetName).Return(expectedVMSS, nil).MaxTimes(1)
301+
mockVMSSClient.EXPECT().CreateOrUpdate(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(nil).MaxTimes(1)
302+
303+
expectedVMSSVMs, _, _ := buildTestVirtualMachineEnv(testCloud, scaleSetName, "", 0, []string{"vmss00-vm-000000"}, "succeeded")
304+
if !test.isDataDiskNull {
305+
for _, vmssvm := range expectedVMSSVMs {
306+
vmssvm.StorageProfile = &compute.StorageProfile{
307+
DataDisks: &[]compute.DataDisk{{
308+
Lun: to.Int32Ptr(0),
309+
Name: to.StringPtr("disk1"),
310+
}},
311+
}
312+
}
313+
}
314+
mockVMSSVMClient := testCloud.VirtualMachineScaleSetVMsClient.(*mockvmssvmclient.MockInterface)
315+
mockVMSSVMClient.EXPECT().List(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any()).Return(expectedVMSSVMs, nil).AnyTimes()
316+
mockVMSSVMClient.EXPECT().Update(gomock.Any(), testCloud.ResourceGroup, scaleSetName, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
317+
dataDisks, err := ss.GetDataDisks(test.nodeName, test.crt)
318+
assert.Equal(t, test.expectedDataDisks, dataDisks, "TestCase[%d]: %s", i, test.desc)
319+
assert.Equal(t, test.expectedErr, err != nil, "TestCase[%d]: %s", i, test.desc)
320+
assert.Equal(t, test.expectedErrMsg, err, "TestCase[%d]: %s, expected error: %v, return error: %v", i, test.desc, test.expectedErrMsg, err)
321+
}
322+
}

0 commit comments

Comments
 (0)