1 package autorest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import (
18 "bytes"
19 "context"
20 "crypto/tls"
21 "fmt"
22 "io/ioutil"
23 "log"
24 "math/rand"
25 "net/http"
26 "net/http/httptest"
27 "reflect"
28 "testing"
29 "time"
30
31 "github.com/Azure/go-autorest/autorest/mocks"
32 )
33
34 func TestLoggingInspectorWithInspection(t *testing.T) {
35 b := bytes.Buffer{}
36 c := Client{}
37 li := LoggingInspector{Logger: log.New(&b, "", 0)}
38 c.RequestInspector = li.WithInspection()
39
40 Prepare(mocks.NewRequestWithContent("Content"),
41 c.WithInspection())
42
43 if len(b.String()) <= 0 {
44 t.Fatal("autorest: LoggingInspector#WithInspection did not record Request to the log")
45 }
46 }
47
48 func TestLoggingInspectorWithInspectionEmitsErrors(t *testing.T) {
49 b := bytes.Buffer{}
50 c := Client{}
51 r := mocks.NewRequestWithContent("Content")
52 li := LoggingInspector{Logger: log.New(&b, "", 0)}
53 c.RequestInspector = li.WithInspection()
54
55 if _, err := Prepare(r,
56 c.WithInspection()); err != nil {
57 t.Error(err)
58 }
59
60 if len(b.String()) <= 0 {
61 t.Fatal("autorest: LoggingInspector#WithInspection did not record Request to the log")
62 }
63 }
64
65 func TestLoggingInspectorWithInspectionRestoresBody(t *testing.T) {
66 b := bytes.Buffer{}
67 c := Client{}
68 r := mocks.NewRequestWithContent("Content")
69 li := LoggingInspector{Logger: log.New(&b, "", 0)}
70 c.RequestInspector = li.WithInspection()
71
72 Prepare(r,
73 c.WithInspection())
74
75 s, _ := ioutil.ReadAll(r.Body)
76 if len(s) <= 0 {
77 t.Fatal("autorest: LoggingInspector#WithInspection did not restore the Request body")
78 }
79 }
80
81 func TestLoggingInspectorByInspecting(t *testing.T) {
82 b := bytes.Buffer{}
83 c := Client{}
84 li := LoggingInspector{Logger: log.New(&b, "", 0)}
85 c.ResponseInspector = li.ByInspecting()
86
87 Respond(mocks.NewResponseWithContent("Content"),
88 c.ByInspecting())
89
90 if len(b.String()) <= 0 {
91 t.Fatal("autorest: LoggingInspector#ByInspection did not record Response to the log")
92 }
93 }
94
95 func TestLoggingInspectorByInspectingEmitsErrors(t *testing.T) {
96 b := bytes.Buffer{}
97 c := Client{}
98 r := mocks.NewResponseWithContent("Content")
99 li := LoggingInspector{Logger: log.New(&b, "", 0)}
100 c.ResponseInspector = li.ByInspecting()
101
102 if err := Respond(r,
103 c.ByInspecting()); err != nil {
104 t.Fatal(err)
105 }
106
107 if len(b.String()) <= 0 {
108 t.Fatal("autorest: LoggingInspector#ByInspection did not record Response to the log")
109 }
110 }
111
112 func TestLoggingInspectorByInspectingRestoresBody(t *testing.T) {
113 b := bytes.Buffer{}
114 c := Client{}
115 r := mocks.NewResponseWithContent("Content")
116 li := LoggingInspector{Logger: log.New(&b, "", 0)}
117 c.ResponseInspector = li.ByInspecting()
118
119 Respond(r,
120 c.ByInspecting())
121
122 s, _ := ioutil.ReadAll(r.Body)
123 if len(s) <= 0 {
124 t.Fatal("autorest: LoggingInspector#ByInspecting did not restore the Response body")
125 }
126 }
127
128 func TestNewClientWithUserAgent(t *testing.T) {
129 ua := "UserAgent"
130 c := NewClientWithUserAgent(ua)
131 completeUA := fmt.Sprintf("%s %s", UserAgent(), ua)
132 if c.UserAgent != completeUA {
133 t.Fatalf("autorest: NewClientWithUserAgent failed to set the UserAgent -- expected %s, received %s",
134 completeUA, c.UserAgent)
135 }
136 r := c.Sender.(*http.Client).Transport.(*http.Transport).TLSClientConfig.Renegotiation
137 if r != tls.RenegotiateNever {
138 t.Fatal("autorest: TestNewClientWithUserAgentTLSRenegotiation expected RenegotiateNever")
139 }
140 }
141
142 func TestNewClientWithOptions(t *testing.T) {
143 const ua = "UserAgent"
144 c1 := NewClientWithOptions(ClientOptions{
145 UserAgent: ua,
146 Renegotiation: tls.RenegotiateFreelyAsClient,
147 })
148 r1 := c1.Sender.(*http.Client).Transport.(*http.Transport).TLSClientConfig.Renegotiation
149 if r1 != tls.RenegotiateFreelyAsClient {
150 t.Fatal("autorest: TestNewClientWithUserAgentTLSRenegotiation expected RenegotiateFreelyAsClient")
151 }
152
153 c2 := NewClientWithUserAgent(ua)
154 r2 := c2.Sender.(*http.Client).Transport.(*http.Transport).TLSClientConfig.Renegotiation
155 if r2 != tls.RenegotiateNever {
156 t.Fatal("autorest: TestNewClientWithUserAgentTLSRenegotiation expected RenegotiateNever")
157 }
158 r1 = c1.Sender.(*http.Client).Transport.(*http.Transport).TLSClientConfig.Renegotiation
159 if r1 != tls.RenegotiateFreelyAsClient {
160 t.Fatal("autorest: TestNewClientWithUserAgentTLSRenegotiation expected RenegotiateFreelyAsClient (overwritten)")
161 }
162 r2 = c2.Sender.(*http.Client).Transport.(*http.Transport).TLSClientConfig.Renegotiation
163 if r2 != tls.RenegotiateNever {
164 t.Fatal("autorest: TestNewClientWithUserAgentTLSRenegotiation expected RenegotiateNever (overwritten)")
165 }
166 }
167
168 func TestAddToUserAgent(t *testing.T) {
169 ua := "UserAgent"
170 c := NewClientWithUserAgent(ua)
171 ext := "extension"
172 err := c.AddToUserAgent(ext)
173 if err != nil {
174 t.Fatalf("autorest: AddToUserAgent returned error -- expected nil, received %s", err)
175 }
176 completeUA := fmt.Sprintf("%s %s %s", UserAgent(), ua, ext)
177
178 if c.UserAgent != completeUA {
179 t.Fatalf("autorest: AddToUserAgent failed to add an extension to the UserAgent -- expected %s, received %s",
180 completeUA, c.UserAgent)
181 }
182
183 err = c.AddToUserAgent("")
184 if err == nil {
185 t.Fatalf("autorest: AddToUserAgent didn't return error -- expected %s, received nil",
186 fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent))
187 }
188 if c.UserAgent != completeUA {
189 t.Fatalf("autorest: AddToUserAgent failed to not add an empty extension to the UserAgent -- expected %s, received %s",
190 completeUA, c.UserAgent)
191 }
192 }
193
194 func TestClientSenderReturnsHttpClientByDefault(t *testing.T) {
195 c := Client{}
196
197 if fmt.Sprintf("%T", c.sender(tls.RenegotiateNever)) != "*http.Client" {
198 t.Fatal("autorest: Client#sender failed to return http.Client by default")
199 }
200 }
201
202 func TestClientSenderReturnsSetSender(t *testing.T) {
203 c := Client{}
204
205 s := mocks.NewSender()
206 c.Sender = s
207
208 if c.sender(tls.RenegotiateNever) != s {
209 t.Fatal("autorest: Client#sender failed to return set Sender")
210 }
211 }
212
213 func TestClientDoInvokesSender(t *testing.T) {
214 c := Client{}
215
216 s := mocks.NewSender()
217 c.Sender = s
218
219 c.Do(&http.Request{})
220 if s.Attempts() != 1 {
221 t.Fatal("autorest: Client#Do failed to invoke the Sender")
222 }
223 }
224
225 func TestClientDoSetsUserAgent(t *testing.T) {
226 ua := "UserAgent"
227 c := Client{UserAgent: ua}
228 r := mocks.NewRequest()
229 s := mocks.NewSender()
230 c.Sender = s
231
232 c.Do(r)
233
234 if r.UserAgent() != ua {
235 t.Fatalf("autorest: Client#Do failed to correctly set User-Agent header: %s=%s",
236 http.CanonicalHeaderKey(headerUserAgent), r.UserAgent())
237 }
238 }
239
240 func TestClientDoSetsAuthorization(t *testing.T) {
241 r := mocks.NewRequest()
242 s := mocks.NewSender()
243 c := Client{Authorizer: mockAuthorizer{}, Sender: s}
244
245 c.Do(r)
246 if len(r.Header.Get(http.CanonicalHeaderKey(headerAuthorization))) <= 0 {
247 t.Fatalf("autorest: Client#Send failed to set Authorization header -- %s=%s",
248 http.CanonicalHeaderKey(headerAuthorization),
249 r.Header.Get(http.CanonicalHeaderKey(headerAuthorization)))
250 }
251 }
252
253 func TestClientDoInvokesRequestInspector(t *testing.T) {
254 r := mocks.NewRequest()
255 s := mocks.NewSender()
256 i := &mockInspector{}
257 c := Client{RequestInspector: i.WithInspection(), Sender: s}
258
259 c.Do(r)
260 if !i.wasInvoked {
261 t.Fatal("autorest: Client#Send failed to invoke the RequestInspector")
262 }
263 }
264
265 func TestClientDoInvokesResponseInspector(t *testing.T) {
266 r := mocks.NewRequest()
267 s := mocks.NewSender()
268 i := &mockInspector{}
269 c := Client{ResponseInspector: i.ByInspecting(), Sender: s}
270
271 c.Do(r)
272 if !i.wasInvoked {
273 t.Fatal("autorest: Client#Send failed to invoke the ResponseInspector")
274 }
275 }
276
277 func TestClientDoReturnsErrorIfPrepareFails(t *testing.T) {
278 c := Client{}
279 s := mocks.NewSender()
280 c.Authorizer = mockFailingAuthorizer{}
281 c.Sender = s
282
283 _, err := c.Do(&http.Request{})
284 if err == nil {
285 t.Fatalf("autorest: Client#Do failed to return an error when Prepare failed")
286 }
287 }
288
289 func TestClientDoDoesNotSendIfPrepareFails(t *testing.T) {
290 c := Client{}
291 s := mocks.NewSender()
292 c.Authorizer = mockFailingAuthorizer{}
293 c.Sender = s
294
295 c.Do(&http.Request{})
296 if s.Attempts() > 0 {
297 t.Fatal("autorest: Client#Do failed to invoke the Sender")
298 }
299 }
300
301 func TestClientAuthorizerReturnsNullAuthorizerByDefault(t *testing.T) {
302 c := Client{}
303
304 if fmt.Sprintf("%T", c.authorizer()) != "autorest.NullAuthorizer" {
305 t.Fatal("autorest: Client#authorizer failed to return the NullAuthorizer by default")
306 }
307 }
308
309 func TestClientAuthorizerReturnsSetAuthorizer(t *testing.T) {
310 c := Client{}
311 c.Authorizer = mockAuthorizer{}
312
313 if fmt.Sprintf("%T", c.authorizer()) != "autorest.mockAuthorizer" {
314 t.Fatal("autorest: Client#authorizer failed to return the set Authorizer")
315 }
316 }
317
318 func TestClientWithAuthorizer(t *testing.T) {
319 c := Client{}
320 c.Authorizer = mockAuthorizer{}
321
322 req, _ := Prepare(&http.Request{},
323 c.WithAuthorization())
324
325 if req.Header.Get(headerAuthorization) == "" {
326 t.Fatal("autorest: Client#WithAuthorizer failed to return the WithAuthorizer from the active Authorizer")
327 }
328 }
329
330 func TestClientWithInspection(t *testing.T) {
331 c := Client{}
332 r := &mockInspector{}
333 c.RequestInspector = r.WithInspection()
334
335 Prepare(&http.Request{},
336 c.WithInspection())
337
338 if !r.wasInvoked {
339 t.Fatal("autorest: Client#WithInspection failed to invoke RequestInspector")
340 }
341 }
342
343 func TestClientWithInspectionSetsDefault(t *testing.T) {
344 c := Client{}
345
346 r1 := &http.Request{}
347 r2, _ := Prepare(r1,
348 c.WithInspection())
349
350 if !reflect.DeepEqual(r1, r2) {
351 t.Fatal("autorest: Client#WithInspection failed to provide a default RequestInspector")
352 }
353 }
354
355 func TestClientByInspecting(t *testing.T) {
356 c := Client{}
357 r := &mockInspector{}
358 c.ResponseInspector = r.ByInspecting()
359
360 Respond(&http.Response{},
361 c.ByInspecting())
362
363 if !r.wasInvoked {
364 t.Fatal("autorest: Client#ByInspecting failed to invoke ResponseInspector")
365 }
366 }
367
368 func TestClientByInspectingSetsDefault(t *testing.T) {
369 c := Client{}
370
371 r := &http.Response{}
372 Respond(r,
373 c.ByInspecting())
374
375 if !reflect.DeepEqual(r, &http.Response{}) {
376 t.Fatal("autorest: Client#ByInspecting failed to provide a default ResponseInspector")
377 }
378 }
379
380 func TestCookies(t *testing.T) {
381 second := "second"
382 expected := http.Cookie{
383 Name: "tastes",
384 Value: "delicious",
385 }
386
387 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
388 http.SetCookie(w, &expected)
389 b, err := ioutil.ReadAll(r.Body)
390 if err != nil {
391 t.Fatalf("autorest: ioutil.ReadAll failed reading request body: %s", err)
392 }
393 if string(b) == second {
394 cookie, err := r.Cookie(expected.Name)
395 if err != nil {
396 t.Fatalf("autorest: r.Cookie could not get request cookie: %s", err)
397 }
398 if cookie == nil {
399 t.Fatalf("autorest: got nil cookie, expecting %v", expected)
400 }
401 if cookie.Value != expected.Value {
402 t.Fatalf("autorest: got cookie value '%s', expecting '%s'", cookie.Value, expected.Name)
403 }
404 }
405 }))
406 defer server.Close()
407
408 client := NewClientWithUserAgent("")
409 _, err := SendWithSender(client, mocks.NewRequestForURL(server.URL))
410 if err != nil {
411 t.Fatalf("autorest: first request failed: %s", err)
412 }
413
414 r2, err := http.NewRequest(http.MethodGet, server.URL, mocks.NewBody(second))
415 if err != nil {
416 t.Fatalf("autorest: failed creating second request: %s", err)
417 }
418
419 _, err = SendWithSender(client, r2)
420 if err != nil {
421 t.Fatalf("autorest: second request failed: %s", err)
422 }
423 }
424
425 func TestResponseIsHTTPStatus(t *testing.T) {
426 r := Response{}
427 if r.IsHTTPStatus(http.StatusBadRequest) {
428 t.Fatal("autorest: expected false for nil response")
429 }
430 r.Response = &http.Response{StatusCode: http.StatusOK}
431 if r.IsHTTPStatus(http.StatusBadRequest) {
432 t.Fatal("autorest: expected false")
433 }
434 if !r.IsHTTPStatus(http.StatusOK) {
435 t.Fatal("autorest: expected true")
436 }
437 }
438
439 func TestResponseHasHTTPStatus(t *testing.T) {
440 r := Response{}
441 if r.HasHTTPStatus(http.StatusBadRequest, http.StatusInternalServerError) {
442 t.Fatal("autorest: expected false for nil response")
443 }
444 r.Response = &http.Response{StatusCode: http.StatusAccepted}
445 if r.HasHTTPStatus(http.StatusBadRequest, http.StatusInternalServerError) {
446 t.Fatal("autorest: expected false")
447 }
448 if !r.HasHTTPStatus(http.StatusOK, http.StatusCreated, http.StatusAccepted) {
449 t.Fatal("autorest: expected true")
450 }
451 if r.HasHTTPStatus() {
452 t.Fatal("autorest: expected false for no status codes")
453 }
454 }
455
456 func randomString(n int) string {
457 const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
458 r := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
459 s := make([]byte, n)
460 for i := range s {
461 s[i] = chars[r.Intn(len(chars))]
462 }
463 return string(s)
464 }
465
466 func TestClientSendMethod(t *testing.T) {
467 sender := mocks.NewSender()
468 sender.AppendResponse(newAcceptedResponse())
469 client := Client{
470 Sender: sender,
471 }
472 req, err := http.NewRequest(http.MethodGet, mocks.TestURL, nil)
473 req = req.WithContext(context.Background())
474 if err != nil {
475 t.Fatal(err)
476 }
477
478 resp, err := client.Send(req)
479 if err != nil {
480 t.Fatal(err)
481 }
482 if resp.StatusCode != http.StatusAccepted {
483 t.Fatalf("expected status code %d, got %d", http.StatusAccepted, resp.StatusCode)
484 }
485
486 sender.AppendResponse(newAcceptedResponse())
487 resp, err = client.Send(req, DefaultSendDecorator())
488 if err != nil {
489 t.Fatal(err)
490 }
491 if v := resp.Header.Get("default-decorator"); v != "true" {
492 t.Fatal("didn't find default-decorator header in response")
493 }
494
495 sender.AppendResponse(newAcceptedResponse())
496 client.SendDecorators = []SendDecorator{ClientSendDecorator()}
497 resp, err = client.Send(req, DefaultSendDecorator())
498 if err != nil {
499 t.Fatal(err)
500 }
501 if v := resp.Header.Get("client-decorator"); v != "true" {
502 t.Fatal("didn't find client-decorator header in response")
503 }
504 if v := resp.Header.Get("default-decorator"); v == "true" {
505 t.Fatal("unexpected default-decorator header in response")
506 }
507
508 sender.AppendResponse(newAcceptedResponse())
509 req = req.WithContext(WithSendDecorators(req.Context(), []SendDecorator{ContextSendDecorator()}))
510 resp, err = client.Send(req, DefaultSendDecorator())
511 if err != nil {
512 t.Fatal(err)
513 }
514 if v := resp.Header.Get("context-decorator"); v != "true" {
515 t.Fatal("didn't find context-decorator header in response")
516 }
517 if v := resp.Header.Get("client-decorator"); v == "true" {
518 t.Fatal("unexpected client-decorator header in response")
519 }
520 if v := resp.Header.Get("default-decorator"); v == "true" {
521 t.Fatal("unexpected default-decorator header in response")
522 }
523 }
524
525 func DefaultSendDecorator() SendDecorator {
526 return func(s Sender) Sender {
527 return SenderFunc(func(r *http.Request) (*http.Response, error) {
528 resp, err := s.Do(r)
529 resp.Header.Set("default-decorator", "true")
530 return resp, err
531 })
532 }
533 }
534
535 func ClientSendDecorator() SendDecorator {
536 return func(s Sender) Sender {
537 return SenderFunc(func(r *http.Request) (*http.Response, error) {
538 resp, err := s.Do(r)
539 resp.Header.Set("client-decorator", "true")
540 return resp, err
541 })
542 }
543 }
544
545 func ContextSendDecorator() SendDecorator {
546 return func(s Sender) Sender {
547 return SenderFunc(func(r *http.Request) (*http.Response, error) {
548 resp, err := s.Do(r)
549 resp.Header.Set("context-decorator", "true")
550 return resp, err
551 })
552 }
553 }
554
View as plain text