github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/msgprocessor/configupdate/configupdate_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package configupdate
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/hyperledger/fabric/common/configtx"
    24  	configtxapi "github.com/hyperledger/fabric/common/configtx/api"
    25  	mockconfigtx "github.com/hyperledger/fabric/common/mocks/configtx"
    26  	mockcrypto "github.com/hyperledger/fabric/common/mocks/crypto"
    27  	cb "github.com/hyperledger/fabric/protos/common"
    28  	"github.com/hyperledger/fabric/protos/utils"
    29  
    30  	"github.com/op/go-logging"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  func init() {
    35  	logging.SetLevel(logging.DEBUG, "")
    36  }
    37  
    38  type mockSupport struct {
    39  	ProposeConfigUpdateVal *cb.ConfigEnvelope
    40  }
    41  
    42  func (ms *mockSupport) ProposeConfigUpdate(env *cb.Envelope) (*cb.ConfigEnvelope, error) {
    43  	var err error
    44  	if ms.ProposeConfigUpdateVal == nil {
    45  		err = fmt.Errorf("Nil result implies error in mock")
    46  	}
    47  	return ms.ProposeConfigUpdateVal, err
    48  }
    49  
    50  type mockSupportManager struct {
    51  	GetChainVal           *mockSupport
    52  	Manager               *mockconfigtx.Manager
    53  	NewChannelConfigError error
    54  }
    55  
    56  func (msm *mockSupportManager) GetChain(chainID string) (Support, bool) {
    57  	return msm.GetChainVal, msm.GetChainVal != nil
    58  }
    59  
    60  func (msm *mockSupportManager) NewChannelConfig(env *cb.Envelope) (configtxapi.Manager, error) {
    61  	msm.Manager.ProposeConfigUpdateVal = &cb.ConfigEnvelope{LastUpdate: env}
    62  	return msm.Manager, msm.NewChannelConfigError
    63  }
    64  
    65  func TestChannelID(t *testing.T) {
    66  	const testChannelID = "foo"
    67  	makeEnvelope := func(payload *cb.Payload) *cb.Envelope {
    68  		return &cb.Envelope{
    69  			Payload: utils.MarshalOrPanic(payload),
    70  		}
    71  	}
    72  
    73  	_, err := channelID(&cb.Envelope{Payload: []byte("foo")})
    74  	assert.Error(t, err, "Payload was missing")
    75  
    76  	_, err = channelID(makeEnvelope(&cb.Payload{}))
    77  	assert.Error(t, err, "Header was missing")
    78  
    79  	_, err = channelID(makeEnvelope(&cb.Payload{
    80  		Header: &cb.Header{ChannelHeader: []byte("bar")},
    81  	}))
    82  	assert.Error(t, err, "ChannelHeader was malformed")
    83  
    84  	_, err = channelID(makeEnvelope(&cb.Payload{
    85  		Header: &cb.Header{
    86  			ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{}),
    87  		},
    88  	}))
    89  	assert.Error(t, err, "Channel ID was empty")
    90  
    91  	result, err := channelID(makeEnvelope(&cb.Payload{
    92  		Header: &cb.Header{
    93  			ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
    94  				ChannelId: testChannelID,
    95  			}),
    96  		},
    97  	}))
    98  	assert.NoError(t, err, "Channel ID was present")
    99  	assert.Equal(t, testChannelID, result, "Channel ID was present")
   100  }
   101  
   102  const systemChannelID = "system_channel"
   103  const testUpdateChannelID = "update_channel"
   104  
   105  func newTestInstance() (*mockSupportManager, *Processor) {
   106  	msm := &mockSupportManager{}
   107  	msm.GetChainVal = &mockSupport{}
   108  	msm.Manager = &mockconfigtx.Manager{}
   109  	return msm, New(systemChannelID, msm, mockcrypto.FakeLocalSigner)
   110  }
   111  
   112  func testConfigUpdate() *cb.Envelope {
   113  	ch := &cb.ChannelHeader{
   114  		ChannelId: testUpdateChannelID,
   115  	}
   116  
   117  	return &cb.Envelope{
   118  		Payload: utils.MarshalOrPanic(&cb.Payload{
   119  			Header: &cb.Header{
   120  				ChannelHeader: utils.MarshalOrPanic(ch),
   121  			},
   122  			Data: utils.MarshalOrPanic(&cb.ConfigUpdateEnvelope{
   123  				ConfigUpdate: utils.MarshalOrPanic(&cb.ConfigUpdate{
   124  					ChannelId: ch.ChannelId,
   125  					WriteSet:  cb.NewConfigGroup(),
   126  				}),
   127  			}),
   128  		}),
   129  	}
   130  }
   131  
   132  type mockErroneousLocalSigner struct {
   133  	SignError error
   134  }
   135  
   136  func (m *mockErroneousLocalSigner) NewSignatureHeader() (*cb.SignatureHeader, error) {
   137  	return nil, m.SignError
   138  }
   139  
   140  func (m *mockErroneousLocalSigner) Sign(message []byte) ([]byte, error) {
   141  	return []byte{}, m.SignError
   142  }
   143  
   144  func TestExistingChannel(t *testing.T) {
   145  	msm, p := newTestInstance()
   146  
   147  	testUpdate := testConfigUpdate()
   148  
   149  	dummyResult := &cb.ConfigEnvelope{LastUpdate: &cb.Envelope{Payload: []byte("DUMMY")}}
   150  
   151  	msm.GetChainVal = &mockSupport{ProposeConfigUpdateVal: dummyResult}
   152  	env, err := p.Process(testUpdate)
   153  	assert.NoError(t, err, "Valid config update")
   154  	_ = utils.UnmarshalPayloadOrPanic(env.Payload)
   155  	assert.Equal(t, dummyResult, configtx.UnmarshalConfigEnvelopeOrPanic(utils.UnmarshalPayloadOrPanic(env.Payload).Data), "Valid config update")
   156  
   157  	msm.GetChainVal = &mockSupport{}
   158  	_, err = p.Process(testUpdate)
   159  	assert.Error(t, err, "Invald ProposeUpdate result")
   160  }
   161  
   162  func TestNewChannel(t *testing.T) {
   163  	msm, p := newTestInstance()
   164  	msm.GetChainVal = nil
   165  
   166  	testUpdate := testConfigUpdate()
   167  
   168  	env, err := p.Process(testUpdate)
   169  	assert.NoError(t, err, "Valid config update")
   170  
   171  	resultChan, err := channelID(env)
   172  	assert.NoError(t, err, "Invalid envelope produced")
   173  
   174  	assert.Equal(t, systemChannelID, resultChan, "Wrapper TX should be bound for system channel")
   175  
   176  	chdr, err := utils.UnmarshalChannelHeader(utils.UnmarshalPayloadOrPanic(env.Payload).Header.ChannelHeader)
   177  	assert.NoError(t, err, "UnmarshalChannelHeader error")
   178  
   179  	assert.Equal(t, int32(cb.HeaderType_ORDERER_TRANSACTION), chdr.Type, "Wrong wrapper tx type")
   180  }
   181  
   182  func TestNewChannelErrorCases(t *testing.T) {
   183  	{
   184  		_, p := newTestInstance()
   185  
   186  		_, err := p.Process(&cb.Envelope{Payload: []byte("foo")})
   187  		assert.Error(t, err, "Invalid env config update")
   188  	}
   189  
   190  	{
   191  		msm, p := newTestInstance()
   192  		testUpdate := testConfigUpdate()
   193  		msm.GetChainVal = nil
   194  		msm.NewChannelConfigError = fmt.Errorf("new channel config error")
   195  
   196  		_, err := p.Process(testUpdate)
   197  		assert.Error(t, err, "Expected channel config error to be returned")
   198  	}
   199  
   200  	{
   201  		msm, p := newTestInstance()
   202  		testUpdate := testConfigUpdate()
   203  		msm.GetChainVal = nil
   204  		msm.Manager.ProposeConfigUpdateError = fmt.Errorf("propose config update error")
   205  
   206  		_, err := p.Process(testUpdate)
   207  		assert.Error(t, err, "Expected propose config update error to be returned")
   208  	}
   209  
   210  	{
   211  		msm := &mockSupportManager{}
   212  		msm.GetChainVal = &mockSupport{}
   213  		msm.Manager = &mockconfigtx.Manager{}
   214  		p := New(
   215  			systemChannelID,
   216  			msm,
   217  			&mockErroneousLocalSigner{SignError: fmt.Errorf("Sign error")})
   218  		msm.GetChainVal = nil
   219  		testUpdate := testConfigUpdate()
   220  
   221  		_, err := p.Process(testUpdate)
   222  		assert.Error(t, err, "Expected sign error to be returned")
   223  	}
   224  
   225  	{
   226  		msm := &mockSupportManager{}
   227  		assert.Panics(
   228  			t,
   229  			func() { New(systemChannelID, msm, mockcrypto.FakeLocalSigner) },
   230  			"Should panic if SupportManager does not contain system channel",
   231  		)
   232  	}
   233  }