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 }