github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/pvtdata/marblechaincodeutil/testutil.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package marblechaincodeutil
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/base64"
    12  	"fmt"
    13  
    14  	"github.com/hechain20/hechain/integration/nwo"
    15  	"github.com/hechain20/hechain/integration/nwo/commands"
    16  
    17  	. "github.com/onsi/gomega"
    18  	"github.com/onsi/gomega/gbytes"
    19  	"github.com/onsi/gomega/gexec"
    20  )
    21  
    22  // AddMarble invokes marbles_private chaincode to add a marble
    23  func AddMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleDetails string, peer *nwo.Peer) {
    24  	marbleDetailsBase64 := base64.StdEncoding.EncodeToString([]byte(marbleDetails))
    25  
    26  	command := commands.ChaincodeInvoke{
    27  		ChannelID: channelID,
    28  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
    29  		Name:      chaincodeName,
    30  		Ctor:      `{"Args":["initMarble"]}`,
    31  		Transient: fmt.Sprintf(`{"marble":"%s"}`, marbleDetailsBase64),
    32  		PeerAddresses: []string{
    33  			n.PeerAddress(peer, nwo.ListenPort),
    34  		},
    35  		WaitForEvent: true,
    36  	}
    37  	invokeChaincode(n, peer, command)
    38  	nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
    39  }
    40  
    41  // DeleteMarble invokes marbles_private chaincode to delete a marble
    42  func DeleteMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleDelete string, peer *nwo.Peer) {
    43  	marbleDeleteBase64 := base64.StdEncoding.EncodeToString([]byte(marbleDelete))
    44  
    45  	command := commands.ChaincodeInvoke{
    46  		ChannelID: channelID,
    47  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
    48  		Name:      chaincodeName,
    49  		Ctor:      `{"Args":["delete"]}`,
    50  		Transient: fmt.Sprintf(`{"marble_delete":"%s"}`, marbleDeleteBase64),
    51  		PeerAddresses: []string{
    52  			n.PeerAddress(peer, nwo.ListenPort),
    53  		},
    54  		WaitForEvent: true,
    55  	}
    56  	invokeChaincode(n, peer, command)
    57  	nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
    58  }
    59  
    60  // TransferMarble invokes marbles_private chaincode to transfer marble's ownership
    61  func TransferMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleOwner string, peer *nwo.Peer) {
    62  	marbleOwnerBase64 := base64.StdEncoding.EncodeToString([]byte(marbleOwner))
    63  
    64  	command := commands.ChaincodeInvoke{
    65  		ChannelID: channelID,
    66  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
    67  		Name:      chaincodeName,
    68  		Ctor:      `{"Args":["transferMarble"]}`,
    69  		Transient: fmt.Sprintf(`{"marble_owner":"%s"}`, marbleOwnerBase64),
    70  		PeerAddresses: []string{
    71  			n.PeerAddress(peer, nwo.ListenPort),
    72  		},
    73  		WaitForEvent: true,
    74  	}
    75  	invokeChaincode(n, peer, command)
    76  	nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
    77  }
    78  
    79  // AssertGetMarblesByRange asserts that
    80  func AssertGetMarblesByRange(n *nwo.Network, channelID, chaincodeName, marbleRange, expectedMsg string, peer *nwo.Peer) {
    81  	query := fmt.Sprintf(`{"Args":["getMarblesByRange", %s]}`, marbleRange)
    82  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peer)
    83  }
    84  
    85  // AssertPresentInCollectionM asserts that the private data for given marble is present in collection
    86  // 'readMarble' at the given peers
    87  func AssertPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
    88  	query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
    89  	expectedMsg := fmt.Sprintf(`"docType":"marble","name":"%s"`, marbleName)
    90  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
    91  }
    92  
    93  // AssertPresentInCollectionMPD asserts that the private data for given marble is present
    94  // in collection 'readMarblePrivateDetails' at the given peers
    95  func AssertPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
    96  	query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
    97  	expectedMsg := fmt.Sprintf(`"docType":"marblePrivateDetails","name":"%s"`, marbleName)
    98  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
    99  }
   100  
   101  // CheckPresentInCollectionM checks then number of peers that have the private data for given marble
   102  // in collection 'readMarble'
   103  func CheckPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) int {
   104  	query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
   105  	expectedMsg := fmt.Sprintf(`{"docType":"marble","name":"%s"`, marbleName)
   106  	command := commands.ChaincodeQuery{
   107  		ChannelID: channelID,
   108  		Name:      chaincodeName,
   109  		Ctor:      query,
   110  	}
   111  	present := 0
   112  	for _, peer := range peerList {
   113  		sess, err := n.PeerUserSession(peer, "User1", command)
   114  		Expect(err).NotTo(HaveOccurred())
   115  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
   116  		if bytes.Contains(sess.Buffer().Contents(), []byte(expectedMsg)) {
   117  			present++
   118  		}
   119  	}
   120  	return present
   121  }
   122  
   123  // CheckPresentInCollectionMPD checks the number of peers that have the private data for given marble
   124  // in collection 'readMarblePrivateDetails'
   125  func CheckPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) int {
   126  	query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
   127  	expectedMsg := fmt.Sprintf(`{"docType":"marblePrivateDetails","name":"%s"`, marbleName)
   128  	command := commands.ChaincodeQuery{
   129  		ChannelID: channelID,
   130  		Name:      chaincodeName,
   131  		Ctor:      query,
   132  	}
   133  	present := 0
   134  	for _, peer := range peerList {
   135  		sess, err := n.PeerUserSession(peer, "User1", command)
   136  		Expect(err).NotTo(HaveOccurred())
   137  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
   138  		if bytes.Contains(sess.Buffer().Contents(), []byte(expectedMsg)) {
   139  			present++
   140  		}
   141  	}
   142  	return present
   143  }
   144  
   145  // AssertNotPresentInCollectionM asserts that the private data for given marble is NOT present
   146  // in collection 'readMarble' at the given peers
   147  func AssertNotPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
   148  	query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
   149  	expectedMsg := "private data matching public hash version is not available"
   150  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
   151  }
   152  
   153  // AssertNotPresentInCollectionMPD asserts that the private data for given marble is NOT present
   154  // in collection 'readMarblePrivateDetails' at the given peers
   155  func AssertNotPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
   156  	query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
   157  	expectedMsg := "private data matching public hash version is not available"
   158  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
   159  }
   160  
   161  // AssertDoesNotExistInCollectionM asserts that the private data for given marble
   162  // does not exist in collection 'readMarble' (i.e., is never created/has been deleted/has been purged)
   163  func AssertDoesNotExistInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
   164  	query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
   165  	expectedMsg := "Marble does not exist"
   166  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
   167  }
   168  
   169  // AssertDoesNotExistInCollectionMPD asserts that the private data for given marble
   170  // does not exist in collection 'readMarblePrivateDetails' (i.e., is never created/has been deleted/has been purged)
   171  func AssertDoesNotExistInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
   172  	query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
   173  	expectedMsg := "Marble private details does not exist"
   174  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
   175  }
   176  
   177  // AssertOwnershipInCollectionM asserts that the private data for given marble is present
   178  // in collection 'readMarble' at the given peers
   179  func AssertOwnershipInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName, owner string, peerList ...*nwo.Peer) {
   180  	query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
   181  	expectedMsg := fmt.Sprintf(`"owner":"%s"`, owner)
   182  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
   183  }
   184  
   185  // AssertNoReadAccessToCollectionMPD asserts that the orgs of the given peers do not have
   186  // read access to private data for the collection readMarblePrivateDetails
   187  func AssertNoReadAccessToCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
   188  	query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
   189  	expectedMsg := "tx creator does not have read access permission"
   190  	queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
   191  }
   192  
   193  func queryChaincodePerPeer(n *nwo.Network, query, channelID, chaincodeName, expectedMsg string, expectSuccess bool, peerList ...*nwo.Peer) {
   194  	command := commands.ChaincodeQuery{
   195  		ChannelID: channelID,
   196  		Name:      chaincodeName,
   197  		Ctor:      query,
   198  	}
   199  	for _, peer := range peerList {
   200  		queryChaincode(n, peer, command, expectedMsg, expectSuccess)
   201  	}
   202  }
   203  
   204  // AssertMarblesPrivateHashM asserts that getMarbleHash is accessible from all peers that has the chaincode instantiated
   205  func AssertMarblesPrivateHashM(n *nwo.Network, channelID, chaincodeName, marbleName string, expectedBytes []byte, peerList []*nwo.Peer) {
   206  	query := fmt.Sprintf(`{"Args":["getMarbleHash","%s"]}`, marbleName)
   207  	verifyPvtdataHash(n, query, channelID, chaincodeName, peerList, expectedBytes)
   208  }
   209  
   210  // AssertMarblesPrivateDetailsHashMPD asserts that getMarblePrivateDetailsHash is accessible from all peers that has the chaincode instantiated
   211  func AssertMarblesPrivateDetailsHashMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, expectedBytes []byte, peerList []*nwo.Peer) {
   212  	query := fmt.Sprintf(`{"Args":["getMarblePrivateDetailsHash","%s"]}`, marbleName)
   213  	verifyPvtdataHash(n, query, channelID, chaincodeName, peerList, expectedBytes)
   214  }
   215  
   216  func invokeChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeInvoke) {
   217  	sess, err := n.PeerUserSession(peer, "User1", command)
   218  	Expect(err).NotTo(HaveOccurred())
   219  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   220  	Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful."))
   221  }
   222  
   223  func queryChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeQuery, expectedMessage string, expectSuccess bool) {
   224  	sess, err := n.PeerUserSession(peer, "User1", command)
   225  	Expect(err).NotTo(HaveOccurred())
   226  	if expectSuccess {
   227  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   228  		Expect(sess).To(gbytes.Say(expectedMessage))
   229  	} else {
   230  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
   231  		Expect(sess.Err).To(gbytes.Say(expectedMessage))
   232  	}
   233  }
   234  
   235  // verifyPvtdataHash verifies the private data hash matches the expected bytes.
   236  // Cannot reuse verifyAccess because the hash bytes are not valid utf8 causing gbytes.Say to fail.
   237  func verifyPvtdataHash(n *nwo.Network, query, channelID, chaincodeName string, peers []*nwo.Peer, expected []byte) {
   238  	command := commands.ChaincodeQuery{
   239  		ChannelID: channelID,
   240  		Name:      chaincodeName,
   241  		Ctor:      query,
   242  	}
   243  
   244  	for _, peer := range peers {
   245  		sess, err := n.PeerUserSession(peer, "User1", command)
   246  		Expect(err).NotTo(HaveOccurred())
   247  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   248  		actual := sess.Buffer().Contents()
   249  		// verify actual bytes contain expected bytes - cannot use equal because session may contain extra bytes
   250  		Expect(bytes.Contains(actual, expected)).To(Equal(true))
   251  	}
   252  }