github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/common/configtx/update_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 configtx 18 19 import ( 20 "fmt" 21 "testing" 22 23 mockconfigtx "github.com/hyperledger/fabric/common/mocks/configtx" 24 mockpolicies "github.com/hyperledger/fabric/common/mocks/policies" 25 cb "github.com/hyperledger/fabric/protos/common" 26 27 "github.com/stretchr/testify/assert" 28 ) 29 30 func TestReadSetNotPresent(t *testing.T) { 31 cm := &configSet{ 32 configMap: make(map[string]comparable), 33 } 34 35 cm.configMap["1"] = comparable{} 36 cm.configMap["2"] = comparable{} 37 38 readSet := make(map[string]comparable) 39 readSet["1"] = comparable{} 40 readSet["3"] = comparable{} 41 42 assert.Error(t, cm.verifyReadSet(readSet), "ReadSet contained '3', not in config") 43 } 44 45 func TestReadSetBackVersioned(t *testing.T) { 46 cm := &configSet{ 47 configMap: make(map[string]comparable), 48 } 49 50 cm.configMap["1"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}} 51 cm.configMap["2"] = comparable{} 52 53 readSet := make(map[string]comparable) 54 readSet["1"] = comparable{} 55 56 assert.Error(t, cm.verifyReadSet(readSet), "ReadSet contained '1', at old version") 57 } 58 59 func TestComputeDeltaSet(t *testing.T) { 60 readSet := make(map[string]comparable) 61 readSet["1"] = comparable{} 62 readSet["2"] = comparable{} 63 64 writeSet := make(map[string]comparable) 65 writeSet["1"] = comparable{} 66 writeSet["2"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}} 67 writeSet["3"] = comparable{} 68 69 result := ComputeDeltaSet(readSet, writeSet) 70 assert.Len(t, result, 2, "Should have two values in the delta set") 71 assert.NotNil(t, result["2"], "Element had version increased") 72 assert.NotNil(t, result["3"], "Element was new") 73 } 74 75 func TestVerifyDeltaSet(t *testing.T) { 76 cm := &configManager{ 77 Resources: &mockconfigtx.Resources{ 78 PolicyManagerVal: &mockpolicies.Manager{ 79 Policy: &mockpolicies.Policy{}, 80 }, 81 }, 82 current: &configSet{ 83 configMap: make(map[string]comparable), 84 }, 85 } 86 87 cm.current.configMap["foo"] = comparable{path: []string{"foo"}} 88 89 t.Run("Green path", func(t *testing.T) { 90 deltaSet := make(map[string]comparable) 91 92 deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}} 93 94 assert.NoError(t, cm.verifyDeltaSet(deltaSet, nil), "Good update") 95 }) 96 97 t.Run("Big Skip", func(t *testing.T) { 98 deltaSet := make(map[string]comparable) 99 100 deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 2}} 101 102 assert.Error(t, cm.verifyDeltaSet(deltaSet, nil), "Version skip from 0 to 2") 103 }) 104 105 t.Run("New item high version", func(t *testing.T) { 106 deltaSet := make(map[string]comparable) 107 108 deltaSet["bar"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}} 109 110 assert.Error(t, cm.verifyDeltaSet(deltaSet, nil), "New key not at version 0") 111 }) 112 113 t.Run("Policy evalaution to false", func(t *testing.T) { 114 deltaSet := make(map[string]comparable) 115 116 deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}} 117 cm.Resources.(*mockconfigtx.Resources).PolicyManagerVal.Policy = &mockpolicies.Policy{Err: fmt.Errorf("Err")} 118 119 assert.Error(t, cm.verifyDeltaSet(deltaSet, nil), "Policy evaluation should have failed") 120 }) 121 122 t.Run("Empty delta set", func(t *testing.T) { 123 err := (&configManager{}).verifyDeltaSet(map[string]comparable{}, nil) 124 assert.Error(t, err, "Empty delta set should be rejected") 125 assert.Contains(t, err.Error(), "Delta set was empty. Update would have no effect.") 126 }) 127 } 128 129 func TestPolicyForItem(t *testing.T) { 130 // Policies are set to different error values to differentiate them in equal assertion 131 rootPolicy := &mockpolicies.Policy{Err: fmt.Errorf("rootPolicy")} 132 fooPolicy := &mockpolicies.Policy{Err: fmt.Errorf("fooPolicy")} 133 134 cm := &configManager{ 135 Resources: &mockconfigtx.Resources{ 136 PolicyManagerVal: &mockpolicies.Manager{ 137 BasePathVal: "root", 138 Policy: rootPolicy, 139 SubManagersMap: map[string]*mockpolicies.Manager{ 140 "foo": &mockpolicies.Manager{ 141 Policy: fooPolicy, 142 BasePathVal: "foo", 143 }, 144 }, 145 }, 146 }, 147 } 148 149 policy, ok := cm.policyForItem(comparable{ 150 path: []string{"root"}, 151 ConfigValue: &cb.ConfigValue{ 152 ModPolicy: "rootPolicy", 153 }, 154 }) 155 assert.True(t, ok) 156 assert.Equal(t, policy, rootPolicy, "Should have found relative policy off the root manager") 157 158 policy, ok = cm.policyForItem(comparable{ 159 path: []string{"root", "wrong"}, 160 ConfigValue: &cb.ConfigValue{ 161 ModPolicy: "rootPolicy", 162 }, 163 }) 164 assert.False(t, ok, "Should not have found rootPolicy off a non-existent manager") 165 166 policy, ok = cm.policyForItem(comparable{ 167 path: []string{"root", "foo"}, 168 ConfigValue: &cb.ConfigValue{ 169 ModPolicy: "foo", 170 }, 171 }) 172 assert.True(t, ok) 173 assert.Equal(t, policy, fooPolicy, "Should not have found relative foo policy the foo manager") 174 175 policy, ok = cm.policyForItem(comparable{ 176 key: "foo", 177 path: []string{"root"}, 178 ConfigGroup: &cb.ConfigGroup{ 179 ModPolicy: "foo", 180 }, 181 }) 182 assert.True(t, ok) 183 assert.Equal(t, policy, fooPolicy, "Should have found relative foo policy for foo group") 184 }