...
1
2
3
4
5
6
7 package servertest
8
9 import (
10 "context"
11 "fmt"
12 "net"
13 "strings"
14 "sync"
15
16 "golang.org/x/tools/internal/jsonrpc2"
17 )
18
19
20 type Connector interface {
21 Connect(context.Context) jsonrpc2.Conn
22 }
23
24
25
26
27 type TCPServer struct {
28 *connList
29
30 Addr string
31
32 ln net.Listener
33 framer jsonrpc2.Framer
34 }
35
36
37
38
39 func NewTCPServer(ctx context.Context, server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *TCPServer {
40 ln, err := net.Listen("tcp", "127.0.0.1:0")
41 if err != nil {
42 panic(fmt.Sprintf("servertest: failed to listen: %v", err))
43 }
44 if framer == nil {
45 framer = jsonrpc2.NewHeaderStream
46 }
47 go jsonrpc2.Serve(ctx, ln, server, 0)
48 return &TCPServer{Addr: ln.Addr().String(), ln: ln, framer: framer, connList: &connList{}}
49 }
50
51
52
53 func (s *TCPServer) Connect(_ context.Context) jsonrpc2.Conn {
54 netConn, err := net.Dial("tcp", s.Addr)
55 if err != nil {
56 panic(fmt.Sprintf("servertest: failed to connect to test instance: %v", err))
57 }
58 conn := jsonrpc2.NewConn(s.framer(netConn))
59 s.add(conn)
60 return conn
61 }
62
63
64 type PipeServer struct {
65 *connList
66 server jsonrpc2.StreamServer
67 framer jsonrpc2.Framer
68 }
69
70
71 func NewPipeServer(server jsonrpc2.StreamServer, framer jsonrpc2.Framer) *PipeServer {
72 if framer == nil {
73 framer = jsonrpc2.NewRawStream
74 }
75 return &PipeServer{server: server, framer: framer, connList: &connList{}}
76 }
77
78
79 func (s *PipeServer) Connect(ctx context.Context) jsonrpc2.Conn {
80 sPipe, cPipe := net.Pipe()
81 serverStream := s.framer(sPipe)
82 serverConn := jsonrpc2.NewConn(serverStream)
83 s.add(serverConn)
84 go s.server.ServeStream(ctx, serverConn)
85
86 clientStream := s.framer(cPipe)
87 clientConn := jsonrpc2.NewConn(clientStream)
88 s.add(clientConn)
89 return clientConn
90 }
91
92
93
94
95 type connList struct {
96 mu sync.Mutex
97 conns []jsonrpc2.Conn
98 }
99
100 func (l *connList) add(conn jsonrpc2.Conn) {
101 l.mu.Lock()
102 defer l.mu.Unlock()
103 l.conns = append(l.conns, conn)
104 }
105
106 func (l *connList) Close() error {
107 l.mu.Lock()
108 defer l.mu.Unlock()
109 var errmsgs []string
110 for _, conn := range l.conns {
111 if err := conn.Close(); err != nil {
112 errmsgs = append(errmsgs, err.Error())
113 }
114 }
115 if len(errmsgs) > 0 {
116 return fmt.Errorf("closing errors:\n%s", strings.Join(errmsgs, "\n"))
117 }
118 return nil
119 }
120
View as plain text