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