github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/peer/deliverevents_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package peer
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  	"io"
    13  	"strings"
    14  	"sync"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/golang/protobuf/proto"
    19  	"github.com/hechain20/hechain/common/deliver"
    20  	"github.com/hechain20/hechain/common/ledger/blockledger"
    21  	"github.com/hechain20/hechain/common/metrics/disabled"
    22  	"github.com/hechain20/hechain/common/policies"
    23  	"github.com/hechain20/hechain/common/util"
    24  	"github.com/hechain20/hechain/core/ledger"
    25  	"github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/rwsetutil"
    26  	fake "github.com/hechain20/hechain/core/peer/mock"
    27  	"github.com/hechain20/hechain/protoutil"
    28  	"github.com/hyperledger/fabric-protos-go/common"
    29  	"github.com/hyperledger/fabric-protos-go/orderer"
    30  	"github.com/hyperledger/fabric-protos-go/peer"
    31  	"github.com/stretchr/testify/mock"
    32  	"github.com/stretchr/testify/require"
    33  	"google.golang.org/grpc/metadata"
    34  	peer2 "google.golang.org/grpc/peer"
    35  )
    36  
    37  // defaultPolicyCheckerProvider policy checker provider used by default,
    38  // generates policy checker which always accepts regardless of arguments
    39  // passed in
    40  var defaultPolicyCheckerProvider = func(_ string) deliver.PolicyCheckerFunc {
    41  	return func(_ *common.Envelope, _ string) error {
    42  		return nil
    43  	}
    44  }
    45  
    46  //go:generate counterfeiter -o mock/peer_ledger.go -fake-name PeerLedger . peerLedger
    47  
    48  type peerLedger interface {
    49  	ledger.PeerLedger
    50  }
    51  
    52  //go:generate counterfeiter -o mock/identity_deserializer_manager.go -fake-name IdentityDeserializerManager . identityDeserializerManager
    53  
    54  type identityDeserializerManager interface {
    55  	IdentityDeserializerManager
    56  }
    57  
    58  //go:generate counterfeiter -o mock/collection_policy_checker.go -fake-name CollectionPolicyChecker . collectionPolicyChecker
    59  
    60  type collectionPolicyChecker interface {
    61  	CollectionPolicyChecker
    62  }
    63  
    64  // mockIterator mock structure implementing
    65  // the blockledger.Iterator interface
    66  type mockIterator struct {
    67  	mock.Mock
    68  }
    69  
    70  func (m *mockIterator) Next() (*common.Block, common.Status) {
    71  	args := m.Called()
    72  	return args.Get(0).(*common.Block), args.Get(1).(common.Status)
    73  }
    74  
    75  func (m *mockIterator) ReadyChan() <-chan struct{} {
    76  	panic("implement me")
    77  }
    78  
    79  func (m *mockIterator) Close() {
    80  }
    81  
    82  // mockReader mock structure implementing
    83  // the blockledger.Reader interface
    84  type mockReader struct {
    85  	mock.Mock
    86  }
    87  
    88  func (m *mockReader) Iterator(startType *orderer.SeekPosition) (blockledger.Iterator, uint64) {
    89  	args := m.Called(startType)
    90  	return args.Get(0).(blockledger.Iterator), args.Get(1).(uint64)
    91  }
    92  
    93  func (m *mockReader) Height() uint64 {
    94  	args := m.Called()
    95  	return args.Get(0).(uint64)
    96  }
    97  
    98  func (m *mockReader) RetrieveBlockByNumber(blockNum uint64) (*common.Block, error) {
    99  	args := m.Called()
   100  	return args.Get(0).(*common.Block), args.Error(1)
   101  }
   102  
   103  // mockChainSupport
   104  type mockChainSupport struct {
   105  	mock.Mock
   106  }
   107  
   108  func (m *mockChainSupport) Sequence() uint64 {
   109  	return m.Called().Get(0).(uint64)
   110  }
   111  
   112  func (m *mockChainSupport) Ledger() ledger.PeerLedger {
   113  	return m.Called().Get(0).(ledger.PeerLedger)
   114  }
   115  
   116  func (m *mockChainSupport) PolicyManager() policies.Manager {
   117  	panic("implement me")
   118  }
   119  
   120  func (m *mockChainSupport) Reader() blockledger.Reader {
   121  	return m.Called().Get(0).(blockledger.Reader)
   122  }
   123  
   124  func (*mockChainSupport) Errored() <-chan struct{} {
   125  	return make(chan struct{})
   126  }
   127  
   128  // mockChainManager mock implementation of the ChainManager interface
   129  type mockChainManager struct {
   130  	mock.Mock
   131  }
   132  
   133  func (m *mockChainManager) GetChain(channelID string) deliver.Chain {
   134  	args := m.Called(channelID)
   135  	return args.Get(0).(deliver.Chain)
   136  }
   137  
   138  // mockDeliverServer mock implementation of the Deliver_DeliverServer
   139  type mockDeliverServer struct {
   140  	mock.Mock
   141  }
   142  
   143  func (m *mockDeliverServer) Context() context.Context {
   144  	return m.Called().Get(0).(context.Context)
   145  }
   146  
   147  func (m *mockDeliverServer) Recv() (*common.Envelope, error) {
   148  	args := m.Called()
   149  	if args.Get(0) == nil {
   150  		return nil, args.Error(1)
   151  	}
   152  	return args.Get(0).(*common.Envelope), args.Error(1)
   153  }
   154  
   155  func (m *mockDeliverServer) Send(response *peer.DeliverResponse) error {
   156  	args := m.Called(response)
   157  	return args.Error(0)
   158  }
   159  
   160  func (*mockDeliverServer) RecvMsg(m interface{}) error {
   161  	panic("implement me")
   162  }
   163  
   164  func (*mockDeliverServer) SendHeader(metadata.MD) error {
   165  	panic("implement me")
   166  }
   167  
   168  func (*mockDeliverServer) SendMsg(m interface{}) error {
   169  	panic("implement me")
   170  }
   171  
   172  func (*mockDeliverServer) SetHeader(metadata.MD) error {
   173  	panic("implement me")
   174  }
   175  
   176  func (*mockDeliverServer) SetTrailer(metadata.MD) {
   177  	panic("implement me")
   178  }
   179  
   180  type testConfig struct {
   181  	channelID     string
   182  	eventName     string
   183  	chaincodeName string
   184  	txID          string
   185  	payload       *common.Payload
   186  	*require.Assertions
   187  }
   188  
   189  type testCase struct {
   190  	name    string
   191  	prepare func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer)
   192  }
   193  
   194  func TestFilteredBlockResponseSenderIsFiltered(t *testing.T) {
   195  	var fbrs interface{} = &filteredBlockResponseSender{}
   196  	filtered, ok := fbrs.(deliver.Filtered)
   197  	require.True(t, ok, "should be filtered")
   198  	require.True(t, filtered.IsFiltered(), "should return true from IsFiltered")
   199  }
   200  
   201  func TestEventsServer_DeliverFiltered(t *testing.T) {
   202  	tests := []testCase{
   203  		{
   204  			name: "Testing deliver of the filtered block events",
   205  			prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   206  				return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   207  					wg.Add(2)
   208  					p := &peer2.Peer{}
   209  					chaincodeActionPayload, err := createChaincodeAction(config.chaincodeName, config.eventName, config.txID)
   210  					config.NoError(err)
   211  
   212  					chainManager := createDefaultSupportMamangerMock(config, chaincodeActionPayload, nil)
   213  					// setup mock deliver server
   214  					deliverServer := &mockDeliverServer{}
   215  					deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   216  
   217  					deliverServer.On("Recv").Return(&common.Envelope{
   218  						Payload: protoutil.MarshalOrPanic(config.payload),
   219  					}, nil).Run(func(_ mock.Arguments) {
   220  						// once we are getting new message we need to mock
   221  						// Recv call to get io.EOF to stop the looping for
   222  						// next message and we can assert for the DeliverResponse
   223  						// value we are getting from the deliver server
   224  						deliverServer.Mock = mock.Mock{}
   225  						deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   226  						deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF)
   227  						deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) {
   228  							defer wg.Done()
   229  							response := args.Get(0).(*peer.DeliverResponse)
   230  							switch response.Type.(type) {
   231  							case *peer.DeliverResponse_Status:
   232  								config.Equal(common.Status_SUCCESS, response.GetStatus())
   233  							case *peer.DeliverResponse_FilteredBlock:
   234  								block := response.GetFilteredBlock()
   235  								config.Equal(uint64(0), block.Number)
   236  								config.Equal(config.channelID, block.ChannelId)
   237  								config.Equal(1, len(block.FilteredTransactions))
   238  								tx := block.FilteredTransactions[0]
   239  								config.Equal(config.txID, tx.Txid)
   240  								config.Equal(peer.TxValidationCode_VALID, tx.TxValidationCode)
   241  								config.Equal(common.HeaderType_ENDORSER_TRANSACTION, tx.Type)
   242  								transactionActions := tx.GetTransactionActions()
   243  								config.NotNil(transactionActions)
   244  								chaincodeActions := transactionActions.ChaincodeActions
   245  								config.Equal(1, len(chaincodeActions))
   246  								config.Equal(config.eventName, chaincodeActions[0].ChaincodeEvent.EventName)
   247  								config.Equal(config.txID, chaincodeActions[0].ChaincodeEvent.TxId)
   248  								config.Equal(config.chaincodeName, chaincodeActions[0].ChaincodeEvent.ChaincodeId)
   249  							default:
   250  								config.FailNow("Unexpected response type")
   251  							}
   252  						}).Return(nil)
   253  					})
   254  
   255  					return chainManager, deliverServer
   256  				}
   257  			}(testConfig{
   258  				channelID:     "testChannelID",
   259  				eventName:     "testEvent",
   260  				chaincodeName: "mycc",
   261  				txID:          "testID",
   262  				payload: &common.Payload{
   263  					Header: &common.Header{
   264  						ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
   265  							ChannelId: "testChannelID",
   266  							Timestamp: util.CreateUtcTimestamp(),
   267  						}),
   268  						SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}),
   269  					},
   270  					Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{
   271  						Start:    &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}},
   272  						Stop:     &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}},
   273  						Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
   274  					}),
   275  				},
   276  				Assertions: require.New(t),
   277  			}),
   278  		},
   279  		{
   280  			name: "Testing deliver of the filtered block events with nil chaincode action payload",
   281  			prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   282  				return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   283  					wg.Add(2)
   284  					p := &peer2.Peer{}
   285  					chainManager := createDefaultSupportMamangerMock(config, nil, nil)
   286  
   287  					// setup mock deliver server
   288  					deliverServer := &mockDeliverServer{}
   289  					deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   290  
   291  					deliverServer.On("Recv").Return(&common.Envelope{
   292  						Payload: protoutil.MarshalOrPanic(config.payload),
   293  					}, nil).Run(func(_ mock.Arguments) {
   294  						// once we are getting new message we need to mock
   295  						// Recv call to get io.EOF to stop the looping for
   296  						// next message and we can assert for the DeliverResponse
   297  						// value we are getting from the deliver server
   298  						deliverServer.Mock = mock.Mock{}
   299  						deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   300  						deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF)
   301  						deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) {
   302  							defer wg.Done()
   303  							response := args.Get(0).(*peer.DeliverResponse)
   304  							switch response.Type.(type) {
   305  							case *peer.DeliverResponse_Status:
   306  								config.Equal(common.Status_SUCCESS, response.GetStatus())
   307  							case *peer.DeliverResponse_FilteredBlock:
   308  								block := response.GetFilteredBlock()
   309  								config.Equal(uint64(0), block.Number)
   310  								config.Equal(config.channelID, block.ChannelId)
   311  								config.Equal(1, len(block.FilteredTransactions))
   312  								tx := block.FilteredTransactions[0]
   313  								config.Equal(config.txID, tx.Txid)
   314  								config.Equal(peer.TxValidationCode_VALID, tx.TxValidationCode)
   315  								config.Equal(common.HeaderType_ENDORSER_TRANSACTION, tx.Type)
   316  								transactionActions := tx.GetTransactionActions()
   317  								config.NotNil(transactionActions)
   318  								chaincodeActions := transactionActions.ChaincodeActions
   319  								// we expecting to get zero chaincode action,
   320  								// since provided nil payload
   321  								config.Equal(0, len(chaincodeActions))
   322  							default:
   323  								config.FailNow("Unexpected response type")
   324  							}
   325  						}).Return(nil)
   326  					})
   327  
   328  					return chainManager, deliverServer
   329  				}
   330  			}(testConfig{
   331  				channelID:     "testChannelID",
   332  				eventName:     "testEvent",
   333  				chaincodeName: "mycc",
   334  				txID:          "testID",
   335  				payload: &common.Payload{
   336  					Header: &common.Header{
   337  						ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
   338  							ChannelId: "testChannelID",
   339  							Timestamp: util.CreateUtcTimestamp(),
   340  						}),
   341  						SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}),
   342  					},
   343  					Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{
   344  						Start:    &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}},
   345  						Stop:     &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}},
   346  						Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
   347  					}),
   348  				},
   349  				Assertions: require.New(t),
   350  			}),
   351  		},
   352  		{
   353  			name: "Testing deliver of the filtered block events with nil payload header",
   354  			prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   355  				return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   356  					wg.Add(1)
   357  					p := &peer2.Peer{}
   358  					chainManager := createDefaultSupportMamangerMock(config, nil, nil)
   359  
   360  					// setup mock deliver server
   361  					deliverServer := &mockDeliverServer{}
   362  					deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   363  
   364  					deliverServer.On("Recv").Return(&common.Envelope{
   365  						Payload: protoutil.MarshalOrPanic(config.payload),
   366  					}, nil).Run(func(_ mock.Arguments) {
   367  						// once we are getting new message we need to mock
   368  						// Recv call to get io.EOF to stop the looping for
   369  						// next message and we can assert for the DeliverResponse
   370  						// value we are getting from the deliver server
   371  						deliverServer.Mock = mock.Mock{}
   372  						deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   373  						deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF)
   374  						deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) {
   375  							defer wg.Done()
   376  							response := args.Get(0).(*peer.DeliverResponse)
   377  							switch response.Type.(type) {
   378  							case *peer.DeliverResponse_Status:
   379  								config.Equal(common.Status_BAD_REQUEST, response.GetStatus())
   380  							case *peer.DeliverResponse_FilteredBlock:
   381  								config.FailNow("Unexpected response type")
   382  							default:
   383  								config.FailNow("Unexpected response type")
   384  							}
   385  						}).Return(nil)
   386  					})
   387  
   388  					return chainManager, deliverServer
   389  				}
   390  			}(testConfig{
   391  				channelID:     "testChannelID",
   392  				eventName:     "testEvent",
   393  				chaincodeName: "mycc",
   394  				txID:          "testID",
   395  				payload: &common.Payload{
   396  					Header: nil,
   397  					Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{
   398  						Start:    &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}},
   399  						Stop:     &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}},
   400  						Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
   401  					}),
   402  				},
   403  				Assertions: require.New(t),
   404  			}),
   405  		},
   406  	}
   407  	for _, test := range tests {
   408  		t.Run(test.name, func(t *testing.T) {
   409  			wg := &sync.WaitGroup{}
   410  			chainManager, deliverServer := test.prepare(wg)
   411  
   412  			metrics := deliver.NewMetrics(&disabled.Provider{})
   413  			server := &DeliverServer{
   414  				DeliverHandler:        deliver.NewHandler(chainManager, time.Second, false, metrics, false),
   415  				PolicyCheckerProvider: defaultPolicyCheckerProvider,
   416  			}
   417  
   418  			err := server.DeliverFiltered(deliverServer)
   419  			wg.Wait()
   420  			// no error expected
   421  			require.NoError(t, err)
   422  		})
   423  	}
   424  }
   425  
   426  func TestEventsServer_DeliverWithPrivateData(t *testing.T) {
   427  	fakeDeserializerMgr := &fake.IdentityDeserializerManager{}
   428  	fakeDeserializerMgr.DeserializerReturns(nil, nil)
   429  	fakeCollPolicyChecker := &fake.CollectionPolicyChecker{}
   430  	fakeCollPolicyChecker.CheckCollectionPolicyReturns(true, nil)
   431  	tests := []testCase{
   432  		{
   433  			name: "Testing deliver block with private data events",
   434  			prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   435  				return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   436  					wg.Add(2)
   437  					p := &peer2.Peer{}
   438  					chaincodeActionPayload, err := createChaincodeAction(config.chaincodeName, config.eventName, config.txID)
   439  					config.NoError(err)
   440  
   441  					pvtData := []*ledger.TxPvtData{
   442  						produceSamplePvtdataOrPanic(0, []string{"ns-0:coll-0", "ns-2:coll-20", "ns-2:coll-21"}),
   443  					}
   444  					chainManager := createDefaultSupportMamangerMock(config, chaincodeActionPayload, pvtData)
   445  
   446  					deliverServer := &mockDeliverServer{}
   447  					deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   448  					deliverServer.On("Recv").Return(&common.Envelope{
   449  						Payload: protoutil.MarshalOrPanic(config.payload),
   450  					}, nil).Run(func(_ mock.Arguments) {
   451  						// mock Recv calls to get io.EOF to stop the looping for next message
   452  						deliverServer.Mock = mock.Mock{}
   453  						deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   454  						deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF)
   455  						deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) {
   456  							defer wg.Done()
   457  							response := args.Get(0).(*peer.DeliverResponse)
   458  							switch response.Type.(type) {
   459  							case *peer.DeliverResponse_Status:
   460  								config.Equal(common.Status_SUCCESS, response.GetStatus())
   461  							case *peer.DeliverResponse_BlockAndPrivateData:
   462  								blockAndPvtData := response.GetBlockAndPrivateData()
   463  								block := blockAndPvtData.Block
   464  								config.Equal(uint64(0), block.Header.Number)
   465  								config.Equal(1, len(blockAndPvtData.PrivateDataMap))
   466  								config.NotNil(blockAndPvtData.PrivateDataMap[uint64(0)])
   467  								txPvtRwset := blockAndPvtData.PrivateDataMap[uint64(0)]
   468  								// expect to have 2 NsPvtRwset (i.e., 2 namespaces)
   469  								config.Equal(2, len(txPvtRwset.NsPvtRwset))
   470  								// check namespace because the index may be out of order
   471  								for _, nsPvtRwset := range txPvtRwset.NsPvtRwset {
   472  									switch nsPvtRwset.Namespace {
   473  									case "ns-0":
   474  										config.Equal(1, len(nsPvtRwset.CollectionPvtRwset))
   475  										config.Equal("coll-0", nsPvtRwset.CollectionPvtRwset[0].CollectionName)
   476  									case "ns-2":
   477  										config.Equal(2, len(nsPvtRwset.CollectionPvtRwset))
   478  										config.Equal("coll-20", nsPvtRwset.CollectionPvtRwset[0].CollectionName)
   479  										config.Equal("coll-21", nsPvtRwset.CollectionPvtRwset[1].CollectionName)
   480  									default:
   481  										config.FailNow("Wrong namespace " + nsPvtRwset.Namespace)
   482  									}
   483  								}
   484  							default:
   485  								config.FailNow("Unexpected response type")
   486  							}
   487  						}).Return(nil)
   488  					})
   489  
   490  					return chainManager, deliverServer
   491  				}
   492  			}(testConfig{
   493  				channelID:     "testChannelID",
   494  				eventName:     "testEvent",
   495  				chaincodeName: "mycc",
   496  				txID:          "testID",
   497  				payload: &common.Payload{
   498  					Header: &common.Header{
   499  						ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
   500  							ChannelId: "testChannelID",
   501  							Timestamp: util.CreateUtcTimestamp(),
   502  						}),
   503  						SignatureHeader: protoutil.MarshalOrPanic(&common.SignatureHeader{}),
   504  					},
   505  					Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{
   506  						Start:    &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}},
   507  						Stop:     &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}},
   508  						Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
   509  					}),
   510  				},
   511  				Assertions: require.New(t),
   512  			}),
   513  		},
   514  		{
   515  			name: "Testing deliver of block with private data events with nil header",
   516  			prepare: func(config testConfig) func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   517  				return func(wg *sync.WaitGroup) (deliver.ChainManager, peer.Deliver_DeliverServer) {
   518  					wg.Add(1)
   519  					p := &peer2.Peer{}
   520  					chainManager := createDefaultSupportMamangerMock(config, nil, nil)
   521  
   522  					deliverServer := &mockDeliverServer{}
   523  					deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   524  					deliverServer.On("Recv").Return(&common.Envelope{
   525  						Payload: protoutil.MarshalOrPanic(config.payload),
   526  					}, nil).Run(func(_ mock.Arguments) {
   527  						// mock Recv calls to get io.EOF to stop the looping for next message
   528  						deliverServer.Mock = mock.Mock{}
   529  						deliverServer.On("Context").Return(peer2.NewContext(context.TODO(), p))
   530  						deliverServer.On("Recv").Return(&common.Envelope{}, io.EOF)
   531  						deliverServer.On("Send", mock.Anything).Run(func(args mock.Arguments) {
   532  							defer wg.Done()
   533  							response := args.Get(0).(*peer.DeliverResponse)
   534  							switch response.Type.(type) {
   535  							case *peer.DeliverResponse_Status:
   536  								config.Equal(common.Status_BAD_REQUEST, response.GetStatus())
   537  							case *peer.DeliverResponse_BlockAndPrivateData:
   538  								config.FailNow("Unexpected response type")
   539  							default:
   540  								config.FailNow("Unexpected response type")
   541  							}
   542  						}).Return(nil)
   543  					})
   544  
   545  					return chainManager, deliverServer
   546  				}
   547  			}(testConfig{
   548  				channelID:     "testChannelID",
   549  				eventName:     "testEvent",
   550  				chaincodeName: "mycc",
   551  				txID:          "testID",
   552  				payload: &common.Payload{
   553  					Header: nil,
   554  					Data: protoutil.MarshalOrPanic(&orderer.SeekInfo{
   555  						Start:    &orderer.SeekPosition{Type: &orderer.SeekPosition_Specified{Specified: &orderer.SeekSpecified{Number: 0}}},
   556  						Stop:     &orderer.SeekPosition{Type: &orderer.SeekPosition_Newest{Newest: &orderer.SeekNewest{}}},
   557  						Behavior: orderer.SeekInfo_BLOCK_UNTIL_READY,
   558  					}),
   559  				},
   560  				Assertions: require.New(t),
   561  			}),
   562  		},
   563  	}
   564  	for _, test := range tests {
   565  		t.Run(test.name, func(t *testing.T) {
   566  			wg := &sync.WaitGroup{}
   567  			chainManager, deliverServer := test.prepare(wg)
   568  
   569  			metrics := deliver.NewMetrics(&disabled.Provider{})
   570  			handler := deliver.NewHandler(chainManager, time.Second, false, metrics, false)
   571  			server := &DeliverServer{
   572  				DeliverHandler:          handler,
   573  				PolicyCheckerProvider:   defaultPolicyCheckerProvider,
   574  				CollectionPolicyChecker: fakeCollPolicyChecker,
   575  				IdentityDeserializerMgr: fakeDeserializerMgr,
   576  			}
   577  
   578  			err := server.DeliverWithPrivateData(deliverServer)
   579  			wg.Wait()
   580  			// no error expected
   581  			require.NoError(t, err)
   582  		})
   583  	}
   584  }
   585  
   586  func createDefaultSupportMamangerMock(config testConfig, chaincodeActionPayload *peer.ChaincodeActionPayload, pvtData []*ledger.TxPvtData) *mockChainManager {
   587  	chainManager := &mockChainManager{}
   588  	iter := &mockIterator{}
   589  	reader := &mockReader{}
   590  	chain := &mockChainSupport{}
   591  	ldgr := &fake.PeerLedger{}
   592  
   593  	payload, err := createEndorsement(config.channelID, config.txID, chaincodeActionPayload)
   594  	config.NoError(err)
   595  
   596  	payloadBytes, err := proto.Marshal(payload)
   597  	config.NoError(err)
   598  
   599  	block, err := createTestBlock([]*common.Envelope{{
   600  		Payload:   payloadBytes,
   601  		Signature: []byte{},
   602  	}})
   603  	config.NoError(err)
   604  
   605  	iter.On("Next").Return(block, common.Status_SUCCESS)
   606  	reader.On("Iterator", mock.Anything).Return(iter, uint64(1))
   607  	reader.On("Height").Return(uint64(1))
   608  	chain.On("Sequence").Return(uint64(0))
   609  	chain.On("Reader").Return(reader)
   610  	chain.On("Ledger").Return(ldgr)
   611  	chainManager.On("GetChain", config.channelID).Return(chain, true)
   612  
   613  	ldgr.GetPvtDataByNumReturns(pvtData, nil)
   614  
   615  	return chainManager
   616  }
   617  
   618  func createEndorsement(channelID string, txID string, chaincodeActionPayload *peer.ChaincodeActionPayload) (*common.Payload, error) {
   619  	var chActionBytes []byte
   620  	var err error
   621  	if chaincodeActionPayload != nil {
   622  		chActionBytes, err = proto.Marshal(chaincodeActionPayload)
   623  		if err != nil {
   624  			return nil, err
   625  		}
   626  	}
   627  
   628  	// the transaction
   629  	txBytes, err := proto.Marshal(&peer.Transaction{
   630  		Actions: []*peer.TransactionAction{
   631  			{
   632  				Payload: chActionBytes,
   633  			},
   634  		},
   635  	})
   636  	if err != nil {
   637  		return nil, err
   638  	}
   639  	// channel header
   640  	chdrBytes, err := proto.Marshal(&common.ChannelHeader{
   641  		ChannelId: channelID,
   642  		TxId:      txID,
   643  		Type:      int32(common.HeaderType_ENDORSER_TRANSACTION),
   644  	})
   645  	if err != nil {
   646  		return nil, err
   647  	}
   648  
   649  	// the payload
   650  	payload := &common.Payload{
   651  		Header: &common.Header{
   652  			ChannelHeader: chdrBytes,
   653  		},
   654  		Data: txBytes,
   655  	}
   656  	return payload, nil
   657  }
   658  
   659  func createChaincodeAction(chaincodeName string, eventName string, txID string) (*peer.ChaincodeActionPayload, error) {
   660  	// chaincode events
   661  	eventsBytes, err := proto.Marshal(&peer.ChaincodeEvent{
   662  		ChaincodeId: chaincodeName,
   663  		EventName:   eventName,
   664  		TxId:        txID,
   665  	})
   666  	if err != nil {
   667  		return nil, err
   668  	}
   669  
   670  	// chaincode action
   671  	actionBytes, err := proto.Marshal(&peer.ChaincodeAction{
   672  		ChaincodeId: &peer.ChaincodeID{
   673  			Name: chaincodeName,
   674  		},
   675  		Events: eventsBytes,
   676  	})
   677  	if err != nil {
   678  		return nil, err
   679  	}
   680  
   681  	// proposal response
   682  	proposalResBytes, err := proto.Marshal(&peer.ProposalResponsePayload{
   683  		Extension: actionBytes,
   684  	})
   685  	if err != nil {
   686  		return nil, err
   687  	}
   688  
   689  	// chaincode action
   690  	chaincodeActionPayload := &peer.ChaincodeActionPayload{
   691  		Action: &peer.ChaincodeEndorsedAction{
   692  			ProposalResponsePayload: proposalResBytes,
   693  			Endorsements:            []*peer.Endorsement{},
   694  		},
   695  	}
   696  	return chaincodeActionPayload, err
   697  }
   698  
   699  func createTestBlock(data []*common.Envelope) (*common.Block, error) {
   700  	// block
   701  	block := &common.Block{
   702  		Header: &common.BlockHeader{
   703  			Number:   0,
   704  			DataHash: []byte{},
   705  		},
   706  		Data:     &common.BlockData{},
   707  		Metadata: &common.BlockMetadata{},
   708  	}
   709  	for _, d := range data {
   710  		envBytes, err := proto.Marshal(d)
   711  		if err != nil {
   712  			return nil, err
   713  		}
   714  
   715  		block.Data.Data = append(block.Data.Data, envBytes)
   716  	}
   717  	// making up metadata
   718  	block.Metadata.Metadata = make([][]byte, 4)
   719  	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = make([]byte, len(data))
   720  	return block, nil
   721  }
   722  
   723  func produceSamplePvtdataOrPanic(txNum uint64, nsColls []string) *ledger.TxPvtData {
   724  	builder := rwsetutil.NewRWSetBuilder()
   725  	for _, nsColl := range nsColls {
   726  		nsCollSplit := strings.Split(nsColl, ":")
   727  		ns := nsCollSplit[0]
   728  		coll := nsCollSplit[1]
   729  		builder.AddToPvtAndHashedWriteSet(ns, coll, fmt.Sprintf("key-%s-%s", ns, coll), []byte(fmt.Sprintf("value-%s-%s", ns, coll)))
   730  	}
   731  	simRes, err := builder.GetTxSimulationResults()
   732  	if err != nil {
   733  		panic(err)
   734  	}
   735  	return &ledger.TxPvtData{SeqInBlock: txNum, WriteSet: simRes.PvtSimulationResults}
   736  }