github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/configtxfilter/filter_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 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 configtxfilter
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	mockconfigtx "github.com/hyperledger/fabric/common/mocks/configtx"
    24  	"github.com/hyperledger/fabric/orderer/common/filter"
    25  	cb "github.com/hyperledger/fabric/protos/common"
    26  	"github.com/hyperledger/fabric/protos/utils"
    27  
    28  	"github.com/golang/protobuf/proto"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  func TestForwardOpaquePayload(t *testing.T) {
    33  	cf := NewFilter(&mockconfigtx.Manager{})
    34  	result, _ := cf.Apply(&cb.Envelope{
    35  		Payload: []byte("Opaque"),
    36  	})
    37  	assert.EqualValues(t, filter.Forward, result, "Should have forwarded opaque message")
    38  }
    39  
    40  func TestForwardNilHeader(t *testing.T) {
    41  	cf := NewFilter(&mockconfigtx.Manager{})
    42  	result, _ := cf.Apply(&cb.Envelope{
    43  		Payload: utils.MarshalOrPanic(&cb.Payload{
    44  			Header: nil,
    45  		}),
    46  	})
    47  	assert.EqualValues(t, filter.Forward, result, "Should have forwarded message with nil header")
    48  }
    49  
    50  func TestForwardBadHeader(t *testing.T) {
    51  	cf := NewFilter(&mockconfigtx.Manager{})
    52  	result, _ := cf.Apply(&cb.Envelope{
    53  		Payload: utils.MarshalOrPanic(&cb.Payload{
    54  			Header: &cb.Header{ChannelHeader: []byte("Hello, world!")},
    55  		}),
    56  	})
    57  	assert.EqualValues(t, filter.Forward, result, "Should have forwarded message with bad header")
    58  }
    59  
    60  func TestForwardNonConfig(t *testing.T) {
    61  	cf := NewFilter(&mockconfigtx.Manager{})
    62  	result, _ := cf.Apply(&cb.Envelope{
    63  		Payload: utils.MarshalOrPanic(&cb.Payload{
    64  			Header: &cb.Header{ChannelHeader: []byte{}},
    65  		}),
    66  	})
    67  	assert.EqualValues(t, filter.Forward, result, "Should have forwarded message with non-config message")
    68  }
    69  
    70  func TestRejectMalformedData(t *testing.T) {
    71  	cf := NewFilter(&mockconfigtx.Manager{})
    72  	result, _ := cf.Apply(&cb.Envelope{
    73  		Payload: utils.MarshalOrPanic(&cb.Payload{
    74  			Header: &cb.Header{
    75  				ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
    76  					Type: int32(cb.HeaderType_CONFIG),
    77  				}),
    78  			},
    79  			Data: []byte("Hello, world!"),
    80  		}),
    81  	})
    82  	assert.EqualValues(t, filter.Reject, result, "Should have rejected message with malformed payload data")
    83  }
    84  
    85  func TestAcceptGoodConfig(t *testing.T) {
    86  	mcm := &mockconfigtx.Manager{}
    87  	cf := NewFilter(mcm)
    88  	configGroup := cb.NewConfigGroup()
    89  	configGroup.Values["Foo"] = &cb.ConfigValue{}
    90  	configUpdateEnv := &cb.ConfigUpdateEnvelope{
    91  		ConfigUpdate: utils.MarshalOrPanic(configGroup),
    92  	}
    93  	configEnv := &cb.ConfigEnvelope{
    94  		LastUpdate: &cb.Envelope{
    95  			Payload: utils.MarshalOrPanic(&cb.Payload{
    96  				Header: &cb.Header{
    97  					ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
    98  						Type: int32(cb.HeaderType_CONFIG_UPDATE),
    99  					}),
   100  				},
   101  				Data: utils.MarshalOrPanic(configUpdateEnv),
   102  			}),
   103  		},
   104  	}
   105  	configEnvBytes := utils.MarshalOrPanic(configEnv)
   106  	configBytes := utils.MarshalOrPanic(&cb.Payload{Header: &cb.Header{ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG)})}, Data: configEnvBytes})
   107  	configEnvelope := &cb.Envelope{
   108  		Payload: configBytes,
   109  	}
   110  	result, committer := cf.Apply(configEnvelope)
   111  	assert.EqualValues(t, filter.Accept, result, "Should have indicated a good config message causes a reconfig")
   112  	assert.True(t, committer.Isolated(), "Config transactions should be isolated to their own block")
   113  
   114  	committer.Commit()
   115  	assert.Equal(t, mcm.AppliedConfigUpdateEnvelope, configEnv, "Should have applied new config on commit got %+v and %+v", mcm.AppliedConfigUpdateEnvelope, configEnv.LastUpdate)
   116  }
   117  
   118  func TestPanicApplyingValidatedConfig(t *testing.T) {
   119  	mcm := &mockconfigtx.Manager{ApplyVal: fmt.Errorf("Error applying config tx")}
   120  	cf := NewFilter(mcm)
   121  	configGroup := cb.NewConfigGroup()
   122  	configGroup.Values["Foo"] = &cb.ConfigValue{}
   123  	configUpdateEnv := &cb.ConfigUpdateEnvelope{
   124  		ConfigUpdate: utils.MarshalOrPanic(configGroup),
   125  	}
   126  	configEnv := &cb.ConfigEnvelope{
   127  		LastUpdate: &cb.Envelope{
   128  			Payload: utils.MarshalOrPanic(&cb.Payload{
   129  				Header: &cb.Header{
   130  					ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{
   131  						Type: int32(cb.HeaderType_CONFIG_UPDATE),
   132  					}),
   133  				},
   134  				Data: utils.MarshalOrPanic(configUpdateEnv),
   135  			}),
   136  		},
   137  	}
   138  	configEnvBytes := utils.MarshalOrPanic(configEnv)
   139  	configBytes := utils.MarshalOrPanic(&cb.Payload{Header: &cb.Header{ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG)})}, Data: configEnvBytes})
   140  	configEnvelope := &cb.Envelope{
   141  		Payload: configBytes,
   142  	}
   143  	result, committer := cf.Apply(configEnvelope)
   144  
   145  	assert.EqualValues(t, filter.Accept, result, "Should have indicated a good config message causes a reconfig")
   146  	assert.True(t, committer.Isolated(), "Config transactions should be isolated to their own block")
   147  	assert.Panics(t, func() { committer.Commit() }, "Should panic upon error applying a validated config tx")
   148  }
   149  
   150  func TestRejectBadConfig(t *testing.T) {
   151  	cf := NewFilter(&mockconfigtx.Manager{ValidateVal: fmt.Errorf("Error")})
   152  	config, _ := proto.Marshal(&cb.ConfigEnvelope{})
   153  	configBytes, _ := proto.Marshal(&cb.Payload{Header: &cb.Header{ChannelHeader: utils.MarshalOrPanic(&cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG)})}, Data: config})
   154  	result, _ := cf.Apply(&cb.Envelope{
   155  		Payload: configBytes,
   156  	})
   157  
   158  	assert.EqualValues(t, filter.Reject, result, "Should have rejected bad config message")
   159  }