go_study/fabric-main/integration/pluggable/pluggable_test.go

206 lines
6.7 KiB
Go

/*
Copyright IBM Corp All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package pluggable
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"syscall"
"time"
docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/integration/channelparticipation"
"github.com/hyperledger/fabric/integration/nwo"
"github.com/hyperledger/fabric/integration/nwo/commands"
"github.com/hyperledger/fabric/integration/nwo/fabricconfig"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/tedsuo/ifrit"
ginkgomon "github.com/tedsuo/ifrit/ginkgomon_v2"
)
var _ = Describe("EndToEnd", func() {
var (
testDir string
client *docker.Client
network *nwo.Network
chaincode nwo.Chaincode
ordererRunner *ginkgomon.Runner
ordererProcess, peerProcess ifrit.Process
endorsementPluginPath string
validationPluginPath string
)
BeforeEach(func() {
var err error
testDir, err = ioutil.TempDir("", "pluggable-suite")
Expect(err).NotTo(HaveOccurred())
// Compile plugins
endorsementPluginPath = compilePlugin("endorsement")
validationPluginPath = compilePlugin("validation")
// Create directories for endorsement and validation activation
dir := filepath.Join(testDir, "endorsement")
err = os.Mkdir(dir, 0o700)
Expect(err).NotTo(HaveOccurred())
SetEndorsementPluginActivationFolder(dir)
dir = filepath.Join(testDir, "validation")
err = os.Mkdir(dir, 0o700)
Expect(err).NotTo(HaveOccurred())
SetValidationPluginActivationFolder(dir)
basicEtcdRaftConfig := nwo.BasicEtcdRaft()
Expect(basicEtcdRaftConfig.Peers).To(HaveLen(2))
// docker client
client, err = docker.NewClientFromEnv()
Expect(err).NotTo(HaveOccurred())
network = nwo.New(basicEtcdRaftConfig, testDir, client, StartPort(), components)
network.GenerateConfigTree()
// modify config
configurePlugins(network, endorsementPluginPath, validationPluginPath)
// generate network config
network.Bootstrap()
// Start all the fabric processes
ordererRunner, ordererProcess, peerProcess = network.StartSingleOrdererNetwork("orderer")
chaincode = nwo.Chaincode{
Name: "mycc",
Version: "0.0",
Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/simple/cmd"),
Lang: "binary",
PackageFile: filepath.Join(testDir, "simplecc.tar.gz"),
Ctor: `{"Args":["init","a","100","b","200"]}`,
SignaturePolicy: `OR ('Org1MSP.member','Org2MSP.member')`,
Sequence: "1",
InitRequired: true,
Label: "my_prebuilt_chaincode",
}
orderer := network.Orderer("orderer")
channelparticipation.JoinOrdererJoinPeersAppChannel(network, "testchannel", orderer, ordererRunner)
nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
})
AfterEach(func() {
// stop the network
if ordererProcess != nil {
ordererProcess.Signal(syscall.SIGTERM)
Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
}
if peerProcess != nil {
peerProcess.Signal(syscall.SIGTERM)
Eventually(peerProcess.Wait(), network.EventuallyTimeout).Should(Receive())
}
// cleanup the network artifacts
network.Cleanup()
os.RemoveAll(testDir)
// cleanup the compiled plugins
os.Remove(endorsementPluginPath)
os.Remove(validationPluginPath)
})
It("executes a basic etcdraft network with specified plugins", func() {
// Make sure plugins activated
peerCount := len(network.Peers)
activations := CountEndorsementPluginActivations()
Expect(activations).To(Equal(peerCount))
activations = CountValidationPluginActivations()
Expect(activations).To(Equal(peerCount))
RunQueryInvokeQuery(network, network.Orderer("orderer"), network.Peer("Org1", "peer0"))
})
})
// compilePlugin compiles the plugin of the given type and returns the path for
// the plugin file.
func compilePlugin(pluginType string) string {
// Building plugins can take quite a while as the build caches won't be
// populated for the 'dynlink' install suffix. While a minute or two is
// usually enough, timeouts have occurred at 2 minutes on slow machines.
const buildTimeout = 5 * time.Minute
pluginFilePath := filepath.Join("testdata", "plugins", pluginType, "plugin.so")
cmd := exec.Command(
"go", "build",
"-x", // print build commands while running
"-buildmode=plugin",
"-o", pluginFilePath,
fmt.Sprintf("github.com/hyperledger/fabric/integration/pluggable/testdata/plugins/%s", pluginType),
)
pw := gexec.NewPrefixedWriter(fmt.Sprintf("[build-plugin-%s] ", pluginType), GinkgoWriter)
sess, err := gexec.Start(cmd, pw, pw)
Expect(err).NotTo(HaveOccurred())
Eventually(sess, buildTimeout).Should(gexec.Exit(0))
Expect(pluginFilePath).To(BeARegularFile())
return pluginFilePath
}
func configurePlugins(network *nwo.Network, endorsement, validation string) {
for _, p := range network.Peers {
core := network.ReadPeerConfig(p)
core.Peer.Handlers.Endorsers = fabricconfig.HandlerMap{
"escc": fabricconfig.Handler{Name: "plugin-escc", Library: endorsement},
}
core.Peer.Handlers.Validators = fabricconfig.HandlerMap{
"vscc": fabricconfig.Handler{Name: "plugin-vscc", Library: validation},
}
network.WritePeerConfig(p, core)
}
}
func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer) {
By("querying the chaincode")
sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say("100"))
sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
Name: "mycc",
Ctor: `{"Args":["invoke","a","b","10"]}`,
PeerAddresses: []string{
n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort),
n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort),
},
WaitForEvent: true,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
ChannelID: "testchannel",
Name: "mycc",
Ctor: `{"Args":["query","a"]}`,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
Expect(sess).To(gbytes.Say("90"))
}