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  }