github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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 names "gopkg.in/juju/names.v2" 16 17 "github.com/juju/juju/api/base" 18 coretesting "github.com/juju/juju/testing" 19 ) 20 21 // newHTTPFixture creates and returns an HTTP fixture to be used in order to 22 // mock controller HTTP requests to the given controller address. 23 // Use it like in the following example: 24 // fix := newHTTPFixture("/my/controller/path", func(w http.ResponseWriter, req *http.Request) { 25 // // Simulate what's returned by the server. 26 // }) 27 // stub := fix.run(c, func(ac base.APICallCloser) { 28 // // Do something with the API caller. 29 // }) 30 // At this point the stub, if the handler has been called, includes one call 31 // with the HTTP method requested while running the test function. 32 func newHTTPFixture(address string, handle func(http.ResponseWriter, *http.Request)) *httpFixture { 33 return &httpFixture{ 34 address: address, 35 handle: handle, 36 } 37 } 38 39 // httpFixture is used to mock controller HTTP API calls. 40 type httpFixture struct { 41 address string 42 handle func(http.ResponseWriter, *http.Request) 43 } 44 45 // run sets up the fixture and run the given test. See newHTTPFixture for an 46 // example of how to use this. 47 func (f *httpFixture) run(c *gc.C, test func(base.APICallCloser)) *testing.Stub { 48 stub := &testing.Stub{} 49 lis, err := net.Listen("tcp", "127.0.0.1:0") 50 c.Assert(err, jc.ErrorIsNil) 51 defer lis.Close() 52 mux := http.NewServeMux() 53 mux.HandleFunc(f.address, func(w http.ResponseWriter, r *http.Request) { 54 stub.AddCall(r.Method) 55 f.handle(w, r) 56 }) 57 go func() { 58 http.Serve(lis, mux) 59 }() 60 test(&httpAPICallCloser{ 61 url: &url.URL{ 62 Scheme: "http", 63 Host: lis.Addr().String(), 64 }, 65 }) 66 return stub 67 } 68 69 var _ base.APICallCloser = (*httpAPICallCloser)(nil) 70 71 // httpAPICallCloser implements base.APICallCloser. 72 type httpAPICallCloser struct { 73 base.APICallCloser 74 url *url.URL 75 } 76 77 // ModelTag implements base.APICallCloser. 78 func (*httpAPICallCloser) ModelTag() (names.ModelTag, bool) { 79 return coretesting.ModelTag, true 80 } 81 82 // BestFacadeVersion implements base.APICallCloser. 83 func (*httpAPICallCloser) BestFacadeVersion(facade string) int { 84 return 42 85 } 86 87 // HTTPClient implements base.APICallCloser. The returned HTTP client can be 88 // used to send requests to the testing server set up in httpFixture.run(). 89 func (ac *httpAPICallCloser) HTTPClient() (*httprequest.Client, error) { 90 return &httprequest.Client{ 91 BaseURL: ac.url.String(), 92 }, nil 93 }