github.com/lzy4123/fabric@v2.1.1+incompatible/common/configtx/update_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package configtx
     8  
     9  import (
    10  	"fmt"
    11  	"reflect"
    12  	"testing"
    13  
    14  	cb "github.com/hyperledger/fabric-protos-go/common"
    15  	mockpolicies "github.com/hyperledger/fabric/common/configtx/mock"
    16  	"github.com/hyperledger/fabric/common/policies"
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestReadSetNotPresent(t *testing.T) {
    21  	vi := &ValidatorImpl{
    22  		configMap: make(map[string]comparable),
    23  	}
    24  
    25  	vi.configMap["1"] = comparable{}
    26  	vi.configMap["2"] = comparable{}
    27  
    28  	readSet := make(map[string]comparable)
    29  	readSet["1"] = comparable{}
    30  	readSet["3"] = comparable{}
    31  
    32  	assert.Error(t, vi.verifyReadSet(readSet), "ReadSet contained '3', not in config")
    33  }
    34  
    35  func TestReadSetBackVersioned(t *testing.T) {
    36  	vi := &ValidatorImpl{
    37  		configMap: make(map[string]comparable),
    38  	}
    39  
    40  	vi.configMap["1"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}}
    41  	vi.configMap["2"] = comparable{}
    42  
    43  	readSet := make(map[string]comparable)
    44  	readSet["1"] = comparable{}
    45  
    46  	assert.Error(t, vi.verifyReadSet(readSet), "ReadSet contained '1', at old version")
    47  }
    48  
    49  func TestComputeDeltaSet(t *testing.T) {
    50  	readSet := make(map[string]comparable)
    51  	readSet["1"] = comparable{}
    52  	readSet["2"] = comparable{}
    53  
    54  	writeSet := make(map[string]comparable)
    55  	writeSet["1"] = comparable{}
    56  	writeSet["2"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}}
    57  	writeSet["3"] = comparable{}
    58  
    59  	result := computeDeltaSet(readSet, writeSet)
    60  	assert.Len(t, result, 2, "Should have two values in the delta set")
    61  	assert.NotNil(t, result["2"], "Element had version increased")
    62  	assert.NotNil(t, result["3"], "Element was new")
    63  }
    64  
    65  func TestVerifyDeltaSet(t *testing.T) {
    66  	pm := &mockpolicies.PolicyManager{}
    67  	pm.GetPolicyReturns(&mockpolicies.Policy{}, true)
    68  	vi := &ValidatorImpl{
    69  		pm:        pm,
    70  		configMap: make(map[string]comparable),
    71  	}
    72  
    73  	vi.configMap["foo"] = comparable{path: []string{"foo"}}
    74  
    75  	t.Run("Green path", func(t *testing.T) {
    76  		deltaSet := make(map[string]comparable)
    77  
    78  		deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1, ModPolicy: "foo"}}
    79  
    80  		assert.NoError(t, vi.verifyDeltaSet(deltaSet, nil), "Good update")
    81  	})
    82  
    83  	t.Run("Bad mod policy", func(t *testing.T) {
    84  		deltaSet := make(map[string]comparable)
    85  
    86  		deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1}}
    87  
    88  		assert.Regexp(t, "invalid mod_policy for element", vi.verifyDeltaSet(deltaSet, nil))
    89  	})
    90  
    91  	t.Run("Big Skip", func(t *testing.T) {
    92  		deltaSet := make(map[string]comparable)
    93  
    94  		deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 2, ModPolicy: "foo"}}
    95  
    96  		assert.Error(t, vi.verifyDeltaSet(deltaSet, nil), "Version skip from 0 to 2")
    97  	})
    98  
    99  	t.Run("New item high version", func(t *testing.T) {
   100  		deltaSet := make(map[string]comparable)
   101  
   102  		deltaSet["bar"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1, ModPolicy: "foo"}}
   103  
   104  		assert.Error(t, vi.verifyDeltaSet(deltaSet, nil), "New key not at version 0")
   105  	})
   106  
   107  	t.Run("Policy evalaution to false", func(t *testing.T) {
   108  		deltaSet := make(map[string]comparable)
   109  
   110  		deltaSet["foo"] = comparable{ConfigValue: &cb.ConfigValue{Version: 1, ModPolicy: "foo"}}
   111  		fakePolicy := &mockpolicies.Policy{}
   112  		fakePolicy.EvaluateSignedDataReturns(fmt.Errorf("MockErr-fakePolicy.Evaluate-1557327297"))
   113  		vi.pm.(*mockpolicies.PolicyManager).GetPolicyReturns(fakePolicy, true)
   114  
   115  		assert.Error(t, vi.verifyDeltaSet(deltaSet, nil), "Policy evaluation should have failed")
   116  	})
   117  
   118  	t.Run("Empty delta set", func(t *testing.T) {
   119  		err := (&ValidatorImpl{}).verifyDeltaSet(map[string]comparable{}, nil)
   120  		assert.Error(t, err, "Empty delta set should be rejected")
   121  		assert.Contains(t, err.Error(), "delta set was empty -- update would have no effect")
   122  	})
   123  }
   124  
   125  func TestPolicyForItem(t *testing.T) {
   126  	// Policies are set to different error values to differentiate them in equal assertion
   127  
   128  	fakeFooPolicy := &mockpolicies.Policy{}
   129  	fakeFooPolicy.EvaluateSignedDataReturns(fmt.Errorf("MockErr-fooPolicy-1557327481"))
   130  	fakeFooPolicyManager := &mockpolicies.PolicyManager{}
   131  	fakeFooPolicyManager.GetPolicyStub = func(s string) (i policies.Policy, b bool) {
   132  		if s == "foo" {
   133  			return fakeFooPolicy, true
   134  		}
   135  		return nil, false
   136  	}
   137  	fakeRootPolicy := &mockpolicies.Policy{}
   138  	fakeRootPolicy.EvaluateSignedDataReturns(fmt.Errorf("MockErr-rootPolicy-1557327456"))
   139  	fakeRootPolicyManager := &mockpolicies.PolicyManager{}
   140  	fakeRootPolicyManager.GetPolicyStub = func(s string) (i policies.Policy, b bool) {
   141  		if s == "rootPolicy" {
   142  			return fakeRootPolicy, true
   143  		}
   144  		return nil, false
   145  	}
   146  	fakeRootPolicyManager.ManagerStub = func(path []string) (manager policies.Manager, b bool) {
   147  		switch {
   148  		case len(path) == 0:
   149  			return fakeRootPolicyManager, true
   150  		case reflect.DeepEqual(path, []string{"foo"}):
   151  			return fakeFooPolicyManager, true
   152  		default:
   153  			return nil, false
   154  		}
   155  	}
   156  
   157  	vi := &ValidatorImpl{
   158  		pm: fakeRootPolicyManager,
   159  	}
   160  
   161  	t.Run("Root manager", func(t *testing.T) {
   162  		policy, ok := vi.policyForItem(comparable{
   163  			path: []string{"root"},
   164  			ConfigValue: &cb.ConfigValue{
   165  				ModPolicy: "rootPolicy",
   166  			},
   167  		})
   168  		assert.True(t, ok)
   169  		assert.Equal(t, policy, fakeRootPolicy, "Should have found relative policy off the root manager")
   170  	})
   171  
   172  	t.Run("Nonexistent manager", func(t *testing.T) {
   173  		_, ok := vi.policyForItem(comparable{
   174  			path: []string{"root", "wrong"},
   175  			ConfigValue: &cb.ConfigValue{
   176  				ModPolicy: "rootPolicy",
   177  			},
   178  		})
   179  		assert.False(t, ok, "Should not have found rootPolicy off a nonexistent manager")
   180  	})
   181  
   182  	t.Run("Foo manager", func(t *testing.T) {
   183  		policy, ok := vi.policyForItem(comparable{
   184  			path: []string{"root", "foo"},
   185  			ConfigValue: &cb.ConfigValue{
   186  				ModPolicy: "foo",
   187  			},
   188  		})
   189  		assert.True(t, ok)
   190  		assert.Equal(t, policy, fakeFooPolicy, "Should have found relative foo policy off the foo manager")
   191  	})
   192  
   193  	t.Run("Foo group", func(t *testing.T) {
   194  		policy, ok := vi.policyForItem(comparable{
   195  			key:  "foo",
   196  			path: []string{"root"},
   197  			ConfigGroup: &cb.ConfigGroup{
   198  				ModPolicy: "foo",
   199  			},
   200  		})
   201  		assert.True(t, ok)
   202  		assert.Equal(t, policy, fakeFooPolicy, "Should have found relative foo policy for foo group")
   203  	})
   204  
   205  	t.Run("Root group manager", func(t *testing.T) {
   206  		policy, ok := vi.policyForItem(comparable{
   207  			path: []string{},
   208  			key:  "root",
   209  			ConfigGroup: &cb.ConfigGroup{
   210  				ModPolicy: "rootPolicy",
   211  			},
   212  		})
   213  		assert.True(t, ok)
   214  		assert.Equal(t, policy, fakeRootPolicy, "Should have found relative policy off the root manager")
   215  	})
   216  }
   217  
   218  func TestValidateModPolicy(t *testing.T) {
   219  	t.Run("Valid", func(t *testing.T) {
   220  		assert.Nil(t, validateModPolicy("/foo/bar"))
   221  	})
   222  	t.Run("Empty", func(t *testing.T) {
   223  		assert.Regexp(t, "mod_policy not set", validateModPolicy(""))
   224  	})
   225  	t.Run("InvalidFirstChar", func(t *testing.T) {
   226  		assert.Regexp(t, "path element at 0 is invalid", validateModPolicy("^foo"))
   227  	})
   228  	t.Run("InvalidRootPath", func(t *testing.T) {
   229  		assert.Regexp(t, "path element at 0 is invalid", validateModPolicy("/"))
   230  	})
   231  	t.Run("InvalidSubPath", func(t *testing.T) {
   232  		assert.Regexp(t, "path element at 1 is invalid", validateModPolicy("foo//bar"))
   233  	})
   234  }