mirror of
https://github.com/linka-cloud/grpc.git
synced 2024-11-23 11:26:26 +00:00
159 lines
4.0 KiB
Go
159 lines
4.0 KiB
Go
|
package testservice
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
"google.golang.org/grpc"
|
||
|
"google.golang.org/grpc/metadata"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
returnHeader = "test-client-header"
|
||
|
)
|
||
|
|
||
|
// TestTestServiceServerImpl can be called to test the underlying TestServiceServer.
|
||
|
func TestTestServiceServerImpl(t *testing.T, client TestServiceClient) {
|
||
|
t.Run("Unary ping", func(t *testing.T) {
|
||
|
want := "hello, world"
|
||
|
hdr := metadata.MD{}
|
||
|
res, err := client.Ping(context.TODO(), &PingRequest{Value: want}, grpc.Header(&hdr))
|
||
|
if err != nil {
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
return
|
||
|
}
|
||
|
checkHeaders(t, hdr)
|
||
|
t.Logf("got %v (%d)", res.Value, res.Counter)
|
||
|
if got := res.Value; got != want {
|
||
|
t.Errorf("res.Value = %q; want %q", got, want)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Error ping", func(t *testing.T) {
|
||
|
_, err := client.PingError(context.TODO(), &PingRequest{})
|
||
|
if err == nil {
|
||
|
t.Errorf("want err; got %v", err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Server streaming ping", func(t *testing.T) {
|
||
|
want := "hello, world"
|
||
|
stream, err := client.PingList(context.TODO(), &PingRequest{Value: want})
|
||
|
if err != nil {
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
if err := stream.CloseSend(); err != nil {
|
||
|
t.Fatalf("closing send channel: %v", err)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
hdr, err := stream.Header()
|
||
|
if err != nil {
|
||
|
t.Errorf("reading headers: %v", err)
|
||
|
}
|
||
|
checkHeaders(t, hdr)
|
||
|
|
||
|
for {
|
||
|
res, err := stream.Recv()
|
||
|
if err != nil {
|
||
|
if err == io.EOF {
|
||
|
checkTrailers(t, stream.Trailer())
|
||
|
return
|
||
|
}
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
return
|
||
|
}
|
||
|
t.Logf("got %v (%d)", res.Value, res.Counter)
|
||
|
if got := res.Value; got != want {
|
||
|
t.Errorf("res.Value = %q; want %q", got, want)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
t.Run("Bidirectional pinging", func(t *testing.T) {
|
||
|
want := "hello, world"
|
||
|
stream, err := client.PingStream(context.TODO())
|
||
|
if err != nil {
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
if err := stream.CloseSend(); err != nil {
|
||
|
t.Fatalf("closing send channel: %v", err)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
d := make(chan struct{})
|
||
|
go func() {
|
||
|
hdr, err := stream.Header()
|
||
|
if err != nil {
|
||
|
t.Errorf("reading headers: %v", err)
|
||
|
}
|
||
|
checkHeaders(t, hdr)
|
||
|
close(d)
|
||
|
}()
|
||
|
|
||
|
for i := 0; i < 25; i++ {
|
||
|
if err := stream.Send(&PingRequest{Value: want}); err != nil {
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
return
|
||
|
}
|
||
|
res, err := stream.Recv()
|
||
|
if err != nil {
|
||
|
t.Errorf("receiving full duplex stream: %w", err)
|
||
|
return
|
||
|
}
|
||
|
t.Logf("got %v (%d)", res.Value, res.Counter)
|
||
|
if got := res.Value; got != want {
|
||
|
t.Errorf("res.Value = %q; want %q", got, want)
|
||
|
}
|
||
|
if got, want := res.Counter, int32(i); got != want {
|
||
|
t.Errorf("res.Counter = %d; want %d", got, want)
|
||
|
}
|
||
|
}
|
||
|
if err := stream.CloseSend(); err != nil {
|
||
|
t.Errorf("closing full duplex stream: %v", err)
|
||
|
}
|
||
|
<-d
|
||
|
})
|
||
|
|
||
|
t.Run("Unary ping with headers", func(t *testing.T) {
|
||
|
want := "hello, world"
|
||
|
req := &PingRequest{Value: want}
|
||
|
|
||
|
ctx := metadata.AppendToOutgoingContext(context.Background(), returnHeader, "I like turtles.")
|
||
|
inHeader := make(metadata.MD)
|
||
|
|
||
|
res, err := client.Ping(ctx, req, grpc.Header(&inHeader))
|
||
|
if err != nil {
|
||
|
t.Errorf("want no err; got %v", err)
|
||
|
return
|
||
|
}
|
||
|
t.Logf("got %v (%d)", res.Value, res.Counter)
|
||
|
if !reflect.DeepEqual(inHeader.Get(returnHeader), []string{"I like turtles."}) {
|
||
|
t.Errorf("did not receive correct return headers")
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func checkTrailers(t *testing.T, md metadata.MD) {
|
||
|
vs := md.Get(PingTrailer)
|
||
|
if want, got := 1, len(vs); want != got {
|
||
|
t.Errorf("trailer %q not present", PingTrailer)
|
||
|
return
|
||
|
}
|
||
|
if want, got := []string{PingTrailerCts}, vs; !reflect.DeepEqual(got, want) {
|
||
|
t.Errorf("trailer mismatch; want %q, got %q", want, got)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func checkHeaders(t *testing.T, md metadata.MD) {
|
||
|
vs := md.Get(PingHeader)
|
||
|
if want, got := 1, len(vs); want != got {
|
||
|
t.Errorf("header %q not present", PingHeader)
|
||
|
return
|
||
|
}
|
||
|
if want, got := []string{PingHeaderCts}, vs; !reflect.DeepEqual(got, want) {
|
||
|
t.Errorf("header mismatch; want %q, got %q", want, got)
|
||
|
}
|
||
|
}
|