github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/policies/inquire/inquire_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package inquire 8 9 import ( 10 "fmt" 11 "testing" 12 13 "github.com/golang/protobuf/proto" 14 "github.com/hyperledger/fabric-protos-go/msp" 15 "github.com/hyperledger/fabric/common/cauthdsl" 16 "github.com/hyperledger/fabric/protoutil" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 type testCase struct { 21 name string 22 policy string 23 expected map[string]struct{} 24 principals []*msp.MSPPrincipal 25 } 26 27 func createPrincipals(orgNames ...string) []*msp.MSPPrincipal { 28 principals := make([]*msp.MSPPrincipal, 0) 29 appendPrincipal := func(orgName string) { 30 principals = append(principals, &msp.MSPPrincipal{ 31 PrincipalClassification: msp.MSPPrincipal_ROLE, 32 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: orgName})}) 33 } 34 for _, org := range orgNames { 35 appendPrincipal(org) 36 } 37 return principals 38 } 39 40 var cases = []testCase{ 41 { 42 name: "orOfAnds", 43 policy: "OR(AND('A.member', 'B.member'), 'C.member', AND('A.member', 'D.member'))", 44 expected: map[string]struct{}{ 45 fmt.Sprintf("%v", []string{"A", "B"}): {}, 46 fmt.Sprintf("%v", []string{"C"}): {}, 47 fmt.Sprintf("%v", []string{"A", "D"}): {}, 48 }, 49 principals: createPrincipals("A", "B", "C", "D", "A"), 50 }, 51 { 52 name: "andOfOrs", 53 policy: "AND('A.member', 'C.member', OR('B.member', 'D.member'))", 54 expected: map[string]struct{}{ 55 fmt.Sprintf("%v", []string{"A", "C", "B"}): {}, 56 fmt.Sprintf("%v", []string{"A", "C", "D"}): {}, 57 }, 58 principals: createPrincipals("A", "C", "B", "D"), 59 }, 60 { 61 name: "orOfOrs", 62 policy: "OR('A.member', OR('B.member', 'C.member'))", 63 expected: map[string]struct{}{ 64 fmt.Sprintf("%v", []string{"A"}): {}, 65 fmt.Sprintf("%v", []string{"B"}): {}, 66 fmt.Sprintf("%v", []string{"C"}): {}, 67 }, 68 principals: createPrincipals("A", "B", "C"), 69 }, 70 { 71 name: "andOfAnds", 72 policy: "AND('A.member', AND('B.member', 'C.member'), AND('D.member','A.member'))", 73 expected: map[string]struct{}{ 74 fmt.Sprintf("%v", []string{"A", "B", "C", "D", "A"}): {}, 75 }, 76 principals: createPrincipals("A", "B", "C", "D"), 77 }, 78 } 79 80 func mspId(principal *msp.MSPPrincipal) string { 81 role := &msp.MSPRole{} 82 proto.Unmarshal(principal.Principal, role) 83 return role.MspIdentifier 84 } 85 86 func TestSatisfiedBy(t *testing.T) { 87 for _, test := range cases { 88 t.Run(test.name, func(t *testing.T) { 89 p, err := cauthdsl.FromString(test.policy) 90 assert.NoError(t, err) 91 92 ip := NewInquireableSignaturePolicy(p) 93 satisfiedBy := ip.SatisfiedBy() 94 95 actual := make(map[string]struct{}) 96 for _, ps := range satisfiedBy { 97 var principals []string 98 for _, principal := range ps { 99 principals = append(principals, mspId(principal)) 100 } 101 actual[fmt.Sprintf("%v", principals)] = struct{}{} 102 } 103 104 assert.Equal(t, test.expected, actual) 105 }) 106 } 107 } 108 109 func TestSatisfiedByTooManyCombinations(t *testing.T) { 110 // We have 26 choose 15 members which is 7,726,160 111 // and we ensure we don't return so many combinations, 112 // but limit it to combinationsUpperBound. 113 114 p, err := cauthdsl.FromString("OutOf(15, 'A.member', 'B.member', 'C.member', 'D.member', 'E.member', 'F.member'," + 115 " 'G.member', 'H.member', 'I.member', 'J.member', 'K.member', 'L.member', 'M.member', 'N.member', 'O.member', " + 116 "'P.member', 'Q.member', 'R.member', 'S.member', 'T.member', 'U.member', 'V.member', 'W.member', 'X.member', " + 117 "'Y.member', 'Z.member')") 118 assert.NoError(t, err) 119 120 ip := NewInquireableSignaturePolicy(p) 121 satisfiedBy := ip.SatisfiedBy() 122 123 actual := make(map[string]struct{}) 124 for _, ps := range satisfiedBy { 125 // Every subset is of size 15, as needed by the endorsement policy. 126 assert.Len(t, ps, 15) 127 var principals []string 128 for _, principal := range ps { 129 principals = append(principals, mspId(principal)) 130 } 131 actual[fmt.Sprintf("%v", principals)] = struct{}{} 132 } 133 // Total combinations are capped by the combinationsUpperBound. 134 assert.True(t, len(actual) < combinationsUpperBound) 135 }