-
Notifications
You must be signed in to change notification settings - Fork 4.7k
server: Set a pprof label on new stream goroutines #9082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
84dda06
f2029fc
3b7e587
c3f70d9
7aaf9c9
5329657
819e7a7
e1d919e
e32f01e
cbcdf44
e176a2b
05172ce
921d8cb
e238722
3854612
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
arjan-bal marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,11 +21,13 @@ package test | |
| import ( | ||
| "context" | ||
| "io" | ||
| "runtime/pprof" | ||
| "sync/atomic" | ||
| "testing" | ||
|
|
||
| "google.golang.org/grpc" | ||
| "google.golang.org/grpc/codes" | ||
| "google.golang.org/grpc/internal/envconfig" | ||
| "google.golang.org/grpc/internal/stubserver" | ||
| "google.golang.org/grpc/status" | ||
|
|
||
|
|
@@ -70,6 +72,110 @@ func (s) TestServerReturningContextError(t *testing.T) { | |
|
|
||
| } | ||
|
|
||
| func pprofCtxCollectLabels(ctx context.Context) map[string]string { | ||
| seenLabels := map[string]string{} | ||
| pprof.ForLabels(ctx, func(k, val string) bool { | ||
| seenLabels[k] = val | ||
| return true | ||
| }) | ||
| return seenLabels | ||
| } | ||
|
|
||
| // TestServerSetGoroutineLabelsInContext verifies that when enabled, the | ||
| // grpc.method runtime/pprof goroutine label gets set in the context that's | ||
| // passed to the handlers | ||
| func (s) TestServerSetGoroutineLabelsInContext(t *testing.T) { | ||
| oldGoroutineLabelCfg := envconfig.LabelServerGoroutines | ||
| defer func() { envconfig.LabelServerGoroutines = oldGoroutineLabelCfg }() | ||
| envconfig.LabelServerGoroutines = envconfig.GoroutineLabelServerMethod | ||
| ss := &stubserver.StubServer{ | ||
| EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { | ||
| ctxLabels := pprofCtxCollectLabels(ctx) | ||
| if val, ok := ctxLabels["grpc.method"]; !ok { | ||
| t.Errorf("missing \"grpc.method\" label; found labels: %v", ctxLabels) | ||
| } else if expVal := "/grpc.testing.TestService/EmptyCall"; val != expVal { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Here and elsewhere s/expVal/wantVal See: https://google.github.io/styleguide/go/decisions#got-before-want
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| t.Errorf("unexpected value for \"grpc.method\" label %q; want %q", ctxLabels["grpc.method"], expVal) | ||
| } | ||
| return &testpb.Empty{}, nil | ||
| }, | ||
| FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error { | ||
| ctxLabels := pprofCtxCollectLabels(stream.Context()) | ||
| if val, ok := ctxLabels["grpc.method"]; !ok { | ||
| t.Errorf("missing \"grpc.method\" label; found labels: %v", ctxLabels) | ||
| } else if expVal := "/grpc.testing.TestService/FullDuplexCall"; val != expVal { | ||
| t.Errorf("unexpected value for \"grpc.method\" label %q; want %q", ctxLabels["grpc.method"], expVal) | ||
| } | ||
| return nil | ||
| }, | ||
| } | ||
| if err := ss.Start(nil); err != nil { | ||
| t.Fatalf("Error starting endpoint server: %v", err) | ||
| } | ||
| defer ss.Stop() | ||
|
|
||
| ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) | ||
| defer cancel() | ||
| _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}) | ||
| if err != nil { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: The assignment and the conditional can be on the same line. Here and elsewhere in this test.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. |
||
| t.Fatalf("ss.Client.EmptyCall() got error %v; want OK", err) | ||
| } | ||
|
|
||
| stream, err := ss.Client.FullDuplexCall(ctx) | ||
| if err != nil { | ||
| t.Fatalf("unexpected error starting the stream: %v", err) | ||
| } | ||
| _, err = stream.Recv() | ||
| if err != io.EOF { | ||
| t.Fatalf("ss.Client.FullDuplexCall().Recv() got error %v; want io.EOF", err) | ||
| } | ||
| } | ||
|
|
||
| // TestServerSetGoroutineLabelsInContextEnvVarDisabled verifies that when disable, the | ||
| // grpc.method runtime/pprof goroutine label does _not_ get set in the context that's | ||
| // passed to the handlers | ||
| func (s) TestServerSetGoroutineLabelsInContextEnvVarDisabled(t *testing.T) { | ||
| oldGoroutineLabelCfg := envconfig.LabelServerGoroutines | ||
| defer func() { envconfig.LabelServerGoroutines = oldGoroutineLabelCfg }() | ||
|
arjan-bal marked this conversation as resolved.
Outdated
|
||
| // clear the existing value | ||
| envconfig.LabelServerGoroutines = 0 | ||
| ss := &stubserver.StubServer{ | ||
| EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { | ||
| ctxLabels := pprofCtxCollectLabels(ctx) | ||
| if val, ok := ctxLabels["grpc.method"]; ok { | ||
| t.Errorf("\"grpc.method\" label set with value %q; found labels: %v", val, ctxLabels) | ||
| } | ||
| return &testpb.Empty{}, nil | ||
| }, | ||
| FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error { | ||
| ctxLabels := pprofCtxCollectLabels(stream.Context()) | ||
| if val, ok := ctxLabels["grpc.method"]; ok { | ||
| t.Errorf("\"grpc.method\" label set with value %q; found labels: %v", val, ctxLabels) | ||
| } | ||
| return nil | ||
| }, | ||
| } | ||
| if err := ss.Start(nil); err != nil { | ||
| t.Fatalf("Error starting endpoint server: %v", err) | ||
| } | ||
| defer ss.Stop() | ||
|
|
||
| ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) | ||
| defer cancel() | ||
| _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}) | ||
| if err != nil { | ||
| t.Fatalf("ss.Client.EmptyCall() got error %v; want OK", err) | ||
| } | ||
|
|
||
| stream, err := ss.Client.FullDuplexCall(ctx) | ||
| if err != nil { | ||
| t.Fatalf("unexpected error starting the stream: %v", err) | ||
| } | ||
| _, err = stream.Recv() | ||
| if err != io.EOF { | ||
| t.Fatalf("ss.Client.FullDuplexCall().Recv() got error %v; want io.EOF", err) | ||
| } | ||
| } | ||
|
|
||
| func (s) TestChainUnaryServerInterceptor(t *testing.T) { | ||
| var ( | ||
| firstIntKey = ctxKey("firstIntKey") | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.