github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/policies/inquire/inquire_test.go (about) 1 /* 2 Copyright hechain. 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/hechain20/hechain/common/policydsl" 15 "github.com/hechain20/hechain/protoutil" 16 "github.com/hyperledger/fabric-protos-go/msp" 17 "github.com/stretchr/testify/require" 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 } 35 for _, org := range orgNames { 36 appendPrincipal(org) 37 } 38 return principals 39 } 40 41 var cases = []testCase{ 42 { 43 name: "orOfAnds", 44 policy: "OR(AND('A.member', 'B.member'), 'C.member', AND('A.member', 'D.member'))", 45 expected: map[string]struct{}{ 46 fmt.Sprintf("%v", []string{"A", "B"}): {}, 47 fmt.Sprintf("%v", []string{"C"}): {}, 48 fmt.Sprintf("%v", []string{"A", "D"}): {}, 49 }, 50 principals: createPrincipals("A", "B", "C", "D", "A"), 51 }, 52 { 53 name: "andOfOrs", 54 policy: "AND('A.member', 'C.member', OR('B.member', 'D.member'))", 55 expected: map[string]struct{}{ 56 fmt.Sprintf("%v", []string{"A", "C", "B"}): {}, 57 fmt.Sprintf("%v", []string{"A", "C", "D"}): {}, 58 }, 59 principals: createPrincipals("A", "C", "B", "D"), 60 }, 61 { 62 name: "orOfOrs", 63 policy: "OR('A.member', OR('B.member', 'C.member'))", 64 expected: map[string]struct{}{ 65 fmt.Sprintf("%v", []string{"A"}): {}, 66 fmt.Sprintf("%v", []string{"B"}): {}, 67 fmt.Sprintf("%v", []string{"C"}): {}, 68 }, 69 principals: createPrincipals("A", "B", "C"), 70 }, 71 { 72 name: "andOfAnds", 73 policy: "AND('A.member', AND('B.member', 'C.member'), AND('D.member','A.member'))", 74 expected: map[string]struct{}{ 75 fmt.Sprintf("%v", []string{"A", "B", "C", "D", "A"}): {}, 76 }, 77 principals: createPrincipals("A", "B", "C", "D"), 78 }, 79 } 80 81 func mspId(principal *msp.MSPPrincipal) string { 82 role := &msp.MSPRole{} 83 proto.Unmarshal(principal.Principal, role) 84 return role.MspIdentifier 85 } 86 87 func TestSatisfiedBy(t *testing.T) { 88 for _, test := range cases { 89 t.Run(test.name, func(t *testing.T) { 90 p, err := policydsl.FromString(test.policy) 91 require.NoError(t, err) 92 93 ip := NewInquireableSignaturePolicy(p) 94 satisfiedBy := ip.SatisfiedBy() 95 96 actual := make(map[string]struct{}) 97 for _, ps := range satisfiedBy { 98 var principals []string 99 for _, principal := range ps { 100 principals = append(principals, mspId(principal)) 101 } 102 actual[fmt.Sprintf("%v", principals)] = struct{}{} 103 } 104 105 require.Equal(t, test.expected, actual) 106 }) 107 } 108 } 109 110 func TestSatisfiedByTooManyCombinations(t *testing.T) { 111 // We have 26 choose 15 members which is 7,726,160 112 // and we ensure we don't return so many combinations, 113 // but limit it to combinationsUpperBound. 114 115 p, err := policydsl.FromString("OutOf(15, 'A.member', 'B.member', 'C.member', 'D.member', 'E.member', 'F.member'," + 116 " 'G.member', 'H.member', 'I.member', 'J.member', 'K.member', 'L.member', 'M.member', 'N.member', 'O.member', " + 117 "'P.member', 'Q.member', 'R.member', 'S.member', 'T.member', 'U.member', 'V.member', 'W.member', 'X.member', " + 118 "'Y.member', 'Z.member')") 119 require.NoError(t, err) 120 121 ip := NewInquireableSignaturePolicy(p) 122 satisfiedBy := ip.SatisfiedBy() 123 124 actual := make(map[string]struct{}) 125 for _, ps := range satisfiedBy { 126 // Every subset is of size 15, as needed by the endorsement policy. 127 require.Len(t, ps, 15) 128 var principals []string 129 for _, principal := range ps { 130 principals = append(principals, mspId(principal)) 131 } 132 actual[fmt.Sprintf("%v", principals)] = struct{}{} 133 } 134 // Total combinations are capped by the combinationsUpperBound. 135 require.True(t, len(actual) < combinationsUpperBound) 136 }