github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/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 }