github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrgrpc/nrgrpc_server_test.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package nrgrpc 5 6 import ( 7 "context" 8 "io" 9 "net" 10 "strings" 11 "testing" 12 "time" 13 14 newrelic "github.com/newrelic/go-agent" 15 "github.com/newrelic/go-agent/_integrations/nrgrpc/testapp" 16 "github.com/newrelic/go-agent/internal" 17 "google.golang.org/grpc" 18 "google.golang.org/grpc/test/bufconn" 19 ) 20 21 // newTestServerAndConn creates a new *grpc.Server and *grpc.ClientConn for use 22 // in testing. It adds instrumentation to both. If app is nil, then 23 // instrumentation is not applied to the server. Be sure to Stop() the server 24 // and Close() the connection when done with them. 25 func newTestServerAndConn(t *testing.T, app newrelic.Application) (*grpc.Server, *grpc.ClientConn) { 26 s := grpc.NewServer( 27 grpc.UnaryInterceptor(UnaryServerInterceptor(app)), 28 grpc.StreamInterceptor(StreamServerInterceptor(app)), 29 ) 30 testapp.RegisterTestApplicationServer(s, &testapp.Server{}) 31 lis := bufconn.Listen(1024 * 1024) 32 33 go func() { 34 s.Serve(lis) 35 }() 36 37 bufDialer := func(string, time.Duration) (net.Conn, error) { 38 return lis.Dial() 39 } 40 conn, err := grpc.Dial("bufnet", 41 grpc.WithDialer(bufDialer), 42 grpc.WithInsecure(), 43 grpc.WithBlock(), // create the connection synchronously 44 grpc.WithUnaryInterceptor(UnaryClientInterceptor), 45 grpc.WithStreamInterceptor(StreamClientInterceptor), 46 ) 47 if err != nil { 48 t.Fatal("failure to create ClientConn", err) 49 } 50 51 return s, conn 52 } 53 54 func TestUnaryServerInterceptor(t *testing.T) { 55 app := testApp() 56 57 s, conn := newTestServerAndConn(t, app) 58 defer s.Stop() 59 defer conn.Close() 60 61 client := testapp.NewTestApplicationClient(conn) 62 txn := app.StartTransaction("client", nil, nil) 63 ctx := newrelic.NewContext(context.Background(), txn) 64 _, err := client.DoUnaryUnary(ctx, &testapp.Message{}) 65 if nil != err { 66 t.Fatal("unable to call client DoUnaryUnary", err) 67 } 68 69 app.ExpectMetrics(t, []internal.WantMetric{ 70 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 71 {Name: "Apdex/Go/TestApplication/DoUnaryUnary", Scope: "", Forced: false, Data: nil}, 72 {Name: "Custom/DoUnaryUnary", Scope: "", Forced: false, Data: nil}, 73 {Name: "Custom/DoUnaryUnary", Scope: "WebTransaction/Go/TestApplication/DoUnaryUnary", Forced: false, Data: nil}, 74 {Name: "DurationByCaller/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 75 {Name: "DurationByCaller/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 76 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 77 {Name: "Supportability/DistributedTrace/AcceptPayload/Success", Scope: "", Forced: true, Data: nil}, 78 {Name: "TransportDuration/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 79 {Name: "TransportDuration/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 80 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 81 {Name: "WebTransaction/Go/TestApplication/DoUnaryUnary", Scope: "", Forced: true, Data: nil}, 82 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 83 {Name: "WebTransactionTotalTime/Go/TestApplication/DoUnaryUnary", Scope: "", Forced: false, Data: nil}, 84 }) 85 app.ExpectTxnEvents(t, []internal.WantEvent{{ 86 Intrinsics: map[string]interface{}{ 87 "guid": internal.MatchAnything, 88 "name": "WebTransaction/Go/TestApplication/DoUnaryUnary", 89 "nr.apdexPerfZone": internal.MatchAnything, 90 "parent.account": 123, 91 "parent.app": 456, 92 "parent.transportDuration": internal.MatchAnything, 93 "parent.transportType": "HTTP", 94 "parent.type": "App", 95 "parentId": internal.MatchAnything, 96 "parentSpanId": internal.MatchAnything, 97 "priority": internal.MatchAnything, 98 "sampled": internal.MatchAnything, 99 "traceId": internal.MatchAnything, 100 }, 101 UserAttributes: map[string]interface{}{}, 102 AgentAttributes: map[string]interface{}{ 103 "httpResponseCode": 0, 104 "request.headers.contentType": "application/grpc", 105 "request.method": "TestApplication/DoUnaryUnary", 106 "request.uri": "grpc://bufnet/TestApplication/DoUnaryUnary", 107 }, 108 }}) 109 app.ExpectSpanEvents(t, []internal.WantEvent{ 110 { 111 Intrinsics: map[string]interface{}{ 112 "category": "generic", 113 "name": "WebTransaction/Go/TestApplication/DoUnaryUnary", 114 "nr.entryPoint": true, 115 "parentId": internal.MatchAnything, 116 }, 117 UserAttributes: map[string]interface{}{}, 118 AgentAttributes: map[string]interface{}{}, 119 }, 120 { 121 Intrinsics: map[string]interface{}{ 122 "category": "generic", 123 "name": "Custom/DoUnaryUnary", 124 "parentId": internal.MatchAnything, 125 }, 126 UserAttributes: map[string]interface{}{}, 127 AgentAttributes: map[string]interface{}{}, 128 }, 129 }) 130 } 131 132 func TestUnaryServerInterceptorError(t *testing.T) { 133 app := testApp() 134 135 s, conn := newTestServerAndConn(t, app) 136 defer s.Stop() 137 defer conn.Close() 138 139 client := testapp.NewTestApplicationClient(conn) 140 _, err := client.DoUnaryUnaryError(context.Background(), &testapp.Message{}) 141 if nil == err { 142 t.Fatal("DoUnaryUnaryError should have returned an error") 143 } 144 145 app.ExpectMetrics(t, []internal.WantMetric{ 146 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 147 {Name: "Apdex/Go/TestApplication/DoUnaryUnaryError", Scope: "", Forced: false, Data: nil}, 148 {Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil}, 149 {Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb", Scope: "", Forced: false, Data: nil}, 150 {Name: "Errors/WebTransaction/Go/TestApplication/DoUnaryUnaryError", Scope: "", Forced: true, Data: nil}, 151 {Name: "Errors/all", Scope: "", Forced: true, Data: nil}, 152 {Name: "Errors/allWeb", Scope: "", Forced: true, Data: nil}, 153 {Name: "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil}, 154 {Name: "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown/allWeb", Scope: "", Forced: false, Data: nil}, 155 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 156 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 157 {Name: "WebTransaction/Go/TestApplication/DoUnaryUnaryError", Scope: "", Forced: true, Data: nil}, 158 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 159 {Name: "WebTransactionTotalTime/Go/TestApplication/DoUnaryUnaryError", Scope: "", Forced: false, Data: nil}, 160 }) 161 app.ExpectTxnEvents(t, []internal.WantEvent{{ 162 Intrinsics: map[string]interface{}{ 163 "guid": internal.MatchAnything, 164 "name": "WebTransaction/Go/TestApplication/DoUnaryUnaryError", 165 "nr.apdexPerfZone": internal.MatchAnything, 166 "priority": internal.MatchAnything, 167 "sampled": internal.MatchAnything, 168 "traceId": internal.MatchAnything, 169 }, 170 UserAttributes: map[string]interface{}{}, 171 AgentAttributes: map[string]interface{}{ 172 "httpResponseCode": 15, 173 "request.headers.contentType": "application/grpc", 174 "request.method": "TestApplication/DoUnaryUnaryError", 175 "request.uri": "grpc://bufnet/TestApplication/DoUnaryUnaryError", 176 }, 177 }}) 178 app.ExpectErrorEvents(t, []internal.WantEvent{{ 179 Intrinsics: map[string]interface{}{ 180 "error.class": "15", 181 "error.message": "response code 15", 182 "guid": internal.MatchAnything, 183 "priority": internal.MatchAnything, 184 "sampled": internal.MatchAnything, 185 "traceId": internal.MatchAnything, 186 "transactionName": "WebTransaction/Go/TestApplication/DoUnaryUnaryError", 187 }, 188 AgentAttributes: map[string]interface{}{ 189 "httpResponseCode": 15, 190 "request.headers.User-Agent": internal.MatchAnything, 191 "request.headers.contentType": "application/grpc", 192 "request.method": "TestApplication/DoUnaryUnaryError", 193 "request.uri": "grpc://bufnet/TestApplication/DoUnaryUnaryError", 194 }, 195 UserAttributes: map[string]interface{}{}, 196 }}) 197 } 198 199 func TestUnaryStreamServerInterceptor(t *testing.T) { 200 app := testApp() 201 202 s, conn := newTestServerAndConn(t, app) 203 defer s.Stop() 204 defer conn.Close() 205 206 client := testapp.NewTestApplicationClient(conn) 207 txn := app.StartTransaction("client", nil, nil) 208 ctx := newrelic.NewContext(context.Background(), txn) 209 stream, err := client.DoUnaryStream(ctx, &testapp.Message{}) 210 if nil != err { 211 t.Fatal("client call to DoUnaryStream failed", err) 212 } 213 var recved int 214 for { 215 _, err := stream.Recv() 216 if err == io.EOF { 217 break 218 } 219 if nil != err { 220 t.Fatal("error receiving message", err) 221 } 222 recved++ 223 } 224 if recved != 3 { 225 t.Fatal("received incorrect number of messages from server", recved) 226 } 227 228 app.ExpectMetrics(t, []internal.WantMetric{ 229 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 230 {Name: "Apdex/Go/TestApplication/DoUnaryStream", Scope: "", Forced: false, Data: nil}, 231 {Name: "Custom/DoUnaryStream", Scope: "", Forced: false, Data: nil}, 232 {Name: "Custom/DoUnaryStream", Scope: "WebTransaction/Go/TestApplication/DoUnaryStream", Forced: false, Data: nil}, 233 {Name: "DurationByCaller/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 234 {Name: "DurationByCaller/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 235 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 236 {Name: "Supportability/DistributedTrace/AcceptPayload/Success", Scope: "", Forced: true, Data: nil}, 237 {Name: "TransportDuration/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 238 {Name: "TransportDuration/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 239 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 240 {Name: "WebTransaction/Go/TestApplication/DoUnaryStream", Scope: "", Forced: true, Data: nil}, 241 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 242 {Name: "WebTransactionTotalTime/Go/TestApplication/DoUnaryStream", Scope: "", Forced: false, Data: nil}, 243 }) 244 app.ExpectTxnEvents(t, []internal.WantEvent{{ 245 Intrinsics: map[string]interface{}{ 246 "guid": internal.MatchAnything, 247 "name": "WebTransaction/Go/TestApplication/DoUnaryStream", 248 "nr.apdexPerfZone": internal.MatchAnything, 249 "parent.account": 123, 250 "parent.app": 456, 251 "parent.transportDuration": internal.MatchAnything, 252 "parent.transportType": "HTTP", 253 "parent.type": "App", 254 "parentId": internal.MatchAnything, 255 "parentSpanId": internal.MatchAnything, 256 "priority": internal.MatchAnything, 257 "sampled": internal.MatchAnything, 258 "traceId": internal.MatchAnything, 259 }, 260 UserAttributes: map[string]interface{}{}, 261 AgentAttributes: map[string]interface{}{ 262 "httpResponseCode": 0, 263 "request.headers.contentType": "application/grpc", 264 "request.method": "TestApplication/DoUnaryStream", 265 "request.uri": "grpc://bufnet/TestApplication/DoUnaryStream", 266 }, 267 }}) 268 app.ExpectSpanEvents(t, []internal.WantEvent{ 269 { 270 Intrinsics: map[string]interface{}{ 271 "category": "generic", 272 "name": "WebTransaction/Go/TestApplication/DoUnaryStream", 273 "nr.entryPoint": true, 274 "parentId": internal.MatchAnything, 275 }, 276 UserAttributes: map[string]interface{}{}, 277 AgentAttributes: map[string]interface{}{}, 278 }, 279 { 280 Intrinsics: map[string]interface{}{ 281 "category": "generic", 282 "name": "Custom/DoUnaryStream", 283 "parentId": internal.MatchAnything, 284 }, 285 UserAttributes: map[string]interface{}{}, 286 AgentAttributes: map[string]interface{}{}, 287 }, 288 }) 289 } 290 291 func TestStreamUnaryServerInterceptor(t *testing.T) { 292 app := testApp() 293 294 s, conn := newTestServerAndConn(t, app) 295 defer s.Stop() 296 defer conn.Close() 297 298 client := testapp.NewTestApplicationClient(conn) 299 txn := app.StartTransaction("client", nil, nil) 300 ctx := newrelic.NewContext(context.Background(), txn) 301 stream, err := client.DoStreamUnary(ctx) 302 if nil != err { 303 t.Fatal("client call to DoStreamUnary failed", err) 304 } 305 for i := 0; i < 3; i++ { 306 if err := stream.Send(&testapp.Message{Text: "Hello DoStreamUnary"}); nil != err { 307 if err == io.EOF { 308 break 309 } 310 t.Fatal("failure to Send", err) 311 } 312 } 313 _, err = stream.CloseAndRecv() 314 if nil != err { 315 t.Fatal("failure to CloseAndRecv", err) 316 } 317 318 app.ExpectMetrics(t, []internal.WantMetric{ 319 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 320 {Name: "Apdex/Go/TestApplication/DoStreamUnary", Scope: "", Forced: false, Data: nil}, 321 {Name: "Custom/DoStreamUnary", Scope: "", Forced: false, Data: nil}, 322 {Name: "Custom/DoStreamUnary", Scope: "WebTransaction/Go/TestApplication/DoStreamUnary", Forced: false, Data: nil}, 323 {Name: "DurationByCaller/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 324 {Name: "DurationByCaller/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 325 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 326 {Name: "Supportability/DistributedTrace/AcceptPayload/Success", Scope: "", Forced: true, Data: nil}, 327 {Name: "TransportDuration/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 328 {Name: "TransportDuration/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 329 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 330 {Name: "WebTransaction/Go/TestApplication/DoStreamUnary", Scope: "", Forced: true, Data: nil}, 331 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 332 {Name: "WebTransactionTotalTime/Go/TestApplication/DoStreamUnary", Scope: "", Forced: false, Data: nil}, 333 }) 334 app.ExpectTxnEvents(t, []internal.WantEvent{{ 335 Intrinsics: map[string]interface{}{ 336 "guid": internal.MatchAnything, 337 "name": "WebTransaction/Go/TestApplication/DoStreamUnary", 338 "nr.apdexPerfZone": internal.MatchAnything, 339 "parent.account": 123, 340 "parent.app": 456, 341 "parent.transportDuration": internal.MatchAnything, 342 "parent.transportType": "HTTP", 343 "parent.type": "App", 344 "parentId": internal.MatchAnything, 345 "parentSpanId": internal.MatchAnything, 346 "priority": internal.MatchAnything, 347 "sampled": internal.MatchAnything, 348 "traceId": internal.MatchAnything, 349 }, 350 UserAttributes: map[string]interface{}{}, 351 AgentAttributes: map[string]interface{}{ 352 "httpResponseCode": 0, 353 "request.headers.contentType": "application/grpc", 354 "request.method": "TestApplication/DoStreamUnary", 355 "request.uri": "grpc://bufnet/TestApplication/DoStreamUnary", 356 }, 357 }}) 358 app.ExpectSpanEvents(t, []internal.WantEvent{ 359 { 360 Intrinsics: map[string]interface{}{ 361 "category": "generic", 362 "name": "WebTransaction/Go/TestApplication/DoStreamUnary", 363 "nr.entryPoint": true, 364 "parentId": internal.MatchAnything, 365 }, 366 UserAttributes: map[string]interface{}{}, 367 AgentAttributes: map[string]interface{}{}, 368 }, 369 { 370 Intrinsics: map[string]interface{}{ 371 "category": "generic", 372 "name": "Custom/DoStreamUnary", 373 "parentId": internal.MatchAnything, 374 }, 375 UserAttributes: map[string]interface{}{}, 376 AgentAttributes: map[string]interface{}{}, 377 }, 378 }) 379 } 380 381 func TestStreamStreamServerInterceptor(t *testing.T) { 382 app := testApp() 383 384 s, conn := newTestServerAndConn(t, app) 385 defer s.Stop() 386 defer conn.Close() 387 388 client := testapp.NewTestApplicationClient(conn) 389 txn := app.StartTransaction("client", nil, nil) 390 ctx := newrelic.NewContext(context.Background(), txn) 391 stream, err := client.DoStreamStream(ctx) 392 if nil != err { 393 t.Fatal("client call to DoStreamStream failed", err) 394 } 395 waitc := make(chan struct{}) 396 go func() { 397 defer close(waitc) 398 var recved int 399 for { 400 _, err := stream.Recv() 401 if err == io.EOF { 402 break 403 } 404 if err != nil { 405 t.Fatal("failure to Recv", err) 406 } 407 recved++ 408 } 409 if recved != 3 { 410 t.Fatal("received incorrect number of messages from server", recved) 411 } 412 }() 413 for i := 0; i < 3; i++ { 414 if err := stream.Send(&testapp.Message{Text: "Hello DoStreamStream"}); err != nil { 415 t.Fatal("failure to Send", err) 416 } 417 } 418 stream.CloseSend() 419 <-waitc 420 421 app.ExpectMetrics(t, []internal.WantMetric{ 422 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 423 {Name: "Apdex/Go/TestApplication/DoStreamStream", Scope: "", Forced: false, Data: nil}, 424 {Name: "Custom/DoStreamStream", Scope: "", Forced: false, Data: nil}, 425 {Name: "Custom/DoStreamStream", Scope: "WebTransaction/Go/TestApplication/DoStreamStream", Forced: false, Data: nil}, 426 {Name: "DurationByCaller/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 427 {Name: "DurationByCaller/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 428 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 429 {Name: "Supportability/DistributedTrace/AcceptPayload/Success", Scope: "", Forced: true, Data: nil}, 430 {Name: "TransportDuration/App/123/456/HTTP/all", Scope: "", Forced: false, Data: nil}, 431 {Name: "TransportDuration/App/123/456/HTTP/allWeb", Scope: "", Forced: false, Data: nil}, 432 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 433 {Name: "WebTransaction/Go/TestApplication/DoStreamStream", Scope: "", Forced: true, Data: nil}, 434 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 435 {Name: "WebTransactionTotalTime/Go/TestApplication/DoStreamStream", Scope: "", Forced: false, Data: nil}, 436 }) 437 app.ExpectTxnEvents(t, []internal.WantEvent{{ 438 Intrinsics: map[string]interface{}{ 439 "guid": internal.MatchAnything, 440 "name": "WebTransaction/Go/TestApplication/DoStreamStream", 441 "nr.apdexPerfZone": internal.MatchAnything, 442 "parent.account": 123, 443 "parent.app": 456, 444 "parent.transportDuration": internal.MatchAnything, 445 "parent.transportType": "HTTP", 446 "parent.type": "App", 447 "parentId": internal.MatchAnything, 448 "parentSpanId": internal.MatchAnything, 449 "priority": internal.MatchAnything, 450 "sampled": internal.MatchAnything, 451 "traceId": internal.MatchAnything, 452 }, 453 UserAttributes: map[string]interface{}{}, 454 AgentAttributes: map[string]interface{}{ 455 "httpResponseCode": 0, 456 "request.headers.contentType": "application/grpc", 457 "request.method": "TestApplication/DoStreamStream", 458 "request.uri": "grpc://bufnet/TestApplication/DoStreamStream", 459 }, 460 }}) 461 app.ExpectSpanEvents(t, []internal.WantEvent{ 462 { 463 Intrinsics: map[string]interface{}{ 464 "category": "generic", 465 "name": "WebTransaction/Go/TestApplication/DoStreamStream", 466 "nr.entryPoint": true, 467 "parentId": internal.MatchAnything, 468 }, 469 UserAttributes: map[string]interface{}{}, 470 AgentAttributes: map[string]interface{}{}, 471 }, 472 { 473 Intrinsics: map[string]interface{}{ 474 "category": "generic", 475 "name": "Custom/DoStreamStream", 476 "parentId": internal.MatchAnything, 477 }, 478 UserAttributes: map[string]interface{}{}, 479 AgentAttributes: map[string]interface{}{}, 480 }, 481 }) 482 } 483 484 func TestStreamServerInterceptorError(t *testing.T) { 485 app := testApp() 486 487 s, conn := newTestServerAndConn(t, app) 488 defer s.Stop() 489 defer conn.Close() 490 491 client := testapp.NewTestApplicationClient(conn) 492 stream, err := client.DoUnaryStreamError(context.Background(), &testapp.Message{}) 493 if nil != err { 494 t.Fatal("client call to DoUnaryStream failed", err) 495 } 496 _, err = stream.Recv() 497 if nil == err { 498 t.Fatal("DoUnaryStreamError should have returned an error") 499 } 500 501 app.ExpectMetrics(t, []internal.WantMetric{ 502 {Name: "Apdex", Scope: "", Forced: true, Data: nil}, 503 {Name: "Apdex/Go/TestApplication/DoUnaryStreamError", Scope: "", Forced: false, Data: nil}, 504 {Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil}, 505 {Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allWeb", Scope: "", Forced: false, Data: nil}, 506 {Name: "Errors/WebTransaction/Go/TestApplication/DoUnaryStreamError", Scope: "", Forced: true, Data: nil}, 507 {Name: "Errors/all", Scope: "", Forced: true, Data: nil}, 508 {Name: "Errors/allWeb", Scope: "", Forced: true, Data: nil}, 509 {Name: "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown/all", Scope: "", Forced: false, Data: nil}, 510 {Name: "ErrorsByCaller/Unknown/Unknown/Unknown/Unknown/allWeb", Scope: "", Forced: false, Data: nil}, 511 {Name: "HttpDispatcher", Scope: "", Forced: true, Data: nil}, 512 {Name: "WebTransaction", Scope: "", Forced: true, Data: nil}, 513 {Name: "WebTransaction/Go/TestApplication/DoUnaryStreamError", Scope: "", Forced: true, Data: nil}, 514 {Name: "WebTransactionTotalTime", Scope: "", Forced: true, Data: nil}, 515 {Name: "WebTransactionTotalTime/Go/TestApplication/DoUnaryStreamError", Scope: "", Forced: false, Data: nil}, 516 }) 517 app.ExpectTxnEvents(t, []internal.WantEvent{{ 518 Intrinsics: map[string]interface{}{ 519 "guid": internal.MatchAnything, 520 "name": "WebTransaction/Go/TestApplication/DoUnaryStreamError", 521 "nr.apdexPerfZone": internal.MatchAnything, 522 "priority": internal.MatchAnything, 523 "sampled": internal.MatchAnything, 524 "traceId": internal.MatchAnything, 525 }, 526 UserAttributes: map[string]interface{}{}, 527 AgentAttributes: map[string]interface{}{ 528 "httpResponseCode": 15, 529 "request.headers.contentType": "application/grpc", 530 "request.method": "TestApplication/DoUnaryStreamError", 531 "request.uri": "grpc://bufnet/TestApplication/DoUnaryStreamError", 532 }, 533 }}) 534 app.ExpectErrorEvents(t, []internal.WantEvent{{ 535 Intrinsics: map[string]interface{}{ 536 "error.class": "15", 537 "error.message": "response code 15", 538 "guid": internal.MatchAnything, 539 "priority": internal.MatchAnything, 540 "sampled": internal.MatchAnything, 541 "traceId": internal.MatchAnything, 542 "transactionName": "WebTransaction/Go/TestApplication/DoUnaryStreamError", 543 }, 544 AgentAttributes: map[string]interface{}{ 545 "httpResponseCode": 15, 546 "request.headers.User-Agent": internal.MatchAnything, 547 "request.headers.contentType": "application/grpc", 548 "request.method": "TestApplication/DoUnaryStreamError", 549 "request.uri": "grpc://bufnet/TestApplication/DoUnaryStreamError", 550 }, 551 UserAttributes: map[string]interface{}{}, 552 }}) 553 } 554 555 func TestUnaryServerInterceptorNilApp(t *testing.T) { 556 s, conn := newTestServerAndConn(t, nil) 557 defer s.Stop() 558 defer conn.Close() 559 560 client := testapp.NewTestApplicationClient(conn) 561 msg, err := client.DoUnaryUnary(context.Background(), &testapp.Message{}) 562 if nil != err { 563 t.Fatal("unable to call client DoUnaryUnary", err) 564 } 565 if !strings.Contains(msg.Text, "content-type") { 566 t.Error("incorrect message received") 567 } 568 } 569 570 func TestStreamServerInterceptorNilApp(t *testing.T) { 571 s, conn := newTestServerAndConn(t, nil) 572 defer s.Stop() 573 defer conn.Close() 574 575 client := testapp.NewTestApplicationClient(conn) 576 stream, err := client.DoStreamUnary(context.Background()) 577 if nil != err { 578 t.Fatal("client call to DoStreamUnary failed", err) 579 } 580 for i := 0; i < 3; i++ { 581 if err := stream.Send(&testapp.Message{Text: "Hello DoStreamUnary"}); nil != err { 582 if err == io.EOF { 583 break 584 } 585 t.Fatal("failure to Send", err) 586 } 587 } 588 msg, err := stream.CloseAndRecv() 589 if nil != err { 590 t.Fatal("failure to CloseAndRecv", err) 591 } 592 if !strings.Contains(msg.Text, "content-type") { 593 t.Error("incorrect message received") 594 } 595 } 596 597 func TestInterceptorsNilAppReturnNonNil(t *testing.T) { 598 uInt := UnaryServerInterceptor(nil) 599 if uInt == nil { 600 t.Error("UnaryServerInterceptor returned nil") 601 } 602 603 sInt := StreamServerInterceptor(nil) 604 if sInt == nil { 605 t.Error("StreamServerInterceptor returned nil") 606 } 607 }