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  }