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