testing.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package plugin
  2. import (
  3. "bytes"
  4. "net"
  5. "net/rpc"
  6. "github.com/mitchellh/go-testing-interface"
  7. "google.golang.org/grpc"
  8. )
  9. // The testing file contains test helpers that you can use outside of
  10. // this package for making it easier to test plugins themselves.
  11. // TestConn is a helper function for returning a client and server
  12. // net.Conn connected to each other.
  13. func TestConn(t testing.T) (net.Conn, net.Conn) {
  14. // Listen to any local port. This listener will be closed
  15. // after a single connection is established.
  16. l, err := net.Listen("tcp", "127.0.0.1:0")
  17. if err != nil {
  18. t.Fatalf("err: %s", err)
  19. }
  20. // Start a goroutine to accept our client connection
  21. var serverConn net.Conn
  22. doneCh := make(chan struct{})
  23. go func() {
  24. defer close(doneCh)
  25. defer l.Close()
  26. var err error
  27. serverConn, err = l.Accept()
  28. if err != nil {
  29. t.Fatalf("err: %s", err)
  30. }
  31. }()
  32. // Connect to the server
  33. clientConn, err := net.Dial("tcp", l.Addr().String())
  34. if err != nil {
  35. t.Fatalf("err: %s", err)
  36. }
  37. // Wait for the server side to acknowledge it has connected
  38. <-doneCh
  39. return clientConn, serverConn
  40. }
  41. // TestRPCConn returns a rpc client and server connected to each other.
  42. func TestRPCConn(t testing.T) (*rpc.Client, *rpc.Server) {
  43. clientConn, serverConn := TestConn(t)
  44. server := rpc.NewServer()
  45. go server.ServeConn(serverConn)
  46. client := rpc.NewClient(clientConn)
  47. return client, server
  48. }
  49. // TestPluginRPCConn returns a plugin RPC client and server that are connected
  50. // together and configured.
  51. func TestPluginRPCConn(t testing.T, ps map[string]Plugin) (*RPCClient, *RPCServer) {
  52. // Create two net.Conns we can use to shuttle our control connection
  53. clientConn, serverConn := TestConn(t)
  54. // Start up the server
  55. server := &RPCServer{Plugins: ps, Stdout: new(bytes.Buffer), Stderr: new(bytes.Buffer)}
  56. go server.ServeConn(serverConn)
  57. // Connect the client to the server
  58. client, err := NewRPCClient(clientConn, ps)
  59. if err != nil {
  60. t.Fatalf("err: %s", err)
  61. }
  62. return client, server
  63. }
  64. // TestPluginGRPCConn returns a plugin gRPC client and server that are connected
  65. // together and configured. This is used to test gRPC connections.
  66. func TestPluginGRPCConn(t testing.T, ps map[string]Plugin) (*GRPCClient, *GRPCServer) {
  67. // Create a listener
  68. l, err := net.Listen("tcp", "127.0.0.1:0")
  69. if err != nil {
  70. t.Fatalf("err: %s", err)
  71. }
  72. // Start up the server
  73. server := &GRPCServer{
  74. Plugins: ps,
  75. Server: DefaultGRPCServer,
  76. Stdout: new(bytes.Buffer),
  77. Stderr: new(bytes.Buffer),
  78. }
  79. if err := server.Init(); err != nil {
  80. t.Fatalf("err: %s", err)
  81. }
  82. go server.Serve(l)
  83. // Connect to the server
  84. conn, err := grpc.Dial(
  85. l.Addr().String(),
  86. grpc.WithBlock(),
  87. grpc.WithInsecure())
  88. if err != nil {
  89. t.Fatalf("err: %s", err)
  90. }
  91. // Connection successful, close the listener
  92. l.Close()
  93. // Create the client
  94. client := &GRPCClient{
  95. Conn: conn,
  96. Plugins: ps,
  97. }
  98. return client, server
  99. }