github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/devmode/devmode_test.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package devmode
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"strconv"
    15  	"syscall"
    16  	"time"
    17  
    18  	docker "github.com/fsouza/go-dockerclient"
    19  	"github.com/hechain20/hechain/integration/nwo"
    20  	"github.com/hechain20/hechain/integration/nwo/commands"
    21  	. "github.com/onsi/ginkgo"
    22  	. "github.com/onsi/gomega"
    23  	"github.com/onsi/gomega/gbytes"
    24  	"github.com/onsi/gomega/gexec"
    25  	"github.com/tedsuo/ifrit"
    26  	"github.com/tedsuo/ifrit/ginkgomon"
    27  )
    28  
    29  var _ = Describe("Devmode", func() {
    30  	var (
    31  		testDir          string
    32  		client           *docker.Client
    33  		network          *nwo.Network
    34  		process          ifrit.Process
    35  		chaincode        nwo.Chaincode
    36  		legacyChaincode  nwo.Chaincode
    37  		chaincodeRunner  *ginkgomon.Runner
    38  		chaincodeProcess ifrit.Process
    39  		channelName      string
    40  	)
    41  
    42  	BeforeEach(func() {
    43  		var err error
    44  		channelName = "testchannel"
    45  		testDir, err = ioutil.TempDir("", "devmode")
    46  		Expect(err).NotTo(HaveOccurred())
    47  
    48  		client, err = docker.NewClientFromEnv()
    49  		Expect(err).NotTo(HaveOccurred())
    50  
    51  		network = nwo.New(devModeSolo, testDir, client, StartPort(), components)
    52  
    53  		network.TLSEnabled = false
    54  		network.Peer("Org1", "peer0").DevMode = true
    55  
    56  		network.GenerateConfigTree()
    57  		network.Bootstrap()
    58  
    59  		networkRunner := network.NetworkGroupRunner()
    60  		process = ifrit.Invoke(networkRunner)
    61  		Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
    62  	})
    63  
    64  	AfterEach(func() {
    65  		if process != nil {
    66  			process.Signal(syscall.SIGTERM)
    67  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
    68  		}
    69  
    70  		if chaincodeProcess != nil {
    71  			chaincodeProcess.Signal(syscall.SIGTERM)
    72  		}
    73  
    74  		if network != nil {
    75  			network.Cleanup()
    76  		}
    77  
    78  		os.RemoveAll(testDir)
    79  	})
    80  
    81  	It("executes chaincode in dev mode using legacy lifecycle", func() {
    82  		legacyChaincode = nwo.Chaincode{
    83  			Name:    "mycc",
    84  			Version: "0.0",
    85  			Path:    "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
    86  			Ctor:    `{"Args":["init","a","100","b","200"]}`,
    87  			Policy:  `OR ('Org1MSP.member')`,
    88  		}
    89  
    90  		org1peer0 := network.Peer("Org1", "peer0")
    91  		orderer := network.Orderer("orderer")
    92  
    93  		By("setting up the channel")
    94  		network.CreateAndJoinChannel(orderer, channelName)
    95  
    96  		By("building chaincode")
    97  		chaincodeExecutePath := components.Build(legacyChaincode.Path)
    98  
    99  		By("running the chaincode")
   100  		legacyChaincodeID := legacyChaincode.Name + ":" + legacyChaincode.Version
   101  		peerChaincodeAddress := network.PeerAddress(org1peer0, nwo.ChaincodePort)
   102  		envs := []string{
   103  			"CORE_PEER_TLS_ENABLED=false",
   104  			"CORE_CHAINCODE_ID_NAME=" + legacyChaincodeID,
   105  			"DEVMODE_ENABLED=true",
   106  		}
   107  		cmd := exec.Command(chaincodeExecutePath, "-peer.address", peerChaincodeAddress)
   108  		cmd.Env = append(cmd.Env, envs...)
   109  		chaincodeRunner = ginkgomon.New(ginkgomon.Config{
   110  			Name:              "chaincode",
   111  			Command:           cmd,
   112  			StartCheckTimeout: 15 * time.Second,
   113  			StartCheck:        "starting up in devmode...",
   114  		})
   115  		chaincodeProcess = ifrit.Invoke(chaincodeRunner)
   116  		Eventually(chaincodeProcess.Ready(), network.EventuallyTimeout).Should(BeClosed())
   117  
   118  		By("installing the chaincode")
   119  		nwo.InstallChaincodeLegacy(network, legacyChaincode, org1peer0)
   120  
   121  		By("instantiating the chaincode")
   122  		nwo.InstantiateChaincodeLegacy(network, channelName, orderer, legacyChaincode, org1peer0, org1peer0)
   123  
   124  		By("querying and invoking the chaincode")
   125  		RunQueryInvokeQuery(network, orderer, org1peer0, channelName, 100)
   126  		Eventually(chaincodeRunner).Should(gbytes.Say("invoking in devmode"))
   127  	})
   128  
   129  	It("executes chaincode in dev mode", func() {
   130  		chaincode = nwo.Chaincode{
   131  			Name:            "mycc",
   132  			Version:         "0.0",
   133  			Path:            components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"),
   134  			Lang:            "binary",
   135  			PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
   136  			Ctor:            `{"Args":["init","a","100","b","200"]}`,
   137  			SignaturePolicy: `OR ('Org1MSP.member')`,
   138  			Sequence:        "1",
   139  			InitRequired:    true,
   140  			Label:           "my_prebuilt_chaincode",
   141  		}
   142  
   143  		org1peer0 := network.Peer("Org1", "peer0")
   144  		orderer := network.Orderer("orderer")
   145  
   146  		By("setting up the channel")
   147  		network.CreateAndJoinChannel(orderer, channelName)
   148  
   149  		By("enabling V2_0 application capabilities")
   150  		nwo.EnableCapabilities(network, channelName, "Application", "V2_0", orderer, org1peer0)
   151  
   152  		By("running the chaincode")
   153  		chaincodeID := chaincode.Name + ":" + chaincode.Version
   154  		peerChaincodeAddress := network.PeerAddress(org1peer0, nwo.ChaincodePort)
   155  		envs := []string{
   156  			"CORE_PEER_TLS_ENABLED=false",
   157  			"CORE_PEER_ADDRESS=" + peerChaincodeAddress,
   158  			"CORE_CHAINCODE_ID_NAME=" + chaincodeID,
   159  			"DEVMODE_ENABLED=true",
   160  		}
   161  
   162  		cmd := exec.Command(chaincode.Path, "-peer.address", peerChaincodeAddress)
   163  		cmd.Env = append(cmd.Env, envs...)
   164  		chaincodeRunner = ginkgomon.New(ginkgomon.Config{
   165  			Name:              "chaincode",
   166  			Command:           cmd,
   167  			StartCheckTimeout: 15 * time.Second,
   168  			StartCheck:        "starting up in devmode...",
   169  		})
   170  		chaincodeProcess = ifrit.Invoke(chaincodeRunner)
   171  		Eventually(chaincodeProcess.Ready(), network.EventuallyTimeout).Should(BeClosed())
   172  
   173  		By("approving chaincode for orgs")
   174  		ApproveChaincodeForMyOrg(network, channelName, orderer, chaincode, org1peer0)
   175  		By("committing the chaincode definition")
   176  		nwo.CheckCommitReadinessUntilReady(network, channelName, chaincode, network.PeerOrgs(), org1peer0)
   177  		nwo.CommitChaincode(network, channelName, orderer, chaincode, org1peer0, org1peer0)
   178  		By("initializing chaincode if required")
   179  		if chaincode.InitRequired {
   180  			nwo.InitChaincode(network, channelName, orderer, chaincode, org1peer0)
   181  		}
   182  
   183  		By("querying and invoking the chaincode")
   184  		RunQueryInvokeQuery(network, orderer, org1peer0, channelName, 100)
   185  		Eventually(chaincodeRunner.Buffer()).Should(gbytes.Say("invoking in devmode"))
   186  
   187  		By("killing chaincode process")
   188  		chaincodeProcess.Signal(syscall.SIGKILL)
   189  		Eventually(chaincodeProcess.Wait(), network.EventuallyTimeout).Should(Receive())
   190  
   191  		By("invoking chaincode after it has been killed, expecting it to fail")
   192  		sess, err := network.PeerUserSession(org1peer0, "User1", commands.ChaincodeInvoke{
   193  			ChannelID: channelName,
   194  			Orderer:   network.OrdererAddress(orderer, nwo.ListenPort),
   195  			Name:      "mycc",
   196  			Ctor:      `{"Args":["invoke","a","b","10"]}`,
   197  			PeerAddresses: []string{
   198  				network.PeerAddress(network.Peer("Org1", "peer0"), nwo.ListenPort),
   199  			},
   200  			WaitForEvent: true,
   201  		})
   202  		Expect(err).NotTo(HaveOccurred())
   203  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   204  
   205  		By("restarting the chaincode process")
   206  		cmd = exec.Command(chaincode.Path, []string{"-peer.address", peerChaincodeAddress}...)
   207  		cmd.Env = append(cmd.Env, envs...)
   208  		chaincodeRunner = ginkgomon.New(ginkgomon.Config{
   209  			Name:              "chaincode",
   210  			Command:           cmd,
   211  			StartCheckTimeout: 15 * time.Second,
   212  			StartCheck:        "starting up in devmode...",
   213  		})
   214  		chaincodeProcess = ifrit.Invoke(chaincodeRunner)
   215  		Eventually(chaincodeProcess.Ready(), network.EventuallyTimeout).Should(BeClosed())
   216  
   217  		By("querying and invoking the chaincode")
   218  		RunQueryInvokeQuery(network, orderer, org1peer0, channelName, 90)
   219  		Eventually(chaincodeRunner).Should(gbytes.Say("invoking in devmode"))
   220  	})
   221  })
   222  
   223  func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string, queryValue int) {
   224  	By("querying the chaincode")
   225  	sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
   226  		ChannelID: channel,
   227  		Name:      "mycc",
   228  		Ctor:      `{"Args":["query","a"]}`,
   229  	})
   230  	Expect(err).NotTo(HaveOccurred())
   231  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   232  	Expect(sess).To(gbytes.Say(strconv.Itoa(queryValue)))
   233  
   234  	By("invoking the chaincode")
   235  	sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
   236  		ChannelID: channel,
   237  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
   238  		Name:      "mycc",
   239  		Ctor:      `{"Args":["invoke","a","b","10"]}`,
   240  		PeerAddresses: []string{
   241  			n.PeerAddress(peer, nwo.ListenPort),
   242  		},
   243  		WaitForEvent: true,
   244  	})
   245  	Expect(err).NotTo(HaveOccurred())
   246  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   247  	Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
   248  
   249  	By("querying the chaincode again")
   250  	sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
   251  		ChannelID: channel,
   252  		Name:      "mycc",
   253  		Ctor:      `{"Args":["query","a"]}`,
   254  	})
   255  	Expect(err).NotTo(HaveOccurred())
   256  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   257  	Expect(sess).To(gbytes.Say(strconv.Itoa(queryValue - 10)))
   258  }
   259  
   260  // ApproveChaincodeForMyOrg should only be used when devmode is enabled.
   261  // It does not set PackageID form ChaincodeApproveForMyOrg command.
   262  func ApproveChaincodeForMyOrg(n *nwo.Network, channel string, orderer *nwo.Orderer, chaincode nwo.Chaincode, peers ...*nwo.Peer) {
   263  	approvedOrgs := map[string]bool{}
   264  	for _, p := range peers {
   265  		if _, ok := approvedOrgs[p.Organization]; !ok {
   266  			sess, err := n.PeerAdminSession(p, commands.ChaincodeApproveForMyOrg{
   267  				ChannelID:           channel,
   268  				Orderer:             n.OrdererAddress(orderer, nwo.ListenPort),
   269  				Name:                chaincode.Name,
   270  				Version:             chaincode.Version,
   271  				Sequence:            chaincode.Sequence,
   272  				EndorsementPlugin:   chaincode.EndorsementPlugin,
   273  				ValidationPlugin:    chaincode.ValidationPlugin,
   274  				SignaturePolicy:     chaincode.SignaturePolicy,
   275  				ChannelConfigPolicy: chaincode.ChannelConfigPolicy,
   276  				InitRequired:        chaincode.InitRequired,
   277  				CollectionsConfig:   chaincode.CollectionsConfig,
   278  				ClientAuth:          n.ClientAuthRequired,
   279  			})
   280  			Expect(err).NotTo(HaveOccurred())
   281  			Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   282  			approvedOrgs[p.Organization] = true
   283  			Eventually(sess.Err, n.EventuallyTimeout).Should(gbytes.Say(`\Qcommitted with status (VALID)\E`))
   284  		}
   285  	}
   286  }
   287  
   288  var devModeSolo = &nwo.Config{
   289  	Organizations: []*nwo.Organization{{
   290  		Name:          "OrdererOrg",
   291  		MSPID:         "OrdererMSP",
   292  		Domain:        "example.com",
   293  		EnableNodeOUs: false,
   294  		Users:         0,
   295  		CA:            &nwo.CA{Hostname: "ca"},
   296  	}, {
   297  		Name:          "Org1",
   298  		MSPID:         "Org1MSP",
   299  		Domain:        "org1.example.com",
   300  		EnableNodeOUs: true,
   301  		Users:         2,
   302  		CA:            &nwo.CA{Hostname: "ca"},
   303  	}},
   304  	Consortiums: []*nwo.Consortium{{
   305  		Name: "SampleConsortium",
   306  		Organizations: []string{
   307  			"Org1",
   308  		},
   309  	}},
   310  	Consensus: &nwo.Consensus{
   311  		Type:            "solo",
   312  		BootstrapMethod: "file",
   313  	},
   314  	SystemChannel: &nwo.SystemChannel{
   315  		Name:    "systemchannel",
   316  		Profile: "OneOrgOrdererGenesis",
   317  	},
   318  	Orderers: []*nwo.Orderer{
   319  		{Name: "orderer", Organization: "OrdererOrg"},
   320  	},
   321  	Channels: []*nwo.Channel{
   322  		{Name: "testchannel", Profile: "OneOrgChannel"},
   323  	},
   324  	Peers: []*nwo.Peer{{
   325  		Name:         "peer0",
   326  		Organization: "Org1",
   327  		Channels: []*nwo.PeerChannel{
   328  			{Name: "testchannel", Anchor: true},
   329  		},
   330  	}},
   331  	Profiles: []*nwo.Profile{{
   332  		Name:     "OneOrgOrdererGenesis",
   333  		Orderers: []string{"orderer"},
   334  	}, {
   335  		Name:          "OneOrgChannel",
   336  		Consortium:    "SampleConsortium",
   337  		Organizations: []string{"Org1"},
   338  	}},
   339  }