10 "github.com/mitchellh/go-testing-interface"
11 "google.golang.org/grpc"
14 // TestOptions allows specifying options that can affect the behavior of the
16 type TestOptions struct {
17 //ServerStdout causes the given value to be used in place of a blank buffer
18 //for RPCServer's Stdout
19 ServerStdout io.ReadCloser
21 //ServerStderr causes the given value to be used in place of a blank buffer
22 //for RPCServer's Stderr
23 ServerStderr io.ReadCloser
26 // The testing file contains test helpers that you can use outside of
27 // this package for making it easier to test plugins themselves.
29 // TestConn is a helper function for returning a client and server
30 // net.Conn connected to each other.
31 func TestConn(t testing.T) (net.Conn, net.Conn) {
32 // Listen to any local port. This listener will be closed
33 // after a single connection is established.
34 l, err := net.Listen("tcp", "127.0.0.1:0")
36 t.Fatalf("err: %s", err)
39 // Start a goroutine to accept our client connection
40 var serverConn net.Conn
41 doneCh := make(chan struct{})
46 serverConn, err = l.Accept()
48 t.Fatalf("err: %s", err)
52 // Connect to the server
53 clientConn, err := net.Dial("tcp", l.Addr().String())
55 t.Fatalf("err: %s", err)
58 // Wait for the server side to acknowledge it has connected
61 return clientConn, serverConn
64 // TestRPCConn returns a rpc client and server connected to each other.
65 func TestRPCConn(t testing.T) (*rpc.Client, *rpc.Server) {
66 clientConn, serverConn := TestConn(t)
68 server := rpc.NewServer()
69 go server.ServeConn(serverConn)
71 client := rpc.NewClient(clientConn)
75 // TestPluginRPCConn returns a plugin RPC client and server that are connected
76 // together and configured.
77 func TestPluginRPCConn(t testing.T, ps map[string]Plugin, opts *TestOptions) (*RPCClient, *RPCServer) {
78 // Create two net.Conns we can use to shuttle our control connection
79 clientConn, serverConn := TestConn(t)
81 // Start up the server
82 server := &RPCServer{Plugins: ps, Stdout: new(bytes.Buffer), Stderr: new(bytes.Buffer)}
84 if opts.ServerStdout != nil {
85 server.Stdout = opts.ServerStdout
87 if opts.ServerStderr != nil {
88 server.Stderr = opts.ServerStderr
91 go server.ServeConn(serverConn)
93 // Connect the client to the server
94 client, err := NewRPCClient(clientConn, ps)
96 t.Fatalf("err: %s", err)
102 // TestGRPCConn returns a gRPC client conn and grpc server that are connected
103 // together and configured. The register function is used to register services
104 // prior to the Serve call. This is used to test gRPC connections.
105 func TestGRPCConn(t testing.T, register func(*grpc.Server)) (*grpc.ClientConn, *grpc.Server) {
107 l, err := net.Listen("tcp", "127.0.0.1:0")
109 t.Fatalf("err: %s", err)
112 server := grpc.NewServer()
116 // Connect to the server
117 conn, err := grpc.Dial(
122 t.Fatalf("err: %s", err)
125 // Connection successful, close the listener
131 // TestPluginGRPCConn returns a plugin gRPC client and server that are connected
132 // together and configured. This is used to test gRPC connections.
133 func TestPluginGRPCConn(t testing.T, ps map[string]Plugin) (*GRPCClient, *GRPCServer) {
135 l, err := net.Listen("tcp", "127.0.0.1:0")
137 t.Fatalf("err: %s", err)
140 // Start up the server
141 server := &GRPCServer{
143 Server: DefaultGRPCServer,
144 Stdout: new(bytes.Buffer),
145 Stderr: new(bytes.Buffer),
147 if err := server.Init(); err != nil {
148 t.Fatalf("err: %s", err)
152 // Connect to the server
153 conn, err := grpc.Dial(
158 t.Fatalf("err: %s", err)
161 brokerGRPCClient := newGRPCBrokerClient(conn)
162 broker := newGRPCBroker(brokerGRPCClient, nil)
164 go brokerGRPCClient.StartStream()
167 client := &GRPCClient{
171 doneCtx: context.Background(),
174 return client, server