github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/e2e_test.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package e2e 8 9 import ( 10 "bufio" 11 "bytes" 12 "context" 13 "crypto/sha256" 14 "encoding/json" 15 "fmt" 16 "io" 17 "io/ioutil" 18 "net/http" 19 "os" 20 "path" 21 "path/filepath" 22 "strings" 23 "syscall" 24 "time" 25 26 docker "github.com/fsouza/go-dockerclient" 27 "github.com/golang/protobuf/proto" 28 "github.com/hechain20/hechain/integration/channelparticipation" 29 "github.com/hechain20/hechain/integration/nwo" 30 "github.com/hechain20/hechain/integration/nwo/commands" 31 "github.com/hechain20/hechain/integration/nwo/fabricconfig" 32 "github.com/hyperledger/fabric-lib-go/healthz" 33 "github.com/hyperledger/fabric-protos-go/orderer/etcdraft" 34 . "github.com/onsi/ginkgo" 35 . "github.com/onsi/gomega" 36 "github.com/onsi/gomega/gbytes" 37 "github.com/onsi/gomega/gexec" 38 "github.com/tedsuo/ifrit" 39 "github.com/tedsuo/ifrit/ginkgomon" 40 ) 41 42 var _ = Describe("EndToEnd", func() { 43 var ( 44 testDir string 45 client *docker.Client 46 network *nwo.Network 47 chaincode nwo.Chaincode 48 process ifrit.Process 49 ) 50 51 BeforeEach(func() { 52 var err error 53 testDir, err = ioutil.TempDir("", "e2e") 54 Expect(err).NotTo(HaveOccurred()) 55 56 client, err = docker.NewClientFromEnv() 57 Expect(err).NotTo(HaveOccurred()) 58 59 chaincode = nwo.Chaincode{ 60 Name: "mycc", 61 Version: "0.0", 62 Path: components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"), 63 Lang: "binary", 64 PackageFile: filepath.Join(testDir, "simplecc.tar.gz"), 65 Ctor: `{"Args":["init","a","100","b","200"]}`, 66 SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`, 67 Sequence: "1", 68 InitRequired: true, 69 Label: "my_prebuilt_chaincode", 70 } 71 }) 72 73 AfterEach(func() { 74 if process != nil { 75 process.Signal(syscall.SIGTERM) 76 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 77 } 78 if network != nil { 79 network.Cleanup() 80 } 81 os.RemoveAll(testDir) 82 }) 83 84 Describe("basic solo network with 2 orgs and no docker", func() { 85 var ( 86 metricsReader *MetricsReader 87 runArtifactsFilePath string 88 ) 89 90 BeforeEach(func() { 91 metricsReader = NewMetricsReader() 92 go metricsReader.Start() 93 94 network = nwo.New(nwo.BasicSolo(), testDir, nil, StartPort(), components) 95 network.MetricsProvider = "statsd" 96 network.StatsdEndpoint = metricsReader.Address() 97 network.Consensus.ChannelParticipationEnabled = true 98 network.Profiles = append(network.Profiles, &nwo.Profile{ 99 Name: "TwoOrgsBaseProfileChannel", 100 Consortium: "SampleConsortium", 101 Orderers: []string{"orderer"}, 102 Organizations: []string{"Org1", "Org2"}, 103 }) 104 network.Channels = append(network.Channels, &nwo.Channel{ 105 Name: "baseprofilechannel", 106 Profile: "TwoOrgsBaseProfileChannel", 107 BaseProfile: "TwoOrgsOrdererGenesis", 108 }) 109 110 runArtifactsFilePath = filepath.Join(testDir, "run-artifacts.txt") 111 os.Setenv("RUN_ARTIFACTS_FILE", runArtifactsFilePath) 112 for i, e := range network.ExternalBuilders { 113 e.PropagateEnvironment = append(e.PropagateEnvironment, "RUN_ARTIFACTS_FILE") 114 network.ExternalBuilders[i] = e 115 } 116 117 network.GenerateConfigTree() 118 for _, peer := range network.PeersWithChannel("testchannel") { 119 core := network.ReadPeerConfig(peer) 120 core.VM = nil 121 network.WritePeerConfig(peer, core) 122 } 123 124 network.Bootstrap() 125 126 networkRunner := network.NetworkGroupRunner() 127 process = ifrit.Invoke(networkRunner) 128 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 129 }) 130 131 AfterEach(func() { 132 if metricsReader != nil { 133 metricsReader.Close() 134 } 135 136 // Terminate the processes but defer the network cleanup to the outer 137 // AfterEach. 138 if process != nil { 139 process.Signal(syscall.SIGTERM) 140 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 141 process = nil 142 } 143 144 // Ensure that the temporary directories generated by launched external 145 // chaincodes have been cleaned up. This must be done after the peers 146 // have been terminated. 147 contents, err := ioutil.ReadFile(runArtifactsFilePath) 148 Expect(err).NotTo(HaveOccurred()) 149 scanner := bufio.NewScanner(bytes.NewBuffer(contents)) 150 for scanner.Scan() { 151 Expect(scanner.Text()).NotTo(BeAnExistingFile()) 152 } 153 }) 154 155 It("executes a basic solo network with 2 orgs and no docker", func() { 156 By("getting the orderer by name") 157 orderer := network.Orderer("orderer") 158 159 By("setting up the channel") 160 network.CreateAndJoinChannel(orderer, "testchannel") 161 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 162 163 By("listing channels with osnadmin") 164 tlsdir := network.OrdererLocalTLSDir(orderer) 165 sess, err := network.Osnadmin(commands.ChannelList{ 166 OrdererAddress: network.OrdererAddress(orderer, nwo.AdminPort), 167 CAFile: filepath.Join(tlsdir, "ca.crt"), 168 ClientCert: filepath.Join(tlsdir, "server.crt"), 169 ClientKey: filepath.Join(tlsdir, "server.key"), 170 }) 171 Expect(err).NotTo(HaveOccurred()) 172 Eventually(sess).Should(gexec.Exit(0)) 173 var channelList channelparticipation.ChannelList 174 err = json.Unmarshal(sess.Out.Contents(), &channelList) 175 Expect(err).NotTo(HaveOccurred()) 176 Expect(channelList).To(Equal(channelparticipation.ChannelList{ 177 SystemChannel: &channelparticipation.ChannelInfoShort{ 178 Name: "systemchannel", 179 URL: "/participation/v1/channels/systemchannel", 180 }, 181 Channels: []channelparticipation.ChannelInfoShort{{ 182 Name: "testchannel", 183 URL: "/participation/v1/channels/testchannel", 184 }}, 185 })) 186 187 By("attempting to install unsupported chaincode without docker") 188 badCC := chaincode 189 badCC.Lang = "unsupported-type" 190 badCC.Label = "chaincode-label" 191 badCC.PackageFile = filepath.Join(testDir, "unsupported-type.tar.gz") 192 nwo.PackageChaincodeBinary(badCC) 193 badCC.SetPackageIDFromPackageFile() 194 sess, err = network.PeerAdminSession( 195 network.Peer("Org1", "peer0"), 196 commands.ChaincodeInstall{ 197 PackageFile: badCC.PackageFile, 198 ClientAuth: network.ClientAuthRequired, 199 }, 200 ) 201 Expect(err).NotTo(HaveOccurred()) 202 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1)) 203 Expect(sess.Err).To(gbytes.Say("docker build is disabled")) 204 205 By("deploying the chaincode") 206 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 207 208 By("ensuring external cc run artifacts exist after deploying") 209 contents, err := ioutil.ReadFile(runArtifactsFilePath) 210 Expect(err).NotTo(HaveOccurred()) 211 scanner := bufio.NewScanner(bytes.NewBuffer(contents)) 212 for scanner.Scan() { 213 Expect(scanner.Text()).To(BeADirectory()) 214 } 215 216 By("getting the client peer by name") 217 peer := network.Peer("Org1", "peer0") 218 219 RunQueryInvokeQuery(network, orderer, peer, "testchannel") 220 RunRespondWith(network, orderer, peer, "testchannel") 221 222 By("evaluating statsd metrics") 223 metricsWriteInterval := 5 * time.Second 224 CheckPeerStatsdStreamMetrics(metricsReader, 2*metricsWriteInterval) 225 CheckPeerStatsdMetrics("org1_peer0", metricsReader, 2*metricsWriteInterval) 226 CheckPeerStatsdMetrics("org2_peer0", metricsReader, 2*metricsWriteInterval) 227 228 By("checking for orderer metrics") 229 CheckOrdererStatsdMetrics("ordererorg_orderer", metricsReader, 2*metricsWriteInterval) 230 231 By("setting up a channel from a base profile") 232 additionalPeer := network.Peer("Org2", "peer0") 233 network.CreateChannel("baseprofilechannel", orderer, peer, additionalPeer) 234 }) 235 }) 236 237 Describe("basic etcdraft network with docker chaincode builds", func() { 238 BeforeEach(func() { 239 network = nwo.New(nwo.MultiChannelEtcdRaft(), testDir, client, StartPort(), components) 240 network.Consensus.ChannelParticipationEnabled = true 241 network.MetricsProvider = "prometheus" 242 network.GenerateConfigTree() 243 network.Bootstrap() 244 245 networkRunner := network.NetworkGroupRunner() 246 process = ifrit.Invoke(networkRunner) 247 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 248 }) 249 250 It("builds and executes transactions with docker chaincode", func() { 251 chaincodePath, err := filepath.Abs("../chaincode/module") 252 Expect(err).NotTo(HaveOccurred()) 253 254 // use these two variants of the same chaincode to ensure we test 255 // the golang docker build for both module and gopath chaincode 256 chaincode := nwo.Chaincode{ 257 Name: "mycc", 258 Version: "0.0", 259 Path: chaincodePath, 260 Lang: "golang", 261 PackageFile: filepath.Join(testDir, "modulecc.tar.gz"), 262 Ctor: `{"Args":["init","a","100","b","200"]}`, 263 SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`, 264 Sequence: "1", 265 InitRequired: true, 266 Label: "my_module_chaincode", 267 } 268 269 gopathChaincode := nwo.Chaincode{ 270 Name: "mycc", 271 Version: "0.0", 272 Path: "github.com/hechain20/hechain/integration/chaincode/simple/cmd", 273 Lang: "golang", 274 PackageFile: filepath.Join(testDir, "simplecc.tar.gz"), 275 Ctor: `{"Args":["init","a","100","b","200"]}`, 276 SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`, 277 Sequence: "1", 278 InitRequired: true, 279 Label: "my_simple_chaincode", 280 } 281 282 orderer := network.Orderer("orderer") 283 284 network.CreateAndJoinChannel(orderer, "testchannel") 285 cl := channelparticipation.List(network, orderer) 286 channelparticipation.ChannelListMatcher(cl, []string{"testchannel"}, []string{"systemchannel"}...) 287 288 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 289 290 // package, install, and approve by org1 - module chaincode 291 packageInstallApproveChaincode(network, "testchannel", orderer, chaincode, network.Peer("Org1", "peer0")) 292 293 // package, install, and approve by org2 - gopath chaincode, same logic 294 packageInstallApproveChaincode(network, "testchannel", orderer, gopathChaincode, network.Peer("Org2", "peer0")) 295 296 testPeers := network.PeersWithChannel("testchannel") 297 nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), testPeers...) 298 nwo.CommitChaincode(network, "testchannel", orderer, chaincode, testPeers[0], testPeers...) 299 nwo.InitChaincode(network, "testchannel", orderer, chaincode, testPeers...) 300 301 By("listing the containers after committing the chaincode definition") 302 initialContainerFilter := map[string][]string{ 303 "name": { 304 chaincodeContainerNameFilter(network, chaincode), 305 chaincodeContainerNameFilter(network, gopathChaincode), 306 }, 307 } 308 309 containers, err := client.ListContainers(docker.ListContainersOptions{Filters: initialContainerFilter}) 310 Expect(err).NotTo(HaveOccurred()) 311 Expect(containers).To(HaveLen(2)) 312 313 RunQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel") 314 315 By("evaluating the operations endpoint and prometheus metrics") 316 CheckPeerOperationEndpoints(network, network.Peer("Org2", "peer0")) 317 CheckOrdererOperationEndpoints(network, orderer) 318 319 // upgrade chaincode to v2.0 with different label 320 chaincode.Version = "1.0" 321 chaincode.Sequence = "2" 322 chaincode.Label = "my_module_chaincode_updated" 323 gopathChaincode.Version = "1.0" 324 gopathChaincode.Sequence = "2" 325 gopathChaincode.Label = "my_simple_chaincode_updated" 326 327 // package, install, and approve by org1 - module chaincode 328 packageInstallApproveChaincode(network, "testchannel", orderer, chaincode, network.Peer("Org1", "peer0")) 329 330 // package, install, and approve by org2 - gopath chaincode, same logic 331 packageInstallApproveChaincode(network, "testchannel", orderer, gopathChaincode, network.Peer("Org2", "peer0")) 332 333 nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), testPeers...) 334 nwo.CommitChaincode(network, "testchannel", orderer, chaincode, testPeers[0], testPeers...) 335 nwo.InitChaincode(network, "testchannel", orderer, chaincode, testPeers...) 336 337 By("listing the containers after updating the chaincode definition") 338 // expect the containers for the previous package id to be stopped 339 containers, err = client.ListContainers(docker.ListContainersOptions{Filters: initialContainerFilter}) 340 Expect(err).NotTo(HaveOccurred()) 341 Expect(containers).To(HaveLen(0)) 342 updatedContainerFilter := map[string][]string{ 343 "name": { 344 chaincodeContainerNameFilter(network, chaincode), 345 chaincodeContainerNameFilter(network, gopathChaincode), 346 }, 347 } 348 containers, err = client.ListContainers(docker.ListContainersOptions{Filters: updatedContainerFilter}) 349 Expect(err).NotTo(HaveOccurred()) 350 Expect(containers).To(HaveLen(2)) 351 352 RunQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel") 353 354 By("retrieving the local mspid of the peer via simple chaincode") 355 sess, err := network.PeerUserSession(network.Peer("Org2", "peer0"), "User1", commands.ChaincodeQuery{ 356 ChannelID: "testchannel", 357 Name: "mycc", 358 Ctor: `{"Args":["mspid"]}`, 359 }) 360 Expect(err).NotTo(HaveOccurred()) 361 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 362 Expect(sess).To(gbytes.Say("Org2MSP")) 363 }) 364 }) 365 366 Describe("basic single node etcdraft network with static leader", func() { 367 var ( 368 peerRunners []*ginkgomon.Runner 369 processes map[string]ifrit.Process 370 ordererProcess ifrit.Process 371 ) 372 373 BeforeEach(func() { 374 network = nwo.New(nwo.MultiChannelEtcdRaft(), testDir, client, StartPort(), components) 375 network.Consensus.ChannelParticipationEnabled = true 376 network.GenerateConfigTree() 377 for _, peer := range network.Peers { 378 core := network.ReadPeerConfig(peer) 379 core.Peer.Gossip.UseLeaderElection = false 380 core.Peer.Gossip.OrgLeader = true 381 core.Peer.Deliveryclient.ReconnectTotalTimeThreshold = time.Duration(time.Second) 382 network.WritePeerConfig(peer, core) 383 } 384 network.Bootstrap() 385 386 ordererRunner := network.OrdererGroupRunner() 387 ordererProcess = ifrit.Invoke(ordererRunner) 388 Eventually(ordererProcess.Ready(), network.EventuallyTimeout).Should(BeClosed()) 389 390 peerRunners = make([]*ginkgomon.Runner, len(network.Peers)) 391 processes = map[string]ifrit.Process{} 392 for i, peer := range network.Peers { 393 pr := network.PeerRunner(peer) 394 peerRunners[i] = pr 395 p := ifrit.Invoke(pr) 396 processes[peer.ID()] = p 397 Eventually(p.Ready(), network.EventuallyTimeout).Should(BeClosed()) 398 } 399 }) 400 401 AfterEach(func() { 402 if ordererProcess != nil { 403 ordererProcess.Signal(syscall.SIGTERM) 404 Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive()) 405 } 406 for _, p := range processes { 407 p.Signal(syscall.SIGTERM) 408 Eventually(p.Wait(), network.EventuallyTimeout).Should(Receive()) 409 } 410 }) 411 412 It("creates two channels with two orgs trying to reconfigure and update metadata", func() { 413 orderer := network.Orderer("orderer") 414 peer := network.Peer("Org1", "peer0") 415 416 By("Create first channel and deploy the chaincode") 417 network.CreateAndJoinChannel(orderer, "testchannel") 418 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 419 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 420 RunQueryInvokeQuery(network, orderer, peer, "testchannel") 421 422 By("Create second channel and deploy chaincode") 423 network.CreateAndJoinChannel(orderer, "testchannel2") 424 cl := channelparticipation.List(network, orderer) 425 channelparticipation.ChannelListMatcher(cl, []string{"testchannel", "testchannel2"}, []string{"systemchannel"}...) 426 427 peers := network.PeersWithChannel("testchannel2") 428 nwo.EnableCapabilities(network, "testchannel2", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 429 nwo.ApproveChaincodeForMyOrg(network, "testchannel2", orderer, chaincode, peers...) 430 nwo.CheckCommitReadinessUntilReady(network, "testchannel2", chaincode, network.PeerOrgs(), peers...) 431 nwo.CommitChaincode(network, "testchannel2", orderer, chaincode, peers[0], peers...) 432 nwo.InitChaincode(network, "testchannel2", orderer, chaincode, peers...) 433 RunQueryInvokeQuery(network, orderer, peer, "testchannel2") 434 435 By("Update consensus metadata to increase snapshot interval") 436 snapDir := path.Join(network.RootDir, "orderers", orderer.ID(), "etcdraft", "snapshot", "testchannel") 437 files, err := ioutil.ReadDir(snapDir) 438 Expect(err).NotTo(HaveOccurred()) 439 numOfSnaps := len(files) 440 441 nwo.UpdateConsensusMetadata(network, peer, orderer, "testchannel", func(originalMetadata []byte) []byte { 442 metadata := &etcdraft.ConfigMetadata{} 443 err := proto.Unmarshal(originalMetadata, metadata) 444 Expect(err).NotTo(HaveOccurred()) 445 446 // update max in flight messages 447 metadata.Options.MaxInflightBlocks = 1000 448 metadata.Options.SnapshotIntervalSize = 10 * 1024 * 1024 // 10 MB 449 450 // write metadata back 451 newMetadata, err := proto.Marshal(metadata) 452 Expect(err).NotTo(HaveOccurred()) 453 return newMetadata 454 }) 455 456 // assert that no new snapshot is taken because SnapshotIntervalSize has just enlarged 457 files, err = ioutil.ReadDir(snapDir) 458 Expect(err).NotTo(HaveOccurred()) 459 Expect(len(files)).To(Equal(numOfSnaps)) 460 461 By("ensuring that static leaders do not give up on retrieving blocks after the orderer goes down") 462 ordererProcess.Signal(syscall.SIGTERM) 463 Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive()) 464 for _, peerRunner := range peerRunners { 465 Eventually(peerRunner.Err(), network.EventuallyTimeout).Should(gbytes.Say("peer is a static leader, ignoring peer.deliveryclient.reconnectTotalTimeThreshold")) 466 } 467 }) 468 }) 469 470 Describe("single node etcdraft network with remapped orderer endpoints", func() { 471 BeforeEach(func() { 472 network = nwo.New(nwo.MinimalRaft(), testDir, client, StartPort(), components) 473 network.GenerateConfigTree() 474 475 configtxConfig := network.ReadConfigTxConfig() 476 ordererEndpoints := configtxConfig.Profiles["SampleDevModeEtcdRaft"].Orderer.Organizations[0].OrdererEndpoints 477 correctOrdererEndpoint := ordererEndpoints[0] 478 ordererEndpoints[0] = "127.0.0.1:1" 479 network.WriteConfigTxConfig(configtxConfig) 480 481 peer := network.Peer("Org1", "peer0") 482 peerConfig := network.ReadPeerConfig(peer) 483 peerConfig.Peer.Deliveryclient.AddressOverrides = []*fabricconfig.AddressOverride{ 484 { 485 From: "127.0.0.1:1", 486 To: correctOrdererEndpoint, 487 CACertsFile: network.CACertsBundlePath(), 488 }, 489 } 490 network.WritePeerConfig(peer, peerConfig) 491 492 network.Bootstrap() 493 494 networkRunner := network.NetworkGroupRunner() 495 process = ifrit.Invoke(networkRunner) 496 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 497 }) 498 499 It("creates and updates channel", func() { 500 orderer := network.Orderer("orderer") 501 502 network.CreateAndJoinChannel(orderer, "testchannel") 503 504 // The below call waits for the config update to commit on the peer, so 505 // it will fail if the orderer addresses are wrong. 506 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 507 }) 508 }) 509 510 Describe("basic solo network with containers being interrupted", func() { 511 BeforeEach(func() { 512 network = nwo.New(nwo.FullSolo(), testDir, client, StartPort(), components) 513 514 network.GenerateConfigTree() 515 network.Bootstrap() 516 517 networkRunner := network.NetworkGroupRunner() 518 process = ifrit.Invoke(networkRunner) 519 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 520 }) 521 522 It("recreates terminated chaincode containers", func() { 523 chaincode := nwo.Chaincode{ 524 Name: "mycc", 525 Version: "0.0", 526 Path: "github.com/hechain20/hechain/integration/chaincode/simple/cmd", 527 Lang: "golang", 528 PackageFile: filepath.Join(testDir, "simplecc.tar.gz"), 529 Ctor: `{"Args":["init","a","100","b","200"]}`, 530 SignaturePolicy: `OR ('Org1MSP.peer', 'Org2MSP.peer')`, 531 Sequence: "1", 532 InitRequired: true, 533 Label: "my_simple_chaincode", 534 } 535 536 peer := network.Peers[0] 537 orderer := network.Orderer("orderer") 538 539 By("creating and joining channels") 540 network.CreateAndJoinChannels(orderer) 541 542 By("enabling new lifecycle capabilities") 543 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 544 By("deploying the chaincode") 545 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 546 547 By("querying and invoking chaincode") 548 RunQueryInvokeQuery(network, orderer, peer, "testchannel") 549 550 By("removing chaincode containers from all peers") 551 listChaincodeContainers := docker.ListContainersOptions{ 552 Filters: map[string][]string{ 553 "name": {chaincodeContainerNameFilter(network, chaincode)}, 554 }, 555 } 556 ctx := context.Background() 557 containers, err := client.ListContainers(listChaincodeContainers) 558 Expect(err).NotTo(HaveOccurred()) 559 Expect(containers).NotTo(BeEmpty()) 560 561 var originalContainerIDs []string 562 for _, container := range containers { 563 originalContainerIDs = append(originalContainerIDs, container.ID) 564 err = client.RemoveContainer(docker.RemoveContainerOptions{ 565 ID: container.ID, 566 RemoveVolumes: true, 567 Force: true, 568 Context: ctx, 569 }) 570 Expect(err).NotTo(HaveOccurred()) 571 } 572 573 By("invoking chaincode against all peers in test channel") 574 for _, peer := range network.Peers { 575 sess, err := network.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ 576 ChannelID: "testchannel", 577 Orderer: network.OrdererAddress(orderer, nwo.ListenPort), 578 Name: "mycc", 579 Ctor: `{"Args":["invoke","a","b","10"]}`, 580 PeerAddresses: []string{ 581 network.PeerAddress(peer, nwo.ListenPort), 582 }, 583 WaitForEvent: true, 584 }) 585 Expect(err).NotTo(HaveOccurred()) 586 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 587 Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200")) 588 } 589 590 By("checking successful removals of all old chaincode containers") 591 newContainers, err := client.ListContainers(listChaincodeContainers) 592 Expect(err).NotTo(HaveOccurred()) 593 Expect(newContainers).To(HaveLen(len(containers))) 594 595 for _, container := range newContainers { 596 Expect(originalContainerIDs).NotTo(ContainElement(container.ID)) 597 } 598 }) 599 }) 600 }) 601 602 func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string) { 603 By("querying the chaincode") 604 sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{ 605 ChannelID: channel, 606 Name: "mycc", 607 Ctor: `{"Args":["query","a"]}`, 608 }) 609 Expect(err).NotTo(HaveOccurred()) 610 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) 611 Expect(sess).To(gbytes.Say("100")) 612 613 sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ 614 ChannelID: channel, 615 Orderer: n.OrdererAddress(orderer, nwo.ListenPort), 616 Name: "mycc", 617 Ctor: `{"Args":["invoke","a","b","10"]}`, 618 PeerAddresses: []string{ 619 n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort), 620 n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort), 621 }, 622 WaitForEvent: true, 623 }) 624 Expect(err).NotTo(HaveOccurred()) 625 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) 626 Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200")) 627 628 sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{ 629 ChannelID: channel, 630 Name: "mycc", 631 Ctor: `{"Args":["query","a"]}`, 632 }) 633 Expect(err).NotTo(HaveOccurred()) 634 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) 635 Expect(sess).To(gbytes.Say("90")) 636 } 637 638 func RunRespondWith(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string) { 639 By("responding with a 300") 640 sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ 641 ChannelID: channel, 642 Orderer: n.OrdererAddress(orderer, nwo.ListenPort), 643 Name: "mycc", 644 Ctor: `{"Args":["respond","300","response-message","response-payload"]}`, 645 PeerAddresses: []string{ 646 n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort), 647 n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort), 648 }, 649 WaitForEvent: true, 650 }) 651 Expect(err).NotTo(HaveOccurred()) 652 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) 653 Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:300")) 654 655 By("responding with a 400") 656 sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{ 657 ChannelID: channel, 658 Orderer: n.OrdererAddress(orderer, nwo.ListenPort), 659 Name: "mycc", 660 Ctor: `{"Args":["respond","400","response-message","response-payload"]}`, 661 PeerAddresses: []string{ 662 n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort), 663 n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort), 664 }, 665 WaitForEvent: true, 666 }) 667 Expect(err).NotTo(HaveOccurred()) 668 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(1)) 669 Expect(sess.Err).To(gbytes.Say(`Error: endorsement failure during invoke.`)) 670 } 671 672 func CheckPeerStatsdMetrics(prefix string, mr *MetricsReader, timeout time.Duration) { 673 By("checking for peer statsd metrics") 674 Eventually(mr.String, timeout).Should(SatisfyAll( 675 ContainSubstring(prefix+".logging.entries_checked.info:"), 676 ContainSubstring(prefix+".logging.entries_written.info:"), 677 ContainSubstring(prefix+".go.mem.gc_completed_count:"), 678 ContainSubstring(prefix+".grpc.server.unary_requests_received.protos_Endorser.ProcessProposal:"), 679 ContainSubstring(prefix+".grpc.server.unary_requests_completed.protos_Endorser.ProcessProposal.OK:"), 680 ContainSubstring(prefix+".grpc.server.unary_request_duration.protos_Endorser.ProcessProposal.OK:"), 681 ContainSubstring(prefix+".ledger.blockchain_height"), 682 ContainSubstring(prefix+".ledger.blockstorage_commit_time"), 683 ContainSubstring(prefix+".ledger.blockstorage_and_pvtdata_commit_time"), 684 )) 685 } 686 687 func CheckPeerStatsdStreamMetrics(mr *MetricsReader, timeout time.Duration) { 688 By("checking for stream metrics") 689 Eventually(mr.String, timeout).Should(SatisfyAll( 690 ContainSubstring(".grpc.server.stream_requests_received.protos_Deliver.DeliverFiltered:"), 691 ContainSubstring(".grpc.server.stream_requests_completed.protos_Deliver.DeliverFiltered.Unknown:"), 692 ContainSubstring(".grpc.server.stream_request_duration.protos_Deliver.DeliverFiltered.Unknown:"), 693 ContainSubstring(".grpc.server.stream_messages_received.protos_Deliver.DeliverFiltered"), 694 ContainSubstring(".grpc.server.stream_messages_sent.protos_Deliver.DeliverFiltered"), 695 )) 696 } 697 698 func CheckOrdererStatsdMetrics(prefix string, mr *MetricsReader, timeout time.Duration) { 699 Eventually(mr.String, timeout).Should(SatisfyAll( 700 ContainSubstring(prefix+".grpc.server.stream_request_duration.orderer_AtomicBroadcast.Broadcast.OK"), 701 ContainSubstring(prefix+".grpc.server.stream_request_duration.orderer_AtomicBroadcast.Deliver."), 702 ContainSubstring(prefix+".logging.entries_checked.info:"), 703 ContainSubstring(prefix+".logging.entries_written.info:"), 704 ContainSubstring(prefix+".go.mem.gc_completed_count:"), 705 ContainSubstring(prefix+".grpc.server.stream_requests_received.orderer_AtomicBroadcast.Deliver:"), 706 ContainSubstring(prefix+".grpc.server.stream_requests_completed.orderer_AtomicBroadcast.Deliver."), 707 ContainSubstring(prefix+".grpc.server.stream_messages_received.orderer_AtomicBroadcast.Deliver"), 708 ContainSubstring(prefix+".grpc.server.stream_messages_sent.orderer_AtomicBroadcast.Deliver"), 709 ContainSubstring(prefix+".ledger.blockchain_height"), 710 ContainSubstring(prefix+".ledger.blockstorage_commit_time"), 711 )) 712 } 713 714 func CheckPeerOperationEndpoints(network *nwo.Network, peer *nwo.Peer) { 715 metricsURL := fmt.Sprintf("https://127.0.0.1:%d/metrics", network.PeerPort(peer, nwo.OperationsPort)) 716 logspecURL := fmt.Sprintf("https://127.0.0.1:%d/logspec", network.PeerPort(peer, nwo.OperationsPort)) 717 healthURL := fmt.Sprintf("https://127.0.0.1:%d/healthz", network.PeerPort(peer, nwo.OperationsPort)) 718 719 authClient, unauthClient := nwo.PeerOperationalClients(network, peer) 720 721 CheckPeerPrometheusMetrics(authClient, metricsURL) 722 CheckLogspecOperations(authClient, logspecURL) 723 CheckHealthEndpoint(authClient, healthURL) 724 725 By("getting the logspec without a client cert") 726 resp, err := unauthClient.Get(logspecURL) 727 Expect(err).NotTo(HaveOccurred()) 728 Expect(resp.StatusCode).To(Equal(http.StatusUnauthorized)) 729 730 By("ensuring health checks do not require a client cert") 731 CheckHealthEndpoint(unauthClient, healthURL) 732 } 733 734 func CheckOrdererOperationEndpoints(network *nwo.Network, orderer *nwo.Orderer) { 735 metricsURL := fmt.Sprintf("https://127.0.0.1:%d/metrics", network.OrdererPort(orderer, nwo.OperationsPort)) 736 logspecURL := fmt.Sprintf("https://127.0.0.1:%d/logspec", network.OrdererPort(orderer, nwo.OperationsPort)) 737 healthURL := fmt.Sprintf("https://127.0.0.1:%d/healthz", network.OrdererPort(orderer, nwo.OperationsPort)) 738 739 authClient, unauthClient := nwo.OrdererOperationalClients(network, orderer) 740 741 CheckOrdererPrometheusMetrics(authClient, metricsURL) 742 CheckLogspecOperations(authClient, logspecURL) 743 CheckHealthEndpoint(authClient, healthURL) 744 745 By("getting the logspec without a client cert") 746 resp, err := unauthClient.Get(logspecURL) 747 Expect(err).NotTo(HaveOccurred()) 748 Expect(resp.StatusCode).To(Equal(http.StatusUnauthorized)) 749 750 By("ensuring health checks do not require a client cert") 751 CheckHealthEndpoint(unauthClient, healthURL) 752 } 753 754 func CheckPeerPrometheusMetrics(client *http.Client, url string) { 755 By("hitting the prometheus metrics endpoint") 756 resp, err := client.Get(url) 757 Expect(err).NotTo(HaveOccurred()) 758 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 759 resp.Body.Close() 760 761 Eventually(getBody(client, url)).Should(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`)) 762 763 By("checking for some expected metrics") 764 body := getBody(client, url)() 765 Expect(body).To(ContainSubstring(`# TYPE go_gc_duration_seconds summary`)) 766 Expect(body).To(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`)) 767 Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_count{code="Unknown",method="DeliverFiltered",service="protos_Deliver"}`)) 768 Expect(body).To(ContainSubstring(`grpc_server_stream_messages_received{method="DeliverFiltered",service="protos_Deliver"}`)) 769 Expect(body).To(ContainSubstring(`grpc_server_stream_messages_sent{method="DeliverFiltered",service="protos_Deliver"}`)) 770 Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_closed counter`)) 771 Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_opened counter`)) 772 Expect(body).To(ContainSubstring(`ledger_blockchain_height`)) 773 Expect(body).To(ContainSubstring(`ledger_blockstorage_commit_time_bucket`)) 774 Expect(body).To(ContainSubstring(`ledger_blockstorage_and_pvtdata_commit_time_bucket`)) 775 } 776 777 func CheckOrdererPrometheusMetrics(client *http.Client, url string) { 778 By("hitting the prometheus metrics endpoint") 779 resp, err := client.Get(url) 780 Expect(err).NotTo(HaveOccurred()) 781 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 782 resp.Body.Close() 783 784 Eventually(getBody(client, url)).Should(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`)) 785 786 By("checking for some expected metrics") 787 body := getBody(client, url)() 788 Expect(body).To(ContainSubstring(`# TYPE go_gc_duration_seconds summary`)) 789 Expect(body).To(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`)) 790 Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_sum{code="OK",method="Deliver",service="orderer_AtomicBroadcast"`)) 791 Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_sum{code="OK",method="Broadcast",service="orderer_AtomicBroadcast"`)) 792 Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_closed counter`)) 793 Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_opened counter`)) 794 Expect(body).To(ContainSubstring(`ledger_blockchain_height`)) 795 Expect(body).To(ContainSubstring(`ledger_blockstorage_commit_time_bucket`)) 796 } 797 798 func CheckLogspecOperations(client *http.Client, logspecURL string) { 799 By("getting the logspec") 800 resp, err := client.Get(logspecURL) 801 Expect(err).NotTo(HaveOccurred()) 802 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 803 bodyBytes, err := ioutil.ReadAll(resp.Body) 804 resp.Body.Close() 805 Expect(err).NotTo(HaveOccurred()) 806 Expect(string(bodyBytes)).To(MatchJSON(`{"spec":"info"}`)) 807 808 updateReq, err := http.NewRequest(http.MethodPut, logspecURL, strings.NewReader(`{"spec":"debug"}`)) 809 Expect(err).NotTo(HaveOccurred()) 810 811 By("setting the logspec") 812 resp, err = client.Do(updateReq) 813 Expect(err).NotTo(HaveOccurred()) 814 Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) 815 resp.Body.Close() 816 817 resp, err = client.Get(logspecURL) 818 Expect(err).NotTo(HaveOccurred()) 819 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 820 bodyBytes, err = ioutil.ReadAll(resp.Body) 821 resp.Body.Close() 822 Expect(err).NotTo(HaveOccurred()) 823 Expect(string(bodyBytes)).To(MatchJSON(`{"spec":"debug"}`)) 824 825 By("resetting the logspec") 826 updateReq, err = http.NewRequest(http.MethodPut, logspecURL, strings.NewReader(`{"spec":"info"}`)) 827 Expect(err).NotTo(HaveOccurred()) 828 resp, err = client.Do(updateReq) 829 Expect(err).NotTo(HaveOccurred()) 830 Expect(resp.StatusCode).To(Equal(http.StatusNoContent)) 831 resp.Body.Close() 832 } 833 834 func CheckHealthEndpoint(client *http.Client, url string) { 835 body := getBody(client, url)() 836 837 var healthStatus healthz.HealthStatus 838 err := json.Unmarshal([]byte(body), &healthStatus) 839 Expect(err).NotTo(HaveOccurred()) 840 Expect(healthStatus.Status).To(Equal(healthz.StatusOK)) 841 } 842 843 func getBody(client *http.Client, url string) func() string { 844 return func() string { 845 resp, err := client.Get(url) 846 Expect(err).NotTo(HaveOccurred()) 847 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 848 bodyBytes, err := ioutil.ReadAll(resp.Body) 849 Expect(err).NotTo(HaveOccurred()) 850 resp.Body.Close() 851 return string(bodyBytes) 852 } 853 } 854 855 func packageInstallApproveChaincode(network *nwo.Network, channel string, orderer *nwo.Orderer, chaincode nwo.Chaincode, peers ...*nwo.Peer) { 856 nwo.PackageChaincode(network, chaincode, peers[0]) 857 nwo.InstallChaincode(network, chaincode, peers...) 858 nwo.ApproveChaincodeForMyOrg(network, channel, orderer, chaincode, peers...) 859 } 860 861 func hashFile(file string) string { 862 f, err := os.Open(file) 863 Expect(err).NotTo(HaveOccurred()) 864 defer f.Close() 865 866 h := sha256.New() 867 _, err = io.Copy(h, f) 868 Expect(err).NotTo(HaveOccurred()) 869 870 return fmt.Sprintf("%x", h.Sum(nil)) 871 } 872 873 func chaincodeContainerNameFilter(n *nwo.Network, chaincode nwo.Chaincode) string { 874 return fmt.Sprintf("^/%s-.*-%s-%s$", n.NetworkID, chaincode.Label, hashFile(chaincode.PackageFile)) 875 }