@@ -123,6 +123,8 @@ type server struct {
123
123
conns map [transport.ServerTransport ]bool
124
124
}
125
125
126
+ type ctxKey string
127
+
126
128
func newTestServer () * server {
127
129
return & server {startedErr : make (chan error , 1 )}
128
130
}
@@ -202,17 +204,217 @@ func (s *server) stop() {
202
204
}
203
205
204
206
func setUp (t * testing.T , port int , maxStreams uint32 ) (* server , * ClientConn ) {
207
+ return setUpWithOptions (t , port , maxStreams )
208
+ }
209
+
210
+ func setUpWithOptions (t * testing.T , port int , maxStreams uint32 , dopts ... DialOption ) (* server , * ClientConn ) {
205
211
server := newTestServer ()
206
212
go server .start (t , port , maxStreams )
207
213
server .wait (t , 2 * time .Second )
208
214
addr := "localhost:" + server .port
209
- cc , err := Dial (addr , WithBlock (), WithInsecure (), WithCodec (testCodec {}))
215
+ dopts = append (dopts , WithBlock (), WithInsecure (), WithCodec (testCodec {}))
216
+ cc , err := Dial (addr , dopts ... )
210
217
if err != nil {
211
218
t .Fatalf ("Failed to create ClientConn: %v" , err )
212
219
}
213
220
return server , cc
214
221
}
215
222
223
+ func (s ) TestUnaryClientInterceptor (t * testing.T ) {
224
+ parentKey := ctxKey ("parentKey" )
225
+
226
+ interceptor := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
227
+ if ctx .Value (parentKey ) == nil {
228
+ t .Fatalf ("interceptor should have %v in context" , parentKey )
229
+ }
230
+ return invoker (ctx , method , req , reply , cc , opts ... )
231
+ }
232
+
233
+ server , cc := setUpWithOptions (t , 0 , math .MaxUint32 , WithUnaryInterceptor (interceptor ))
234
+ defer func () {
235
+ cc .Close ()
236
+ server .stop ()
237
+ }()
238
+
239
+ var reply string
240
+ ctx := context .Background ()
241
+ parentCtx := context .WithValue (ctx , ctxKey ("parentKey" ), 0 )
242
+ if err := cc .Invoke (parentCtx , "/foo/bar" , & expectedRequest , & reply ); err != nil || reply != expectedResponse {
243
+ t .Fatalf ("grpc.Invoke(_, _, _, _, _) = %v, want <nil>" , err )
244
+ }
245
+ }
246
+
247
+ func (s ) TestChainUnaryClientInterceptor (t * testing.T ) {
248
+ var (
249
+ parentKey = ctxKey ("parentKey" )
250
+ firstIntKey = ctxKey ("firstIntKey" )
251
+ secondIntKey = ctxKey ("secondIntKey" )
252
+ )
253
+
254
+ firstInt := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
255
+ if ctx .Value (parentKey ) == nil {
256
+ t .Fatalf ("first interceptor should have %v in context" , parentKey )
257
+ }
258
+ if ctx .Value (firstIntKey ) != nil {
259
+ t .Fatalf ("first interceptor should not have %v in context" , firstIntKey )
260
+ }
261
+ if ctx .Value (secondIntKey ) != nil {
262
+ t .Fatalf ("first interceptor should not have %v in context" , secondIntKey )
263
+ }
264
+ firstCtx := context .WithValue (ctx , firstIntKey , 1 )
265
+ err := invoker (firstCtx , method , req , reply , cc , opts ... )
266
+ * (reply .(* string )) += "1"
267
+ return err
268
+ }
269
+
270
+ secondInt := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
271
+ if ctx .Value (parentKey ) == nil {
272
+ t .Fatalf ("second interceptor should have %v in context" , parentKey )
273
+ }
274
+ if ctx .Value (firstIntKey ) == nil {
275
+ t .Fatalf ("second interceptor should have %v in context" , firstIntKey )
276
+ }
277
+ if ctx .Value (secondIntKey ) != nil {
278
+ t .Fatalf ("second interceptor should not have %v in context" , secondIntKey )
279
+ }
280
+ secondCtx := context .WithValue (ctx , secondIntKey , 2 )
281
+ err := invoker (secondCtx , method , req , reply , cc , opts ... )
282
+ * (reply .(* string )) += "2"
283
+ return err
284
+ }
285
+
286
+ lastInt := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
287
+ if ctx .Value (parentKey ) == nil {
288
+ t .Fatalf ("last interceptor should have %v in context" , parentKey )
289
+ }
290
+ if ctx .Value (firstIntKey ) == nil {
291
+ t .Fatalf ("last interceptor should have %v in context" , firstIntKey )
292
+ }
293
+ if ctx .Value (secondIntKey ) == nil {
294
+ t .Fatalf ("last interceptor should have %v in context" , secondIntKey )
295
+ }
296
+ err := invoker (ctx , method , req , reply , cc , opts ... )
297
+ * (reply .(* string )) += "3"
298
+ return err
299
+ }
300
+
301
+ server , cc := setUpWithOptions (t , 0 , math .MaxUint32 , WithChainUnaryInterceptor (firstInt , secondInt , lastInt ))
302
+ defer func () {
303
+ cc .Close ()
304
+ server .stop ()
305
+ }()
306
+
307
+ var reply string
308
+ ctx := context .Background ()
309
+ parentCtx := context .WithValue (ctx , ctxKey ("parentKey" ), 0 )
310
+ if err := cc .Invoke (parentCtx , "/foo/bar" , & expectedRequest , & reply ); err != nil || reply != expectedResponse + "321" {
311
+ t .Fatalf ("grpc.Invoke(_, _, _, _, _) = %v, want <nil>" , err )
312
+ }
313
+ }
314
+
315
+ func (s ) TestChainOnBaseUnaryClientInterceptor (t * testing.T ) {
316
+ var (
317
+ parentKey = ctxKey ("parentKey" )
318
+ baseIntKey = ctxKey ("baseIntKey" )
319
+ )
320
+
321
+ baseInt := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
322
+ if ctx .Value (parentKey ) == nil {
323
+ t .Fatalf ("base interceptor should have %v in context" , parentKey )
324
+ }
325
+ if ctx .Value (baseIntKey ) != nil {
326
+ t .Fatalf ("base interceptor should not have %v in context" , baseIntKey )
327
+ }
328
+ baseCtx := context .WithValue (ctx , baseIntKey , 1 )
329
+ return invoker (baseCtx , method , req , reply , cc , opts ... )
330
+ }
331
+
332
+ chainInt := func (ctx context.Context , method string , req , reply interface {}, cc * ClientConn , invoker UnaryInvoker , opts ... CallOption ) error {
333
+ if ctx .Value (parentKey ) == nil {
334
+ t .Fatalf ("chain interceptor should have %v in context" , parentKey )
335
+ }
336
+ if ctx .Value (baseIntKey ) == nil {
337
+ t .Fatalf ("chain interceptor should have %v in context" , baseIntKey )
338
+ }
339
+ return invoker (ctx , method , req , reply , cc , opts ... )
340
+ }
341
+
342
+ server , cc := setUpWithOptions (t , 0 , math .MaxUint32 , WithUnaryInterceptor (baseInt ), WithChainUnaryInterceptor (chainInt ))
343
+ defer func () {
344
+ cc .Close ()
345
+ server .stop ()
346
+ }()
347
+
348
+ var reply string
349
+ ctx := context .Background ()
350
+ parentCtx := context .WithValue (ctx , ctxKey ("parentKey" ), 0 )
351
+ if err := cc .Invoke (parentCtx , "/foo/bar" , & expectedRequest , & reply ); err != nil || reply != expectedResponse {
352
+ t .Fatalf ("grpc.Invoke(_, _, _, _, _) = %v, want <nil>" , err )
353
+ }
354
+ }
355
+
356
+ func (s ) TestChainStreamClientInterceptor (t * testing.T ) {
357
+ var (
358
+ parentKey = ctxKey ("parentKey" )
359
+ firstIntKey = ctxKey ("firstIntKey" )
360
+ secondIntKey = ctxKey ("secondIntKey" )
361
+ )
362
+
363
+ firstInt := func (ctx context.Context , desc * StreamDesc , cc * ClientConn , method string , streamer Streamer , opts ... CallOption ) (ClientStream , error ) {
364
+ if ctx .Value (parentKey ) == nil {
365
+ t .Fatalf ("first interceptor should have %v in context" , parentKey )
366
+ }
367
+ if ctx .Value (firstIntKey ) != nil {
368
+ t .Fatalf ("first interceptor should not have %v in context" , firstIntKey )
369
+ }
370
+ if ctx .Value (secondIntKey ) != nil {
371
+ t .Fatalf ("first interceptor should not have %v in context" , secondIntKey )
372
+ }
373
+ firstCtx := context .WithValue (ctx , firstIntKey , 1 )
374
+ return streamer (firstCtx , desc , cc , method , opts ... )
375
+ }
376
+
377
+ secondInt := func (ctx context.Context , desc * StreamDesc , cc * ClientConn , method string , streamer Streamer , opts ... CallOption ) (ClientStream , error ) {
378
+ if ctx .Value (parentKey ) == nil {
379
+ t .Fatalf ("second interceptor should have %v in context" , parentKey )
380
+ }
381
+ if ctx .Value (firstIntKey ) == nil {
382
+ t .Fatalf ("second interceptor should have %v in context" , firstIntKey )
383
+ }
384
+ if ctx .Value (secondIntKey ) != nil {
385
+ t .Fatalf ("second interceptor should not have %v in context" , secondIntKey )
386
+ }
387
+ secondCtx := context .WithValue (ctx , secondIntKey , 2 )
388
+ return streamer (secondCtx , desc , cc , method , opts ... )
389
+ }
390
+
391
+ lastInt := func (ctx context.Context , desc * StreamDesc , cc * ClientConn , method string , streamer Streamer , opts ... CallOption ) (ClientStream , error ) {
392
+ if ctx .Value (parentKey ) == nil {
393
+ t .Fatalf ("last interceptor should have %v in context" , parentKey )
394
+ }
395
+ if ctx .Value (firstIntKey ) == nil {
396
+ t .Fatalf ("last interceptor should have %v in context" , firstIntKey )
397
+ }
398
+ if ctx .Value (secondIntKey ) == nil {
399
+ t .Fatalf ("last interceptor should have %v in context" , secondIntKey )
400
+ }
401
+ return streamer (ctx , desc , cc , method , opts ... )
402
+ }
403
+
404
+ server , cc := setUpWithOptions (t , 0 , math .MaxUint32 , WithChainStreamInterceptor (firstInt , secondInt , lastInt ))
405
+ defer func () {
406
+ cc .Close ()
407
+ server .stop ()
408
+ }()
409
+
410
+ ctx := context .Background ()
411
+ parentCtx := context .WithValue (ctx , ctxKey ("parentKey" ), 0 )
412
+ _ , err := cc .NewStream (parentCtx , & StreamDesc {}, "/foo/bar" )
413
+ if err != nil {
414
+ t .Fatalf ("grpc.NewStream(_, _, _) = %v, want <nil>" , err )
415
+ }
416
+ }
417
+
216
418
func (s ) TestInvoke (t * testing.T ) {
217
419
server , cc := setUp (t , 0 , math .MaxUint32 )
218
420
var reply string
0 commit comments