go_study/fabric-main/orderer/common/server/server_test.go

152 lines
3.3 KiB
Go

/*
Copyright IBM Corp. 2017 All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package server
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"
"github.com/golang/protobuf/proto"
cb "github.com/hyperledger/fabric-protos-go/common"
ab "github.com/hyperledger/fabric-protos-go/orderer"
localconfig "github.com/hyperledger/fabric/orderer/common/localconfig"
"github.com/hyperledger/fabric/orderer/common/multichannel"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
)
func TestBroadcastNoPanic(t *testing.T) {
// Defer recovers from the panic
_ = (&server{}).Broadcast(nil)
}
func TestDeliverNoPanic(t *testing.T) {
// Defer recovers from the panic
_ = (&server{}).Deliver(nil)
}
type recvr interface {
Recv() (*cb.Envelope, error)
}
type mockBroadcastSrv struct {
grpc.ServerStream
msg *cb.Envelope
err error
}
func (mbs *mockBroadcastSrv) Recv() (*cb.Envelope, error) {
return mbs.msg, mbs.err
}
func (mbs *mockBroadcastSrv) Send(br *ab.BroadcastResponse) error {
panic("Unimplemented")
}
type mockDeliverSrv struct {
grpc.ServerStream
msg *cb.Envelope
err error
}
func (mds *mockDeliverSrv) CreateStatusReply(status cb.Status) proto.Message {
return &ab.DeliverResponse{
Type: &ab.DeliverResponse_Status{Status: status},
}
}
func (mds *mockDeliverSrv) CreateBlockReply(block *cb.Block) proto.Message {
return &ab.DeliverResponse{
Type: &ab.DeliverResponse_Block{Block: block},
}
}
func (mds *mockDeliverSrv) Recv() (*cb.Envelope, error) {
return mds.msg, mds.err
}
func (mds *mockDeliverSrv) Send(br *ab.DeliverResponse) error {
panic("Unimplemented")
}
func testMsgTrace(handler func(dir string, msg *cb.Envelope) recvr, t *testing.T) {
dir := t.TempDir()
msg := &cb.Envelope{Payload: []byte("somedata")}
r := handler(dir, msg)
rMsg, err := r.Recv()
require.Equal(t, msg, rMsg)
require.Nil(t, err)
var fileData []byte
for i := 0; i < 100; i++ {
// Writing the trace file is deliberately non-blocking, wait up to a second, checking every 10 ms to see if the file now exists.
time.Sleep(10 * time.Millisecond)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
require.Nil(t, err)
if path == dir {
return nil
}
require.Nil(t, fileData, "Should only be one file")
fileData, err = ioutil.ReadFile(path)
require.Nil(t, err)
return nil
})
if fileData != nil {
break
}
}
require.Equal(t, protoutil.MarshalOrPanic(msg), fileData)
}
func TestBroadcastMsgTrace(t *testing.T) {
testMsgTrace(func(dir string, msg *cb.Envelope) recvr {
return &broadcastMsgTracer{
AtomicBroadcast_BroadcastServer: &mockBroadcastSrv{
msg: msg,
},
msgTracer: msgTracer{
debug: &localconfig.Debug{
BroadcastTraceDir: dir,
},
function: "Broadcast",
},
}
}, t)
}
func TestDeliverMsgTrace(t *testing.T) {
testMsgTrace(func(dir string, msg *cb.Envelope) recvr {
return &deliverMsgTracer{
Receiver: &mockDeliverSrv{
msg: msg,
},
msgTracer: msgTracer{
debug: &localconfig.Debug{
DeliverTraceDir: dir,
},
function: "Deliver",
},
}
}, t)
}
func TestDeliverNoChannel(t *testing.T) {
r := &multichannel.Registrar{}
ds := &deliverSupport{Registrar: r}
chain := ds.GetChain("mychannel")
require.Nil(t, chain)
require.True(t, chain == nil)
}