github.com/lzy4123/fabric@v2.1.1+incompatible/internal/peer/lifecycle/chaincode/queryinstalled_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package chaincode_test 8 9 import ( 10 "encoding/json" 11 "fmt" 12 13 "github.com/golang/protobuf/proto" 14 pb "github.com/hyperledger/fabric-protos-go/peer" 15 lb "github.com/hyperledger/fabric-protos-go/peer/lifecycle" 16 "github.com/hyperledger/fabric/bccsp/sw" 17 "github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode" 18 "github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode/mock" 19 "github.com/pkg/errors" 20 "github.com/spf13/cobra" 21 22 . "github.com/onsi/ginkgo" 23 . "github.com/onsi/gomega" 24 "github.com/onsi/gomega/gbytes" 25 ) 26 27 var _ = Describe("QueryInstalled", func() { 28 Describe("InstalledQuerier", func() { 29 var ( 30 mockProposalResponse *pb.ProposalResponse 31 mockEndorserClient *mock.EndorserClient 32 mockSigner *mock.Signer 33 input *chaincode.InstalledQueryInput 34 installedQuerier *chaincode.InstalledQuerier 35 ) 36 37 BeforeEach(func() { 38 mockEndorserClient = &mock.EndorserClient{} 39 qicr := &lb.QueryInstalledChaincodesResult{ 40 InstalledChaincodes: []*lb.QueryInstalledChaincodesResult_InstalledChaincode{ 41 { 42 PackageId: "packageid1", 43 Label: "label1", 44 }, 45 }, 46 } 47 qicrBytes, err := proto.Marshal(qicr) 48 Expect(err).NotTo(HaveOccurred()) 49 mockProposalResponse = &pb.ProposalResponse{ 50 Response: &pb.Response{ 51 Status: 200, 52 Payload: qicrBytes, 53 }, 54 } 55 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 56 57 mockSigner = &mock.Signer{} 58 buffer := gbytes.NewBuffer() 59 input = &chaincode.InstalledQueryInput{} 60 61 installedQuerier = &chaincode.InstalledQuerier{ 62 Input: input, 63 EndorserClient: mockEndorserClient, 64 Signer: mockSigner, 65 Writer: buffer, 66 } 67 }) 68 69 It("queries installed chaincodes and writes the output as human readable plain-text", func() { 70 err := installedQuerier.Query() 71 Expect(err).NotTo(HaveOccurred()) 72 Eventually(installedQuerier.Writer).Should(gbytes.Say("Installed chaincodes on peer:")) 73 Eventually(installedQuerier.Writer).Should(gbytes.Say("Package ID: packageid1, Label: label1")) 74 }) 75 76 Context("when JSON-formatted output is requested", func() { 77 BeforeEach(func() { 78 installedQuerier.Input.OutputFormat = "json" 79 }) 80 81 It("queries installed chaincodes and writes the output as JSON", func() { 82 err := installedQuerier.Query() 83 Expect(err).NotTo(HaveOccurred()) 84 expectedOutput := &lb.QueryInstalledChaincodesResult{ 85 InstalledChaincodes: []*lb.QueryInstalledChaincodesResult_InstalledChaincode{ 86 { 87 PackageId: "packageid1", 88 Label: "label1", 89 }, 90 }, 91 } 92 json, err := json.MarshalIndent(expectedOutput, "", "\t") 93 Eventually(installedQuerier.Writer).Should(gbytes.Say(fmt.Sprintf(`\Q%s\E`, string(json)))) 94 }) 95 }) 96 97 Context("when the signer cannot be serialized", func() { 98 BeforeEach(func() { 99 mockSigner.SerializeReturns(nil, errors.New("cafe")) 100 }) 101 102 It("returns an error", func() { 103 err := installedQuerier.Query() 104 Expect(err).To(MatchError("failed to create proposal: failed to serialize identity: cafe")) 105 }) 106 }) 107 108 Context("when the signer fails to sign the proposal", func() { 109 BeforeEach(func() { 110 mockSigner.SignReturns(nil, errors.New("tea")) 111 }) 112 113 It("returns an error", func() { 114 err := installedQuerier.Query() 115 Expect(err).To(MatchError("failed to create signed proposal: tea")) 116 }) 117 }) 118 119 Context("when the endorser fails to endorse the proposal", func() { 120 BeforeEach(func() { 121 mockEndorserClient.ProcessProposalReturns(nil, errors.New("latte")) 122 }) 123 124 It("returns an error", func() { 125 err := installedQuerier.Query() 126 Expect(err).To(MatchError("failed to endorse proposal: latte")) 127 }) 128 }) 129 130 Context("when the endorser returns a nil proposal response", func() { 131 BeforeEach(func() { 132 mockProposalResponse = nil 133 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 134 }) 135 136 It("returns an error", func() { 137 err := installedQuerier.Query() 138 Expect(err).To(MatchError("received nil proposal response")) 139 }) 140 }) 141 142 Context("when the endorser returns a proposal response with a nil response", func() { 143 BeforeEach(func() { 144 mockProposalResponse.Response = nil 145 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 146 }) 147 148 It("returns an error", func() { 149 err := installedQuerier.Query() 150 Expect(err).To(MatchError("received proposal response with nil response")) 151 }) 152 }) 153 154 Context("when the endorser returns a non-success status", func() { 155 BeforeEach(func() { 156 mockProposalResponse.Response = &pb.Response{ 157 Status: 500, 158 Message: "capuccino", 159 } 160 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 161 }) 162 163 It("returns an error", func() { 164 err := installedQuerier.Query() 165 Expect(err).To(MatchError("query failed with status: 500 - capuccino")) 166 }) 167 }) 168 169 Context("when the payload contains bytes that aren't a QueryInstalledChaincodesResult", func() { 170 BeforeEach(func() { 171 mockProposalResponse.Response = &pb.Response{ 172 Payload: []byte("badpayloadbadpayload"), 173 Status: 200, 174 } 175 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 176 }) 177 178 It("returns an error", func() { 179 err := installedQuerier.Query() 180 Expect(err).To(MatchError(ContainSubstring("failed to unmarshal proposal response's response payload"))) 181 }) 182 }) 183 }) 184 185 Describe("QueryInstalledCmd", func() { 186 var ( 187 queryInstalledCmd *cobra.Command 188 ) 189 190 BeforeEach(func() { 191 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 192 Expect(err).To(BeNil()) 193 queryInstalledCmd = chaincode.QueryInstalledCmd(nil, cryptoProvider) 194 queryInstalledCmd.SetArgs([]string{ 195 "--peerAddresses=querypeer1", 196 "--tlsRootCertFiles=tls1", 197 }) 198 }) 199 200 AfterEach(func() { 201 chaincode.ResetFlags() 202 }) 203 204 It("attempts to connect to the endorser", func() { 205 err := queryInstalledCmd.Execute() 206 Expect(err).To(MatchError(ContainSubstring("failed to retrieve endorser client"))) 207 }) 208 209 Context("when more than one peer address is provided", func() { 210 BeforeEach(func() { 211 queryInstalledCmd.SetArgs([]string{ 212 "--peerAddresses=queryinstalledpeer1", 213 "--tlsRootCertFiles=tls1", 214 "--peerAddresses=queryinstalledpeer2", 215 "--tlsRootCertFiles=tls2", 216 }) 217 }) 218 219 It("returns an error", func() { 220 err := queryInstalledCmd.Execute() 221 Expect(err).To(MatchError(ContainSubstring("failed to validate peer connection parameters"))) 222 }) 223 }) 224 }) 225 })