github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/deliver/deliver_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package deliver
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    26  	mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
    27  	"github.com/hyperledger/fabric/common/policies"
    28  	"github.com/hyperledger/fabric/orderer/common/ledger"
    29  	ramledger "github.com/hyperledger/fabric/orderer/common/ledger/ram"
    30  	cb "github.com/hyperledger/fabric/protos/common"
    31  	ab "github.com/hyperledger/fabric/protos/orderer"
    32  	"github.com/hyperledger/fabric/protos/utils"
    33  	logging "github.com/op/go-logging"
    34  	"github.com/stretchr/testify/assert"
    35  	"google.golang.org/grpc"
    36  )
    37  
    38  var genesisBlock = cb.NewBlock(0, nil)
    39  
    40  var systemChainID = "systemChain"
    41  
    42  const ledgerSize = 10
    43  
    44  func init() {
    45  	logging.SetLevel(logging.DEBUG, "")
    46  }
    47  
    48  type mockD struct {
    49  	grpc.ServerStream
    50  	recvChan chan *cb.Envelope
    51  	sendChan chan *ab.DeliverResponse
    52  }
    53  
    54  func newMockD() *mockD {
    55  	return &mockD{
    56  		recvChan: make(chan *cb.Envelope),
    57  		sendChan: make(chan *ab.DeliverResponse),
    58  	}
    59  }
    60  
    61  func (m *mockD) Send(br *ab.DeliverResponse) error {
    62  	m.sendChan <- br
    63  	return nil
    64  }
    65  
    66  func (m *mockD) Recv() (*cb.Envelope, error) {
    67  	msg, ok := <-m.recvChan
    68  	if !ok {
    69  		return msg, io.EOF
    70  	}
    71  	return msg, nil
    72  }
    73  
    74  type erroneousRecvMockD struct {
    75  	grpc.ServerStream
    76  }
    77  
    78  func (m *erroneousRecvMockD) Send(br *ab.DeliverResponse) error {
    79  	return nil
    80  }
    81  
    82  func (m *erroneousRecvMockD) Recv() (*cb.Envelope, error) {
    83  	// The point here is to simulate an error other than EOF.
    84  	// We don't bother to create a new custom error type.
    85  	return nil, io.ErrUnexpectedEOF
    86  }
    87  
    88  type erroneousSendMockD struct {
    89  	grpc.ServerStream
    90  	recvVal *cb.Envelope
    91  }
    92  
    93  func (m *erroneousSendMockD) Send(br *ab.DeliverResponse) error {
    94  	// The point here is to simulate an error other than EOF.
    95  	// We don't bother to create a new custom error type.
    96  	return io.ErrUnexpectedEOF
    97  }
    98  
    99  func (m *erroneousSendMockD) Recv() (*cb.Envelope, error) {
   100  	return m.recvVal, nil
   101  }
   102  
   103  type mockSupportManager struct {
   104  	chains map[string]*mockSupport
   105  }
   106  
   107  func (mm *mockSupportManager) GetChain(chainID string) (Support, bool) {
   108  	cs, ok := mm.chains[chainID]
   109  	return cs, ok
   110  }
   111  
   112  type mockSupport struct {
   113  	ledger        ledger.ReadWriter
   114  	policyManager *mockpolicies.Manager
   115  	erroredChan   chan struct{}
   116  	configSeq     uint64
   117  }
   118  
   119  func (mcs *mockSupport) Errored() <-chan struct{} {
   120  	return mcs.erroredChan
   121  }
   122  
   123  func (mcs *mockSupport) Sequence() uint64 {
   124  	return mcs.configSeq
   125  }
   126  
   127  func (mcs *mockSupport) PolicyManager() policies.Manager {
   128  	return mcs.policyManager
   129  }
   130  
   131  func (mcs *mockSupport) Reader() ledger.Reader {
   132  	return mcs.ledger
   133  }
   134  
   135  func NewRAMLedger() ledger.ReadWriter {
   136  	rlf := ramledger.New(ledgerSize + 1)
   137  	rl, _ := rlf.GetOrCreate(provisional.TestChainID)
   138  	rl.Append(genesisBlock)
   139  	return rl
   140  }
   141  
   142  func initializeDeliverHandler() Handler {
   143  	mm := newMockMultichainManager()
   144  	for i := 1; i < ledgerSize; i++ {
   145  		l := mm.chains[systemChainID].ledger
   146  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   147  	}
   148  
   149  	return NewHandlerImpl(mm)
   150  }
   151  
   152  func newMockMultichainManager() *mockSupportManager {
   153  	rl := NewRAMLedger()
   154  	mm := &mockSupportManager{
   155  		chains: make(map[string]*mockSupport),
   156  	}
   157  	mm.chains[systemChainID] = &mockSupport{
   158  		ledger:        rl,
   159  		policyManager: &mockpolicies.Manager{Policy: &mockpolicies.Policy{}},
   160  		erroredChan:   make(chan struct{}),
   161  	}
   162  	return mm
   163  }
   164  
   165  var seekOldest = &ab.SeekPosition{Type: &ab.SeekPosition_Oldest{Oldest: &ab.SeekOldest{}}}
   166  var seekNewest = &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
   167  
   168  func seekSpecified(number uint64) *ab.SeekPosition {
   169  	return &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: number}}}
   170  }
   171  
   172  func makeSeek(chainID string, seekInfo *ab.SeekInfo) *cb.Envelope {
   173  	return &cb.Envelope{
   174  		Payload: utils.MarshalOrPanic(&cb.Payload{
   175  			Header: &cb.Header{
   176  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   177  					ChannelId: chainID,
   178  				}),
   179  				SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}),
   180  			},
   181  			Data: utils.MarshalOrPanic(seekInfo),
   182  		}),
   183  	}
   184  }
   185  
   186  func TestWholeChainSeek(t *testing.T) {
   187  	m := newMockD()
   188  	defer close(m.recvChan)
   189  
   190  	ds := initializeDeliverHandler()
   191  	go ds.Handle(m)
   192  
   193  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekOldest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   194  
   195  	count := uint64(0)
   196  	for {
   197  		select {
   198  		case deliverReply := <-m.sendChan:
   199  			if deliverReply.GetBlock() == nil {
   200  				if deliverReply.GetStatus() != cb.Status_SUCCESS {
   201  					t.Fatalf("Received an error on the reply channel")
   202  				}
   203  				if count != ledgerSize {
   204  					t.Fatalf("Expected %d blocks but got %d", ledgerSize, count)
   205  				}
   206  				return
   207  			}
   208  			if deliverReply.GetBlock().Header.Number != count {
   209  				t.Fatalf("Expected block %d but got block %d", count, deliverReply.GetBlock().Header.Number)
   210  			}
   211  		case <-time.After(time.Second):
   212  			t.Fatalf("Timed out waiting to get all blocks")
   213  		}
   214  		count++
   215  	}
   216  }
   217  
   218  func TestNewestSeek(t *testing.T) {
   219  	m := newMockD()
   220  	defer close(m.recvChan)
   221  
   222  	ds := initializeDeliverHandler()
   223  	go ds.Handle(m)
   224  
   225  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekNewest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   226  
   227  	select {
   228  	case deliverReply := <-m.sendChan:
   229  		if deliverReply.GetBlock() == nil {
   230  			t.Fatalf("Received an error on the reply channel")
   231  		}
   232  		if deliverReply.GetBlock().Header.Number != uint64(ledgerSize-1) {
   233  			t.Fatalf("Expected only the most recent block")
   234  		}
   235  	case <-time.After(time.Second):
   236  		t.Fatalf("Timed out waiting to get all blocks")
   237  	}
   238  }
   239  
   240  func TestSpecificSeek(t *testing.T) {
   241  	m := newMockD()
   242  	defer close(m.recvChan)
   243  
   244  	ds := initializeDeliverHandler()
   245  	go ds.Handle(m)
   246  
   247  	specifiedStart := uint64(3)
   248  	specifiedStop := uint64(7)
   249  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(specifiedStart), Stop: seekSpecified(specifiedStop), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   250  
   251  	count := uint64(0)
   252  	for {
   253  		select {
   254  		case deliverReply := <-m.sendChan:
   255  			if deliverReply.GetBlock() == nil {
   256  				if deliverReply.GetStatus() != cb.Status_SUCCESS {
   257  					t.Fatalf("Received an error on the reply channel")
   258  				}
   259  				return
   260  			}
   261  			if expected := specifiedStart + count; deliverReply.GetBlock().Header.Number != expected {
   262  				t.Fatalf("Expected block %d but got block %d", expected, deliverReply.GetBlock().Header.Number)
   263  			}
   264  		case <-time.After(time.Second):
   265  			t.Fatalf("Timed out waiting to get all blocks")
   266  		}
   267  		count++
   268  	}
   269  }
   270  
   271  func TestUnauthorizedSeek(t *testing.T) {
   272  	mm := newMockMultichainManager()
   273  	for i := 1; i < ledgerSize; i++ {
   274  		l := mm.chains[systemChainID].ledger
   275  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   276  	}
   277  	mm.chains[systemChainID].policyManager.Policy.Err = fmt.Errorf("Fail to evaluate policy")
   278  
   279  	m := newMockD()
   280  	defer close(m.recvChan)
   281  	ds := NewHandlerImpl(mm)
   282  
   283  	go ds.Handle(m)
   284  
   285  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(0)), Stop: seekSpecified(uint64(0)), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   286  
   287  	select {
   288  	case deliverReply := <-m.sendChan:
   289  		if deliverReply.GetStatus() != cb.Status_FORBIDDEN {
   290  			t.Fatalf("Received wrong error on the reply channel")
   291  		}
   292  	case <-time.After(time.Second):
   293  		t.Fatalf("Timed out waiting to get all blocks")
   294  	}
   295  }
   296  
   297  func TestRevokedAuthorizationSeek(t *testing.T) {
   298  	mm := newMockMultichainManager()
   299  	for i := 1; i < ledgerSize; i++ {
   300  		l := mm.chains[systemChainID].ledger
   301  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   302  	}
   303  
   304  	m := newMockD()
   305  	defer close(m.recvChan)
   306  	ds := NewHandlerImpl(mm)
   307  
   308  	go ds.Handle(m)
   309  
   310  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   311  
   312  	select {
   313  	case deliverReply := <-m.sendChan:
   314  		assert.NotNil(t, deliverReply.GetBlock(), "First should succeed")
   315  	case <-time.After(time.Second):
   316  		t.Fatalf("Timed out waiting to get all blocks")
   317  	}
   318  
   319  	mm.chains[systemChainID].policyManager.Policy.Err = fmt.Errorf("Fail to evaluate policy")
   320  	mm.chains[systemChainID].configSeq++
   321  	l := mm.chains[systemChainID].ledger
   322  	l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", ledgerSize+1))}}))
   323  
   324  	select {
   325  	case deliverReply := <-m.sendChan:
   326  		assert.Equal(t, cb.Status_FORBIDDEN, deliverReply.GetStatus(), "Second should been forbidden ")
   327  	case <-time.After(time.Second):
   328  		t.Fatalf("Timed out waiting to get all blocks")
   329  	}
   330  
   331  }
   332  
   333  func TestOutOfBoundSeek(t *testing.T) {
   334  	m := newMockD()
   335  	defer close(m.recvChan)
   336  
   337  	ds := initializeDeliverHandler()
   338  	go ds.Handle(m)
   339  
   340  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(3 * ledgerSize)), Stop: seekSpecified(uint64(3 * ledgerSize)), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   341  
   342  	select {
   343  	case deliverReply := <-m.sendChan:
   344  		if deliverReply.GetStatus() != cb.Status_NOT_FOUND {
   345  			t.Fatalf("Received wrong error on the reply channel")
   346  		}
   347  	case <-time.After(time.Second):
   348  		t.Fatalf("Timed out waiting to get all blocks")
   349  	}
   350  }
   351  
   352  func TestFailFastSeek(t *testing.T) {
   353  	m := newMockD()
   354  	defer close(m.recvChan)
   355  
   356  	ds := initializeDeliverHandler()
   357  	go ds.Handle(m)
   358  
   359  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_FAIL_IF_NOT_READY})
   360  
   361  	select {
   362  	case deliverReply := <-m.sendChan:
   363  		if deliverReply.GetBlock() == nil {
   364  			t.Fatalf("Expected to receive first block")
   365  		}
   366  	case <-time.After(time.Second):
   367  		t.Fatalf("Timed out waiting to get all blocks")
   368  	}
   369  
   370  	select {
   371  	case deliverReply := <-m.sendChan:
   372  		if deliverReply.GetStatus() != cb.Status_NOT_FOUND {
   373  			t.Fatalf("Expected to receive failure for second block")
   374  		}
   375  	case <-time.After(time.Second):
   376  		t.Fatalf("Timed out waiting to get all blocks")
   377  	}
   378  }
   379  
   380  func TestBlockingSeek(t *testing.T) {
   381  	mm := newMockMultichainManager()
   382  	for i := 1; i < ledgerSize; i++ {
   383  		l := mm.chains[systemChainID].ledger
   384  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   385  	}
   386  
   387  	m := newMockD()
   388  	defer close(m.recvChan)
   389  	ds := NewHandlerImpl(mm)
   390  
   391  	go ds.Handle(m)
   392  
   393  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   394  
   395  	select {
   396  	case deliverReply := <-m.sendChan:
   397  		if deliverReply.GetBlock() == nil {
   398  			t.Fatalf("Expected to receive first block")
   399  		}
   400  	case <-time.After(time.Second):
   401  		t.Fatalf("Timed out waiting to get first block")
   402  	}
   403  
   404  	select {
   405  	case <-m.sendChan:
   406  		t.Fatalf("Should not have delivered an error or second block")
   407  	case <-time.After(50 * time.Millisecond):
   408  	}
   409  
   410  	l := mm.chains[systemChainID].ledger
   411  	l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", ledgerSize+1))}}))
   412  
   413  	select {
   414  	case deliverReply := <-m.sendChan:
   415  		if deliverReply.GetBlock() == nil {
   416  			t.Fatalf("Expected to receive new block")
   417  		}
   418  	case <-time.After(time.Second):
   419  		t.Fatalf("Timed out waiting to get new block")
   420  	}
   421  
   422  	select {
   423  	case deliverReply := <-m.sendChan:
   424  		if deliverReply.GetStatus() != cb.Status_SUCCESS {
   425  			t.Fatalf("Expected delivery to complete")
   426  		}
   427  	case <-time.After(time.Second):
   428  		t.Fatalf("Timed out waiting to get all blocks")
   429  	}
   430  }
   431  
   432  func TestErroredSeek(t *testing.T) {
   433  	mm := newMockMultichainManager()
   434  	ms := mm.chains[systemChainID]
   435  	l := ms.ledger
   436  	close(ms.erroredChan)
   437  	for i := 1; i < ledgerSize; i++ {
   438  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   439  	}
   440  
   441  	m := newMockD()
   442  	defer close(m.recvChan)
   443  	ds := NewHandlerImpl(mm)
   444  
   445  	go ds.Handle(m)
   446  
   447  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   448  
   449  	select {
   450  	case deliverReply := <-m.sendChan:
   451  		assert.Equal(t, cb.Status_SERVICE_UNAVAILABLE, deliverReply.GetStatus(), "Mock support errored")
   452  	case <-time.After(time.Second):
   453  		t.Fatalf("Timed out waiting for error response")
   454  	}
   455  }
   456  
   457  func TestErroredBlockingSeek(t *testing.T) {
   458  	mm := newMockMultichainManager()
   459  	ms := mm.chains[systemChainID]
   460  	l := ms.ledger
   461  	for i := 1; i < ledgerSize; i++ {
   462  		l.Append(ledger.CreateNextBlock(l, []*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}))
   463  	}
   464  
   465  	m := newMockD()
   466  	defer close(m.recvChan)
   467  	ds := NewHandlerImpl(mm)
   468  
   469  	go ds.Handle(m)
   470  
   471  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(uint64(ledgerSize - 1)), Stop: seekSpecified(ledgerSize), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   472  
   473  	select {
   474  	case deliverReply := <-m.sendChan:
   475  		assert.NotNil(t, deliverReply.GetBlock(), "Expected first block")
   476  	case <-time.After(time.Second):
   477  		t.Fatalf("Timed out waiting to get first block")
   478  	}
   479  
   480  	close(ms.erroredChan)
   481  
   482  	select {
   483  	case deliverReply := <-m.sendChan:
   484  		assert.Equal(t, cb.Status_SERVICE_UNAVAILABLE, deliverReply.GetStatus(), "Mock support errored")
   485  	case <-time.After(time.Second):
   486  		t.Fatalf("Timed out waiting for error response")
   487  	}
   488  }
   489  
   490  func TestSGracefulShutdown(t *testing.T) {
   491  	m := newMockD()
   492  	ds := NewHandlerImpl(nil)
   493  
   494  	close(m.recvChan)
   495  	assert.NoError(t, ds.Handle(m), "Expected no error for hangup")
   496  }
   497  
   498  func TestReversedSeqSeek(t *testing.T) {
   499  	m := newMockD()
   500  	defer close(m.recvChan)
   501  
   502  	ds := initializeDeliverHandler()
   503  	go ds.Handle(m)
   504  
   505  	specifiedStart := uint64(7)
   506  	specifiedStop := uint64(3)
   507  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekSpecified(specifiedStart), Stop: seekSpecified(specifiedStop), Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   508  
   509  	select {
   510  	case deliverReply := <-m.sendChan:
   511  		if deliverReply.GetStatus() != cb.Status_BAD_REQUEST {
   512  			t.Fatalf("Received wrong error on the reply channel")
   513  		}
   514  	case <-time.After(time.Second):
   515  		t.Fatalf("Timed out waiting to get all blocks")
   516  	}
   517  }
   518  
   519  func TestBadStreamRecv(t *testing.T) {
   520  	bh := NewHandlerImpl(nil)
   521  	assert.Error(t, bh.Handle(&erroneousRecvMockD{}), "Should catch unexpected stream error")
   522  }
   523  
   524  func TestBadStreamSend(t *testing.T) {
   525  	m := &erroneousSendMockD{recvVal: makeSeek(systemChainID, &ab.SeekInfo{Start: seekNewest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})}
   526  	ds := initializeDeliverHandler()
   527  	assert.Error(t, ds.Handle(m), "Should catch unexpected stream error")
   528  }
   529  
   530  func TestOldestSeek(t *testing.T) {
   531  	m := newMockD()
   532  	defer close(m.recvChan)
   533  
   534  	ds := initializeDeliverHandler()
   535  	go ds.Handle(m)
   536  
   537  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekOldest, Stop: seekOldest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   538  
   539  	select {
   540  	case deliverReply := <-m.sendChan:
   541  		assert.NotEqual(t, nil, deliverReply.GetBlock(), "Received an error on the reply channel")
   542  		assert.Equal(t, uint64(0), deliverReply.GetBlock().Header.Number, "Expected only the most recent block")
   543  	case <-time.After(time.Second):
   544  		t.Fatalf("Timed out waiting to get all blocks")
   545  	}
   546  }
   547  
   548  func TestNoPayloadSeek(t *testing.T) {
   549  	m := newMockD()
   550  	defer close(m.recvChan)
   551  
   552  	ds := initializeDeliverHandler()
   553  	go ds.Handle(m)
   554  
   555  	m.recvChan <- &cb.Envelope{Payload: []byte("Foo")}
   556  
   557  	select {
   558  	case deliverReply := <-m.sendChan:
   559  		assert.Equal(t, cb.Status_BAD_REQUEST, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   560  	case <-time.After(time.Second):
   561  		t.Fatalf("Timed out waiting to get all blocks")
   562  	}
   563  }
   564  
   565  func TestNilPayloadHeaderSeek(t *testing.T) {
   566  	m := newMockD()
   567  	defer close(m.recvChan)
   568  
   569  	ds := initializeDeliverHandler()
   570  	go ds.Handle(m)
   571  
   572  	m.recvChan <- &cb.Envelope{Payload: utils.MarshalOrPanic(&cb.Payload{})}
   573  
   574  	select {
   575  	case deliverReply := <-m.sendChan:
   576  		assert.Equal(t, cb.Status_BAD_REQUEST, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   577  	case <-time.After(time.Second):
   578  		t.Fatalf("Timed out waiting to get all blocks")
   579  	}
   580  }
   581  
   582  func TestBadChannelHeader(t *testing.T) {
   583  	m := newMockD()
   584  	defer close(m.recvChan)
   585  
   586  	ds := initializeDeliverHandler()
   587  	go ds.Handle(m)
   588  
   589  	m.recvChan <- &cb.Envelope{Payload: utils.MarshalOrPanic(&cb.Payload{
   590  		Header: &cb.Header{ChannelHeader: []byte("Foo")},
   591  	})}
   592  
   593  	select {
   594  	case deliverReply := <-m.sendChan:
   595  		assert.Equal(t, cb.Status_BAD_REQUEST, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   596  	case <-time.After(time.Second):
   597  		t.Fatalf("Timed out waiting to get all blocks")
   598  	}
   599  }
   600  
   601  func TestChainNotFound(t *testing.T) {
   602  	mm := &mockSupportManager{
   603  		chains: make(map[string]*mockSupport),
   604  	}
   605  
   606  	m := newMockD()
   607  	defer close(m.recvChan)
   608  
   609  	ds := NewHandlerImpl(mm)
   610  	go ds.Handle(m)
   611  
   612  	m.recvChan <- makeSeek(systemChainID, &ab.SeekInfo{Start: seekNewest, Stop: seekNewest, Behavior: ab.SeekInfo_BLOCK_UNTIL_READY})
   613  
   614  	select {
   615  	case deliverReply := <-m.sendChan:
   616  		assert.Equal(t, cb.Status_NOT_FOUND, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   617  	case <-time.After(time.Second):
   618  		t.Fatalf("Timed out waiting to get all blocks")
   619  	}
   620  }
   621  
   622  func TestBadSeekInfoPayload(t *testing.T) {
   623  	m := newMockD()
   624  	defer close(m.recvChan)
   625  
   626  	ds := initializeDeliverHandler()
   627  	go ds.Handle(m)
   628  
   629  	m.recvChan <- &cb.Envelope{
   630  		Payload: utils.MarshalOrPanic(&cb.Payload{
   631  			Header: &cb.Header{
   632  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   633  					ChannelId: systemChainID,
   634  				}),
   635  				SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}),
   636  			},
   637  			Data: []byte("Foo"),
   638  		}),
   639  	}
   640  
   641  	select {
   642  	case deliverReply := <-m.sendChan:
   643  		assert.Equal(t, cb.Status_BAD_REQUEST, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   644  	case <-time.After(time.Second):
   645  		t.Fatalf("Timed out waiting to get all blocks")
   646  	}
   647  }
   648  
   649  func TestMissingSeekPosition(t *testing.T) {
   650  	m := newMockD()
   651  	defer close(m.recvChan)
   652  
   653  	ds := initializeDeliverHandler()
   654  	go ds.Handle(m)
   655  
   656  	m.recvChan <- &cb.Envelope{
   657  		Payload: utils.MarshalOrPanic(&cb.Payload{
   658  			Header: &cb.Header{
   659  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   660  					ChannelId: systemChainID,
   661  				}),
   662  				SignatureHeader: utils.MarshalOrPanic(&cb.SignatureHeader{}),
   663  			},
   664  			Data: nil,
   665  		}),
   666  	}
   667  
   668  	select {
   669  	case deliverReply := <-m.sendChan:
   670  		assert.Equal(t, cb.Status_BAD_REQUEST, deliverReply.GetStatus(), "Received wrong error on the reply channel")
   671  	case <-time.After(time.Second):
   672  		t.Fatalf("Timed out waiting to get all blocks")
   673  	}
   674  }