Skip to content

Commit 0171b12

Browse files
authored
Merge pull request kubernetes#91041 from weijiehu/azureroutetableclient
Improves unittest CC for azure_routetableclient
2 parents f9f2875 + 0d9d03a commit 0171b12

File tree

2 files changed

+222
-3
lines changed

2 files changed

+222
-3
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ go_test(
2828
srcs = ["azure_routetableclient_test.go"],
2929
embed = [":go_default_library"],
3030
deps = [
31+
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
3132
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients:go_default_library",
3233
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient:go_default_library",
3334
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient/mockarmclient:go_default_library",
35+
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
3436
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network:go_default_library",
3537
"//vendor/github.com/Azure/go-autorest/autorest:go_default_library",
3638
"//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library",

staging/src/k8s.io/legacy-cloud-providers/azure/clients/routetableclient/azure_routetableclient_test.go

Lines changed: 220 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,69 @@ import (
2525
"io/ioutil"
2626
"net/http"
2727
"testing"
28+
"time"
2829

2930
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network"
3031
"github.com/Azure/go-autorest/autorest"
3132
"github.com/Azure/go-autorest/autorest/to"
3233
"github.com/golang/mock/gomock"
3334
"github.com/stretchr/testify/assert"
3435

36+
"k8s.io/client-go/util/flowcontrol"
3537
azclients "k8s.io/legacy-cloud-providers/azure/clients"
3638
"k8s.io/legacy-cloud-providers/azure/clients/armclient"
3739
"k8s.io/legacy-cloud-providers/azure/clients/armclient/mockarmclient"
40+
"k8s.io/legacy-cloud-providers/azure/retry"
3841
)
3942

43+
// 2065-01-24 05:20:00 +0000 UTC
44+
func getFutureTime() time.Time {
45+
return time.Unix(3000000000, 0)
46+
}
47+
48+
func TestNew(t *testing.T) {
49+
config := &azclients.ClientConfig{
50+
SubscriptionID: "sub",
51+
ResourceManagerEndpoint: "endpoint",
52+
Location: "eastus",
53+
RateLimitConfig: &azclients.RateLimitConfig{
54+
CloudProviderRateLimit: true,
55+
CloudProviderRateLimitQPS: 0.5,
56+
CloudProviderRateLimitBucket: 1,
57+
CloudProviderRateLimitQPSWrite: 0.5,
58+
CloudProviderRateLimitBucketWrite: 1,
59+
},
60+
Backoff: &retry.Backoff{Steps: 1},
61+
}
62+
63+
routetableClient := New(config)
64+
assert.Equal(t, "sub", routetableClient.subscriptionID)
65+
assert.NotEmpty(t, routetableClient.rateLimiterReader)
66+
assert.NotEmpty(t, routetableClient.rateLimiterWriter)
67+
}
68+
69+
func TestGet(t *testing.T) {
70+
ctrl := gomock.NewController(t)
71+
defer ctrl.Finish()
72+
73+
resourceID := "/subscriptions/subscriptionID/resourceGroups/rg/providers/Microsoft.Network/routeTables/rt1"
74+
response := &http.Response{
75+
StatusCode: http.StatusOK,
76+
Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
77+
}
78+
79+
armClient := mockarmclient.NewMockInterface(ctrl)
80+
armClient.EXPECT().GetResource(gomock.Any(), resourceID, "").Return(response, nil).Times(1)
81+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
82+
83+
routetableClient := getTestRouteTableClient(armClient)
84+
expected := network.RouteTable{}
85+
expected.Response = autorest.Response{Response: response}
86+
result, rerr := routetableClient.Get(context.TODO(), "rg", "rt1", "")
87+
assert.Equal(t, expected, result)
88+
assert.Nil(t, rerr)
89+
}
90+
4091
func TestGetNotFound(t *testing.T) {
4192
ctrl := gomock.NewController(t)
4293
defer ctrl.Finish()
@@ -79,24 +130,166 @@ func TestGetInternalError(t *testing.T) {
79130
assert.Equal(t, http.StatusInternalServerError, rerr.HTTPStatusCode)
80131
}
81132

133+
func TestGetNeverRateLimiter(t *testing.T) {
134+
ctrl := gomock.NewController(t)
135+
defer ctrl.Finish()
136+
137+
rtGetErr := &retry.Error{
138+
RawError: fmt.Errorf("azure cloud provider rate limited(%s) for operation %q", "read", "RouteTableGet"),
139+
Retriable: true,
140+
}
141+
142+
armClient := mockarmclient.NewMockInterface(ctrl)
143+
144+
routetableClient := getTestRouteTableClientWithNeverRateLimiter(armClient)
145+
expected := network.RouteTable{}
146+
result, rerr := routetableClient.Get(context.TODO(), "rg", "rt1", "")
147+
assert.Equal(t, expected, result)
148+
assert.Equal(t, rtGetErr, rerr)
149+
}
150+
151+
func TestGetRetryAfterReader(t *testing.T) {
152+
ctrl := gomock.NewController(t)
153+
defer ctrl.Finish()
154+
155+
rtGetErr := &retry.Error{
156+
RawError: fmt.Errorf("azure cloud provider throttled for operation %s with reason %q", "RouteTableGet", "client throttled"),
157+
Retriable: true,
158+
RetryAfter: getFutureTime(),
159+
}
160+
161+
armClient := mockarmclient.NewMockInterface(ctrl)
162+
163+
routetableClient := getTestRouteTableClientWithRetryAfterReader(armClient)
164+
expected := network.RouteTable{}
165+
result, rerr := routetableClient.Get(context.TODO(), "rg", "rt1", "")
166+
assert.Equal(t, expected, result)
167+
assert.Equal(t, rtGetErr, rerr)
168+
}
169+
170+
func TestGetThrottle(t *testing.T) {
171+
ctrl := gomock.NewController(t)
172+
defer ctrl.Finish()
173+
174+
resourceID := "/subscriptions/subscriptionID/resourceGroups/rg/providers/Microsoft.Network/routeTables/rt1"
175+
response := &http.Response{
176+
StatusCode: http.StatusTooManyRequests,
177+
Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
178+
}
179+
throttleErr := &retry.Error{
180+
HTTPStatusCode: http.StatusTooManyRequests,
181+
RawError: fmt.Errorf("error"),
182+
Retriable: true,
183+
RetryAfter: time.Unix(100, 0),
184+
}
185+
armClient := mockarmclient.NewMockInterface(ctrl)
186+
armClient.EXPECT().GetResource(gomock.Any(), resourceID, "").Return(response, throttleErr).Times(1)
187+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
188+
189+
routetableClient := getTestRouteTableClient(armClient)
190+
result, rerr := routetableClient.Get(context.TODO(), "rg", "rt1", "")
191+
assert.Empty(t, result)
192+
assert.Equal(t, throttleErr, rerr)
193+
}
194+
82195
func TestCreateOrUpdate(t *testing.T) {
83196
ctrl := gomock.NewController(t)
84197
defer ctrl.Finish()
85198

86-
lb := getTestRouteTable("rt1")
199+
rt1 := getTestRouteTable("rt1")
87200
armClient := mockarmclient.NewMockInterface(ctrl)
88201
response := &http.Response{
89202
StatusCode: http.StatusOK,
90203
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
91204
}
92-
armClient.EXPECT().PutResourceWithDecorators(gomock.Any(), to.String(lb.ID), lb, gomock.Any()).Return(response, nil).Times(1)
205+
armClient.EXPECT().PutResourceWithDecorators(gomock.Any(), to.String(rt1.ID), rt1, gomock.Any()).Return(response, nil).Times(1)
93206
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
94207

95208
rtClient := getTestRouteTableClient(armClient)
96-
rerr := rtClient.CreateOrUpdate(context.TODO(), "rg", "rt1", lb, "")
209+
rerr := rtClient.CreateOrUpdate(context.TODO(), "rg", "rt1", rt1, "*")
97210
assert.Nil(t, rerr)
98211
}
99212

213+
func TestCreateOrUpdateWithNeverRateLimiter(t *testing.T) {
214+
ctrl := gomock.NewController(t)
215+
defer ctrl.Finish()
216+
217+
rcCreateOrUpdatetErr := &retry.Error{
218+
RawError: fmt.Errorf("azure cloud provider rate limited(%s) for operation %q", "write", "RouteTableCreateOrUpdate"),
219+
Retriable: true,
220+
}
221+
222+
rt1 := getTestRouteTable("rt1")
223+
armClient := mockarmclient.NewMockInterface(ctrl)
224+
225+
routetableClient := getTestRouteTableClientWithNeverRateLimiter(armClient)
226+
rerr := routetableClient.CreateOrUpdate(context.TODO(), "rg", "rt1", rt1, "")
227+
assert.Equal(t, rcCreateOrUpdatetErr, rerr)
228+
}
229+
230+
func TestCreateOrUpdateRetryAfterReader(t *testing.T) {
231+
ctrl := gomock.NewController(t)
232+
defer ctrl.Finish()
233+
234+
rcCreateOrUpdateErr := &retry.Error{
235+
RawError: fmt.Errorf("azure cloud provider throttled for operation %s with reason %q", "RouteTableCreateOrUpdate", "client throttled"),
236+
Retriable: true,
237+
RetryAfter: getFutureTime(),
238+
}
239+
240+
rt1 := getTestRouteTable("rt1")
241+
armClient := mockarmclient.NewMockInterface(ctrl)
242+
243+
routetableClient := getTestRouteTableClientWithRetryAfterReader(armClient)
244+
rerr := routetableClient.CreateOrUpdate(context.TODO(), "rg", "rt1", rt1, "")
245+
assert.NotNil(t, rerr)
246+
assert.Equal(t, rcCreateOrUpdateErr, rerr)
247+
}
248+
249+
func TestCreateOrUpdateThrottle(t *testing.T) {
250+
ctrl := gomock.NewController(t)
251+
defer ctrl.Finish()
252+
253+
response := &http.Response{
254+
StatusCode: http.StatusTooManyRequests,
255+
Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
256+
}
257+
throttleErr := &retry.Error{
258+
HTTPStatusCode: http.StatusTooManyRequests,
259+
RawError: fmt.Errorf("error"),
260+
Retriable: true,
261+
RetryAfter: time.Unix(100, 0),
262+
}
263+
264+
rt1 := getTestRouteTable("rt1")
265+
armClient := mockarmclient.NewMockInterface(ctrl)
266+
armClient.EXPECT().PutResourceWithDecorators(gomock.Any(), to.String(rt1.ID), rt1, gomock.Any()).Return(response, throttleErr).Times(1)
267+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
268+
269+
routetableClient := getTestRouteTableClient(armClient)
270+
rerr := routetableClient.CreateOrUpdate(context.TODO(), "rg", "rt1", rt1, "")
271+
assert.Equal(t, throttleErr, rerr)
272+
}
273+
274+
func TestCreateOrUpdateWithCreateOrUpdateResponderError(t *testing.T) {
275+
ctrl := gomock.NewController(t)
276+
defer ctrl.Finish()
277+
278+
rt1 := getTestRouteTable("rt1")
279+
armClient := mockarmclient.NewMockInterface(ctrl)
280+
response := &http.Response{
281+
StatusCode: http.StatusNotFound,
282+
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
283+
}
284+
285+
armClient.EXPECT().PutResourceWithDecorators(gomock.Any(), to.String(rt1.ID), rt1, gomock.Any()).Return(response, nil).Times(1)
286+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
287+
288+
routetableClient := getTestRouteTableClient(armClient)
289+
rerr := routetableClient.CreateOrUpdate(context.TODO(), "rg", "rt1", rt1, "")
290+
assert.NotNil(t, rerr)
291+
}
292+
100293
func getTestRouteTable(name string) network.RouteTable {
101294
return network.RouteTable{
102295
ID: to.StringPtr(fmt.Sprintf("/subscriptions/subscriptionID/resourceGroups/rg/providers/Microsoft.Network/routeTables/%s", name)),
@@ -114,3 +307,27 @@ func getTestRouteTableClient(armClient armclient.Interface) *Client {
114307
rateLimiterWriter: rateLimiterWriter,
115308
}
116309
}
310+
311+
func getTestRouteTableClientWithNeverRateLimiter(armClient armclient.Interface) *Client {
312+
rateLimiterReader := flowcontrol.NewFakeNeverRateLimiter()
313+
rateLimiterWriter := flowcontrol.NewFakeNeverRateLimiter()
314+
return &Client{
315+
armClient: armClient,
316+
subscriptionID: "subscriptionID",
317+
rateLimiterReader: rateLimiterReader,
318+
rateLimiterWriter: rateLimiterWriter,
319+
}
320+
}
321+
322+
func getTestRouteTableClientWithRetryAfterReader(armClient armclient.Interface) *Client {
323+
rateLimiterReader := flowcontrol.NewFakeAlwaysRateLimiter()
324+
rateLimiterWriter := flowcontrol.NewFakeAlwaysRateLimiter()
325+
return &Client{
326+
armClient: armClient,
327+
subscriptionID: "subscriptionID",
328+
rateLimiterReader: rateLimiterReader,
329+
rateLimiterWriter: rateLimiterWriter,
330+
RetryAfterReader: getFutureTime(),
331+
RetryAfterWriter: getFutureTime(),
332+
}
333+
}

0 commit comments

Comments
 (0)