Skip to content

Commit

Permalink
Refactor and export pvtdata test funcs for marbles_private chaincode (#…
Browse files Browse the repository at this point in the history
…2048)

Signed-off-by: Wenjian Qiao <wenjianq@gmail.com>
  • Loading branch information
wenjianqiao authored Oct 27, 2020
1 parent b810925 commit 687f58d
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 276 deletions.
21 changes: 21 additions & 0 deletions integration/pvtdata/implicit_coll_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/hyperledger/fabric/integration/nwo/commands"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"

"github.com/tedsuo/ifrit"
)
Expand Down Expand Up @@ -174,6 +176,25 @@ func readImplicitCollection(n *nwo.Network, peer *nwo.Peer, chaincodeName string
queryChaincode(n, peer, command, expectedMsg, expectSuccess)
}

func invokeChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeInvoke) {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful."))
}

func queryChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeQuery, expectedMessage string, expectSuccess bool) {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
if expectSuccess {
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say(expectedMessage))
} else {
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
Expect(sess.Err).To(gbytes.Say(expectedMessage))
}
}

func discoverAllPeers(n *nwo.Network, peer *nwo.Peer, channelID string, retries int, retryInterval time.Duration) {
var discoveredPeers []nwo.DiscoveredPeer
numPeers := len(n.Peers)
Expand Down
252 changes: 252 additions & 0 deletions integration/pvtdata/marblechaincodeutil/testutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/*
Copyright IBM Corp All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package marblechaincodeutil

import (
"bytes"
"encoding/base64"
"fmt"

"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"

. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)

// AddMarble invokes marbles_private chaincode to add a marble
func AddMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleDetails string, peer *nwo.Peer) {
marbleDetailsBase64 := base64.StdEncoding.EncodeToString([]byte(marbleDetails))

command := commands.ChaincodeInvoke{
ChannelID: channelID,
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
Name: chaincodeName,
Ctor: `{"Args":["initMarble"]}`,
Transient: fmt.Sprintf(`{"marble":"%s"}`, marbleDetailsBase64),
PeerAddresses: []string{
n.PeerAddress(peer, nwo.ListenPort),
},
WaitForEvent: true,
}
invokeChaincode(n, peer, command)
nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
}

// DeleteMarble invokes marbles_private chaincode to delete a marble
func DeleteMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleDelete string, peer *nwo.Peer) {
marbleDeleteBase64 := base64.StdEncoding.EncodeToString([]byte(marbleDelete))

command := commands.ChaincodeInvoke{
ChannelID: channelID,
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
Name: chaincodeName,
Ctor: `{"Args":["delete"]}`,
Transient: fmt.Sprintf(`{"marble_delete":"%s"}`, marbleDeleteBase64),
PeerAddresses: []string{
n.PeerAddress(peer, nwo.ListenPort),
},
WaitForEvent: true,
}
invokeChaincode(n, peer, command)
nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
}

// TransferMarble invokes marbles_private chaincode to transfer marble's ownership
func TransferMarble(n *nwo.Network, orderer *nwo.Orderer, channelID, chaincodeName, marbleOwner string, peer *nwo.Peer) {
marbleOwnerBase64 := base64.StdEncoding.EncodeToString([]byte(marbleOwner))

command := commands.ChaincodeInvoke{
ChannelID: channelID,
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
Name: chaincodeName,
Ctor: `{"Args":["transferMarble"]}`,
Transient: fmt.Sprintf(`{"marble_owner":"%s"}`, marbleOwnerBase64),
PeerAddresses: []string{
n.PeerAddress(peer, nwo.ListenPort),
},
WaitForEvent: true,
}
invokeChaincode(n, peer, command)
nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peer, channelID), n.Peers...)
}

// AssertGetMarblesByRange asserts that
func AssertGetMarblesByRange(n *nwo.Network, channelID, chaincodeName, marbleRange, expectedMsg string, peer *nwo.Peer) {
query := fmt.Sprintf(`{"Args":["getMarblesByRange", %s]}`, marbleRange)
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peer)
}

// AssertPresentInCollectionM asserts that the private data for given marble is present in collection
// 'readMarble' at the given peers
func AssertPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
expectedMsg := fmt.Sprintf(`"docType":"marble","name":"%s"`, marbleName)
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
}

// AssertPresentInCollectionMPD asserts that the private data for given marble is present
// in collection 'readMarblePrivateDetails' at the given peers
func AssertPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
expectedMsg := fmt.Sprintf(`"docType":"marblePrivateDetails","name":"%s"`, marbleName)
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
}

// CheckPresentInCollectionM checks then number of peers that have the private data for given marble
// in collection 'readMarble'
func CheckPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) int {
query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
expectedMsg := fmt.Sprintf(`{"docType":"marble","name":"%s"`, marbleName)
command := commands.ChaincodeQuery{
ChannelID: channelID,
Name: chaincodeName,
Ctor: query,
}
present := 0
for _, peer := range peerList {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
if bytes.Contains(sess.Buffer().Contents(), []byte(expectedMsg)) {
present++
}
}
return present
}

// CheckPresentInCollectionMPD checks the number of peers that have the private data for given marble
// in collection 'readMarblePrivateDetails'
func CheckPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) int {
query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
expectedMsg := fmt.Sprintf(`{"docType":"marblePrivateDetails","name":"%s"`, marbleName)
command := commands.ChaincodeQuery{
ChannelID: channelID,
Name: chaincodeName,
Ctor: query,
}
present := 0
for _, peer := range peerList {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
if bytes.Contains(sess.Buffer().Contents(), []byte(expectedMsg)) {
present++
}
}
return present
}

// AssertNotPresentInCollectionM asserts that the private data for given marble is NOT present
// in collection 'readMarble' at the given peers
func AssertNotPresentInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
expectedMsg := "private data matching public hash version is not available"
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
}

// AssertNotPresentInCollectionMPD asserts that the private data for given marble is NOT present
// in collection 'readMarblePrivateDetails' at the given peers
func AssertNotPresentInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
expectedMsg := "private data matching public hash version is not available"
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
}

// AssertDoesNotExistInCollectionM asserts that the private data for given marble
// does not exist in collection 'readMarble' (i.e., is never created/has been deleted/has been purged)
func AssertDoesNotExistInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
expectedMsg := "Marble does not exist"
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
}

// AssertDoesNotExistInCollectionMPD asserts that the private data for given marble
// does not exist in collection 'readMarblePrivateDetails' (i.e., is never created/has been deleted/has been purged)
func AssertDoesNotExistInCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
expectedMsg := "Marble private details does not exist"
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
}

// AssertOwnershipInCollectionM asserts that the private data for given marble is present
// in collection 'readMarble' at the given peers
func AssertOwnershipInCollectionM(n *nwo.Network, channelID, chaincodeName, marbleName, owner string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarble","%s"]}`, marbleName)
expectedMsg := fmt.Sprintf(`"owner":"%s"`, owner)
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, true, peerList...)
}

// AssertNoReadAccessToCollectionMPD asserts that the orgs of the given peers do not have
// read access to private data for the collection readMarblePrivateDetails
func AssertNoReadAccessToCollectionMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, peerList ...*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["readMarblePrivateDetails","%s"]}`, marbleName)
expectedMsg := "tx creator does not have read access permission"
queryChaincodePerPeer(n, query, channelID, chaincodeName, expectedMsg, false, peerList...)
}

func queryChaincodePerPeer(n *nwo.Network, query, channelID, chaincodeName, expectedMsg string, expectSuccess bool, peerList ...*nwo.Peer) {
command := commands.ChaincodeQuery{
ChannelID: channelID,
Name: chaincodeName,
Ctor: query,
}
for _, peer := range peerList {
queryChaincode(n, peer, command, expectedMsg, expectSuccess)
}
}

// AssertMarblesPrivateHashM asserts that getMarbleHash is accessible from all peers that has the chaincode instantiated
func AssertMarblesPrivateHashM(n *nwo.Network, channelID, chaincodeName, marbleName string, expectedBytes []byte, peerList []*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["getMarbleHash","%s"]}`, marbleName)
verifyPvtdataHash(n, query, channelID, chaincodeName, peerList, expectedBytes)
}

// AssertMarblesPrivateDetailsHashMPD asserts that getMarblePrivateDetailsHash is accessible from all peers that has the chaincode instantiated
func AssertMarblesPrivateDetailsHashMPD(n *nwo.Network, channelID, chaincodeName, marbleName string, expectedBytes []byte, peerList []*nwo.Peer) {
query := fmt.Sprintf(`{"Args":["getMarblePrivateDetailsHash","%s"]}`, marbleName)
verifyPvtdataHash(n, query, channelID, chaincodeName, peerList, expectedBytes)
}

func invokeChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeInvoke) {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful."))
}

func queryChaincode(n *nwo.Network, peer *nwo.Peer, command commands.ChaincodeQuery, expectedMessage string, expectSuccess bool) {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
if expectSuccess {
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say(expectedMessage))
} else {
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
Expect(sess.Err).To(gbytes.Say(expectedMessage))
}
}

// verifyPvtdataHash verifies the private data hash matches the expected bytes.
// Cannot reuse verifyAccess because the hash bytes are not valid utf8 causing gbytes.Say to fail.
func verifyPvtdataHash(n *nwo.Network, query, channelID, chaincodeName string, peers []*nwo.Peer, expected []byte) {
command := commands.ChaincodeQuery{
ChannelID: channelID,
Name: chaincodeName,
Ctor: query,
}

for _, peer := range peers {
sess, err := n.PeerUserSession(peer, "User1", command)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
actual := sess.Buffer().Contents()
// verify actual bytes contain expected bytes - cannot use equal because session may contain extra bytes
Expect(bytes.Contains(actual, expected)).To(Equal(true))
}
}
Loading

0 comments on commit 687f58d

Please sign in to comment.