Skip to content

Commit

Permalink
server: populate WireLength on stats.InPayload for unary RPCs
Browse files Browse the repository at this point in the history
Fixes #2692 which was incompletely fixed by #2711.

Also adds a basic unit test which provides scaffolding for further testing of
the stats logic.
  • Loading branch information
ajwerner committed Jul 24, 2019
1 parent 9771422 commit 1a729ca
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
9 changes: 5 additions & 4 deletions server.go
Expand Up @@ -971,10 +971,11 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
}
if sh != nil {
sh.HandleRPC(stream.Context(), &stats.InPayload{
RecvTime: time.Now(),
Payload: v,
Data: d,
Length: len(d),
RecvTime: time.Now(),
Payload: v,
WireLength: payInfo.wireLength,
Data: d,
Length: len(d),
})
}
if binlog != nil {
Expand Down
112 changes: 112 additions & 0 deletions test/stats_test.go
@@ -0,0 +1,112 @@
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package test

import (
"context"
"net"
"testing"

"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/stats"
)

// TestStatsHandlerRPCWireLength ensure that the WireLength fields of stats.RPCStats
// information carries sane values.
func (s) TestStatsHandlerRPCWireLength(t *testing.T) {
lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("failed to create listener: %v", err)
}
sh := statsHandler{
handleRPC: func(_ context.Context, rpcStats stats.RPCStats) {
switch s := rpcStats.(type) {
case *stats.InPayload:
if len(s.Data) > 0 && s.WireLength == 0 {
t.Errorf("WireLength cannot be zero for a non-zero InPayload: %+v", s)
}
case *stats.OutPayload:
if len(s.Data) > 0 && s.WireLength == 0 {
t.Errorf("WireLength cannot be zero for a non-zero OutPayload: %+v", s)
}
}
},
}
server := grpc.NewServer(
grpc.StatsHandler(&sh),
)
healthServer := health.NewServer()
grpc_health_v1.RegisterHealthServer(server, healthServer)

defer server.Stop()
go server.Serve(lis)
c, err := grpc.Dial(lis.Addr().String(),
grpc.WithStatsHandler(&sh),
grpc.WithInsecure())
if err != nil {
t.Fatalf("Failed to listen: %v", err)
}
defer c.Close()
if !c.WaitForStateChange(context.TODO(), connectivity.Ready) {
t.Fatal()
}
const service = "foo"
healthServer.SetServingStatus(service, grpc_health_v1.HealthCheckResponse_SERVING)
hc := grpc_health_v1.NewHealthClient(c)
req := &grpc_health_v1.HealthCheckRequest{
Service: service,
}
if _, err := hc.Check(context.TODO(), req); err != nil {
t.Fatalf("failed to check health: %v", err)
}
w, err := hc.Watch(context.TODO(), req)
if err != nil {
t.Fatalf("failed to watch: %v", err)
}
if _, err := w.Recv(); err != nil {
t.Fatalf("failed to receive a health update: %v", err)
}
}

// statsHandler implements stats.Handler and allows clients to mock the HandleRPC method.
type statsHandler struct {
handleRPC func(ctx context.Context, rpcStats stats.RPCStats)
}

var _ stats.Handler = (*statsHandler)(nil)

func (s *statsHandler) HandleConn(context.Context, stats.ConnStats) {
}

func (s *statsHandler) TagConn(ctx context.Context, _ *stats.ConnTagInfo) context.Context {
return ctx
}

func (s *statsHandler) HandleRPC(ctx context.Context, rpcStats stats.RPCStats) {
if s.handleRPC != nil {
s.handleRPC(ctx, rpcStats)
}
}

func (s *statsHandler) TagRPC(ctx context.Context, _ *stats.RPCTagInfo) context.Context {
return ctx
}

0 comments on commit 1a729ca

Please sign in to comment.