1package plugin 2 3import ( 4 "bytes" 5 "io" 6 "os" 7 "sync" 8 "testing" 9 "time" 10 11 hclog "github.com/hashicorp/go-hclog" 12) 13 14func TestClient_App(t *testing.T) { 15 pluginLogger := hclog.New(&hclog.LoggerOptions{ 16 Level: hclog.Trace, 17 Output: os.Stderr, 18 JSONFormat: true, 19 }) 20 21 testPlugin := &testInterfaceImpl{ 22 logger: pluginLogger, 23 } 24 25 client, _ := TestPluginRPCConn(t, map[string]Plugin{ 26 "test": &testInterfacePlugin{Impl: testPlugin}, 27 }, nil) 28 defer client.Close() 29 30 raw, err := client.Dispense("test") 31 if err != nil { 32 t.Fatalf("err: %s", err) 33 } 34 35 impl, ok := raw.(testInterface) 36 if !ok { 37 t.Fatalf("bad: %#v", raw) 38 } 39 40 result := impl.Double(21) 41 if result != 42 { 42 t.Fatalf("bad: %#v", result) 43 } 44} 45 46func TestClient_syncStreams(t *testing.T) { 47 // Create streams for the server that we can talk to 48 stdout_r, stdout_w := io.Pipe() 49 stderr_r, stderr_w := io.Pipe() 50 51 client, _ := TestPluginRPCConn(t, map[string]Plugin{}, &TestOptions{ 52 ServerStdout: stdout_r, 53 ServerStderr: stderr_r, 54 }) 55 56 // Start the data copying 57 var stdout_out, stderr_out safeBuffer 58 stdout := &safeBuffer{ 59 b: bytes.NewBufferString("stdouttest"), 60 } 61 stderr := &safeBuffer{ 62 b: bytes.NewBufferString("stderrtest"), 63 } 64 go client.SyncStreams(&stdout_out, &stderr_out) 65 go io.Copy(stdout_w, stdout) 66 go io.Copy(stderr_w, stderr) 67 68 // Unfortunately I can't think of a better way to make sure all the 69 // copies above go through so let's just exit. 70 time.Sleep(100 * time.Millisecond) 71 72 // Close everything, and lets test the result 73 client.Close() 74 stdout_w.Close() 75 stderr_w.Close() 76 77 if v := stdout_out.String(); v != "stdouttest" { 78 t.Fatalf("bad: %q", v) 79 } 80 if v := stderr_out.String(); v != "stderrtest" { 81 t.Fatalf("bad: %q", v) 82 } 83} 84 85type safeBuffer struct { 86 sync.Mutex 87 b *bytes.Buffer 88} 89 90func (s *safeBuffer) Write(p []byte) (n int, err error) { 91 s.Lock() 92 defer s.Unlock() 93 if s.b == nil { 94 s.b = new(bytes.Buffer) 95 } 96 return s.b.Write(p) 97} 98 99func (s *safeBuffer) Read(p []byte) (n int, err error) { 100 s.Lock() 101 defer s.Unlock() 102 if s.b == nil { 103 s.b = new(bytes.Buffer) 104 } 105 return s.b.Read(p) 106} 107 108func (s *safeBuffer) String() string { 109 s.Lock() 110 defer s.Unlock() 111 if s.b == nil { 112 s.b = new(bytes.Buffer) 113 } 114 return s.b.String() 115} 116