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