mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-19 09:39:59 +00:00
961c878e0d
Switch to using Go modules. This migrates our vendor.json to use Go 1.11's modules system, and replaces the vendor folder with the output of go mod vendor. The vendored code should remain basically the same; I believe some tree shaking of packages and support scripts/licenses/READMEs/etc. happened. This also fixes Travis and our Makefile to no longer use govendor.
181 lines
4.5 KiB
Go
181 lines
4.5 KiB
Go
package plugin
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"net"
|
|
"net/rpc"
|
|
|
|
hclog "github.com/hashicorp/go-hclog"
|
|
"github.com/hashicorp/go-plugin/internal/proto"
|
|
"github.com/mitchellh/go-testing-interface"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// TestOptions allows specifying options that can affect the behavior of the
|
|
// test functions
|
|
type TestOptions struct {
|
|
//ServerStdout causes the given value to be used in place of a blank buffer
|
|
//for RPCServer's Stdout
|
|
ServerStdout io.ReadCloser
|
|
|
|
//ServerStderr causes the given value to be used in place of a blank buffer
|
|
//for RPCServer's Stderr
|
|
ServerStderr io.ReadCloser
|
|
}
|
|
|
|
// The testing file contains test helpers that you can use outside of
|
|
// this package for making it easier to test plugins themselves.
|
|
|
|
// TestConn is a helper function for returning a client and server
|
|
// net.Conn connected to each other.
|
|
func TestConn(t testing.T) (net.Conn, net.Conn) {
|
|
// Listen to any local port. This listener will be closed
|
|
// after a single connection is established.
|
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Start a goroutine to accept our client connection
|
|
var serverConn net.Conn
|
|
doneCh := make(chan struct{})
|
|
go func() {
|
|
defer close(doneCh)
|
|
defer l.Close()
|
|
var err error
|
|
serverConn, err = l.Accept()
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
}()
|
|
|
|
// Connect to the server
|
|
clientConn, err := net.Dial("tcp", l.Addr().String())
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Wait for the server side to acknowledge it has connected
|
|
<-doneCh
|
|
|
|
return clientConn, serverConn
|
|
}
|
|
|
|
// TestRPCConn returns a rpc client and server connected to each other.
|
|
func TestRPCConn(t testing.T) (*rpc.Client, *rpc.Server) {
|
|
clientConn, serverConn := TestConn(t)
|
|
|
|
server := rpc.NewServer()
|
|
go server.ServeConn(serverConn)
|
|
|
|
client := rpc.NewClient(clientConn)
|
|
return client, server
|
|
}
|
|
|
|
// TestPluginRPCConn returns a plugin RPC client and server that are connected
|
|
// together and configured.
|
|
func TestPluginRPCConn(t testing.T, ps map[string]Plugin, opts *TestOptions) (*RPCClient, *RPCServer) {
|
|
// Create two net.Conns we can use to shuttle our control connection
|
|
clientConn, serverConn := TestConn(t)
|
|
|
|
// Start up the server
|
|
server := &RPCServer{Plugins: ps, Stdout: new(bytes.Buffer), Stderr: new(bytes.Buffer)}
|
|
if opts != nil {
|
|
if opts.ServerStdout != nil {
|
|
server.Stdout = opts.ServerStdout
|
|
}
|
|
if opts.ServerStderr != nil {
|
|
server.Stderr = opts.ServerStderr
|
|
}
|
|
}
|
|
go server.ServeConn(serverConn)
|
|
|
|
// Connect the client to the server
|
|
client, err := NewRPCClient(clientConn, ps)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
return client, server
|
|
}
|
|
|
|
// TestGRPCConn returns a gRPC client conn and grpc server that are connected
|
|
// together and configured. The register function is used to register services
|
|
// prior to the Serve call. This is used to test gRPC connections.
|
|
func TestGRPCConn(t testing.T, register func(*grpc.Server)) (*grpc.ClientConn, *grpc.Server) {
|
|
// Create a listener
|
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
server := grpc.NewServer()
|
|
register(server)
|
|
go server.Serve(l)
|
|
|
|
// Connect to the server
|
|
conn, err := grpc.Dial(
|
|
l.Addr().String(),
|
|
grpc.WithBlock(),
|
|
grpc.WithInsecure())
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Connection successful, close the listener
|
|
l.Close()
|
|
|
|
return conn, server
|
|
}
|
|
|
|
// TestPluginGRPCConn returns a plugin gRPC client and server that are connected
|
|
// together and configured. This is used to test gRPC connections.
|
|
func TestPluginGRPCConn(t testing.T, ps map[string]Plugin) (*GRPCClient, *GRPCServer) {
|
|
// Create a listener
|
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Start up the server
|
|
server := &GRPCServer{
|
|
Plugins: ps,
|
|
DoneCh: make(chan struct{}),
|
|
Server: DefaultGRPCServer,
|
|
Stdout: new(bytes.Buffer),
|
|
Stderr: new(bytes.Buffer),
|
|
logger: hclog.Default(),
|
|
}
|
|
if err := server.Init(); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
go server.Serve(l)
|
|
|
|
// Connect to the server
|
|
conn, err := grpc.Dial(
|
|
l.Addr().String(),
|
|
grpc.WithBlock(),
|
|
grpc.WithInsecure())
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
brokerGRPCClient := newGRPCBrokerClient(conn)
|
|
broker := newGRPCBroker(brokerGRPCClient, nil)
|
|
go broker.Run()
|
|
go brokerGRPCClient.StartStream()
|
|
|
|
// Create the client
|
|
client := &GRPCClient{
|
|
Conn: conn,
|
|
Plugins: ps,
|
|
broker: broker,
|
|
doneCtx: context.Background(),
|
|
controller: proto.NewGRPCControllerClient(conn),
|
|
}
|
|
|
|
return client, server
|
|
}
|