github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/controller/http_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package controller_test
     5  
     6  import (
     7  	"net"
     8  	"net/http"
     9  	"net/url"
    10  
    11  	"github.com/juju/httprequest"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/api/base"
    17  )
    18  
    19  // newHTTPFixture creates and returns an HTTP fixture to be used in order to
    20  // mock controller HTTP requests to the given controller address.
    21  // Use it like in the following example:
    22  //   fix := newHTTPFixture("/my/controller/path", func(w http.ResponseWriter, req *http.Request) {
    23  //       // Simulate what's returned by the server.
    24  //   })
    25  //   stub := fix.run(c, func(ac base.APICallCloser) {
    26  //       // Do something with the API caller.
    27  //   })
    28  // At this point the stub, if the handler has been called, includes one call
    29  // with the HTTP method requested while running the test function.
    30  func newHTTPFixture(address string, handle func(http.ResponseWriter, *http.Request)) *httpFixture {
    31  	return &httpFixture{
    32  		address: address,
    33  		handle:  handle,
    34  	}
    35  }
    36  
    37  // httpFixture is used to mock controller HTTP API calls.
    38  type httpFixture struct {
    39  	address string
    40  	handle  func(http.ResponseWriter, *http.Request)
    41  }
    42  
    43  // run sets up the fixture and run the given test. See newHTTPFixture for an
    44  // example of how to use this.
    45  func (f *httpFixture) run(c *gc.C, test func(base.APICallCloser)) *testing.Stub {
    46  	stub := &testing.Stub{}
    47  	lis, err := net.Listen("tcp", "127.0.0.1:0")
    48  	c.Assert(err, jc.ErrorIsNil)
    49  	defer lis.Close()
    50  	mux := http.NewServeMux()
    51  	mux.HandleFunc(f.address, func(w http.ResponseWriter, r *http.Request) {
    52  		stub.AddCall(r.Method)
    53  		f.handle(w, r)
    54  	})
    55  	go func() {
    56  		http.Serve(lis, mux)
    57  	}()
    58  	test(&httpAPICallCloser{
    59  		url: &url.URL{
    60  			Scheme: "http",
    61  			Host:   lis.Addr().String(),
    62  		},
    63  	})
    64  	return stub
    65  }
    66  
    67  var _ base.APICallCloser = (*httpAPICallCloser)(nil)
    68  
    69  // httpAPICallCloser implements base.APICallCloser.
    70  type httpAPICallCloser struct {
    71  	base.APICallCloser
    72  	url *url.URL
    73  }
    74  
    75  // BestFacadeVersion implements base.APICallCloser.
    76  func (*httpAPICallCloser) BestFacadeVersion(facade string) int {
    77  	return 42
    78  }
    79  
    80  // HTTPClient implements base.APICallCloser. The returned HTTP client can be
    81  // used to send requests to the testing server set up in httpFixture.run().
    82  func (ac *httpAPICallCloser) HTTPClient() (*httprequest.Client, error) {
    83  	return &httprequest.Client{
    84  		BaseURL: ac.url.String(),
    85  	}, nil
    86  }