Skip to content

Commit

Permalink
test: modify tests to use stubserver (grpc#7951)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvsravani authored Jan 29, 2025
1 parent 59411f2 commit 7e1c9b2
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 112 deletions.
80 changes: 41 additions & 39 deletions test/goaway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,19 @@ import (
func (s) TestGracefulClientOnGoAway(t *testing.T) {
const maxConnAge = 100 * time.Millisecond
const testTime = maxConnAge * 10

lis, err := testutils.LocalTCPListener()
if err != nil {
t.Fatalf("Failed to create listener: %v", err)
}
ss := &stubserver.StubServer{
Listener: lis,
EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
S: grpc.NewServer(grpc.KeepaliveParams(keepalive.ServerParameters{MaxConnectionAge: maxConnAge})),
}

s := grpc.NewServer(grpc.KeepaliveParams(keepalive.ServerParameters{MaxConnectionAge: maxConnAge}))
defer s.Stop()
testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("Failed to create listener: %v", err)
}
go s.Serve(lis)
stubserver.StartTestService(t, ss)
defer ss.S.Stop()

cc, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
Expand All @@ -82,7 +79,6 @@ func (s) TestGracefulClientOnGoAway(t *testing.T) {

ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()

endTime := time.Now().Add(testTime)
for time.Now().Before(endTime) {
if _, err := c.EmptyCall(ctx, &testpb.Empty{}); err != nil {
Expand Down Expand Up @@ -547,40 +543,48 @@ func (s) TestGoAwayThenClose(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()

lis1, err := net.Listen("tcp", "localhost:0")
lis1, err := testutils.LocalTCPListener()
if err != nil {
t.Fatalf("Error while listening. Err: %v", err)
}
s1 := grpc.NewServer()
defer s1.Stop()
ts := &funcServer{
unaryCall: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
fullDuplexCall: func(stream testgrpc.TestService_FullDuplexCallServer) error {
if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
t.Errorf("unexpected error from send: %v", err)
return err
}
// Wait forever.
_, err := stream.Recv()
if err == nil {
t.Error("expected to never receive any message")
}

unaryCallF := func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
}
fullDuplexCallF := func(stream testgrpc.TestService_FullDuplexCallServer) error {
if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
t.Errorf("Unexpected error from send: %v", err)
return err
},
}
// Wait until a message is received from client
_, err := stream.Recv()
if err == nil {
t.Error("Expected to never receive any message")
}
return err
}
testgrpc.RegisterTestServiceServer(s1, ts)
go s1.Serve(lis1)
ss1 := &stubserver.StubServer{
Listener: lis1,
UnaryCallF: unaryCallF,
FullDuplexCallF: fullDuplexCallF,
S: grpc.NewServer(),
}
stubserver.StartTestService(t, ss1)
defer ss1.S.Stop()

conn2Established := grpcsync.NewEvent()
lis2, err := listenWithNotifyingListener("tcp", "localhost:0", conn2Established)
if err != nil {
t.Fatalf("Error while listening. Err: %v", err)
}
s2 := grpc.NewServer()
defer s2.Stop()
testgrpc.RegisterTestServiceServer(s2, ts)
ss2 := &stubserver.StubServer{
Listener: lis2,
UnaryCallF: unaryCallF,
FullDuplexCallF: fullDuplexCallF,
S: grpc.NewServer(),
}
stubserver.StartTestService(t, ss2)
defer ss2.S.Stop()

r := manual.NewBuilderWithScheme("whatever")
r.InitialState(resolver.State{Addresses: []resolver.Address{
Expand Down Expand Up @@ -613,10 +617,8 @@ func (s) TestGoAwayThenClose(t *testing.T) {
t.Fatalf("unexpected error from first recv: %v", err)
}

go s2.Serve(lis2)

t.Log("Gracefully stopping server 1.")
go s1.GracefulStop()
go ss1.S.GracefulStop()

t.Log("Waiting for the ClientConn to enter IDLE state.")
testutils.AwaitState(ctx, t, cc, connectivity.Idle)
Expand All @@ -637,7 +639,7 @@ func (s) TestGoAwayThenClose(t *testing.T) {
lis2.Close()

t.Log("Hard closing connection 1.")
s1.Stop()
ss1.S.Stop()

t.Log("Waiting for the first stream to error.")
if _, err = stream.Recv(); err == nil {
Expand Down
67 changes: 29 additions & 38 deletions test/insecure_creds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package test

import (
"context"
"net"
"strings"
"testing"

Expand All @@ -29,6 +28,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal/stubserver"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status"

Expand Down Expand Up @@ -83,7 +83,13 @@ func (s) TestInsecureCreds(t *testing.T) {

for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
lis, err := testutils.LocalTCPListener()
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}

ss := &stubserver.StubServer{
Listener: lis,
EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
if !test.serverInsecureCreds {
return &testpb.Empty{}, nil
Expand All @@ -104,28 +110,16 @@ func (s) TestInsecureCreds(t *testing.T) {
return &testpb.Empty{}, nil
},
}

sOpts := []grpc.ServerOption{}
if test.serverInsecureCreds {
sOpts = append(sOpts, grpc.Creds(insecure.NewCredentials()))
ss.S = grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
} else {
ss.S = grpc.NewServer(sOpts...)
}
s := grpc.NewServer(sOpts...)
defer s.Stop()

testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}

go s.Serve(lis)

stubserver.StartTestService(t, ss)
defer ss.S.Stop()
addr := lis.Addr().String()
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
if test.clientInsecureCreds {
opts = []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
}
cc, err := grpc.NewClient(addr, opts...)
if err != nil {
t.Fatalf("grpc.NewClient(%q) failed: %v", addr, err)
Expand All @@ -143,21 +137,20 @@ func (s) TestInsecureCreds(t *testing.T) {
}

func (s) TestInsecureCreds_WithPerRPCCredentials_AsCallOption(t *testing.T) {
lis, err := testutils.LocalTCPListener()
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}

ss := &stubserver.StubServer{
Listener: lis,
EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
S: grpc.NewServer(grpc.Creds(insecure.NewCredentials())),
}

s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
defer s.Stop()
testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}
go s.Serve(lis)
stubserver.StartTestService(t, ss)
defer ss.S.Stop()

addr := lis.Addr().String()
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
Expand All @@ -179,21 +172,19 @@ func (s) TestInsecureCreds_WithPerRPCCredentials_AsCallOption(t *testing.T) {
}

func (s) TestInsecureCreds_WithPerRPCCredentials_AsDialOption(t *testing.T) {
lis, err := testutils.LocalTCPListener()
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}
ss := &stubserver.StubServer{
Listener: lis,
EmptyCallF: func(_ context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
S: grpc.NewServer(grpc.Creds(insecure.NewCredentials())),
}

s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
defer s.Stop()
testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("net.Listen(tcp, localhost:0) failed: %v", err)
}
go s.Serve(lis)
stubserver.StartTestService(t, ss)
defer ss.S.Stop()

addr := lis.Addr().String()
dopts := []grpc.DialOption{
Expand Down
60 changes: 25 additions & 35 deletions test/local_creds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,21 @@ import (
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/credentials/local"
"google.golang.org/grpc/internal/stubserver"
"google.golang.org/grpc/internal/testutils"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status"

testgrpc "google.golang.org/grpc/interop/grpc_testing"
testpb "google.golang.org/grpc/interop/grpc_testing"
)

func testLocalCredsE2ESucceed(network, address string) error {
func testLocalCredsE2ESucceed(t *testing.T, network, address string) error {
lis, err := net.Listen(network, address)
if err != nil {
return fmt.Errorf("Failed to create listener: %v", err)
}
ss := &stubserver.StubServer{
Listener: lis,
EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
pr, ok := peer.FromContext(ctx)
if !ok {
Expand Down Expand Up @@ -69,20 +75,10 @@ func testLocalCredsE2ESucceed(network, address string) error {
}
return &testpb.Empty{}, nil
},
S: grpc.NewServer(grpc.Creds(local.NewCredentials())),
}

sopts := []grpc.ServerOption{grpc.Creds(local.NewCredentials())}
s := grpc.NewServer(sopts...)
defer s.Stop()

testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen(network, address)
if err != nil {
return fmt.Errorf("Failed to create listener: %v", err)
}

go s.Serve(lis)
stubserver.StartTestService(t, ss)
defer ss.S.Stop()

var cc *grpc.ClientConn
lisAddr := lis.Addr().String()
Expand Down Expand Up @@ -114,14 +110,14 @@ func testLocalCredsE2ESucceed(network, address string) error {
}

func (s) TestLocalCredsLocalhost(t *testing.T) {
if err := testLocalCredsE2ESucceed("tcp", "localhost:0"); err != nil {
if err := testLocalCredsE2ESucceed(t, "tcp", "localhost:0"); err != nil {
t.Fatalf("Failed e2e test for localhost: %v", err)
}
}

func (s) TestLocalCredsUDS(t *testing.T) {
addr := fmt.Sprintf("/tmp/grpc_fullstck_test%d", time.Now().UnixNano())
if err := testLocalCredsE2ESucceed("unix", addr); err != nil {
if err := testLocalCredsE2ESucceed(t, "unix", addr); err != nil {
t.Fatalf("Failed e2e test for UDS: %v", err)
}
}
Expand Down Expand Up @@ -162,24 +158,11 @@ func spoofDialer(addr net.Addr) func(target string, t time.Duration) (net.Conn,
}
}

func testLocalCredsE2EFail(dopts []grpc.DialOption) error {
ss := &stubserver.StubServer{
EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
}

sopts := []grpc.ServerOption{grpc.Creds(local.NewCredentials())}
s := grpc.NewServer(sopts...)
defer s.Stop()

testgrpc.RegisterTestServiceServer(s, ss)

lis, err := net.Listen("tcp", "localhost:0")
func testLocalCredsE2EFail(t *testing.T, dopts []grpc.DialOption) error {
lis, err := testutils.LocalTCPListener()
if err != nil {
return fmt.Errorf("Failed to create listener: %v", err)
}

var fakeClientAddr, fakeServerAddr net.Addr
fakeClientAddr = &net.IPAddr{
IP: netip.MustParseAddr("10.8.9.10").AsSlice(),
Expand All @@ -189,8 +172,15 @@ func testLocalCredsE2EFail(dopts []grpc.DialOption) error {
IP: netip.MustParseAddr("10.8.9.11").AsSlice(),
Zone: "",
}

go s.Serve(spoofListener(lis, fakeClientAddr))
ss := &stubserver.StubServer{
Listener: spoofListener(lis, fakeClientAddr),
EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) {
return &testpb.Empty{}, nil
},
S: grpc.NewServer(grpc.Creds(local.NewCredentials())),
}
stubserver.StartTestService(t, ss)
defer ss.S.Stop()

cc, err := grpc.NewClient(lis.Addr().String(), append(dopts, grpc.WithDialer(spoofDialer(fakeServerAddr)))...)
if err != nil {
Expand All @@ -214,15 +204,15 @@ func (s) TestLocalCredsClientFail(t *testing.T) {
// Use local creds at client-side which should lead to client-side failure.
opts := []grpc.DialOption{grpc.WithTransportCredentials(local.NewCredentials())}
want := status.Error(codes.Unavailable, "transport: authentication handshake failed: local credentials rejected connection to non-local address")
if err := testLocalCredsE2EFail(opts); !isExpected(err, want) {
if err := testLocalCredsE2EFail(t, opts); !isExpected(err, want) {
t.Fatalf("testLocalCredsE2EFail() = %v; want %v", err, want)
}
}

func (s) TestLocalCredsServerFail(t *testing.T) {
// Use insecure at client-side which should lead to server-side failure.
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
if err := testLocalCredsE2EFail(opts); status.Code(err) != codes.Unavailable {
if err := testLocalCredsE2EFail(t, opts); status.Code(err) != codes.Unavailable {
t.Fatalf("testLocalCredsE2EFail() = %v; want %v", err, codes.Unavailable)
}
}

0 comments on commit 7e1c9b2

Please sign in to comment.