func TestClientStatsStreamingRPCError(t *testing.T) { var ( mu sync.Mutex got []*gotData ) stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { got = append(got, &gotData{ctx, true, s}) } }) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { got = append(got, &gotData{ctx, true, s}) } }) stats.RegisterConnTagger(tagConnCtx) stats.RegisterRPCTagger(tagRPCCtx) stats.Start() defer stats.Stop() te := newTest(t, "gzip") te.startServer(&testServer{}) defer te.tearDown() count := 5 failfast := true reqs, resps, err := te.doFullDuplexCallRoundtrip(&rpcConfig{count: count, success: false, failfast: failfast}) if err == nil { t.Fatalf("got error <nil>; want <non-nil>") } te.srv.GracefulStop() // Wait for the server to stop. expect := &expectedData{ method: "/grpc.testing.TestService/FullDuplexCall", serverAddr: te.srvAddr, compression: "gzip", requests: reqs, responses: resps, err: err, failfast: failfast, } checkFuncs := map[int]*checkFuncWithCount{ connbegin: {checkConnBegin, 1}, begin: {checkBegin, 1}, outHeader: {checkOutHeader, 1}, outPayload: {checkOutPayload, 1}, inHeader: {checkInHeader, 1}, inTrailer: {checkInTrailer, 1}, end: {checkEnd, 1}, connend: {checkConnEnd, 1}, } checkClientStats(t, got, expect, checkFuncs) }
func TestClientStatsUnaryRPC(t *testing.T) { var ( mu sync.Mutex got []*gotData ) stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { got = append(got, &gotData{ctx, true, s}) } }) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { got = append(got, &gotData{ctx, true, s}) } }) stats.RegisterConnTagger(tagConnCtx) stats.RegisterRPCTagger(tagRPCCtx) stats.Start() defer stats.Stop() te := newTest(t, "") te.startServer(&testServer{}) defer te.tearDown() failfast := false req, resp, err := te.doUnaryCall(&rpcConfig{success: true, failfast: failfast}) if err != nil { t.Fatalf(err.Error()) } te.srv.GracefulStop() // Wait for the server to stop. expect := &expectedData{ method: "/grpc.testing.TestService/UnaryCall", serverAddr: te.srvAddr, requests: []*testpb.SimpleRequest{req}, responses: []*testpb.SimpleResponse{resp}, failfast: failfast, } checkFuncs := map[int]*checkFuncWithCount{ connbegin: {checkConnBegin, 1}, begin: {checkBegin, 1}, outHeader: {checkOutHeader, 1}, outPayload: {checkOutPayload, 1}, inHeader: {checkInHeader, 1}, inPayload: {checkInPayload, 1}, inTrailer: {checkInTrailer, 1}, end: {checkEnd, 1}, connend: {checkConnEnd, 1}, } checkClientStats(t, got, expect, checkFuncs) }
func TestServerStatsUnaryRPCError(t *testing.T) { var ( mu sync.Mutex got []*gotData ) stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) { mu.Lock() defer mu.Unlock() if !s.IsClient() { got = append(got, &gotData{ctx, false, s}) } }) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) { mu.Lock() defer mu.Unlock() if !s.IsClient() { got = append(got, &gotData{ctx, false, s}) } }) stats.RegisterConnTagger(tagConnCtx) stats.RegisterRPCTagger(tagRPCCtx) stats.Start() defer stats.Stop() te := newTest(t, "") te.startServer(&testServer{}) defer te.tearDown() req, resp, err := te.doUnaryCall(&rpcConfig{success: false}) if err == nil { t.Fatalf("got error <nil>; want <non-nil>") } te.srv.GracefulStop() // Wait for the server to stop. expect := &expectedData{ method: "/grpc.testing.TestService/UnaryCall", serverAddr: te.srvAddr, requests: []*testpb.SimpleRequest{req}, responses: []*testpb.SimpleResponse{resp}, err: err, } checkFuncs := []func(t *testing.T, d *gotData, e *expectedData){ checkConnBegin, checkInHeader, checkBegin, checkInPayload, checkOutHeader, checkOutTrailer, checkEnd, checkConnEnd, } checkServerStats(t, got, expect, checkFuncs) }
func TestStartStop(t *testing.T) { stats.RegisterRPCHandler(nil) stats.RegisterConnHandler(nil) stats.Start() if stats.On() { t.Fatalf("stats.Start() with nil handler, stats.On() = true, want false") } stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) {}) stats.RegisterConnHandler(nil) stats.Start() if !stats.On() { t.Fatalf("stats.Start() with non-nil handler, stats.On() = false, want true") } stats.Stop() stats.RegisterRPCHandler(nil) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) {}) stats.Start() if !stats.On() { t.Fatalf("stats.Start() with non-nil conn handler, stats.On() = false, want true") } stats.Stop() stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) {}) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) {}) if stats.On() { t.Fatalf("after stats.RegisterRPCHandler(), stats.On() = true, want false") } stats.Start() if !stats.On() { t.Fatalf("after stats.Start(_), stats.On() = false, want true") } stats.Stop() if stats.On() { t.Fatalf("after stats.Stop(), stats.On() = true, want false") } }
func testClientStats(t *testing.T, tc *testConfig, cc *rpcConfig, checkFuncs map[int]*checkFuncWithCount) { var ( mu sync.Mutex gotRPC []*gotData gotConn []*gotData ) stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { gotRPC = append(gotRPC, &gotData{ctx, true, s}) } }) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) { mu.Lock() defer mu.Unlock() if s.IsClient() { gotConn = append(gotConn, &gotData{ctx, true, s}) } }) stats.RegisterConnTagger(tagConnCtx) stats.RegisterRPCTagger(tagRPCCtx) stats.Start() te := newTest(t, tc) te.startServer(&testServer{}) defer te.tearDown() var ( reqs []*testpb.SimpleRequest resps []*testpb.SimpleResponse err error ) if !cc.streaming { req, resp, e := te.doUnaryCall(cc) reqs = []*testpb.SimpleRequest{req} resps = []*testpb.SimpleResponse{resp} err = e } else { reqs, resps, err = te.doFullDuplexCallRoundtrip(cc) } if cc.success != (err == nil) { t.Fatalf("cc.success: %v, got error: %v", cc.success, err) } te.cc.Close() te.srv.GracefulStop() // Wait for the server to stop. lenRPCStats := 0 for _, v := range checkFuncs { lenRPCStats += v.c } for { mu.Lock() if len(gotRPC) >= lenRPCStats { mu.Unlock() break } mu.Unlock() time.Sleep(10 * time.Millisecond) } for { mu.Lock() if _, ok := gotConn[len(gotConn)-1].s.(*stats.ConnEnd); ok { mu.Unlock() break } mu.Unlock() time.Sleep(10 * time.Millisecond) } expect := &expectedData{ serverAddr: te.srvAddr, compression: tc.compress, requests: reqs, responses: resps, failfast: cc.failfast, err: err, } if !cc.streaming { expect.method = "/grpc.testing.TestService/UnaryCall" } else { expect.method = "/grpc.testing.TestService/FullDuplexCall" } checkConnStats(t, gotConn) checkClientStats(t, gotRPC, expect, checkFuncs) }
func TestServerStatsStreamingRPC(t *testing.T) { var ( mu sync.Mutex got []*gotData ) stats.RegisterRPCHandler(func(ctx context.Context, s stats.RPCStats) { mu.Lock() defer mu.Unlock() if !s.IsClient() { got = append(got, &gotData{ctx, false, s}) } }) stats.RegisterConnHandler(func(ctx context.Context, s stats.ConnStats) { mu.Lock() defer mu.Unlock() if !s.IsClient() { got = append(got, &gotData{ctx, false, s}) } }) stats.RegisterConnTagger(tagConnCtx) stats.RegisterRPCTagger(tagRPCCtx) stats.Start() defer stats.Stop() te := newTest(t, "gzip") te.startServer(&testServer{}) defer te.tearDown() count := 5 reqs, resps, err := te.doFullDuplexCallRoundtrip(&rpcConfig{count: count, success: true}) if err == nil { t.Fatalf(err.Error()) } te.srv.GracefulStop() // Wait for the server to stop. expect := &expectedData{ method: "/grpc.testing.TestService/FullDuplexCall", serverAddr: te.srvAddr, compression: "gzip", requests: reqs, responses: resps, } checkFuncs := []func(t *testing.T, d *gotData, e *expectedData){ checkConnBegin, checkInHeader, checkBegin, checkOutHeader, } ioPayFuncs := []func(t *testing.T, d *gotData, e *expectedData){ checkInPayload, checkOutPayload, } for i := 0; i < count; i++ { checkFuncs = append(checkFuncs, ioPayFuncs...) } checkFuncs = append(checkFuncs, checkOutTrailer, checkEnd, checkConnEnd, ) checkServerStats(t, got, expect, checkFuncs) }