9
9
"bytes"
10
10
"context"
11
11
"fmt"
12
+ "io"
12
13
"io/ioutil"
13
14
"os"
14
15
"os/exec"
@@ -34,8 +35,7 @@ type EnvMode int
34
35
const (
35
36
// Singleton mode uses a separate cache for each test.
36
37
Singleton EnvMode = 1 << iota
37
- // Shared mode uses a Shared cache.
38
- Shared
38
+
39
39
// Forwarded forwards connections to an in-process gopls instance.
40
40
Forwarded
41
41
// SeparateProcess runs a separate gopls process, and forwards connections to
@@ -150,12 +150,11 @@ func (r *Runner) Run(t *testing.T, filedata string, test func(e *Env)) {
150
150
func (r * Runner ) RunInMode (modes EnvMode , t * testing.T , filedata string , test func (e * Env )) {
151
151
t .Helper ()
152
152
tests := []struct {
153
- name string
154
- mode EnvMode
155
- getConnector func (context.Context , * testing.T ) (servertest. Connector , func ())
153
+ name string
154
+ mode EnvMode
155
+ getServer func (context.Context , * testing.T ) jsonrpc2. StreamServer
156
156
}{
157
- {"singleton" , Singleton , r .singletonEnv },
158
- {"shared" , Shared , r .sharedEnv },
157
+ {"singleton" , Singleton , singletonEnv },
159
158
{"forwarded" , Forwarded , r .forwardedEnv },
160
159
{"separate_process" , SeparateProcess , r .separateProcessEnv },
161
160
}
@@ -169,15 +168,24 @@ func (r *Runner) RunInMode(modes EnvMode, t *testing.T, filedata string, test fu
169
168
t .Helper ()
170
169
ctx , cancel := context .WithTimeout (context .Background (), r .timeout )
171
170
defer cancel ()
171
+ ctx = debug .WithInstance (ctx , "" , "" )
172
+
172
173
ws , err := fake .NewWorkspace ("lsprpc" , []byte (filedata ))
173
174
if err != nil {
174
175
t .Fatal (err )
175
176
}
176
177
defer ws .Close ()
177
- ts , cleanup := tc .getConnector (ctx , t )
178
- defer cleanup ()
178
+ ss := tc .getServer (ctx , t )
179
+ ls := & loggingServer {delegate : ss }
180
+ ts := servertest .NewPipeServer (ctx , ls )
181
+ defer func () {
182
+ ts .Close ()
183
+ }()
179
184
env := NewEnv (ctx , t , ws , ts )
180
185
defer func () {
186
+ if t .Failed () {
187
+ ls .printBuffers (t .Name (), os .Stderr )
188
+ }
181
189
if err := env .E .Shutdown (ctx ); err != nil {
182
190
panic (err )
183
191
}
@@ -187,42 +195,47 @@ func (r *Runner) RunInMode(modes EnvMode, t *testing.T, filedata string, test fu
187
195
}
188
196
}
189
197
190
- func (r * Runner ) singletonEnv (ctx context.Context , t * testing.T ) (servertest.Connector , func ()) {
191
- ctx = debug .WithInstance (ctx , "" , "" )
192
- ss := lsprpc .NewStreamServer (cache .New (ctx , nil ))
193
- ts := servertest .NewPipeServer (ctx , ss )
194
- cleanup := func () {
195
- ts .Close ()
198
+ type loggingServer struct {
199
+ delegate jsonrpc2.StreamServer
200
+
201
+ mu sync.Mutex
202
+ buffers []* bytes.Buffer
203
+ }
204
+
205
+ func (s * loggingServer ) ServeStream (ctx context.Context , stream jsonrpc2.Stream ) error {
206
+ s .mu .Lock ()
207
+ var buf bytes.Buffer
208
+ s .buffers = append (s .buffers , & buf )
209
+ s .mu .Unlock ()
210
+ logStream := protocol .LoggingStream (stream , & buf )
211
+ return s .delegate .ServeStream (ctx , logStream )
212
+ }
213
+
214
+ func (s * loggingServer ) printBuffers (testname string , w io.Writer ) {
215
+ s .mu .Lock ()
216
+ defer s .mu .Unlock ()
217
+
218
+ for i , buf := range s .buffers {
219
+ fmt .Fprintf (os .Stderr , "#### Start Gopls Test Logs %d of %d for %q\n " , i + 1 , len (s .buffers ), testname )
220
+ io .Copy (w , buf )
221
+ fmt .Fprintf (os .Stderr , "#### End Gopls Test Logs %d of %d for %q\n " , i + 1 , len (s .buffers ), testname )
196
222
}
197
- return ts , cleanup
198
223
}
199
224
200
- func ( r * Runner ) sharedEnv ( ctx context.Context , t * testing.T ) (servertest. Connector , func ()) {
201
- return r . getTestServer (), func () {}
225
+ func singletonEnv ( ctx context.Context , t * testing.T ) jsonrpc2. StreamServer {
226
+ return lsprpc . NewStreamServer ( cache . New ( ctx , nil ))
202
227
}
203
228
204
- func (r * Runner ) forwardedEnv (ctx context.Context , t * testing.T ) (servertest.Connector , func ()) {
205
- ctx = debug .WithInstance (ctx , "" , "" )
229
+ func (r * Runner ) forwardedEnv (ctx context.Context , t * testing.T ) jsonrpc2.StreamServer {
206
230
ts := r .getTestServer ()
207
- forwarder := lsprpc .NewForwarder ("tcp" , ts .Addr )
208
- ts2 := servertest .NewPipeServer (ctx , forwarder )
209
- cleanup := func () {
210
- ts2 .Close ()
211
- }
212
- return ts2 , cleanup
231
+ return lsprpc .NewForwarder ("tcp" , ts .Addr )
213
232
}
214
233
215
- func (r * Runner ) separateProcessEnv (ctx context.Context , t * testing.T ) (servertest.Connector , func ()) {
216
- ctx = debug .WithInstance (ctx , "" , "" )
217
- socket := r .getRemoteSocket (t )
234
+ func (r * Runner ) separateProcessEnv (ctx context.Context , t * testing.T ) jsonrpc2.StreamServer {
218
235
// TODO(rfindley): can we use the autostart behavior here, instead of
219
236
// pre-starting the remote?
220
- forwarder := lsprpc .NewForwarder ("unix" , socket )
221
- ts2 := servertest .NewPipeServer (ctx , forwarder )
222
- cleanup := func () {
223
- ts2 .Close ()
224
- }
225
- return ts2 , cleanup
237
+ socket := r .getRemoteSocket (t )
238
+ return lsprpc .NewForwarder ("unix" , socket )
226
239
}
227
240
228
241
// Env holds an initialized fake Editor, Workspace, and Server, which may be
0 commit comments