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 }