github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrhttprouter/nrhttprouter_test.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package nrhttprouter 5 6 import ( 7 "fmt" 8 "net/http" 9 "net/http/httptest" 10 "testing" 11 12 "github.com/julienschmidt/httprouter" 13 newrelic "github.com/newrelic/go-agent" 14 "github.com/newrelic/go-agent/internal" 15 "github.com/newrelic/go-agent/internal/integrationsupport" 16 ) 17 18 func TestMethodFunctions(t *testing.T) { 19 20 methodFuncs := []struct { 21 Method string 22 Fn func(*Router) func(string, httprouter.Handle) 23 }{ 24 {Method: "DELETE", Fn: func(r *Router) func(string, httprouter.Handle) { return r.DELETE }}, 25 {Method: "GET", Fn: func(r *Router) func(string, httprouter.Handle) { return r.GET }}, 26 {Method: "HEAD", Fn: func(r *Router) func(string, httprouter.Handle) { return r.HEAD }}, 27 {Method: "OPTIONS", Fn: func(r *Router) func(string, httprouter.Handle) { return r.OPTIONS }}, 28 {Method: "PATCH", Fn: func(r *Router) func(string, httprouter.Handle) { return r.PATCH }}, 29 {Method: "POST", Fn: func(r *Router) func(string, httprouter.Handle) { return r.POST }}, 30 {Method: "PUT", Fn: func(r *Router) func(string, httprouter.Handle) { return r.PUT }}, 31 } 32 33 for _, md := range methodFuncs { 34 app := integrationsupport.NewBasicTestApp() 35 router := New(app) 36 md.Fn(router)("/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { 37 // Test that the Transaction is used as the response writer. 38 w.WriteHeader(500) 39 w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name")))) 40 }) 41 response := httptest.NewRecorder() 42 req, err := http.NewRequest(md.Method, "/hello/person", nil) 43 if err != nil { 44 t.Fatal(err) 45 } 46 router.ServeHTTP(response, req) 47 if respBody := response.Body.String(); respBody != "hi person" { 48 t.Error("wrong response body", respBody) 49 } 50 app.ExpectTxnMetrics(t, internal.WantTxn{ 51 Name: md.Method + " /hello/:name", 52 IsWeb: true, 53 NumErrors: 1, 54 }) 55 } 56 } 57 58 func TestGetNoApplication(t *testing.T) { 59 router := New(nil) 60 61 router.GET("/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { 62 w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name")))) 63 }) 64 response := httptest.NewRecorder() 65 req, err := http.NewRequest("GET", "/hello/person", nil) 66 if err != nil { 67 t.Fatal(err) 68 } 69 router.ServeHTTP(response, req) 70 if respBody := response.Body.String(); respBody != "hi person" { 71 t.Error("wrong response body", respBody) 72 } 73 } 74 75 func TestHandle(t *testing.T) { 76 app := integrationsupport.NewBasicTestApp() 77 router := New(app) 78 79 router.Handle("GET", "/hello/:name", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { 80 // Test that the Transaction is used as the response writer. 81 w.WriteHeader(500) 82 w.Write([]byte(fmt.Sprintf("hi %s", ps.ByName("name")))) 83 if txn := newrelic.FromContext(r.Context()); txn != nil { 84 txn.AddAttribute("color", "purple") 85 } 86 }) 87 response := httptest.NewRecorder() 88 req, err := http.NewRequest("GET", "/hello/person", nil) 89 if err != nil { 90 t.Fatal(err) 91 } 92 router.ServeHTTP(response, req) 93 if respBody := response.Body.String(); respBody != "hi person" { 94 t.Error("wrong response body", respBody) 95 } 96 app.ExpectTxnMetrics(t, internal.WantTxn{ 97 Name: "GET /hello/:name", 98 IsWeb: true, 99 NumErrors: 1, 100 }) 101 app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{ 102 { 103 Intrinsics: map[string]interface{}{ 104 "name": "WebTransaction/Go/GET /hello/:name", 105 "nr.apdexPerfZone": internal.MatchAnything, 106 }, 107 UserAttributes: map[string]interface{}{ 108 "color": "purple", 109 }, 110 AgentAttributes: map[string]interface{}{ 111 "httpResponseCode": 500, 112 "request.method": "GET", 113 "request.uri": "/hello/person", 114 }, 115 }, 116 }) 117 } 118 119 func TestHandler(t *testing.T) { 120 app := integrationsupport.NewBasicTestApp() 121 router := New(app) 122 123 router.Handler("GET", "/hello/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 124 // Test that the Transaction is used as the response writer. 125 w.WriteHeader(500) 126 w.Write([]byte("hi there")) 127 if txn := newrelic.FromContext(r.Context()); txn != nil { 128 txn.AddAttribute("color", "purple") 129 } 130 })) 131 response := httptest.NewRecorder() 132 req, err := http.NewRequest("GET", "/hello/", nil) 133 if err != nil { 134 t.Fatal(err) 135 } 136 router.ServeHTTP(response, req) 137 if respBody := response.Body.String(); respBody != "hi there" { 138 t.Error("wrong response body", respBody) 139 } 140 app.ExpectTxnMetrics(t, internal.WantTxn{ 141 Name: "GET /hello/", 142 IsWeb: true, 143 NumErrors: 1, 144 }) 145 app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{ 146 { 147 Intrinsics: map[string]interface{}{ 148 "name": "WebTransaction/Go/GET /hello/", 149 "nr.apdexPerfZone": internal.MatchAnything, 150 }, 151 UserAttributes: map[string]interface{}{ 152 "color": "purple", 153 }, 154 AgentAttributes: map[string]interface{}{ 155 "httpResponseCode": 500, 156 "request.method": "GET", 157 "request.uri": "/hello/", 158 }, 159 }, 160 }) 161 } 162 163 func TestHandlerMissingApplication(t *testing.T) { 164 router := New(nil) 165 166 router.Handler("GET", "/hello/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 167 w.WriteHeader(500) 168 w.Write([]byte("hi there")) 169 })) 170 response := httptest.NewRecorder() 171 req, err := http.NewRequest("GET", "/hello/", nil) 172 if err != nil { 173 t.Fatal(err) 174 } 175 router.ServeHTTP(response, req) 176 if respBody := response.Body.String(); respBody != "hi there" { 177 t.Error("wrong response body", respBody) 178 } 179 } 180 181 func TestHandlerFunc(t *testing.T) { 182 app := integrationsupport.NewBasicTestApp() 183 router := New(app) 184 185 router.HandlerFunc("GET", "/hello/", func(w http.ResponseWriter, r *http.Request) { 186 // Test that the Transaction is used as the response writer. 187 w.WriteHeader(500) 188 w.Write([]byte("hi there")) 189 }) 190 response := httptest.NewRecorder() 191 req, err := http.NewRequest("GET", "/hello/", nil) 192 if err != nil { 193 t.Fatal(err) 194 } 195 router.ServeHTTP(response, req) 196 if respBody := response.Body.String(); respBody != "hi there" { 197 t.Error("wrong response body", respBody) 198 } 199 app.ExpectTxnMetrics(t, internal.WantTxn{ 200 Name: "GET /hello/", 201 IsWeb: true, 202 NumErrors: 1, 203 }) 204 } 205 206 func TestNotFound(t *testing.T) { 207 app := integrationsupport.NewBasicTestApp() 208 router := New(app) 209 210 router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 211 // Test that the Transaction is used as the response writer. 212 w.WriteHeader(500) 213 w.Write([]byte("not found!")) 214 if txn := newrelic.FromContext(r.Context()); txn != nil { 215 txn.AddAttribute("color", "purple") 216 } 217 }) 218 response := httptest.NewRecorder() 219 req, err := http.NewRequest("GET", "/hello/", nil) 220 if err != nil { 221 t.Fatal(err) 222 } 223 router.ServeHTTP(response, req) 224 if respBody := response.Body.String(); respBody != "not found!" { 225 t.Error("wrong response body", respBody) 226 } 227 app.ExpectTxnMetrics(t, internal.WantTxn{ 228 Name: "NotFound", 229 IsWeb: true, 230 NumErrors: 1, 231 }) 232 app.(internal.Expect).ExpectTxnEvents(t, []internal.WantEvent{ 233 { 234 Intrinsics: map[string]interface{}{ 235 "name": "WebTransaction/Go/NotFound", 236 "nr.apdexPerfZone": internal.MatchAnything, 237 }, 238 UserAttributes: map[string]interface{}{ 239 "color": "purple", 240 }, 241 AgentAttributes: map[string]interface{}{ 242 "httpResponseCode": 500, 243 "request.method": "GET", 244 "request.uri": "/hello/", 245 }, 246 }, 247 }) 248 } 249 250 func TestNotFoundMissingApplication(t *testing.T) { 251 router := New(nil) 252 253 router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 254 // Test that the Transaction is used as the response writer. 255 w.WriteHeader(500) 256 w.Write([]byte("not found!")) 257 }) 258 response := httptest.NewRecorder() 259 req, err := http.NewRequest("GET", "/hello/", nil) 260 if err != nil { 261 t.Fatal(err) 262 } 263 router.ServeHTTP(response, req) 264 if respBody := response.Body.String(); respBody != "not found!" { 265 t.Error("wrong response body", respBody) 266 } 267 } 268 269 func TestNotFoundNotSet(t *testing.T) { 270 app := integrationsupport.NewBasicTestApp() 271 router := New(app) 272 273 response := httptest.NewRecorder() 274 req, err := http.NewRequest("GET", "/hello/", nil) 275 if err != nil { 276 t.Fatal(err) 277 } 278 router.ServeHTTP(response, req) 279 if response.Code != 404 { 280 t.Error(response.Code) 281 } 282 app.ExpectTxnMetrics(t, internal.WantTxn{ 283 Name: "NotFound", 284 IsWeb: true, 285 }) 286 }