209 lines
7.4 KiB
Go
209 lines
7.4 KiB
Go
/*
|
|
Copyright IBM Corp. 2017 All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package msgprocessor
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
cb "github.com/hyperledger/fabric-protos-go/common"
|
|
"github.com/hyperledger/fabric-protos-go/orderer"
|
|
"github.com/hyperledger/fabric/bccsp/sw"
|
|
"github.com/hyperledger/fabric/common/channelconfig"
|
|
"github.com/hyperledger/fabric/internal/pkg/identity"
|
|
"github.com/hyperledger/fabric/orderer/common/msgprocessor/mocks"
|
|
"github.com/hyperledger/fabric/protoutil"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const testChannelID = "foo"
|
|
|
|
type mockSystemChannelFilterSupport struct {
|
|
ProposeConfigUpdateVal *cb.ConfigEnvelope
|
|
ProposeConfigUpdateErr error
|
|
SequenceVal uint64
|
|
OrdererConfigVal channelconfig.Orderer
|
|
}
|
|
|
|
func (ms *mockSystemChannelFilterSupport) ProposeConfigUpdate(env *cb.Envelope) (*cb.ConfigEnvelope, error) {
|
|
return ms.ProposeConfigUpdateVal, ms.ProposeConfigUpdateErr
|
|
}
|
|
|
|
func (ms *mockSystemChannelFilterSupport) Sequence() uint64 {
|
|
return ms.SequenceVal
|
|
}
|
|
|
|
func (ms *mockSystemChannelFilterSupport) Signer() identity.SignerSerializer {
|
|
return nil
|
|
}
|
|
|
|
func (ms *mockSystemChannelFilterSupport) ChannelID() string {
|
|
return testChannelID
|
|
}
|
|
|
|
func (ms *mockSystemChannelFilterSupport) OrdererConfig() (channelconfig.Orderer, bool) {
|
|
if ms.OrdererConfigVal == nil {
|
|
return nil, false
|
|
}
|
|
|
|
return ms.OrdererConfigVal, true
|
|
}
|
|
|
|
func TestClassifyMsg(t *testing.T) {
|
|
t.Run("ConfigUpdate", func(t *testing.T) {
|
|
class := (&StandardChannel{}).ClassifyMsg(&cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG_UPDATE)})
|
|
require.Equal(t, class, ConfigUpdateMsg)
|
|
})
|
|
t.Run("OrdererTx", func(t *testing.T) {
|
|
class := (&StandardChannel{}).ClassifyMsg(&cb.ChannelHeader{Type: int32(cb.HeaderType_ORDERER_TRANSACTION)})
|
|
require.Equal(t, class, UnsupportedMsg)
|
|
})
|
|
t.Run("ConfigTx", func(t *testing.T) {
|
|
class := (&StandardChannel{}).ClassifyMsg(&cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG)})
|
|
require.Equal(t, class, ConfigMsg)
|
|
})
|
|
t.Run("EndorserTx", func(t *testing.T) {
|
|
class := (&StandardChannel{}).ClassifyMsg(&cb.ChannelHeader{Type: int32(cb.HeaderType_ENDORSER_TRANSACTION)})
|
|
require.Equal(t, class, NormalMsg)
|
|
})
|
|
}
|
|
|
|
func TestProcessNormalMsg(t *testing.T) {
|
|
t.Run("Normal", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
SequenceVal: 7,
|
|
OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
cs, err := NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessNormalMsg(nil)
|
|
require.Equal(t, cs, ms.SequenceVal)
|
|
require.Nil(t, err)
|
|
})
|
|
t.Run("Maintenance", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
SequenceVal: 7,
|
|
OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_MAINTENANCE),
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
_, err = NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessNormalMsg(nil)
|
|
require.EqualError(t, err, "normal transactions are rejected: maintenance mode")
|
|
})
|
|
}
|
|
|
|
func TestConfigUpdateMsg(t *testing.T) {
|
|
t.Run("BadUpdate", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
|
|
ProposeConfigUpdateErr: fmt.Errorf("An error"),
|
|
OrdererConfigVal: &mocks.OrdererConfig{},
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
config, cs, err := NewStandardChannel(ms, NewRuleSet(nil), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{})
|
|
require.Nil(t, config)
|
|
require.Equal(t, uint64(0), cs)
|
|
require.EqualError(t, err, "error applying config update to existing channel 'foo': An error")
|
|
})
|
|
t.Run("BadMsg", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
|
|
ProposeConfigUpdateErr: fmt.Errorf("An error"),
|
|
OrdererConfigVal: &mocks.OrdererConfig{},
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
config, cs, err := NewStandardChannel(ms, NewRuleSet([]Rule{EmptyRejectRule}), cryptoProvider).ProcessConfigUpdateMsg(&cb.Envelope{})
|
|
require.Nil(t, config)
|
|
require.Equal(t, uint64(0), cs)
|
|
require.NotNil(t, err)
|
|
})
|
|
t.Run("SignedEnvelopeFailure", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
OrdererConfigVal: &mocks.OrdererConfig{},
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
config, cs, err := NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigUpdateMsg(nil)
|
|
require.Nil(t, config)
|
|
require.Equal(t, uint64(0), cs)
|
|
require.NotNil(t, err)
|
|
require.Regexp(t, "Marshal called with nil", err)
|
|
})
|
|
t.Run("Success", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
SequenceVal: 7,
|
|
ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
|
|
OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
stdChan := NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
|
|
stdChan.maintenanceFilter = AcceptRule
|
|
config, cs, err := stdChan.ProcessConfigUpdateMsg(nil)
|
|
require.NotNil(t, config)
|
|
require.Equal(t, cs, ms.SequenceVal)
|
|
require.Nil(t, err)
|
|
})
|
|
}
|
|
|
|
func TestProcessConfigMsg(t *testing.T) {
|
|
t.Run("WrongType", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
SequenceVal: 7,
|
|
ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
|
|
OrdererConfigVal: &mocks.OrdererConfig{},
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
_, _, err = NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider).ProcessConfigMsg(&cb.Envelope{
|
|
Payload: protoutil.MarshalOrPanic(&cb.Payload{
|
|
Header: &cb.Header{
|
|
ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
|
|
ChannelId: testChannelID,
|
|
Type: int32(cb.HeaderType_ORDERER_TRANSACTION),
|
|
}),
|
|
},
|
|
}),
|
|
})
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("Success", func(t *testing.T) {
|
|
ms := &mockSystemChannelFilterSupport{
|
|
SequenceVal: 7,
|
|
ProposeConfigUpdateVal: &cb.ConfigEnvelope{},
|
|
OrdererConfigVal: newMockOrdererConfig(true, orderer.ConsensusType_STATE_NORMAL),
|
|
}
|
|
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
|
|
require.NoError(t, err)
|
|
stdChan := NewStandardChannel(ms, NewRuleSet([]Rule{AcceptRule}), cryptoProvider)
|
|
stdChan.maintenanceFilter = AcceptRule
|
|
config, cs, err := stdChan.ProcessConfigMsg(&cb.Envelope{
|
|
Payload: protoutil.MarshalOrPanic(&cb.Payload{
|
|
Header: &cb.Header{
|
|
ChannelHeader: protoutil.MarshalOrPanic(&cb.ChannelHeader{
|
|
ChannelId: testChannelID,
|
|
Type: int32(cb.HeaderType_CONFIG),
|
|
}),
|
|
},
|
|
}),
|
|
})
|
|
require.NotNil(t, config)
|
|
require.Equal(t, cs, ms.SequenceVal)
|
|
require.Nil(t, err)
|
|
hdr, err := protoutil.ChannelHeader(config)
|
|
require.NoError(t, err)
|
|
require.Equal(
|
|
t,
|
|
int32(cb.HeaderType_CONFIG),
|
|
hdr.Type,
|
|
"Expect type of returned envelope to be %d, but got %d", cb.HeaderType_CONFIG, hdr.Type)
|
|
})
|
|
}
|