github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/fake_handler.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "io/ioutil" 21 "net/http" 22 "net/url" 23 "reflect" 24 "sync" 25 ) 26 27 // TestInterface is a simple interface providing Errorf, to make injection for 28 // testing easier (insert 'yo dawg' meme here). 29 type TestInterface interface { 30 Errorf(format string, args ...interface{}) 31 Logf(format string, args ...interface{}) 32 } 33 34 // LogInterface is a simple interface to allow injection of Logf to report serving errors. 35 type LogInterface interface { 36 Logf(format string, args ...interface{}) 37 } 38 39 // FakeHandler is to assist in testing HTTP requests. Notice that FakeHandler is 40 // not thread safe and you must not direct traffic to except for the request 41 // you want to test. You can do this by hiding it in an http.ServeMux. 42 type FakeHandler struct { 43 RequestReceived *http.Request 44 RequestBody string 45 StatusCode int 46 ResponseBody string 47 // For logging - you can use a *testing.T 48 // This will keep log messages associated with the test. 49 T LogInterface 50 51 // Enforce "only one use" constraint. 52 lock sync.Mutex 53 requestCount int 54 hasBeenChecked bool 55 } 56 57 func (f *FakeHandler) ServeHTTP(response http.ResponseWriter, request *http.Request) { 58 f.lock.Lock() 59 defer f.lock.Unlock() 60 f.requestCount++ 61 if f.hasBeenChecked { 62 panic("got request after having been validated") 63 } 64 65 f.RequestReceived = request 66 response.WriteHeader(f.StatusCode) 67 response.Write([]byte(f.ResponseBody)) 68 69 bodyReceived, err := ioutil.ReadAll(request.Body) 70 if err != nil && f.T != nil { 71 f.T.Logf("Received read error: %v", err) 72 } 73 f.RequestBody = string(bodyReceived) 74 } 75 76 func (f *FakeHandler) ValidateRequestCount(t TestInterface, count int) bool { 77 ok := true 78 f.lock.Lock() 79 defer f.lock.Unlock() 80 if f.requestCount != count { 81 ok = false 82 t.Logf("Expected %d call, but got %d. Only the last call is recorded and checked.", count, f.requestCount) 83 } 84 f.hasBeenChecked = true 85 return ok 86 } 87 88 // ValidateRequest verifies that FakeHandler received a request with expected path, method, and body. 89 func (f *FakeHandler) ValidateRequest(t TestInterface, expectedPath, expectedMethod string, body *string) { 90 f.lock.Lock() 91 defer f.lock.Unlock() 92 if f.requestCount != 1 { 93 t.Logf("Expected 1 call, but got %v. Only the last call is recorded and checked.", f.requestCount) 94 } 95 f.hasBeenChecked = true 96 97 expectURL, err := url.Parse(expectedPath) 98 if err != nil { 99 t.Errorf("Couldn't parse %v as a URL.", expectedPath) 100 } 101 if f.RequestReceived == nil { 102 t.Errorf("Unexpected nil request received for %s", expectedPath) 103 return 104 } 105 if f.RequestReceived.URL.Path != expectURL.Path { 106 t.Errorf("Unexpected request path for request %#v, received: %q, expected: %q", f.RequestReceived, f.RequestReceived.URL.Path, expectURL.Path) 107 } 108 if e, a := expectURL.Query(), f.RequestReceived.URL.Query(); !reflect.DeepEqual(e, a) { 109 t.Errorf("Unexpected query for request %#v, received: %q, expected: %q", f.RequestReceived, a, e) 110 } 111 if f.RequestReceived.Method != expectedMethod { 112 t.Errorf("Unexpected method: %q, expected: %q", f.RequestReceived.Method, expectedMethod) 113 } 114 if body != nil { 115 if *body != f.RequestBody { 116 t.Errorf("Received body:\n%s\n Doesn't match expected body:\n%s", f.RequestBody, *body) 117 } 118 } 119 }