From b6d95e2b2ec2188e775c52ab7a3c678e914dcb8f Mon Sep 17 00:00:00 2001 From: "Mark S. Lewis" Date: Fri, 18 Oct 2024 16:07:10 +0100 Subject: [PATCH] Refactor block eventing unit tests (#760) Simplify tests by using an abstraction to the eventing set up and invocation so that a set of common tests can be applied to block, filtered block, and block and private data unit tests. Signed-off-by: Mark S. Lewis --- go.mod | 2 +- go.sum | 4 +- pkg/client/blockevents_test.go | 255 +--------- pkg/client/blockeventscommon_test.go | 443 ++++++++++++++++++ pkg/client/blockeventsfiltered_test.go | 255 +--------- pkg/client/blockeventswithprivatedata_test.go | 255 +--------- pkg/client/protobuf_test.go | 4 + 7 files changed, 480 insertions(+), 738 deletions(-) create mode 100644 pkg/client/blockeventscommon_test.go diff --git a/go.mod b/go.mod index ae4125ec4..95bf4d3e8 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/stretchr/testify v1.9.0 golang.org/x/crypto v0.28.0 google.golang.org/grpc v1.67.1 - google.golang.org/protobuf v1.34.2 + google.golang.org/protobuf v1.35.1 ) require ( diff --git a/go.sum b/go.sum index 7182b770b..f71fd7402 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/client/blockevents_test.go b/pkg/client/blockevents_test.go index 0c524701e..06dc5e9cd 100644 --- a/pkg/client/blockevents_test.go +++ b/pkg/client/blockevents_test.go @@ -5,185 +5,14 @@ package client import ( "context" - "errors" - "io" "testing" "github.com/hyperledger/fabric-protos-go-apiv2/common" - "github.com/hyperledger/fabric-protos-go-apiv2/orderer" "github.com/hyperledger/fabric-protos-go-apiv2/peer" "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) func TestBlockEvents(t *testing.T) { - t.Run("Returns connect error", func(t *testing.T) { - expected := NewStatusError(t, codes.Aborted, "BLOCK_EVENTS_ERROR") - - mockConnection := NewMockClientConnInterface(t) - ExpectDeliver(mockConnection, WithNewStreamError(expected)) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.BlockEvents(ctx) - - require.Equal(t, status.Code(expected), status.Code(err), "status code") - require.ErrorIs(t, err, expected, "error type: %T", err) - require.ErrorContains(t, err, expected.Error(), "message") - }) - - for testName, testCase := range map[string]struct { - options []BlockEventsOption - expected *orderer.SeekInfo - }{ - "Sends valid request with default start position": { - options: nil, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Sends valid request with specified start block number": { - options: []BlockEventsOption{ - WithStartBlock(418), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses specified start block instead of unset checkpoint": { - options: []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointBlock(500) - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 501, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block zero with set transaction ID instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointTransaction(0, "transctionId") - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 0, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses default start position with unset checkpoint and no start block": { - options: []BlockEventsOption{ - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - } { - t.Run(testName, func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliver(mockConnection, WithNewStreamResult(mockStream)) - - messages := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(messages)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.BlockEvents(ctx, testCase.options...) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-messages).GetPayload(), payload) - AssertValidBlockEventRequestHeader(t, payload, network.Name()) - actual := &orderer.SeekInfo{} - AssertUnmarshal(t, payload.GetData(), actual) - - AssertProtoEqual(t, testCase.expected, actual) - }) - } - - t.Run("Closes event channel on receive error", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliver(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Return(errors.New("fake")) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockEvents(ctx, WithStartBlock(418)) - require.NoError(t, err) - - actual, ok := <-receive - - require.False(t, ok, "Expected event listening to be cancelled, got %v", actual) - }) - t.Run("Receives events", func(t *testing.T) { expected := []*common.Block{ { @@ -208,13 +37,6 @@ func TestBlockEvents(t *testing.T) { }, } - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliver(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - var responses []*peer.DeliverResponse for _, block := range expected { responses = append(responses, &peer.DeliverResponse{ @@ -223,29 +45,23 @@ func TestBlockEvents(t *testing.T) { }, }) } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewBlockEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) for _, event := range expected { - actual := <-receive + actual := <-tester.BlockEvents AssertProtoEqual(t, event, actual) } }) t.Run("Closes event channel on non-block message", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliver(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - block := &common.Block{ Header: &common.BlockHeader{ Number: 1, @@ -273,13 +89,14 @@ func TestBlockEvents(t *testing.T) { }, }, } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewBlockEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) expected := []*common.Block{ @@ -288,60 +105,8 @@ func TestBlockEvents(t *testing.T) { nil, } for _, event := range expected { - actual := <-receive + actual := <-tester.BlockEvents AssertProtoEqual(t, event, actual) } }) - - t.Run("Uses specified gRPC call options", func(t *testing.T) { - expected := grpc.WaitForReady(true) - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - options := make(chan []grpc.CallOption, 1) - ExpectDeliver(mockConnection, CaptureNewStreamOptions(options), WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - request, err := network.NewBlockEventsRequest() - require.NoError(t, err, "NewBlockEventsRequest") - - _, err = request.Events(ctx, expected) - require.NoError(t, err, "Events") - - require.Contains(t, (<-options), expected, "CallOptions") - }) - - t.Run("Sends request with TLS client certificate hash", func(t *testing.T) { - expected := []byte("TLS_CLIENT_CERTIFICATE_HASH") - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliver(mockConnection, WithNewStreamResult(mockStream)) - - requests := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(requests)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection), WithTLSClientCertificateHash(expected)) - _, err := network.BlockEvents(ctx) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-requests).GetPayload(), payload) - channelHeader := &common.ChannelHeader{} - AssertUnmarshal(t, payload.GetHeader().GetChannelHeader(), channelHeader) - - require.Equal(t, expected, channelHeader.GetTlsCertHash()) - }) } diff --git a/pkg/client/blockeventscommon_test.go b/pkg/client/blockeventscommon_test.go new file mode 100644 index 000000000..ce634d8a6 --- /dev/null +++ b/pkg/client/blockeventscommon_test.go @@ -0,0 +1,443 @@ +// Copyright IBM Corp. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "context" + "errors" + "io" + "testing" + + "github.com/hyperledger/fabric-protos-go-apiv2/common" + "github.com/hyperledger/fabric-protos-go-apiv2/orderer" + "github.com/hyperledger/fabric-protos-go-apiv2/peer" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +func TestCommonBlockEvents(t *testing.T) { + for eventType, newTester := range map[string]func(*testing.T) blockEventsTester{ + "Block": func(t *testing.T) blockEventsTester { + return NewBlockEventsTest(t) + }, + "FilteredBlock": func(t *testing.T) blockEventsTester { + return NewFilteredBlockEventsTest(t) + }, + "BlockAndPrivateData": func(t *testing.T) blockEventsTester { + return NewBlockAndPrivateDataEventsTest(t) + }, + } { + t.Run(eventType, func(t *testing.T) { + t.Run("Returns connect error", func(t *testing.T) { + expected := NewStatusError(t, codes.Aborted, "BLOCK_EVENTS_ERROR") + + tester := newTester(t) + tester.SetConnectError(expected) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + err := tester.Events(ctx) + + require.Equal(t, status.Code(expected), status.Code(err), "status code") + require.ErrorIs(t, err, expected, "error type: %T", err) + require.ErrorContains(t, err, expected.Error(), "message") + }) + }) + + for testName, testCase := range map[string]struct { + options []BlockEventsOption + expected *orderer.SeekInfo + }{ + "Sends valid request with default start position": { + options: nil, + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_NextCommit{ + NextCommit: &orderer.SeekNextCommit{}, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + "Sends valid request with specified start block number": { + options: []BlockEventsOption{ + WithStartBlock(418), + }, + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Specified{ + Specified: &orderer.SeekSpecified{ + Number: 418, + }, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + "Uses specified start block instead of unset checkpoint": { + options: []BlockEventsOption{ + WithStartBlock(418), + WithCheckpoint(new(InMemoryCheckpointer)), + }, + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Specified{ + Specified: &orderer.SeekSpecified{ + Number: 418, + }, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + "Uses checkpoint block instead of specified start block": { + options: func() []BlockEventsOption { + checkpointer := new(InMemoryCheckpointer) + checkpointer.CheckpointBlock(500) + return []BlockEventsOption{ + WithStartBlock(418), + WithCheckpoint(checkpointer), + } + }(), + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Specified{ + Specified: &orderer.SeekSpecified{ + Number: 501, + }, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + "Uses checkpoint block zero with set transaction ID instead of specified start block": { + options: func() []BlockEventsOption { + checkpointer := new(InMemoryCheckpointer) + checkpointer.CheckpointTransaction(0, "transctionId") + return []BlockEventsOption{ + WithStartBlock(418), + WithCheckpoint(checkpointer), + } + }(), + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_Specified{ + Specified: &orderer.SeekSpecified{ + Number: 0, + }, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + "Uses default start position with unset checkpoint and no start block": { + options: []BlockEventsOption{ + WithCheckpoint(new(InMemoryCheckpointer)), + }, + expected: &orderer.SeekInfo{ + Start: &orderer.SeekPosition{ + Type: &orderer.SeekPosition_NextCommit{ + NextCommit: &orderer.SeekNextCommit{}, + }, + }, + Stop: seekLargestBlockNumber(), + }, + }, + } { + t.Run(testName, func(t *testing.T) { + networkName := "NETWORK" + + tester := newTester(t) + tester.SetNetworkName(networkName) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + err := tester.Events(ctx, testCase.options...) + require.NoError(t, err) + + payload := &common.Payload{} + AssertUnmarshal(t, (<-tester.Requests()).GetPayload(), payload) + AssertValidBlockEventRequestHeader(t, payload, networkName) + actual := &orderer.SeekInfo{} + AssertUnmarshal(t, payload.GetData(), actual) + + AssertProtoEqual(t, testCase.expected, actual) + }) + } + + t.Run("Closes event channel on receive error", func(t *testing.T) { + tester := newTester(t) + tester.SetReceiveError(errors.New("fake")) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + err := tester.Events(ctx) + require.NoError(t, err) + + actual, ok := tester.Receive() + + require.False(t, ok, "Expected event listening to be cancelled, got %v", actual) + }) + + t.Run("Uses specified gRPC call options", func(t *testing.T) { + expected := grpc.WaitForReady(true) + + tester := newTester(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + err := tester.EventsWithCallOptions(ctx, expected) + require.NoError(t, err) + + require.Contains(t, (<-tester.CallOptions()), expected, "CallOptions") + }) + + t.Run("Sends request with TLS client certificate hash", func(t *testing.T) { + expected := []byte("TLS_CLIENT_CERTIFICATE_HASH") + + tester := newTester(t) + tester.SetGatewayOptions(WithTLSClientCertificateHash(expected)) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + err := tester.Events(ctx) + require.NoError(t, err) + + payload := &common.Payload{} + AssertUnmarshal(t, (<-tester.Requests()).GetPayload(), payload) + channelHeader := &common.ChannelHeader{} + AssertUnmarshal(t, payload.GetHeader().GetChannelHeader(), channelHeader) + + require.Equal(t, expected, channelHeader.GetTlsCertHash()) + }) + } +} + +type blockEventsTester interface { + SetConnectError(error) + SetNetworkName(string) + SetGatewayOptions(...ConnectOption) + SetReceiveError(error) + SetResponses(...*peer.DeliverResponse) + Events(context.Context, ...BlockEventsOption) error + Requests() <-chan *common.Envelope + EventsWithCallOptions(context.Context, ...grpc.CallOption) error + CallOptions() <-chan []grpc.CallOption + Receive() (proto.Message, bool) +} + +type baseBlockEventsTest struct { + t *testing.T + connectError error + networkName string + gatewayOptions []ConnectOption + receiveError error + responses []*peer.DeliverResponse + requests chan *common.Envelope + callOptions chan []grpc.CallOption +} + +func (b *baseBlockEventsTest) SetConnectError(err error) { + b.connectError = err +} + +func (b *baseBlockEventsTest) SetNetworkName(channel string) { + b.networkName = channel +} + +func (b *baseBlockEventsTest) SetGatewayOptions(options ...ConnectOption) { + b.gatewayOptions = append(b.gatewayOptions, options...) +} + +func (b *baseBlockEventsTest) SetReceiveError(err error) { + b.receiveError = err +} + +func (b *baseBlockEventsTest) SetResponses(responses ...*peer.DeliverResponse) { + b.responses = append(b.responses, responses...) +} + +func (b *baseBlockEventsTest) Requests() <-chan *common.Envelope { + return b.requests +} + +func (b *baseBlockEventsTest) CallOptions() <-chan []grpc.CallOption { + return b.callOptions +} + +func (b *baseBlockEventsTest) deliverOptions() []newStreamFunction { + var result []newStreamFunction + if b.connectError != nil { + result = append(result, WithNewStreamError(b.connectError)) + } else { + mockStream := NewMockClientStream(b.t) + b.callOptions = make(chan []grpc.CallOption, 1) + result = append(result, CaptureNewStreamOptions(b.callOptions), WithNewStreamResult(mockStream)) + + b.requests = make(chan *common.Envelope, 1) + ExpectSendMsg(mockStream, CaptureSendMsg(b.requests)) + mockStream.EXPECT().CloseSend().Maybe().Return(nil) + + if b.receiveError != nil { + ExpectRecvMsg(mockStream).Return(b.receiveError) + } else if len(b.responses) > 0 { + ExpectRecvMsg(mockStream, WithRecvMsgs(b.responses...)) + } else { + ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) + } + } + + return result +} + +func (b *baseBlockEventsTest) newNetwork(connection grpc.ClientConnInterface) *Network { + options := []ConnectOption{ + WithClientConnection(connection), + } + options = append(options, b.gatewayOptions...) + return AssertNewTestNetwork(b.t, b.networkName, options...) +} + +type blockEventsTest struct { + baseBlockEventsTest + BlockEvents <-chan *common.Block +} + +func NewBlockEventsTest(t *testing.T) *blockEventsTest { + return &blockEventsTest{ + baseBlockEventsTest: baseBlockEventsTest{ + t: t, + }, + } +} + +func (b *blockEventsTest) Events(ctx context.Context, options ...BlockEventsOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliver(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + events, err := network.BlockEvents(ctx, options...) + + b.BlockEvents = events + + return err +} + +func (b *blockEventsTest) EventsWithCallOptions(ctx context.Context, options ...grpc.CallOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliver(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + request, err := network.NewBlockEventsRequest() + require.NoError(b.t, err, "NewBlockEventsRequest") + + events, err := request.Events(ctx, options...) + + b.BlockEvents = events + + return err +} + +func (b *blockEventsTest) Receive() (proto.Message, bool) { + event, ok := <-b.BlockEvents + return event, ok +} + +type filteredBlockEventsTest struct { + baseBlockEventsTest + FilteredBlockEvents <-chan *peer.FilteredBlock +} + +func NewFilteredBlockEventsTest(t *testing.T) *filteredBlockEventsTest { + return &filteredBlockEventsTest{ + baseBlockEventsTest: baseBlockEventsTest{ + t: t, + }, + } +} + +func (b *filteredBlockEventsTest) Events(ctx context.Context, options ...BlockEventsOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliverFiltered(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + events, err := network.FilteredBlockEvents(ctx, options...) + + b.FilteredBlockEvents = events + + return err +} + +func (b *filteredBlockEventsTest) EventsWithCallOptions(ctx context.Context, options ...grpc.CallOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliverFiltered(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + request, err := network.NewFilteredBlockEventsRequest() + require.NoError(b.t, err, "NewFilteredBlockEventsRequest") + + events, err := request.Events(ctx, options...) + + b.FilteredBlockEvents = events + + return err +} + +func (b *filteredBlockEventsTest) Receive() (proto.Message, bool) { + event, ok := <-b.FilteredBlockEvents + return event, ok +} + +type blockAndPrivateDataEventsTest struct { + baseBlockEventsTest + BlocksAndPrivateData <-chan *peer.BlockAndPrivateData +} + +func NewBlockAndPrivateDataEventsTest(t *testing.T) *blockAndPrivateDataEventsTest { + return &blockAndPrivateDataEventsTest{ + baseBlockEventsTest: baseBlockEventsTest{ + t: t, + }, + } +} + +func (b *blockAndPrivateDataEventsTest) Events(ctx context.Context, options ...BlockEventsOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliverWithPrivateData(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + events, err := network.BlockAndPrivateDataEvents(ctx, options...) + + b.BlocksAndPrivateData = events + + return err +} + +func (b *blockAndPrivateDataEventsTest) EventsWithCallOptions(ctx context.Context, options ...grpc.CallOption) error { + mockConnection := NewMockClientConnInterface(b.t) + ExpectDeliverWithPrivateData(mockConnection, b.deliverOptions()...) + + network := b.newNetwork(mockConnection) + request, err := network.NewBlockAndPrivateDataEventsRequest() + require.NoError(b.t, err, "NewBlockAndPrivateDataEventsRequest") + + events, err := request.Events(ctx, options...) + + b.BlocksAndPrivateData = events + + return err +} + +func (b *blockAndPrivateDataEventsTest) Receive() (proto.Message, bool) { + event, ok := <-b.BlocksAndPrivateData + return event, ok +} diff --git a/pkg/client/blockeventsfiltered_test.go b/pkg/client/blockeventsfiltered_test.go index 46aa3e2b4..07a97441f 100644 --- a/pkg/client/blockeventsfiltered_test.go +++ b/pkg/client/blockeventsfiltered_test.go @@ -5,185 +5,14 @@ package client import ( "context" - "errors" - "io" "testing" "github.com/hyperledger/fabric-protos-go-apiv2/common" - "github.com/hyperledger/fabric-protos-go-apiv2/orderer" "github.com/hyperledger/fabric-protos-go-apiv2/peer" "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) func TestFilteredBlockEvents(t *testing.T) { - t.Run("Returns connect error", func(t *testing.T) { - expected := NewStatusError(t, codes.Aborted, "BLOCK_EVENTS_ERROR") - - mockConnection := NewMockClientConnInterface(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamError(expected)) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.FilteredBlockEvents(ctx) - - require.Equal(t, status.Code(expected), status.Code(err), "status code") - require.ErrorIs(t, err, expected, "error type: %T", err) - require.ErrorContains(t, err, expected.Error(), "message") - }) - - for testName, testCase := range map[string]struct { - options []BlockEventsOption - expected *orderer.SeekInfo - }{ - "Sends valid request with default start position": { - options: nil, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Sends valid request with specified start block number": { - options: []BlockEventsOption{ - WithStartBlock(418), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses specified start block instead of unset checkpoint": { - options: []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointBlock(500) - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 501, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block zero with set transaction ID instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointTransaction(0, "transctionId") - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 0, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses default start position with unset checkpoint and no start block": { - options: []BlockEventsOption{ - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - } { - t.Run(testName, func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamResult(mockStream)) - - messages := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(messages)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.FilteredBlockEvents(ctx, testCase.options...) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-messages).GetPayload(), payload) - AssertValidBlockEventRequestHeader(t, payload, network.Name()) - actual := &orderer.SeekInfo{} - AssertUnmarshal(t, payload.GetData(), actual) - - AssertProtoEqual(t, testCase.expected, actual) - }) - } - - t.Run("Closes event channel on receive error", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Return(errors.New("fake")) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.FilteredBlockEvents(ctx, WithStartBlock(418)) - require.NoError(t, err) - - actual, ok := <-receive - - require.False(t, ok, "Expected event listening to be cancelled, got %v", actual) - }) - t.Run("Receives events", func(t *testing.T) { expected := []*peer.FilteredBlock{ { @@ -206,13 +35,6 @@ func TestFilteredBlockEvents(t *testing.T) { }, } - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - var responses []*peer.DeliverResponse for _, block := range expected { responses = append(responses, &peer.DeliverResponse{ @@ -221,29 +43,23 @@ func TestFilteredBlockEvents(t *testing.T) { }, }) } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewFilteredBlockEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.FilteredBlockEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) for _, event := range expected { - actual := <-receive + actual := <-tester.FilteredBlockEvents AssertProtoEqual(t, event, actual) } }) t.Run("Closes event channel on non-block message", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - block := &peer.FilteredBlock{ ChannelId: "NETWORK", Number: 1, @@ -270,13 +86,14 @@ func TestFilteredBlockEvents(t *testing.T) { }, }, } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewFilteredBlockEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.FilteredBlockEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) expected := []*peer.FilteredBlock{ @@ -285,60 +102,8 @@ func TestFilteredBlockEvents(t *testing.T) { nil, } for _, event := range expected { - actual := <-receive + actual := <-tester.FilteredBlockEvents AssertProtoEqual(t, event, actual) } }) - - t.Run("Uses specified gRPC call options", func(t *testing.T) { - expected := grpc.WaitForReady(true) - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - options := make(chan []grpc.CallOption, 1) - ExpectDeliverFiltered(mockConnection, CaptureNewStreamOptions(options), WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - request, err := network.NewFilteredBlockEventsRequest() - require.NoError(t, err, "NewFilteredBlockEventsRequest") - - _, err = request.Events(ctx, expected) - require.NoError(t, err, "Events") - - require.Contains(t, (<-options), expected, "CallOptions") - }) - - t.Run("Sends request with TLS client certificate hash", func(t *testing.T) { - expected := []byte("TLS_CLIENT_CERTIFICATE_HASH") - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverFiltered(mockConnection, WithNewStreamResult(mockStream)) - - requests := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(requests)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection), WithTLSClientCertificateHash(expected)) - _, err := network.FilteredBlockEvents(ctx) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-requests).GetPayload(), payload) - channelHeader := &common.ChannelHeader{} - AssertUnmarshal(t, payload.GetHeader().GetChannelHeader(), channelHeader) - - require.Equal(t, expected, channelHeader.GetTlsCertHash()) - }) } diff --git a/pkg/client/blockeventswithprivatedata_test.go b/pkg/client/blockeventswithprivatedata_test.go index c3970fca3..1f968f959 100644 --- a/pkg/client/blockeventswithprivatedata_test.go +++ b/pkg/client/blockeventswithprivatedata_test.go @@ -5,186 +5,15 @@ package client import ( "context" - "errors" - "io" "testing" "github.com/hyperledger/fabric-protos-go-apiv2/common" "github.com/hyperledger/fabric-protos-go-apiv2/ledger/rwset" - "github.com/hyperledger/fabric-protos-go-apiv2/orderer" "github.com/hyperledger/fabric-protos-go-apiv2/peer" "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) func TestBlockAndPrivateDataEvents(t *testing.T) { - t.Run("Returns connect error", func(t *testing.T) { - expected := NewStatusError(t, codes.Aborted, "BLOCK_EVENTS_ERROR") - - mockConnection := NewMockClientConnInterface(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamError(expected)) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.BlockAndPrivateDataEvents(ctx) - - require.Equal(t, status.Code(expected), status.Code(err), "status code") - require.ErrorIs(t, err, expected, "error type: %T", err) - require.ErrorContains(t, err, expected.Error(), "message") - }) - - for testName, testCase := range map[string]struct { - options []BlockEventsOption - expected *orderer.SeekInfo - }{ - "Sends valid request with default start position": { - options: nil, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Sends valid request with specified start block number": { - options: []BlockEventsOption{ - WithStartBlock(418), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses specified start block instead of unset checkpoint": { - options: []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 418, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointBlock(500) - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 501, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses checkpoint block zero with set transaction ID instead of specified start block": { - options: func() []BlockEventsOption { - checkpointer := new(InMemoryCheckpointer) - checkpointer.CheckpointTransaction(0, "transctionId") - return []BlockEventsOption{ - WithStartBlock(418), - WithCheckpoint(checkpointer), - } - }(), - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_Specified{ - Specified: &orderer.SeekSpecified{ - Number: 0, - }, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - "Uses default start position with unset checkpoint and no start block": { - options: []BlockEventsOption{ - WithCheckpoint(new(InMemoryCheckpointer)), - }, - expected: &orderer.SeekInfo{ - Start: &orderer.SeekPosition{ - Type: &orderer.SeekPosition_NextCommit{ - NextCommit: &orderer.SeekNextCommit{}, - }, - }, - Stop: seekLargestBlockNumber(), - }, - }, - } { - t.Run(testName, func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamResult(mockStream)) - - messages := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(messages)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - _, err := network.BlockAndPrivateDataEvents(ctx, testCase.options...) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-messages).GetPayload(), payload) - AssertValidBlockEventRequestHeader(t, payload, network.Name()) - actual := &orderer.SeekInfo{} - AssertUnmarshal(t, payload.GetData(), actual) - - AssertProtoEqual(t, testCase.expected, actual) - }) - } - - t.Run("Closes event channel on receive error", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Return(errors.New("fake")) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockAndPrivateDataEvents(ctx, WithStartBlock(418)) - require.NoError(t, err) - - actual, ok := <-receive - - require.False(t, ok, "Expected event listening to be cancelled, got %v", actual) - }) - t.Run("Receives events", func(t *testing.T) { expected := []*peer.BlockAndPrivateData{ { @@ -225,13 +54,6 @@ func TestBlockAndPrivateDataEvents(t *testing.T) { }, } - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - var responses []*peer.DeliverResponse for _, block := range expected { responses = append(responses, &peer.DeliverResponse{ @@ -240,29 +62,23 @@ func TestBlockAndPrivateDataEvents(t *testing.T) { }, }) } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewBlockAndPrivateDataEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockAndPrivateDataEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) for _, event := range expected { - actual := <-receive + actual := <-tester.BlocksAndPrivateData AssertProtoEqual(t, event, actual) } }) t.Run("Closes event channel on non-block message", func(t *testing.T) { - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - block := &peer.BlockAndPrivateData{ Block: &common.Block{ Header: &common.BlockHeader{ @@ -298,13 +114,14 @@ func TestBlockAndPrivateDataEvents(t *testing.T) { }, }, } - ExpectRecvMsg(mockStream, WithRecvMsgs(responses...)) + + tester := NewBlockAndPrivateDataEventsTest(t) + tester.SetResponses(responses...) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - receive, err := network.BlockAndPrivateDataEvents(ctx) + err := tester.Events(ctx) require.NoError(t, err) expected := []*peer.BlockAndPrivateData{ @@ -313,60 +130,8 @@ func TestBlockAndPrivateDataEvents(t *testing.T) { nil, } for _, event := range expected { - actual := <-receive + actual := <-tester.BlocksAndPrivateData AssertProtoEqual(t, event, actual) } }) - - t.Run("Uses specified gRPC call options", func(t *testing.T) { - expected := grpc.WaitForReady(true) - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - options := make(chan []grpc.CallOption, 1) - ExpectDeliverWithPrivateData(mockConnection, CaptureNewStreamOptions(options), WithNewStreamResult(mockStream)) - - ExpectSendMsg(mockStream) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection)) - request, err := network.NewBlockAndPrivateDataEventsRequest() - require.NoError(t, err, "NewBlockAndPrivateDataEventsRequest") - - _, err = request.Events(ctx, expected) - require.NoError(t, err, "Events") - - require.Contains(t, (<-options), expected, "CallOptions") - }) - - t.Run("Sends request with TLS client certificate hash", func(t *testing.T) { - expected := []byte("TLS_CLIENT_CERTIFICATE_HASH") - - mockConnection := NewMockClientConnInterface(t) - mockStream := NewMockClientStream(t) - ExpectDeliverWithPrivateData(mockConnection, WithNewStreamResult(mockStream)) - - requests := make(chan *common.Envelope, 1) - ExpectSendMsg(mockStream, CaptureSendMsg(requests)) - mockStream.EXPECT().CloseSend().Maybe().Return(nil) - ExpectRecvMsg(mockStream).Maybe().Return(io.EOF) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - network := AssertNewTestNetwork(t, "NETWORK", WithClientConnection(mockConnection), WithTLSClientCertificateHash(expected)) - _, err := network.BlockAndPrivateDataEvents(ctx) - require.NoError(t, err) - - payload := &common.Payload{} - AssertUnmarshal(t, (<-requests).GetPayload(), payload) - channelHeader := &common.ChannelHeader{} - AssertUnmarshal(t, payload.GetHeader().GetChannelHeader(), channelHeader) - - require.Equal(t, expected, channelHeader.GetTlsCertHash()) - }) } diff --git a/pkg/client/protobuf_test.go b/pkg/client/protobuf_test.go index 8a720d73e..dc02d536e 100644 --- a/pkg/client/protobuf_test.go +++ b/pkg/client/protobuf_test.go @@ -40,6 +40,10 @@ func AssertProtoEqual(t *testing.T, expected protoreflect.ProtoMessage, actual p } func formatProto(message proto.Message) string { + if message == nil { + return fmt.Sprintf("%T", message) + } + marshal := prototext.MarshalOptions{ Multiline: true, Indent: "\t",