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