mirror of
https://github.com/linka-cloud/grpc.git
synced 2024-12-23 01:10:46 +00:00
212 lines
5.4 KiB
Go
212 lines
5.4 KiB
Go
|
package proxy_test
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"testing"
|
||
|
|
||
|
"google.golang.org/grpc"
|
||
|
"google.golang.org/grpc/metadata"
|
||
|
"google.golang.org/grpc/test/bufconn"
|
||
|
|
||
|
"go.linka.cloud/grpc-toolkit/proxy"
|
||
|
"go.linka.cloud/grpc-toolkit/proxy/testservice"
|
||
|
)
|
||
|
|
||
|
var testBackend = flag.String("test-backend", "", "Service providing TestServiceServer")
|
||
|
|
||
|
// TestIntegrationV1 is a regression test of the proxy.
|
||
|
func TestLegacyBehaviour(t *testing.T) {
|
||
|
// These bufconns are test listeners used to make connections between our
|
||
|
// services. This test actually starts two fully functional grpc services.
|
||
|
proxyBc := bufconn.Listen(10)
|
||
|
|
||
|
// Setup is a little thorough, but here's the gist of it:
|
||
|
// 1. Create the test backend using testservice.DefaultTestServiceServer
|
||
|
// 2. Create the proxy backend using this package
|
||
|
// 3. Make calls to 1 via 2.
|
||
|
|
||
|
// 1.
|
||
|
//lint:ignore SA1019 regression test
|
||
|
testCC, err := backendDialer(t, grpc.WithCodec(proxy.Codec()))
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// 2.
|
||
|
go func() {
|
||
|
// Second, we need to implement the SteamDirector.
|
||
|
directorFn := func(ctx context.Context, fullMethodName string) (context.Context, grpc.ClientConnInterface, error) {
|
||
|
md, _ := metadata.FromIncomingContext(ctx)
|
||
|
outCtx := metadata.NewOutgoingContext(ctx, md.Copy())
|
||
|
return outCtx, testCC, nil
|
||
|
}
|
||
|
|
||
|
// Set up the proxy server and then serve from it like in step one.
|
||
|
proxySrv := grpc.NewServer(
|
||
|
//lint:ignore SA1019 regression test
|
||
|
grpc.CustomCodec(proxy.Codec()), // was previously needed for proxy to function.
|
||
|
grpc.UnknownServiceHandler(proxy.TransparentHandler(directorFn)),
|
||
|
)
|
||
|
// run the proxy backend
|
||
|
go func() {
|
||
|
t.Log("Running proxySrv")
|
||
|
if err := proxySrv.Serve(proxyBc); err != nil {
|
||
|
if err == grpc.ErrServerStopped {
|
||
|
return
|
||
|
}
|
||
|
t.Logf("running proxy server: %v", err)
|
||
|
}
|
||
|
}()
|
||
|
t.Cleanup(func() {
|
||
|
t.Log("Gracefully stopping proxySrv")
|
||
|
proxySrv.GracefulStop()
|
||
|
})
|
||
|
}()
|
||
|
|
||
|
// 3.
|
||
|
// Connect to the proxy. We should not need to do anything special here -
|
||
|
// users do not need to know they're talking to a proxy.
|
||
|
proxyCC, err := grpc.Dial(
|
||
|
"bufnet",
|
||
|
grpc.WithInsecure(),
|
||
|
grpc.WithBlock(),
|
||
|
grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) {
|
||
|
return proxyBc.Dial()
|
||
|
}),
|
||
|
)
|
||
|
if err != nil {
|
||
|
t.Fatalf("dialing proxy: %v", err)
|
||
|
}
|
||
|
proxyClient := testservice.NewTestServiceClient(proxyCC)
|
||
|
|
||
|
// 4. Run the tests!
|
||
|
testservice.TestTestServiceServerImpl(t, proxyClient)
|
||
|
}
|
||
|
|
||
|
func TestNewProxy(t *testing.T) {
|
||
|
proxyBc := bufconn.Listen(10)
|
||
|
|
||
|
// Setup is a little thorough, but here's the gist of it:
|
||
|
// 1. Create the test backend using testservice.DefaultTestServiceServer
|
||
|
// 2. Create the proxy backend using this package
|
||
|
// 3. Make calls to 1 via 2.
|
||
|
|
||
|
// 1.
|
||
|
// First, we need to create a client connection to this backend.
|
||
|
testCC, err := backendDialer(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// 2.
|
||
|
go func() {
|
||
|
t.Helper()
|
||
|
|
||
|
// First, we need to create a client connection to this backend.
|
||
|
proxySrv := proxy.NewProxy(testCC)
|
||
|
|
||
|
// run the proxy backend
|
||
|
go func() {
|
||
|
t.Log("Running proxySrv")
|
||
|
if err := proxySrv.Serve(proxyBc); err != nil {
|
||
|
if err == grpc.ErrServerStopped {
|
||
|
return
|
||
|
}
|
||
|
t.Logf("running proxy server: %v", err)
|
||
|
}
|
||
|
}()
|
||
|
t.Cleanup(func() {
|
||
|
t.Log("Gracefully stopping proxySrv")
|
||
|
proxySrv.GracefulStop()
|
||
|
})
|
||
|
}()
|
||
|
|
||
|
// 3.
|
||
|
// Connect to the proxy. We should not need to do anything special here -
|
||
|
// users do not need to know they're talking to a proxy.
|
||
|
t.Logf("dialing %s", proxyBc.Addr())
|
||
|
proxyCC, err := grpc.Dial(
|
||
|
proxyBc.Addr().String(),
|
||
|
grpc.WithInsecure(),
|
||
|
grpc.WithBlock(),
|
||
|
grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) {
|
||
|
return proxyBc.Dial()
|
||
|
}),
|
||
|
)
|
||
|
if err != nil {
|
||
|
t.Fatalf("dialing proxy: %v", err)
|
||
|
}
|
||
|
proxyClient := testservice.NewTestServiceClient(proxyCC)
|
||
|
|
||
|
// 4. Run the tests!
|
||
|
testservice.TestTestServiceServerImpl(t, proxyClient)
|
||
|
}
|
||
|
|
||
|
// backendDialer dials the testservice.TestServiceServer either by connecting
|
||
|
// to the user-supplied server, or by creating a mock server using bufconn.
|
||
|
func backendDialer(t *testing.T, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||
|
t.Helper()
|
||
|
|
||
|
if *testBackend != "" {
|
||
|
return backendSvcDialer(t, *testBackend, opts...)
|
||
|
}
|
||
|
|
||
|
backendBc := bufconn.Listen(10)
|
||
|
// set up the backend using a "real" server over a bufconn
|
||
|
testSrv := grpc.NewServer()
|
||
|
testservice.RegisterTestServiceServer(testSrv, testservice.DefaultTestServiceServer)
|
||
|
|
||
|
// run the test backend
|
||
|
go func() {
|
||
|
t.Log("Running testSrv")
|
||
|
if err := testSrv.Serve(backendBc); err != nil {
|
||
|
if err == grpc.ErrServerStopped {
|
||
|
return
|
||
|
}
|
||
|
t.Logf("running test server: %v", err)
|
||
|
}
|
||
|
}()
|
||
|
t.Cleanup(func() {
|
||
|
t.Log("Gracefully stopping testSrv")
|
||
|
testSrv.GracefulStop()
|
||
|
})
|
||
|
|
||
|
opts = append(opts,
|
||
|
grpc.WithInsecure(),
|
||
|
grpc.WithBlock(),
|
||
|
grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) {
|
||
|
return backendBc.Dial()
|
||
|
}),
|
||
|
)
|
||
|
|
||
|
backendCC, err := grpc.Dial(
|
||
|
"bufnet",
|
||
|
opts...,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("dialing backend: %v", err)
|
||
|
}
|
||
|
return backendCC, nil
|
||
|
}
|
||
|
|
||
|
func backendSvcDialer(t *testing.T, addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||
|
opts = append(opts,
|
||
|
grpc.WithInsecure(),
|
||
|
grpc.WithBlock(),
|
||
|
)
|
||
|
|
||
|
t.Logf("connecting to %s", addr)
|
||
|
cc, err := grpc.Dial(
|
||
|
addr,
|
||
|
opts...,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("dialing backend: %v", err)
|
||
|
}
|
||
|
|
||
|
return cc, nil
|
||
|
}
|