github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/common/config/proposer_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 config
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	cb "github.com/hyperledger/fabric/protos/common"
    24  	"github.com/hyperledger/fabric/protos/utils"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  	logging "github.com/op/go-logging"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func init() {
    32  	logging.SetLevel(logging.DEBUG, "")
    33  }
    34  
    35  type mockValues struct {
    36  	ProtoMsgMap    map[string]proto.Message
    37  	ValidateReturn error
    38  }
    39  
    40  func (v *mockValues) Deserialize(key string, value []byte) (proto.Message, error) {
    41  	msg, ok := v.ProtoMsgMap[key]
    42  	if !ok {
    43  		return nil, fmt.Errorf("Missing message key: %s", key)
    44  	}
    45  	err := proto.Unmarshal(value, msg)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	return msg, nil
    51  }
    52  
    53  func (v *mockValues) Validate(interface{}, map[string]ValueProposer) error {
    54  	return v.ValidateReturn
    55  }
    56  
    57  func (v *mockValues) Commit() {}
    58  
    59  func newMockValues() *mockValues {
    60  	return &mockValues{
    61  		ProtoMsgMap: make(map[string]proto.Message),
    62  	}
    63  }
    64  
    65  type mockHandler struct {
    66  	AllocateReturn *mockValues
    67  	NewGroupMap    map[string]ValueProposer
    68  	NewGroupError  error
    69  }
    70  
    71  func (h *mockHandler) Allocate() Values {
    72  	return h.AllocateReturn
    73  }
    74  
    75  func (h *mockHandler) NewGroup(name string) (ValueProposer, error) {
    76  	group, ok := h.NewGroupMap[name]
    77  	if !ok {
    78  		return nil, fmt.Errorf("Missing group implies error")
    79  	}
    80  	return group, nil
    81  }
    82  
    83  func newMockHandler() *mockHandler {
    84  	return &mockHandler{
    85  		AllocateReturn: newMockValues(),
    86  		NewGroupMap:    make(map[string]ValueProposer),
    87  	}
    88  }
    89  
    90  func TestDoubleSameBegin(t *testing.T) {
    91  	p := NewProposer(&mockHandler{AllocateReturn: &mockValues{}})
    92  	p.BeginValueProposals(p, nil)
    93  	assert.Panics(t, func() { p.BeginValueProposals(p, nil) }, "Two begins back to back should have caused a panic")
    94  }
    95  
    96  func TestDoubleDifferentBegin(t *testing.T) {
    97  	p := NewProposer(&mockHandler{AllocateReturn: &mockValues{}})
    98  	p.BeginValueProposals(t, nil)
    99  	p.BeginValueProposals(p, nil)
   100  	// This function would panic on error
   101  }
   102  
   103  func TestCommitWithoutBegin(t *testing.T) {
   104  	p := NewProposer(&mockHandler{AllocateReturn: &mockValues{}})
   105  	assert.Panics(t, func() { p.CommitProposals(t) }, "Commit without begin should have caused a panic")
   106  }
   107  
   108  func TestRollback(t *testing.T) {
   109  	p := NewProposer(&mockHandler{AllocateReturn: &mockValues{}})
   110  	p.pending[t] = &config{}
   111  	p.RollbackProposals(t)
   112  	assert.Nil(t, p.pending[t], "Should have cleared pending config on rollback")
   113  }
   114  
   115  func TestGoodKeys(t *testing.T) {
   116  	mh := newMockHandler()
   117  	mh.AllocateReturn.ProtoMsgMap["Envelope"] = &cb.Envelope{}
   118  	mh.AllocateReturn.ProtoMsgMap["Payload"] = &cb.Payload{}
   119  
   120  	p := NewProposer(mh)
   121  	vd, _, err := p.BeginValueProposals(t, nil)
   122  	assert.NoError(t, err)
   123  
   124  	env := &cb.Envelope{Payload: []byte("SOME DATA")}
   125  	pay := &cb.Payload{Data: []byte("SOME OTHER DATA")}
   126  
   127  	msg, err := vd.Deserialize("Envelope", utils.MarshalOrPanic(env))
   128  	assert.NoError(t, err)
   129  	assert.Equal(t, msg, env)
   130  
   131  	msg, err = vd.Deserialize("Payload", utils.MarshalOrPanic(pay))
   132  	assert.NoError(t, err)
   133  	assert.Equal(t, msg, pay)
   134  }
   135  
   136  func TestBadMarshaling(t *testing.T) {
   137  	mh := newMockHandler()
   138  	mh.AllocateReturn.ProtoMsgMap["Envelope"] = &cb.Envelope{}
   139  
   140  	p := NewProposer(mh)
   141  	vd, _, err := p.BeginValueProposals(t, nil)
   142  	assert.NoError(t, err)
   143  
   144  	_, err = vd.Deserialize("Envelope", []byte("GARBAGE"))
   145  	assert.Error(t, err, "Should have errored unmarshaling")
   146  }
   147  
   148  func TestBadMissingMessage(t *testing.T) {
   149  	mh := newMockHandler()
   150  	mh.AllocateReturn.ProtoMsgMap["Payload"] = &cb.Payload{}
   151  
   152  	p := NewProposer(mh)
   153  	vd, _, err := p.BeginValueProposals(t, nil)
   154  	assert.NoError(t, err)
   155  
   156  	_, err = vd.Deserialize("Envelope", utils.MarshalOrPanic(&cb.Envelope{}))
   157  	assert.Error(t, err, "Should have errored on unexpected message")
   158  }
   159  
   160  func TestGroups(t *testing.T) {
   161  	mh := newMockHandler()
   162  	mh.NewGroupMap["foo"] = nil
   163  	mh.NewGroupMap["bar"] = nil
   164  
   165  	p := NewProposer(mh)
   166  	_, _, err := p.BeginValueProposals(t, []string{"foo", "bar"})
   167  	assert.NoError(t, err, "Both groups were present")
   168  	p.CommitProposals(t)
   169  
   170  	mh.NewGroupMap = make(map[string]ValueProposer)
   171  	_, _, err = p.BeginValueProposals(t, []string{"foo", "bar"})
   172  	assert.NoError(t, err, "Should not have tried to recreate the groups")
   173  	p.CommitProposals(t)
   174  
   175  	_, _, err = p.BeginValueProposals(t, []string{"foo", "other"})
   176  	assert.Error(t, err, "Should not have errored when trying to create 'other'")
   177  
   178  	_, _, err = p.BeginValueProposals(t, []string{"foo"})
   179  	assert.NoError(t, err, "Should be able to begin again without rolling back because of error")
   180  }