github.com/true-sqn/fabric@v2.1.1+incompatible/internal/peer/channel/create_test.go (about)

     1  /*
     2  Copyright Digital Asset Holdings, LLC All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package channel
     8  
     9  import (
    10  	"bytes"
    11  	"errors"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"net"
    15  	"os"
    16  	"path/filepath"
    17  	"regexp"
    18  	"sync"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/golang/protobuf/proto"
    23  	cb "github.com/hyperledger/fabric-protos-go/common"
    24  	"github.com/hyperledger/fabric-protos-go/orderer"
    25  	"github.com/hyperledger/fabric/core/config/configtest"
    26  	"github.com/hyperledger/fabric/internal/peer/common"
    27  	"github.com/hyperledger/fabric/internal/peer/common/mock"
    28  	"github.com/hyperledger/fabric/internal/pkg/identity"
    29  	msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
    30  	"github.com/hyperledger/fabric/protoutil"
    31  	"github.com/spf13/viper"
    32  	"github.com/stretchr/testify/assert"
    33  	"google.golang.org/grpc"
    34  )
    35  
    36  //go:generate counterfeiter -o mock/signer_serializer.go --fake-name SignerSerializer . signerSerializer
    37  
    38  type signerSerializer interface {
    39  	identity.SignerSerializer
    40  }
    41  
    42  type timeoutOrderer struct {
    43  	counter int
    44  	net.Listener
    45  	*grpc.Server
    46  	nextExpectedSeek uint64
    47  	t                *testing.T
    48  	blockChannel     chan uint64
    49  }
    50  
    51  func newOrderer(port int, t *testing.T) *timeoutOrderer {
    52  	srv := grpc.NewServer()
    53  	lsnr, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
    54  	if err != nil {
    55  		panic(err)
    56  	}
    57  	o := &timeoutOrderer{Server: srv,
    58  		Listener:         lsnr,
    59  		t:                t,
    60  		nextExpectedSeek: uint64(1),
    61  		blockChannel:     make(chan uint64, 1),
    62  		counter:          int(1),
    63  	}
    64  	orderer.RegisterAtomicBroadcastServer(srv, o)
    65  	go srv.Serve(lsnr)
    66  	return o
    67  }
    68  
    69  func (o *timeoutOrderer) Shutdown() {
    70  	o.Server.Stop()
    71  	o.Listener.Close()
    72  }
    73  
    74  func (*timeoutOrderer) Broadcast(orderer.AtomicBroadcast_BroadcastServer) error {
    75  	panic("Should not have been called")
    76  }
    77  
    78  func (o *timeoutOrderer) SendBlock(seq uint64) {
    79  	o.blockChannel <- seq
    80  }
    81  
    82  func (o *timeoutOrderer) Deliver(stream orderer.AtomicBroadcast_DeliverServer) error {
    83  	o.timeoutIncrement()
    84  	if o.counter > 5 {
    85  		o.sendBlock(stream, 0)
    86  	}
    87  	return nil
    88  }
    89  
    90  func (o *timeoutOrderer) sendBlock(stream orderer.AtomicBroadcast_DeliverServer, seq uint64) {
    91  	block := &cb.Block{
    92  		Header: &cb.BlockHeader{
    93  			Number: seq,
    94  		},
    95  	}
    96  	stream.Send(&orderer.DeliverResponse{
    97  		Type: &orderer.DeliverResponse_Block{Block: block},
    98  	})
    99  }
   100  
   101  func (o *timeoutOrderer) timeoutIncrement() {
   102  	o.counter++
   103  }
   104  
   105  var once sync.Once
   106  
   107  /// mock deliver client for UT
   108  type mockDeliverClient struct {
   109  	err error
   110  }
   111  
   112  func (m *mockDeliverClient) readBlock() (*cb.Block, error) {
   113  	if m.err != nil {
   114  		return nil, m.err
   115  	}
   116  	return &cb.Block{}, nil
   117  }
   118  
   119  func (m *mockDeliverClient) GetSpecifiedBlock(num uint64) (*cb.Block, error) {
   120  	return m.readBlock()
   121  }
   122  
   123  func (m *mockDeliverClient) GetOldestBlock() (*cb.Block, error) {
   124  	return m.readBlock()
   125  }
   126  
   127  func (m *mockDeliverClient) GetNewestBlock() (*cb.Block, error) {
   128  	return m.readBlock()
   129  }
   130  
   131  func (m *mockDeliverClient) Close() error {
   132  	return nil
   133  }
   134  
   135  // InitMSP init MSP
   136  func InitMSP() {
   137  	once.Do(initMSP)
   138  }
   139  
   140  func initMSP() {
   141  	err := msptesttools.LoadMSPSetupForTesting()
   142  	if err != nil {
   143  		panic(fmt.Errorf("Fatal error when reading MSP config: err %s", err))
   144  	}
   145  }
   146  
   147  func mockBroadcastClientFactory() (common.BroadcastClient, error) {
   148  	return common.GetMockBroadcastClient(nil), nil
   149  }
   150  
   151  func TestCreateChain(t *testing.T) {
   152  	defer resetFlags()
   153  
   154  	InitMSP()
   155  	cleanup := configtest.SetDevFabricConfigPath(t)
   156  	defer cleanup()
   157  
   158  	mockchain := "mockchain"
   159  
   160  	defer os.Remove(mockchain + ".block")
   161  
   162  	signer, err := common.GetDefaultSigner()
   163  	if err != nil {
   164  		t.Fatalf("Get default signer error: %v", err)
   165  	}
   166  
   167  	mockCF := &ChannelCmdFactory{
   168  		BroadcastFactory: mockBroadcastClientFactory,
   169  		Signer:           signer,
   170  		DeliverClient:    &mockDeliverClient{},
   171  	}
   172  
   173  	cmd := createCmd(mockCF)
   174  
   175  	AddFlags(cmd)
   176  
   177  	args := []string{"-c", mockchain, "-o", "localhost:7050"}
   178  	cmd.SetArgs(args)
   179  
   180  	if err := cmd.Execute(); err != nil {
   181  		t.Fail()
   182  		t.Errorf("expected create command to succeed")
   183  	}
   184  
   185  	filename := mockchain + ".block"
   186  	if _, err := os.Stat(filename); err != nil {
   187  		t.Fail()
   188  		t.Errorf("expected %s to exist", filename)
   189  	}
   190  }
   191  
   192  func TestCreateChainWithOutputBlock(t *testing.T) {
   193  	defer resetFlags()
   194  
   195  	InitMSP()
   196  	cleanup := configtest.SetDevFabricConfigPath(t)
   197  	defer cleanup()
   198  
   199  	mockchain := "mockchain"
   200  
   201  	signer, err := common.GetDefaultSigner()
   202  	if err != nil {
   203  		t.Fatalf("Get default signer error: %v", err)
   204  	}
   205  
   206  	mockCF := &ChannelCmdFactory{
   207  		BroadcastFactory: mockBroadcastClientFactory,
   208  		Signer:           signer,
   209  		DeliverClient:    &mockDeliverClient{},
   210  	}
   211  
   212  	cmd := createCmd(mockCF)
   213  	AddFlags(cmd)
   214  
   215  	tempDir, err := ioutil.TempDir("", "create-output")
   216  	if err != nil {
   217  		t.Fatalf("failed to create temporary directory")
   218  	}
   219  	defer os.RemoveAll(tempDir)
   220  
   221  	outputBlockPath := filepath.Join(tempDir, "output.block")
   222  	args := []string{"-c", mockchain, "-o", "localhost:7050", "--outputBlock", outputBlockPath}
   223  	cmd.SetArgs(args)
   224  	defer func() { outputBlock = "" }()
   225  
   226  	err = cmd.Execute()
   227  	assert.NoError(t, err, "execute should succeed")
   228  
   229  	_, err = os.Stat(outputBlockPath)
   230  	assert.NoErrorf(t, err, "expected %s to exist", outputBlockPath)
   231  }
   232  
   233  func TestCreateChainWithDefaultAnchorPeers(t *testing.T) {
   234  	defer resetFlags()
   235  
   236  	InitMSP()
   237  	cleanup := configtest.SetDevFabricConfigPath(t)
   238  	defer cleanup()
   239  
   240  	mockchain := "mockchain"
   241  
   242  	defer os.Remove(mockchain + ".block")
   243  
   244  	signer, err := common.GetDefaultSigner()
   245  	if err != nil {
   246  		t.Fatalf("Get default signer error: %v", err)
   247  	}
   248  
   249  	mockCF := &ChannelCmdFactory{
   250  		BroadcastFactory: mockBroadcastClientFactory,
   251  		Signer:           signer,
   252  		DeliverClient:    &mockDeliverClient{},
   253  	}
   254  
   255  	cmd := createCmd(mockCF)
   256  	AddFlags(cmd)
   257  	args := []string{"-c", mockchain, "-o", "localhost:7050"}
   258  	cmd.SetArgs(args)
   259  
   260  	if err := cmd.Execute(); err != nil {
   261  		t.Fail()
   262  		t.Errorf("expected create command to succeed")
   263  	}
   264  }
   265  
   266  func TestCreateChainWithWaitSuccess(t *testing.T) {
   267  	defer resetFlags()
   268  
   269  	InitMSP()
   270  	cleanup := configtest.SetDevFabricConfigPath(t)
   271  	defer cleanup()
   272  
   273  	mockchain := "mockchain"
   274  
   275  	signer, err := common.GetDefaultSigner()
   276  	if err != nil {
   277  		t.Fatalf("Get default signer error: %v", err)
   278  	}
   279  
   280  	mockCF := &ChannelCmdFactory{
   281  		BroadcastFactory: mockBroadcastClientFactory,
   282  		Signer:           signer,
   283  		DeliverClient:    &mockDeliverClient{err: nil},
   284  	}
   285  	fakeOrderer := newOrderer(8101, t)
   286  	defer fakeOrderer.Shutdown()
   287  
   288  	cmd := createCmd(mockCF)
   289  	AddFlags(cmd)
   290  	args := []string{"-c", mockchain, "-o", "localhost:8101", "-t", "10s"}
   291  	cmd.SetArgs(args)
   292  
   293  	if err := cmd.Execute(); err != nil {
   294  		t.Fail()
   295  		t.Errorf("expected create command to succeed")
   296  	}
   297  }
   298  
   299  func TestCreateChainWithTimeoutErr(t *testing.T) {
   300  	defer viper.Reset()
   301  	defer resetFlags()
   302  
   303  	InitMSP()
   304  	cleanup := configtest.SetDevFabricConfigPath(t)
   305  	defer cleanup()
   306  
   307  	mockchain := "mockchain"
   308  
   309  	signer, err := common.GetDefaultSigner()
   310  	if err != nil {
   311  		t.Fatalf("Get default signer error: %v", err)
   312  	}
   313  
   314  	mockCF := &ChannelCmdFactory{
   315  		BroadcastFactory: mockBroadcastClientFactory,
   316  		Signer:           signer,
   317  		DeliverClient:    &mockDeliverClient{err: errors.New("bobsled")},
   318  	}
   319  	fakeOrderer := newOrderer(8102, t)
   320  	defer fakeOrderer.Shutdown()
   321  
   322  	// failure - connects to orderer but times out waiting for channel to
   323  	// be created
   324  	cmd := createCmd(mockCF)
   325  	AddFlags(cmd)
   326  	channelCmd.AddCommand(cmd)
   327  	args := []string{"create", "-c", mockchain, "-o", "localhost:8102", "-t", "10ms", "--connTimeout", "1s"}
   328  	channelCmd.SetArgs(args)
   329  
   330  	if err := channelCmd.Execute(); err == nil {
   331  		t.Error("expected create chain to fail with deliver error")
   332  	} else {
   333  		assert.Contains(t, err.Error(), "timeout waiting for channel creation")
   334  	}
   335  
   336  	// failure - point to bad port and time out connecting to orderer
   337  	args = []string{"create", "-c", mockchain, "-o", "localhost:0", "-t", "1s", "--connTimeout", "10ms"}
   338  	channelCmd.SetArgs(args)
   339  
   340  	if err := channelCmd.Execute(); err == nil {
   341  		t.Error("expected create chain to fail with deliver error")
   342  	} else {
   343  		assert.Contains(t, err.Error(), "failed connecting")
   344  	}
   345  }
   346  
   347  func TestCreateChainBCFail(t *testing.T) {
   348  	defer resetFlags()
   349  
   350  	InitMSP()
   351  	cleanup := configtest.SetDevFabricConfigPath(t)
   352  	defer cleanup()
   353  
   354  	mockchain := "mockchain"
   355  
   356  	defer os.Remove(mockchain + ".block")
   357  
   358  	signer, err := common.GetDefaultSigner()
   359  	if err != nil {
   360  		t.Fatalf("Get default signer error: %v", err)
   361  	}
   362  
   363  	sendErr := errors.New("luge")
   364  	mockCF := &ChannelCmdFactory{
   365  		BroadcastFactory: func() (common.BroadcastClient, error) {
   366  			return common.GetMockBroadcastClient(sendErr), nil
   367  		},
   368  		Signer:        signer,
   369  		DeliverClient: &mockDeliverClient{},
   370  	}
   371  
   372  	cmd := createCmd(mockCF)
   373  	AddFlags(cmd)
   374  	args := []string{"-c", mockchain, "-o", "localhost:7050"}
   375  	cmd.SetArgs(args)
   376  
   377  	expectedErrMsg := sendErr.Error()
   378  	if err := cmd.Execute(); err == nil {
   379  		t.Error("expected create chain to fail with broadcast error")
   380  	} else {
   381  		if err.Error() != expectedErrMsg {
   382  			t.Errorf("Run create chain get unexpected error: %s(expected %s)", err.Error(), expectedErrMsg)
   383  		}
   384  	}
   385  }
   386  
   387  func TestCreateChainDeliverFail(t *testing.T) {
   388  	defer resetFlags()
   389  
   390  	InitMSP()
   391  	cleanup := configtest.SetDevFabricConfigPath(t)
   392  	defer cleanup()
   393  
   394  	mockchain := "mockchain"
   395  
   396  	defer os.Remove(mockchain + ".block")
   397  
   398  	signer, err := common.GetDefaultSigner()
   399  	if err != nil {
   400  		t.Fatalf("Get default signer error: %v", err)
   401  	}
   402  
   403  	sendErr := fmt.Errorf("skeleton")
   404  	mockCF := &ChannelCmdFactory{
   405  		BroadcastFactory: func() (common.BroadcastClient, error) {
   406  			return common.GetMockBroadcastClient(sendErr), nil
   407  		},
   408  		Signer:        signer,
   409  		DeliverClient: &mockDeliverClient{err: sendErr},
   410  	}
   411  	cmd := createCmd(mockCF)
   412  	AddFlags(cmd)
   413  	args := []string{"-c", mockchain, "-o", "localhost:7050"}
   414  	cmd.SetArgs(args)
   415  
   416  	expectedErrMsg := sendErr.Error()
   417  	if err := cmd.Execute(); err == nil {
   418  		t.Errorf("expected create chain to fail with deliver error")
   419  	} else {
   420  		if err.Error() != expectedErrMsg {
   421  			t.Errorf("Run create chain get unexpected error: %s(expected %s)", err.Error(), expectedErrMsg)
   422  		}
   423  	}
   424  }
   425  
   426  func createTxFile(filename string, typ cb.HeaderType, channelID string) (*cb.Envelope, error) {
   427  	ch := &cb.ChannelHeader{Type: int32(typ), ChannelId: channelID}
   428  	data, err := proto.Marshal(ch)
   429  	if err != nil {
   430  		return nil, err
   431  	}
   432  
   433  	p := &cb.Payload{Header: &cb.Header{ChannelHeader: data}}
   434  	data, err = proto.Marshal(p)
   435  	if err != nil {
   436  		return nil, err
   437  	}
   438  
   439  	env := &cb.Envelope{Payload: data}
   440  	data, err = proto.Marshal(env)
   441  	if err != nil {
   442  		return nil, err
   443  	}
   444  
   445  	if err = ioutil.WriteFile(filename, data, 0644); err != nil {
   446  		return nil, err
   447  	}
   448  
   449  	return env, nil
   450  }
   451  
   452  func TestCreateChainFromTx(t *testing.T) {
   453  	defer resetFlags()
   454  	InitMSP()
   455  	cleanup := configtest.SetDevFabricConfigPath(t)
   456  	defer cleanup()
   457  
   458  	mockchannel := "mockchannel"
   459  	dir, err := ioutil.TempDir("", "createtestfromtx-")
   460  	if err != nil {
   461  		t.Fatalf("couldn't create temp dir")
   462  	}
   463  	defer os.RemoveAll(dir) // clean up
   464  
   465  	//this could be created by the create command
   466  	defer os.Remove(mockchannel + ".block")
   467  
   468  	file := filepath.Join(dir, mockchannel)
   469  
   470  	signer, err := common.GetDefaultSigner()
   471  	if err != nil {
   472  		t.Fatalf("Get default signer error: %v", err)
   473  	}
   474  	mockCF := &ChannelCmdFactory{
   475  		BroadcastFactory: mockBroadcastClientFactory,
   476  		Signer:           signer,
   477  		DeliverClient:    &mockDeliverClient{},
   478  	}
   479  
   480  	cmd := createCmd(mockCF)
   481  	AddFlags(cmd)
   482  
   483  	// Error case 0
   484  	args := []string{"-c", "", "-f", file, "-o", "localhost:7050"}
   485  	cmd.SetArgs(args)
   486  	err = cmd.Execute()
   487  	assert.Error(t, err, "Create command should have failed because channel ID is not specified")
   488  	assert.Contains(t, err.Error(), "must supply channel ID")
   489  
   490  	// Error case 1
   491  	args = []string{"-c", mockchannel, "-f", file, "-o", "localhost:7050"}
   492  	cmd.SetArgs(args)
   493  	err = cmd.Execute()
   494  	assert.Error(t, err, "Create command should have failed because tx file does not exist")
   495  	var msgExpr = regexp.MustCompile(`channel create configuration tx file not found.*no such file or directory`)
   496  	assert.True(t, msgExpr.MatchString(err.Error()))
   497  
   498  	// Success case: -f option is empty
   499  	args = []string{"-c", mockchannel, "-f", "", "-o", "localhost:7050"}
   500  	cmd.SetArgs(args)
   501  	err = cmd.Execute()
   502  	assert.NoError(t, err)
   503  
   504  	// Success case
   505  	args = []string{"-c", mockchannel, "-f", file, "-o", "localhost:7050"}
   506  	cmd.SetArgs(args)
   507  	_, err = createTxFile(file, cb.HeaderType_CONFIG_UPDATE, mockchannel)
   508  	assert.NoError(t, err, "Couldn't create tx file")
   509  	err = cmd.Execute()
   510  	assert.NoError(t, err)
   511  }
   512  
   513  func TestCreateChainInvalidTx(t *testing.T) {
   514  	defer resetFlags()
   515  
   516  	InitMSP()
   517  	cleanup := configtest.SetDevFabricConfigPath(t)
   518  	defer cleanup()
   519  
   520  	mockchannel := "mockchannel"
   521  
   522  	dir, err := ioutil.TempDir("", "createinvaltest-")
   523  	if err != nil {
   524  		t.Fatalf("couldn't create temp dir")
   525  	}
   526  
   527  	defer os.RemoveAll(dir) // clean up
   528  
   529  	//this is created by create command
   530  	defer os.Remove(mockchannel + ".block")
   531  
   532  	file := filepath.Join(dir, mockchannel)
   533  
   534  	signer, err := common.GetDefaultSigner()
   535  	if err != nil {
   536  		t.Fatalf("Get default signer error: %v", err)
   537  	}
   538  
   539  	mockCF := &ChannelCmdFactory{
   540  		BroadcastFactory: mockBroadcastClientFactory,
   541  		Signer:           signer,
   542  		DeliverClient:    &mockDeliverClient{},
   543  	}
   544  
   545  	cmd := createCmd(mockCF)
   546  
   547  	AddFlags(cmd)
   548  
   549  	args := []string{"-c", mockchannel, "-f", file, "-o", "localhost:7050"}
   550  	cmd.SetArgs(args)
   551  
   552  	//bad type CONFIG
   553  	if _, err = createTxFile(file, cb.HeaderType_CONFIG, mockchannel); err != nil {
   554  		t.Fatalf("couldn't create tx file")
   555  	}
   556  
   557  	defer os.Remove(file)
   558  
   559  	if err = cmd.Execute(); err == nil {
   560  		t.Errorf("expected error")
   561  	} else if _, ok := err.(InvalidCreateTx); !ok {
   562  		t.Errorf("invalid error")
   563  	}
   564  
   565  	//bad channel name - does not match one specified in command
   566  	if _, err = createTxFile(file, cb.HeaderType_CONFIG_UPDATE, "different_channel"); err != nil {
   567  		t.Fatalf("couldn't create tx file")
   568  	}
   569  
   570  	if err = cmd.Execute(); err == nil {
   571  		t.Errorf("expected error")
   572  	} else if _, ok := err.(InvalidCreateTx); !ok {
   573  		t.Errorf("invalid error")
   574  	}
   575  
   576  	//empty channel
   577  	if _, err = createTxFile(file, cb.HeaderType_CONFIG_UPDATE, ""); err != nil {
   578  		t.Fatalf("couldn't create tx file")
   579  	}
   580  
   581  	if err := cmd.Execute(); err == nil {
   582  		t.Errorf("expected error")
   583  	} else if _, ok := err.(InvalidCreateTx); !ok {
   584  		t.Errorf("invalid error")
   585  	}
   586  }
   587  
   588  func TestCreateChainNilCF(t *testing.T) {
   589  	defer viper.Reset()
   590  	defer resetFlags()
   591  
   592  	InitMSP()
   593  	cleanup := configtest.SetDevFabricConfigPath(t)
   594  	defer cleanup()
   595  
   596  	mockchannel := "mockchannel"
   597  	dir, err := ioutil.TempDir("", "createinvaltest-")
   598  	assert.NoError(t, err, "Couldn't create temp dir")
   599  	defer os.RemoveAll(dir) // clean up
   600  
   601  	//this is created by create command
   602  	defer os.Remove(mockchannel + ".block")
   603  	file := filepath.Join(dir, mockchannel)
   604  
   605  	// Error case: grpc error
   606  	viper.Set("orderer.client.connTimeout", 10*time.Millisecond)
   607  	cmd := createCmd(nil)
   608  	AddFlags(cmd)
   609  	args := []string{"-c", mockchannel, "-f", file, "-o", "localhost:7050"}
   610  	cmd.SetArgs(args)
   611  	err = cmd.Execute()
   612  	assert.Error(t, err)
   613  	assert.Contains(t, err.Error(), "failed to create deliver client")
   614  
   615  	// Error case: invalid ordering service endpoint
   616  	args = []string{"-c", mockchannel, "-f", file, "-o", "localhost"}
   617  	cmd.SetArgs(args)
   618  	err = cmd.Execute()
   619  	assert.Error(t, err)
   620  	assert.Contains(t, err.Error(), "ordering service endpoint localhost is not valid or missing")
   621  
   622  	// Error case: invalid ca file
   623  	defer os.RemoveAll(dir) // clean up
   624  	channelCmd.AddCommand(cmd)
   625  	args = []string{"create", "-c", mockchannel, "-f", file, "-o", "localhost:7050", "--tls", "true", "--cafile", dir + "/ca.pem"}
   626  	channelCmd.SetArgs(args)
   627  	err = channelCmd.Execute()
   628  	assert.Error(t, err)
   629  	t.Log(err)
   630  	assert.Contains(t, err.Error(), "no such file or directory")
   631  }
   632  
   633  func TestSanityCheckAndSignChannelCreateTx(t *testing.T) {
   634  	defer resetFlags()
   635  
   636  	signer := &mock.SignerSerializer{}
   637  	env := &cb.Envelope{}
   638  	env.Payload = make([]byte, 10)
   639  	var err error
   640  
   641  	// Error case 1
   642  	env, err = sanityCheckAndSignConfigTx(env, signer)
   643  	assert.Error(t, err, "Error expected for nil payload")
   644  	assert.Contains(t, err.Error(), "bad payload")
   645  
   646  	// Error case 2
   647  	p := &cb.Payload{Header: nil}
   648  	data, err1 := proto.Marshal(p)
   649  	assert.NoError(t, err1)
   650  	env = &cb.Envelope{Payload: data}
   651  	env, err = sanityCheckAndSignConfigTx(env, signer)
   652  	assert.Error(t, err, "Error expected for bad payload header")
   653  	assert.Contains(t, err.Error(), "bad header")
   654  
   655  	// Error case 3
   656  	bites := bytes.NewBufferString("foo").Bytes()
   657  	p = &cb.Payload{Header: &cb.Header{ChannelHeader: bites}}
   658  	data, err = proto.Marshal(p)
   659  	assert.NoError(t, err)
   660  	env = &cb.Envelope{Payload: data}
   661  	env, err = sanityCheckAndSignConfigTx(env, signer)
   662  	assert.Error(t, err, "Error expected for bad channel header")
   663  	assert.Contains(t, err.Error(), "could not unmarshall channel header")
   664  
   665  	// Error case 4
   666  	mockchannel := "mockchannel"
   667  	cid := channelID
   668  	channelID = mockchannel
   669  	defer func() {
   670  		channelID = cid
   671  	}()
   672  	ch := &cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG_UPDATE), ChannelId: mockchannel}
   673  	data, err = proto.Marshal(ch)
   674  	assert.NoError(t, err)
   675  	p = &cb.Payload{Header: &cb.Header{ChannelHeader: data}, Data: bytes.NewBufferString("foo").Bytes()}
   676  	data, err = proto.Marshal(p)
   677  	assert.NoError(t, err)
   678  	env = &cb.Envelope{Payload: data}
   679  	env, err = sanityCheckAndSignConfigTx(env, signer)
   680  	assert.Error(t, err, "Error expected for bad payload data")
   681  	assert.Contains(t, err.Error(), "Bad config update env")
   682  
   683  	// Error case 5
   684  	signer = &mock.SignerSerializer{}
   685  	signer.SerializeReturns(nil, errors.New("bad signer header"))
   686  	env, err = protoutil.CreateSignedEnvelope(
   687  		cb.HeaderType_CONFIG_UPDATE,
   688  		"mockchannel",
   689  		nil,
   690  		&cb.ConfigEnvelope{},
   691  		0,
   692  		0)
   693  	assert.NoError(t, err)
   694  	env, err = sanityCheckAndSignConfigTx(env, signer)
   695  	assert.EqualError(t, err, "bad signer header")
   696  
   697  	// Error case 6
   698  	signer = &mock.SignerSerializer{}
   699  	signer.SignReturns(nil, errors.New("signer failed to sign"))
   700  	env, err = protoutil.CreateSignedEnvelope(
   701  		cb.HeaderType_CONFIG_UPDATE,
   702  		"mockchannel",
   703  		nil,
   704  		&cb.ConfigEnvelope{},
   705  		0,
   706  		0)
   707  	assert.NoError(t, err)
   708  	env, err = sanityCheckAndSignConfigTx(env, signer)
   709  	assert.EqualError(t, err, "signer failed to sign")
   710  }