1 package azure
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import (
18 "encoding/json"
19 "fmt"
20 "io/ioutil"
21 "net/http"
22 "reflect"
23 "strconv"
24 "strings"
25 "testing"
26 "time"
27
28 "github.com/Azure/go-autorest/autorest"
29 "github.com/Azure/go-autorest/autorest/mocks"
30 )
31
32 const (
33 headerAuthorization = "Authorization"
34 longDelay = 5 * time.Second
35 retryDelay = 10 * time.Millisecond
36 testLogPrefix = "azure:"
37 )
38
39
40 func ExampleWithClientID() {
41 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
42 req, _ := autorest.Prepare(&http.Request{},
43 autorest.AsGet(),
44 autorest.WithBaseURL("https://microsoft.com/a/b/c/"))
45
46 c := autorest.Client{Sender: mocks.NewSender()}
47 c.RequestInspector = WithReturningClientID(uuid)
48
49 autorest.SendWithSender(c, req)
50 fmt.Printf("Inspector added the %s header with the value %s\n",
51 HeaderClientID, req.Header.Get(HeaderClientID))
52 fmt.Printf("Inspector added the %s header with the value %s\n",
53 HeaderReturnClientID, req.Header.Get(HeaderReturnClientID))
54
55
56
57 }
58
59 func TestWithReturningClientIDReturnsError(t *testing.T) {
60 var errIn error
61 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
62 _, errOut := autorest.Prepare(&http.Request{},
63 withErrorPrepareDecorator(&errIn),
64 WithReturningClientID(uuid))
65
66 if errOut == nil || errIn != errOut {
67 t.Fatalf("azure: WithReturningClientID failed to exit early when receiving an error -- expected (%v), received (%v)",
68 errIn, errOut)
69 }
70 }
71
72 func TestWithClientID(t *testing.T) {
73 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
74 req, _ := autorest.Prepare(&http.Request{},
75 WithClientID(uuid))
76
77 if req.Header.Get(HeaderClientID) != uuid {
78 t.Fatalf("azure: WithClientID failed to set %s -- expected %s, received %s",
79 HeaderClientID, uuid, req.Header.Get(HeaderClientID))
80 }
81 }
82
83 func TestWithReturnClientID(t *testing.T) {
84 b := false
85 req, _ := autorest.Prepare(&http.Request{},
86 WithReturnClientID(b))
87
88 if req.Header.Get(HeaderReturnClientID) != strconv.FormatBool(b) {
89 t.Fatalf("azure: WithReturnClientID failed to set %s -- expected %s, received %s",
90 HeaderClientID, strconv.FormatBool(b), req.Header.Get(HeaderClientID))
91 }
92 }
93
94 func TestExtractClientID(t *testing.T) {
95 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
96 resp := mocks.NewResponse()
97 mocks.SetResponseHeader(resp, HeaderClientID, uuid)
98
99 if ExtractClientID(resp) != uuid {
100 t.Fatalf("azure: ExtractClientID failed to extract the %s -- expected %s, received %s",
101 HeaderClientID, uuid, ExtractClientID(resp))
102 }
103 }
104
105 func TestExtractRequestID(t *testing.T) {
106 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
107 resp := mocks.NewResponse()
108 mocks.SetResponseHeader(resp, HeaderRequestID, uuid)
109
110 if ExtractRequestID(resp) != uuid {
111 t.Fatalf("azure: ExtractRequestID failed to extract the %s -- expected %s, received %s",
112 HeaderRequestID, uuid, ExtractRequestID(resp))
113 }
114 }
115
116 func TestIsAzureError_ReturnsTrueForAzureError(t *testing.T) {
117 if !IsAzureError(&RequestError{}) {
118 t.Fatalf("azure: IsAzureError failed to return true for an Azure Service error")
119 }
120 }
121
122 func TestIsAzureError_ReturnsFalseForNonAzureError(t *testing.T) {
123 if IsAzureError(fmt.Errorf("An Error")) {
124 t.Fatalf("azure: IsAzureError return true for an non-Azure Service error")
125 }
126 }
127
128 func TestNewErrorWithError_UsesReponseStatusCode(t *testing.T) {
129 e := NewErrorWithError(fmt.Errorf("Error"), "packageType", "method", mocks.NewResponseWithStatus("Forbidden", http.StatusForbidden), "message")
130 if e.StatusCode != http.StatusForbidden {
131 t.Fatalf("azure: NewErrorWithError failed to use the Status Code of the passed Response -- expected %v, received %v", http.StatusForbidden, e.StatusCode)
132 }
133 }
134
135 func TestNewErrorWithError_ReturnsUnwrappedError(t *testing.T) {
136 e1 := RequestError{}
137 e1.ServiceError = &ServiceError{Code: "42", Message: "A Message"}
138 e1.StatusCode = 200
139 e1.RequestID = "A RequestID"
140 e2 := NewErrorWithError(&e1, "packageType", "method", nil, "message")
141
142 if !reflect.DeepEqual(e1, e2) {
143 t.Fatalf("azure: NewErrorWithError wrapped an RequestError -- expected %T, received %T", e1, e2)
144 }
145 }
146
147 func TestNewErrorWithError_WrapsAnError(t *testing.T) {
148 e1 := fmt.Errorf("Inner Error")
149 var e2 interface{} = NewErrorWithError(e1, "packageType", "method", nil, "message")
150
151 if _, ok := e2.(RequestError); !ok {
152 t.Fatalf("azure: NewErrorWithError failed to wrap a standard error -- received %T", e2)
153 }
154 }
155
156 func TestWithErrorUnlessStatusCode_NotAnAzureError(t *testing.T) {
157 body := `<html>
158 <head>
159 <title>IIS Error page</title>
160 </head>
161 <body>Some non-JSON error page</body>
162 </html>`
163 r := mocks.NewResponseWithContent(body)
164 r.Request = mocks.NewRequest()
165 r.StatusCode = http.StatusBadRequest
166 r.Status = http.StatusText(r.StatusCode)
167
168 err := autorest.Respond(r,
169 WithErrorUnlessStatusCode(http.StatusOK),
170 autorest.ByClosing())
171 ok, _ := err.(*RequestError)
172 if ok != nil {
173 t.Fatalf("azure: azure.RequestError returned from malformed response: %v", err)
174 }
175
176
177 defer r.Body.Close()
178 b, err := ioutil.ReadAll(r.Body)
179 if err != nil {
180 t.Fatal(err)
181 }
182 if string(b) != body {
183 t.Fatalf("response body is wrong. got=%q exptected=%q", string(b), body)
184 }
185 }
186
187 func TestWithErrorUnlessStatusCode_FoundAzureErrorWithoutDetails(t *testing.T) {
188 j := `{
189 "error": {
190 "code": "InternalError",
191 "message": "Azure is having trouble right now."
192 }
193 }`
194 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
195 r := mocks.NewResponseWithContent(j)
196 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
197 r.Request = mocks.NewRequest()
198 r.StatusCode = http.StatusInternalServerError
199 r.Status = http.StatusText(r.StatusCode)
200
201 err := autorest.Respond(r,
202 WithErrorUnlessStatusCode(http.StatusOK),
203 autorest.ByClosing())
204
205 if err == nil {
206 t.Fatalf("azure: returned nil error for proper error response")
207 }
208 azErr, ok := err.(*RequestError)
209 if !ok {
210 t.Fatalf("azure: returned error is not azure.RequestError: %T", err)
211 }
212
213 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Azure is having trouble right now.\""
214 if !reflect.DeepEqual(expected, azErr.Error()) {
215 t.Fatalf("azure: service error is not unmarshaled properly.\nexpected=%v\ngot=%v", expected, azErr.Error())
216 }
217
218 if expected := http.StatusInternalServerError; azErr.StatusCode != expected {
219 t.Fatalf("azure: got wrong StatusCode=%d Expected=%d", azErr.StatusCode, expected)
220 }
221 if expected := uuid; azErr.RequestID != expected {
222 t.Fatalf("azure: wrong request ID in error. expected=%q; got=%q", expected, azErr.RequestID)
223 }
224
225 _ = azErr.Error()
226
227
228 defer r.Body.Close()
229 b, err := ioutil.ReadAll(r.Body)
230 if err != nil {
231 t.Fatal(err)
232 }
233 if string(b) != j {
234 t.Fatalf("response body is wrong. got=%q expected=%q", string(b), j)
235 }
236
237 }
238
239 func TestWithErrorUnlessStatusCode_FoundAzureFullError(t *testing.T) {
240 j := `{
241 "error": {
242 "code": "InternalError",
243 "message": "Azure is having trouble right now.",
244 "target": "target1",
245 "details": [{"code": "conflict1", "message":"error message1"},
246 {"code": "conflict2", "message":"error message2"}],
247 "innererror": { "customKey": "customValue" },
248 "additionalInfo": [{"type": "someErrorType", "info": {"someProperty": "someValue"}}]
249 }
250 }`
251 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
252 r := mocks.NewResponseWithContent(j)
253 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
254 r.Request = mocks.NewRequest()
255 r.StatusCode = http.StatusInternalServerError
256 r.Status = http.StatusText(r.StatusCode)
257
258 err := autorest.Respond(r,
259 WithErrorUnlessStatusCode(http.StatusOK),
260 autorest.ByClosing())
261
262 if err == nil {
263 t.Fatalf("azure: returned nil error for proper error response")
264 }
265 azErr, ok := err.(*RequestError)
266 if !ok {
267 t.Fatalf("azure: returned error is not azure.RequestError: %T", err)
268 }
269
270 if expected := "InternalError"; azErr.ServiceError.Code != expected {
271 t.Fatalf("azure: wrong error code. expected=%q; got=%q", expected, azErr.ServiceError.Code)
272 }
273
274 if azErr.ServiceError.Message == "" {
275 t.Fatalf("azure: error message is not unmarshaled properly")
276 }
277
278 if *azErr.ServiceError.Target == "" {
279 t.Fatalf("azure: error target is not unmarshaled properly")
280 }
281
282 d, _ := json.Marshal(azErr.ServiceError.Details)
283 if string(d) != `[{"code":"conflict1","message":"error message1"},{"code":"conflict2","message":"error message2"}]` {
284 t.Fatalf("azure: error details is not unmarshaled properly")
285 }
286
287 i, _ := json.Marshal(azErr.ServiceError.InnerError)
288 if string(i) != `{"customKey":"customValue"}` {
289 t.Fatalf("azure: inner error is not unmarshaled properly")
290 }
291
292 a, _ := json.Marshal(azErr.ServiceError.AdditionalInfo)
293 if string(a) != `[{"info":{"someProperty":"someValue"},"type":"someErrorType"}]` {
294 t.Fatalf("azure: error additional info is not unmarshaled properly")
295 }
296
297 if expected := http.StatusInternalServerError; azErr.StatusCode != expected {
298 t.Fatalf("azure: got wrong StatusCode=%v Expected=%d", azErr.StatusCode, expected)
299 }
300 if expected := uuid; azErr.RequestID != expected {
301 t.Fatalf("azure: wrong request ID in error. expected=%q; got=%q", expected, azErr.RequestID)
302 }
303
304 _ = azErr.Error()
305
306
307 defer r.Body.Close()
308 b, err := ioutil.ReadAll(r.Body)
309 if err != nil {
310 t.Fatal(err)
311 }
312 if string(b) != j {
313 t.Fatalf("response body is wrong. got=%q expected=%q", string(b), j)
314 }
315
316 }
317
318 func TestWithErrorUnlessStatusCode_LiteralNullValueInResponse(t *testing.T) {
319
320
321 j := `null`
322 r := mocks.NewResponseWithContent(j)
323 mocks.SetResponseHeader(r, HeaderContentType, "application/json; charset=utf-8")
324 r.Request = mocks.NewRequest()
325 r.StatusCode = http.StatusInternalServerError
326 r.Status = http.StatusText(r.StatusCode)
327
328 err := autorest.Respond(r,
329 WithErrorUnlessStatusCode(http.StatusOK),
330 autorest.ByClosing())
331 if err == nil {
332 t.Fatalf("azure: returned nil error for proper error response")
333 }
334 azErr, ok := err.(*RequestError)
335 if !ok {
336 t.Fatalf("azure: returned error is not azure.RequestError: %T", err)
337 }
338
339 expected := &ServiceError{
340 Code: "Unknown",
341 Message: "Unknown service error",
342 Details: []map[string]interface{}{
343 {"HttpResponse.Body": "null"},
344 },
345 }
346
347 if !reflect.DeepEqual(expected, azErr.ServiceError) {
348 t.Fatalf("azure: service error is not unmarshaled properly. expected=%q\ngot=%q", expected, azErr.ServiceError)
349 }
350 }
351
352 func TestWithErrorUnlessStatusCode_NoAzureError(t *testing.T) {
353 j := `{
354 "Status":"NotFound"
355 }`
356 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
357 r := mocks.NewResponseWithContent(j)
358 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
359 r.Request = mocks.NewRequest()
360 r.StatusCode = http.StatusInternalServerError
361 r.Status = http.StatusText(r.StatusCode)
362
363 err := autorest.Respond(r,
364 WithErrorUnlessStatusCode(http.StatusOK),
365 autorest.ByClosing())
366 if err == nil {
367 t.Fatalf("azure: returned nil error for proper error response")
368 }
369 azErr, ok := err.(*RequestError)
370 if !ok {
371 t.Fatalf("azure: returned error is not azure.RequestError: %T", err)
372 }
373
374 expected := &ServiceError{
375 Code: "Unknown",
376 Message: "Unknown service error",
377 Details: []map[string]interface{}{
378 {"Status": "NotFound"},
379 },
380 }
381
382 if !reflect.DeepEqual(expected, azErr.ServiceError) {
383 t.Fatalf("azure: service error is not unmarshaled properly. expected=%q\ngot=%q", expected, azErr.ServiceError)
384 }
385
386 if expected := http.StatusInternalServerError; azErr.StatusCode != expected {
387 t.Fatalf("azure: got wrong StatusCode=%v Expected=%d", azErr.StatusCode, expected)
388 }
389 if expected := uuid; azErr.RequestID != expected {
390 t.Fatalf("azure: wrong request ID in error. expected=%q; got=%q", expected, azErr.RequestID)
391 }
392
393 _ = azErr.Error()
394
395
396 defer r.Body.Close()
397 b, err := ioutil.ReadAll(r.Body)
398 if err != nil {
399 t.Fatal(err)
400 }
401 if string(b) != j {
402 t.Fatalf("response body is wrong. got=%q expected=%q", string(b), j)
403 }
404
405 }
406
407 func TestWithErrorUnlessStatusCode_UnwrappedError(t *testing.T) {
408 j := `{
409 "code": "InternalError",
410 "message": "Azure is having trouble right now.",
411 "target": "target1",
412 "details": [{"code": "conflict1", "message":"error message1"},
413 {"code": "conflict2", "message":"error message2"}],
414 "innererror": { "customKey": "customValue" },
415 "additionalInfo": [{"type": "someErrorType", "info": {"someProperty": "someValue"}}]
416 }`
417 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
418 r := mocks.NewResponseWithContent(j)
419 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
420 r.Request = mocks.NewRequest()
421 r.StatusCode = http.StatusInternalServerError
422 r.Status = http.StatusText(r.StatusCode)
423
424 err := autorest.Respond(r,
425 WithErrorUnlessStatusCode(http.StatusOK),
426 autorest.ByClosing())
427
428 if err == nil {
429 t.Fatal("azure: returned nil error for proper error response")
430 }
431
432 azErr, ok := err.(*RequestError)
433 if !ok {
434 t.Fatalf("returned error is not azure.RequestError: %T", err)
435 }
436
437 if expected := http.StatusInternalServerError; azErr.StatusCode != expected {
438 t.Logf("Incorrect StatusCode got: %v want: %d", azErr.StatusCode, expected)
439 t.Fail()
440 }
441
442 if expected := "Azure is having trouble right now."; azErr.Message != expected {
443 t.Logf("Incorrect Message\n\tgot: %q\n\twant: %q", azErr.Message, expected)
444 t.Fail()
445 }
446
447 if expected := uuid; azErr.RequestID != expected {
448 t.Logf("Incorrect request ID\n\tgot: %q\n\twant: %q", azErr.RequestID, expected)
449 t.Fail()
450 }
451
452 if azErr.ServiceError == nil {
453 t.Logf("`ServiceError` was nil when it shouldn't have been.")
454 t.Fail()
455 }
456
457 if expected := "target1"; *azErr.ServiceError.Target != expected {
458 t.Logf("Incorrect Target\n\tgot: %q\n\twant: %q", *azErr.ServiceError.Target, expected)
459 t.Fail()
460 }
461
462 expectedServiceErrorDetails := `[{"code":"conflict1","message":"error message1"},{"code":"conflict2","message":"error message2"}]`
463 if azErr.ServiceError.Details == nil {
464 t.Logf("`ServiceError.Details` was nil when it should have been %q", expectedServiceErrorDetails)
465 t.Fail()
466 } else if details, _ := json.Marshal(azErr.ServiceError.Details); expectedServiceErrorDetails != string(details) {
467 t.Logf("Error details was not unmarshaled properly.\n\tgot: %q\n\twant: %q", string(details), expectedServiceErrorDetails)
468 t.Fail()
469 }
470
471 expectedServiceErrorInnerError := `{"customKey":"customValue"}`
472 if azErr.ServiceError.InnerError == nil {
473 t.Logf("`ServiceError.InnerError` was nil when it should have been %q", expectedServiceErrorInnerError)
474 t.Fail()
475 } else if innerError, _ := json.Marshal(azErr.ServiceError.InnerError); expectedServiceErrorInnerError != string(innerError) {
476 t.Logf("Inner error was not unmarshaled properly.\n\tgot: %q\n\twant: %q", string(innerError), expectedServiceErrorInnerError)
477 t.Fail()
478 }
479
480 expectedServiceErrorAdditionalInfo := `[{"info":{"someProperty":"someValue"},"type":"someErrorType"}]`
481 if azErr.ServiceError.AdditionalInfo == nil {
482 t.Logf("`ServiceError.AdditionalInfo` was nil when it should have been %q", expectedServiceErrorAdditionalInfo)
483 t.Fail()
484 } else if additionalInfo, _ := json.Marshal(azErr.ServiceError.AdditionalInfo); expectedServiceErrorAdditionalInfo != string(additionalInfo) {
485 t.Logf("Additional info was not unmarshaled properly.\n\tgot: %q\n\twant: %q", string(additionalInfo), expectedServiceErrorAdditionalInfo)
486 t.Fail()
487 }
488
489
490 defer r.Body.Close()
491 b, err := ioutil.ReadAll(r.Body)
492 if err != nil {
493 t.Error(err)
494 }
495 if string(b) != j {
496 t.Fatalf("response body is wrong. got=%q expected=%q", string(b), j)
497 }
498
499 }
500
501 func TestRequestErrorString_WithError(t *testing.T) {
502 j := `{
503 "error": {
504 "code": "InternalError",
505 "message": "Conflict",
506 "target": "target1",
507 "details": [{"code": "conflict1", "message":"error message1"}],
508 "innererror": { "customKey": "customValue" },
509 "additionalInfo": [{"type": "someErrorType", "info": {"someProperty": "someValue"}}]
510 }
511 }`
512 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
513 r := mocks.NewResponseWithContent(j)
514 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
515 r.Request = mocks.NewRequest()
516 r.StatusCode = http.StatusInternalServerError
517 r.Status = http.StatusText(r.StatusCode)
518
519 err := autorest.Respond(r,
520 WithErrorUnlessStatusCode(http.StatusOK),
521 autorest.ByClosing())
522
523 if err == nil {
524 t.Fatalf("azure: returned nil error for proper error response")
525 }
526 azErr, _ := err.(*RequestError)
527 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Target=\"target1\" Details=[{\"code\":\"conflict1\",\"message\":\"error message1\"}] InnerError={\"customKey\":\"customValue\"} AdditionalInfo=[{\"info\":{\"someProperty\":\"someValue\"},\"type\":\"someErrorType\"}]"
528 if expected != azErr.Error() {
529 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
530 }
531 }
532
533 func TestRequestErrorString_WithErrorNonConforming(t *testing.T) {
534
535
536 j := `{
537 "error": {
538 "code": "InternalError",
539 "message": "Conflict",
540 "details": {"code": "conflict1", "message":"error message1"},
541 "innererror": [{ "customKey": "customValue" }]
542 }
543 }`
544 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
545 r := mocks.NewResponseWithContent(j)
546 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
547 r.Request = mocks.NewRequest()
548 r.StatusCode = http.StatusInternalServerError
549 r.Status = http.StatusText(r.StatusCode)
550
551 err := autorest.Respond(r,
552 WithErrorUnlessStatusCode(http.StatusOK),
553 autorest.ByClosing())
554
555 if err == nil {
556 t.Fatalf("azure: returned nil error for proper error response")
557 }
558 azErr, _ := err.(*RequestError)
559 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Details=[{\"code\":\"conflict1\",\"message\":\"error message1\"}] InnerError={\"customKey\":\"customValue\"}"
560 if expected != azErr.Error() {
561 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
562 }
563 }
564
565 func TestRequestErrorString_WithErrorNonConforming2(t *testing.T) {
566
567 j := `{
568 "error": {
569 "code": "InternalError",
570 "message": "Conflict",
571 "details": {"code": "conflict1", "message":"error message1"},
572 "innererror": "something bad happened"
573 }
574 }`
575 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
576 r := mocks.NewResponseWithContent(j)
577 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
578 r.Request = mocks.NewRequest()
579 r.StatusCode = http.StatusInternalServerError
580 r.Status = http.StatusText(r.StatusCode)
581
582 err := autorest.Respond(r,
583 WithErrorUnlessStatusCode(http.StatusOK),
584 autorest.ByClosing())
585
586 if err == nil {
587 t.Fatalf("azure: returned nil error for proper error response")
588 }
589 azErr, _ := err.(*RequestError)
590 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Details=[{\"code\":\"conflict1\",\"message\":\"error message1\"}] InnerError={\"error\":\"something bad happened\"}"
591 if expected != azErr.Error() {
592 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
593 }
594 }
595
596 func TestRequestErrorString_WithErrorNonConforming3(t *testing.T) {
597
598
599 j := `{
600 "error": {
601 "code": "InternalError",
602 "message": "Conflict",
603 "details": {"code": "conflict1", "message":"error message1"},
604 "innererror": [{ "customKey": "customValue" }, { "customKey2": "customValue2" }]
605 }
606 }`
607 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
608 r := mocks.NewResponseWithContent(j)
609 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
610 r.Request = mocks.NewRequest()
611 r.StatusCode = http.StatusInternalServerError
612 r.Status = http.StatusText(r.StatusCode)
613
614 err := autorest.Respond(r,
615 WithErrorUnlessStatusCode(http.StatusOK),
616 autorest.ByClosing())
617
618 if err == nil {
619 t.Fatalf("azure: returned nil error for proper error response")
620 }
621 azErr, _ := err.(*RequestError)
622 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Details=[{\"code\":\"conflict1\",\"message\":\"error message1\"}] InnerError={\"multi\":[{\"customKey\":\"customValue\"},{\"customKey2\":\"customValue2\"}]}"
623 if expected != azErr.Error() {
624 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
625 }
626 }
627
628 func TestRequestErrorString_WithErrorNonConforming4(t *testing.T) {
629
630 j := `{
631 "error": {
632 "code": "InternalError",
633 "message": "Conflict",
634 "details": "something bad happened"
635 }
636 }`
637 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
638 r := mocks.NewResponseWithContent(j)
639 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
640 r.Request = mocks.NewRequest()
641 r.StatusCode = http.StatusInternalServerError
642 r.Status = http.StatusText(r.StatusCode)
643
644 err := autorest.Respond(r,
645 WithErrorUnlessStatusCode(http.StatusOK),
646 autorest.ByClosing())
647
648 if err == nil {
649 t.Fatalf("azure: returned nil error for proper error response")
650 }
651 azErr, _ := err.(*RequestError)
652 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Details=[{\"raw\":\"something bad happened\"}]"
653 if expected != azErr.Error() {
654 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
655 }
656 }
657
658 func TestRequestErrorString_WithErrorNonConforming5(t *testing.T) {
659
660 j := `{
661 "error": {
662 "code": "InternalError",
663 "message": "Conflict",
664 "details": {"code": "conflict1", "message":"error message1"},
665 "innererror": 500
666 }
667 }`
668 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
669 r := mocks.NewResponseWithContent(j)
670 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
671 r.Request = mocks.NewRequest()
672 r.StatusCode = http.StatusInternalServerError
673 r.Status = http.StatusText(r.StatusCode)
674
675 err := autorest.Respond(r,
676 WithErrorUnlessStatusCode(http.StatusOK),
677 autorest.ByClosing())
678
679 if err == nil {
680 t.Fatalf("azure: returned nil error for proper error response")
681 }
682 azErr, _ := err.(*RequestError)
683 expected := "autorest/azure: Service returned an error. Status=500 Code=\"InternalError\" Message=\"Conflict\" Details=[{\"code\":\"conflict1\",\"message\":\"error message1\"}] InnerError={\"raw\":500}"
684 if expected != azErr.Error() {
685 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, azErr.Error())
686 }
687 }
688
689 func TestRequestErrorString_WithErrorNonConforming6(t *testing.T) {
690
691 j := `{
692 "code": 409,
693 "message": "Conflict",
694 "details": "something bad happened"
695 }`
696 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
697 r := mocks.NewResponseWithContent(j)
698 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
699 r.Request = mocks.NewRequest()
700 r.StatusCode = http.StatusInternalServerError
701 r.Status = http.StatusText(r.StatusCode)
702
703 err := autorest.Respond(r,
704 WithErrorUnlessStatusCode(http.StatusOK),
705 autorest.ByClosing())
706
707 if err == nil {
708 t.Fatalf("azure: returned nil error for proper error response")
709 }
710 if _, ok := err.(*RequestError); ok {
711 t.Fatal("unexpected RequestError when unmarshalling fails")
712 }
713 }
714
715 func TestParseResourceID_WithValidBasicResourceID(t *testing.T) {
716
717 basicResourceID := "/subscriptions/subid-3-3-4/resourceGroups/regGroupVladdb/providers/Microsoft.Network/LoadBalancer/testResourceName"
718 want := Resource{
719 SubscriptionID: "subid-3-3-4",
720 ResourceGroup: "regGroupVladdb",
721 Provider: "Microsoft.Network",
722 ResourceType: "LoadBalancer",
723 ResourceName: "testResourceName",
724 }
725 got, err := ParseResourceID(basicResourceID)
726
727 if err != nil {
728 t.Fatalf("azure: error returned while parsing valid resourceId")
729 }
730
731 if got != want {
732 t.Logf("got: %+v\nwant: %+v", got, want)
733 t.Fail()
734 }
735
736 reGenResourceID := got.String()
737 if !strings.EqualFold(basicResourceID, reGenResourceID) {
738 t.Logf("got: %+v\nwant: %+v", reGenResourceID, basicResourceID)
739 t.Fail()
740 }
741 }
742
743 func TestParseResourceID_WithValidSubResourceID(t *testing.T) {
744 subresourceID := "/subscriptions/subid-3-3-4/resourceGroups/regGroupVladdb/providers/Microsoft.Network/LoadBalancer/resource/is/a/subresource/actualresourceName"
745 want := Resource{
746 SubscriptionID: "subid-3-3-4",
747 ResourceGroup: "regGroupVladdb",
748 Provider: "Microsoft.Network",
749 ResourceType: "LoadBalancer",
750 ResourceName: "actualresourceName",
751 }
752 got, err := ParseResourceID(subresourceID)
753
754 if err != nil {
755 t.Fatalf("azure: error returned while parsing valid resourceId")
756 }
757
758 if got != want {
759 t.Logf("got: %+v\nwant: %+v", got, want)
760 t.Fail()
761 }
762 }
763
764 func TestParseResourceID_WithIncompleteResourceID(t *testing.T) {
765 basicResourceID := "/subscriptions/subid-3-3-4/resourceGroups/regGroupVladdb/providers/Microsoft.Network/"
766 want := Resource{}
767
768 got, err := ParseResourceID(basicResourceID)
769
770 if err == nil {
771 t.Fatalf("azure: no error returned on incomplete resource id")
772 }
773
774 if got != want {
775 t.Logf("got: %+v\nwant: %+v", got, want)
776 t.Fail()
777 }
778 }
779
780 func TestParseResourceID_WithMalformedResourceID(t *testing.T) {
781 malformedResourceID := "/providers/subid-3-3-4/resourceGroups/regGroupVladdb/subscriptions/Microsoft.Network/LoadBalancer/testResourceName"
782 want := Resource{}
783
784 got, err := ParseResourceID(malformedResourceID)
785
786 if err == nil {
787 t.Fatalf("azure: error returned while parsing malformed resourceID")
788 }
789
790 if got != want {
791 t.Logf("got: %+v\nwant: %+v", got, want)
792 t.Fail()
793 }
794 }
795
796 func TestRequestErrorString_WithXMLError(t *testing.T) {
797 j := `<?xml version="1.0" encoding="utf-8"?>
798 <Error>
799 <Code>InternalError</Code>
800 <Message>Internal service error.</Message>
801 </Error> `
802 uuid := "71FDB9F4-5E49-4C12-B266-DE7B4FD999A6"
803 r := mocks.NewResponseWithContent(j)
804 mocks.SetResponseHeader(r, HeaderRequestID, uuid)
805 r.Request = mocks.NewRequest()
806 r.StatusCode = http.StatusInternalServerError
807 r.Status = http.StatusText(r.StatusCode)
808 r.Header.Add("Content-Type", "text/xml")
809
810 err := autorest.Respond(r,
811 WithErrorUnlessStatusCode(http.StatusOK),
812 autorest.ByClosing())
813
814 if err == nil {
815 t.Fatalf("azure: returned nil error for proper error response")
816 }
817 azErr, _ := err.(*RequestError)
818 const expected = `autorest/azure: Service returned an error. Status=500 Code="InternalError" Message="Internal service error."`
819 if got := azErr.Error(); expected != got {
820 fmt.Println(got)
821 t.Fatalf("azure: send wrong RequestError.\nexpected=%v\ngot=%v", expected, got)
822 }
823 }
824
825 func withErrorPrepareDecorator(e *error) autorest.PrepareDecorator {
826 return func(p autorest.Preparer) autorest.Preparer {
827 return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
828 *e = fmt.Errorf("azure: Faux Prepare Error")
829 return r, *e
830 })
831 }
832 }
833
834 func withAsyncResponseDecorator(n int) autorest.SendDecorator {
835 i := 0
836 return func(s autorest.Sender) autorest.Sender {
837 return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) {
838 resp, err := s.Do(r)
839 if err == nil {
840 if i < n {
841 resp.StatusCode = http.StatusCreated
842 resp.Header = http.Header{}
843 resp.Header.Add(http.CanonicalHeaderKey(headerAsyncOperation), mocks.TestURL)
844 i++
845 } else {
846 resp.StatusCode = http.StatusOK
847 resp.Header.Del(http.CanonicalHeaderKey(headerAsyncOperation))
848 }
849 }
850 return resp, err
851 })
852 }
853 }
854
855 type mockAuthorizer struct{}
856
857 func (ma mockAuthorizer) WithAuthorization() autorest.PrepareDecorator {
858 return autorest.WithHeader(headerAuthorization, mocks.TestAuthorizationHeader)
859 }
860
861 type mockFailingAuthorizer struct{}
862
863 func (mfa mockFailingAuthorizer) WithAuthorization() autorest.PrepareDecorator {
864 return func(p autorest.Preparer) autorest.Preparer {
865 return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
866 return r, fmt.Errorf("ERROR: mockFailingAuthorizer returned expected error")
867 })
868 }
869 }
870
871 type mockInspector struct {
872 wasInvoked bool
873 }
874
875 func (mi *mockInspector) WithInspection() autorest.PrepareDecorator {
876 return func(p autorest.Preparer) autorest.Preparer {
877 return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
878 mi.wasInvoked = true
879 return p.Prepare(r)
880 })
881 }
882 }
883
884 func (mi *mockInspector) ByInspecting() autorest.RespondDecorator {
885 return func(r autorest.Responder) autorest.Responder {
886 return autorest.ResponderFunc(func(resp *http.Response) error {
887 mi.wasInvoked = true
888 return r.Respond(resp)
889 })
890 }
891 }
892
View as plain text