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  }