...

Source file src/github.com/Azure/go-autorest/autorest/client_test.go

Documentation: github.com/Azure/go-autorest/autorest

     1  package autorest
     2  
     3  // Copyright 2017 Microsoft Corporation
     4  //
     5  //  Licensed under the Apache License, Version 2.0 (the "License");
     6  //  you may not use this file except in compliance with the License.
     7  //  You may obtain a copy of the License at
     8  //
     9  //      http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  //  Unless required by applicable law or agreed to in writing, software
    12  //  distributed under the License is distributed on an "AS IS" BASIS,
    13  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  //  See the License for the specific language governing permissions and
    15  //  limitations under the License.
    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  	// ensure default value doesn't stomp over previous value
   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  	// no SendDecorators
   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  	// default SendDecorators
   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  	// using client SendDecorators
   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  	// using context SendDecorators
   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