@@ -18,6 +18,7 @@ package broadcast
18
18
19
19
import (
20
20
"fmt"
21
+ "io"
21
22
"testing"
22
23
"time"
23
24
@@ -58,11 +59,48 @@ func (m *mockB) Send(br *ab.BroadcastResponse) error {
58
59
func (m * mockB ) Recv () (* cb.Envelope , error ) {
59
60
msg , ok := <- m .recvChan
60
61
if ! ok {
61
- return msg , fmt . Errorf ( "Channel closed" )
62
+ return msg , io . EOF
62
63
}
63
64
return msg , nil
64
65
}
65
66
67
+ type erroneousRecvMockB struct {
68
+ grpc.ServerStream
69
+ }
70
+
71
+ func (m * erroneousRecvMockB ) Send (br * ab.BroadcastResponse ) error {
72
+ return nil
73
+ }
74
+
75
+ func (m * erroneousRecvMockB ) Recv () (* cb.Envelope , error ) {
76
+ // The point here is to simulate an error other than EOF.
77
+ // We don't bother to create a new custom error type.
78
+ return nil , io .ErrUnexpectedEOF
79
+ }
80
+
81
+ type erroneousSendMockB struct {
82
+ grpc.ServerStream
83
+ recvVal * cb.Envelope
84
+ }
85
+
86
+ func (m * erroneousSendMockB ) Send (br * ab.BroadcastResponse ) error {
87
+ // The point here is to simulate an error other than EOF.
88
+ // We don't bother to create a new custom error type.
89
+ return io .ErrUnexpectedEOF
90
+ }
91
+
92
+ func (m * erroneousSendMockB ) Recv () (* cb.Envelope , error ) {
93
+ return m .recvVal , nil
94
+ }
95
+
96
+ var RejectRule = filter .Rule (rejectRule {})
97
+
98
+ type rejectRule struct {}
99
+
100
+ func (r rejectRule ) Apply (message * cb.Envelope ) (filter.Action , filter.Committer ) {
101
+ return filter .Reject , nil
102
+ }
103
+
66
104
type mockSupportManager struct {
67
105
chains map [string ]* mockSupport
68
106
ProcessVal * cb.Envelope
@@ -244,3 +282,129 @@ func TestBadConfigUpdate(t *testing.T) {
244
282
reply := <- m .sendChan
245
283
assert .NotEqual (t , cb .Status_SUCCESS , reply .Status , "Should have rejected CONFIG_UPDATE" )
246
284
}
285
+
286
+ func TestGracefulShutdown (t * testing.T ) {
287
+ bh := NewHandlerImpl (nil )
288
+ m := newMockB ()
289
+ close (m .recvChan )
290
+ assert .NoError (t , bh .Handle (m ), "Should exit normally upon EOF" )
291
+ }
292
+
293
+ func TestRejected (t * testing.T ) {
294
+ filters := filter .NewRuleSet ([]filter.Rule {RejectRule })
295
+ mm := & mockSupportManager {
296
+ chains : map [string ]* mockSupport {string (systemChain ): {filters : filters }},
297
+ }
298
+ mm .ProcessVal = & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {Header : & cb.Header {ChannelHeader : utils .MarshalOrPanic (& cb.ChannelHeader {ChannelId : systemChain })}})}
299
+ bh := NewHandlerImpl (mm )
300
+ m := newMockB ()
301
+ defer close (m .recvChan )
302
+ go bh .Handle (m )
303
+
304
+ newChannelId := "New Chain"
305
+
306
+ m .recvChan <- makeConfigMessage (newChannelId )
307
+ reply := <- m .sendChan
308
+ assert .Equal (t , cb .Status_BAD_REQUEST , reply .Status , "Should have rejected CONFIG_UPDATE" )
309
+ }
310
+
311
+ func TestBadStreamRecv (t * testing.T ) {
312
+ bh := NewHandlerImpl (nil )
313
+ assert .Error (t , bh .Handle (& erroneousRecvMockB {}), "Should catch unexpected stream error" )
314
+ }
315
+
316
+ func TestBadStreamSend (t * testing.T ) {
317
+ mm , _ := getMockSupportManager ()
318
+ mm .ProcessVal = & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {Header : & cb.Header {ChannelHeader : utils .MarshalOrPanic (& cb.ChannelHeader {ChannelId : systemChain })}})}
319
+ bh := NewHandlerImpl (mm )
320
+ m := & erroneousSendMockB {recvVal : makeConfigMessage ("New Chain" )}
321
+ assert .Error (t , bh .Handle (m ), "Should catch unexpected stream error" )
322
+ }
323
+
324
+ func TestMalformedEnvelope (t * testing.T ) {
325
+ mm , _ := getMockSupportManager ()
326
+ bh := NewHandlerImpl (mm )
327
+ m := newMockB ()
328
+ defer close (m .recvChan )
329
+ go bh .Handle (m )
330
+
331
+ m .recvChan <- & cb.Envelope {Payload : []byte ("foo" )}
332
+ reply := <- m .sendChan
333
+ assert .Equal (t , cb .Status_BAD_REQUEST , reply .Status , "Should have rejected the malformed message" )
334
+ }
335
+
336
+ func TestMissingHeader (t * testing.T ) {
337
+ mm , _ := getMockSupportManager ()
338
+ bh := NewHandlerImpl (mm )
339
+ m := newMockB ()
340
+ defer close (m .recvChan )
341
+ go bh .Handle (m )
342
+
343
+ m .recvChan <- & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {})}
344
+ reply := <- m .sendChan
345
+ assert .Equal (t , cb .Status_BAD_REQUEST , reply .Status , "Should have rejected the payload without header" )
346
+ }
347
+
348
+ func TestBadChannelHeader (t * testing.T ) {
349
+ mm , _ := getMockSupportManager ()
350
+ bh := NewHandlerImpl (mm )
351
+ m := newMockB ()
352
+ defer close (m .recvChan )
353
+ go bh .Handle (m )
354
+
355
+ m .recvChan <- & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {Header : & cb.Header {ChannelHeader : []byte ("foo" )}})}
356
+ reply := <- m .sendChan
357
+ assert .Equal (t , cb .Status_BAD_REQUEST , reply .Status , "Should have rejected bad header" )
358
+ }
359
+
360
+ func TestBadPayloadAfterProcessing (t * testing.T ) {
361
+ mm , _ := getMockSupportManager ()
362
+ mm .ProcessVal = & cb.Envelope {Payload : []byte ("foo" )}
363
+ bh := NewHandlerImpl (mm )
364
+ m := newMockB ()
365
+ defer close (m .recvChan )
366
+ go bh .Handle (m )
367
+
368
+ m .recvChan <- makeConfigMessage ("New Chain" )
369
+ reply := <- m .sendChan
370
+ assert .Equal (t , cb .Status_INTERNAL_SERVER_ERROR , reply .Status , "Should respond with internal server error" )
371
+ }
372
+
373
+ func TestNilHeaderAfterProcessing (t * testing.T ) {
374
+ mm , _ := getMockSupportManager ()
375
+ mm .ProcessVal = & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {})}
376
+ bh := NewHandlerImpl (mm )
377
+ m := newMockB ()
378
+ defer close (m .recvChan )
379
+ go bh .Handle (m )
380
+
381
+ m .recvChan <- makeConfigMessage ("New Chain" )
382
+ reply := <- m .sendChan
383
+ assert .Equal (t , cb .Status_INTERNAL_SERVER_ERROR , reply .Status , "Should respond with internal server error" )
384
+ }
385
+
386
+ func TestBadChannelHeaderAfterProcessing (t * testing.T ) {
387
+ mm , _ := getMockSupportManager ()
388
+ mm .ProcessVal = & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {Header : & cb.Header {ChannelHeader : []byte ("foo" )}})}
389
+ bh := NewHandlerImpl (mm )
390
+ m := newMockB ()
391
+ defer close (m .recvChan )
392
+ go bh .Handle (m )
393
+
394
+ m .recvChan <- makeConfigMessage ("New Chain" )
395
+ reply := <- m .sendChan
396
+ assert .Equal (t , cb .Status_INTERNAL_SERVER_ERROR , reply .Status , "Should respond with internal server error" )
397
+ }
398
+
399
+ func TestEmptyChannelIDAfterProcessing (t * testing.T ) {
400
+ mm , _ := getMockSupportManager ()
401
+ mm .ProcessVal = & cb.Envelope {Payload : utils .MarshalOrPanic (& cb.Payload {Header : & cb.Header {ChannelHeader : utils .MarshalOrPanic (& cb.ChannelHeader {})}})}
402
+ bh := NewHandlerImpl (mm )
403
+ m := newMockB ()
404
+ defer close (m .recvChan )
405
+ go bh .Handle (m )
406
+
407
+ m .recvChan <- makeConfigMessage ("New Chain" )
408
+ reply := <- m .sendChan
409
+ assert .Equal (t , cb .Status_INTERNAL_SERVER_ERROR , reply .Status , "Should respond with internal server error" )
410
+ }
0 commit comments