github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/bccsp/sw" 17 "github.com/osdi23p228/fabric/internal/peer/lifecycle/chaincode" 18 "github.com/osdi23p228/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 Expect(err).NotTo(HaveOccurred()) 94 Eventually(installedQuerier.Writer).Should(gbytes.Say(fmt.Sprintf(`\Q%s\E`, string(json)))) 95 }) 96 }) 97 98 Context("when the signer cannot be serialized", func() { 99 BeforeEach(func() { 100 mockSigner.SerializeReturns(nil, errors.New("cafe")) 101 }) 102 103 It("returns an error", func() { 104 err := installedQuerier.Query() 105 Expect(err).To(MatchError("failed to create proposal: failed to serialize identity: cafe")) 106 }) 107 }) 108 109 Context("when the signer fails to sign the proposal", func() { 110 BeforeEach(func() { 111 mockSigner.SignReturns(nil, errors.New("tea")) 112 }) 113 114 It("returns an error", func() { 115 err := installedQuerier.Query() 116 Expect(err).To(MatchError("failed to create signed proposal: tea")) 117 }) 118 }) 119 120 Context("when the endorser fails to endorse the proposal", func() { 121 BeforeEach(func() { 122 mockEndorserClient.ProcessProposalReturns(nil, errors.New("latte")) 123 }) 124 125 It("returns an error", func() { 126 err := installedQuerier.Query() 127 Expect(err).To(MatchError("failed to endorse proposal: latte")) 128 }) 129 }) 130 131 Context("when the endorser returns a nil proposal response", func() { 132 BeforeEach(func() { 133 mockProposalResponse = nil 134 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 135 }) 136 137 It("returns an error", func() { 138 err := installedQuerier.Query() 139 Expect(err).To(MatchError("received nil proposal response")) 140 }) 141 }) 142 143 Context("when the endorser returns a proposal response with a nil response", func() { 144 BeforeEach(func() { 145 mockProposalResponse.Response = nil 146 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 147 }) 148 149 It("returns an error", func() { 150 err := installedQuerier.Query() 151 Expect(err).To(MatchError("received proposal response with nil response")) 152 }) 153 }) 154 155 Context("when the endorser returns a non-success status", func() { 156 BeforeEach(func() { 157 mockProposalResponse.Response = &pb.Response{ 158 Status: 500, 159 Message: "capuccino", 160 } 161 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 162 }) 163 164 It("returns an error", func() { 165 err := installedQuerier.Query() 166 Expect(err).To(MatchError("query failed with status: 500 - capuccino")) 167 }) 168 }) 169 170 Context("when the payload contains bytes that aren't a QueryInstalledChaincodesResult", func() { 171 BeforeEach(func() { 172 mockProposalResponse.Response = &pb.Response{ 173 Payload: []byte("badpayloadbadpayload"), 174 Status: 200, 175 } 176 mockEndorserClient.ProcessProposalReturns(mockProposalResponse, nil) 177 }) 178 179 It("returns an error", func() { 180 err := installedQuerier.Query() 181 Expect(err).To(MatchError(ContainSubstring("failed to unmarshal proposal response's response payload"))) 182 }) 183 }) 184 }) 185 186 Describe("QueryInstalledCmd", func() { 187 var queryInstalledCmd *cobra.Command 188 189 BeforeEach(func() { 190 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 191 Expect(err).To(BeNil()) 192 queryInstalledCmd = chaincode.QueryInstalledCmd(nil, cryptoProvider) 193 queryInstalledCmd.SilenceErrors = true 194 queryInstalledCmd.SilenceUsage = true 195 queryInstalledCmd.SetArgs([]string{ 196 "--peerAddresses=querypeer1", 197 "--tlsRootCertFiles=tls1", 198 }) 199 }) 200 201 AfterEach(func() { 202 chaincode.ResetFlags() 203 }) 204 205 It("attempts to connect to the endorser", func() { 206 err := queryInstalledCmd.Execute() 207 Expect(err).To(MatchError(ContainSubstring("failed to retrieve endorser client"))) 208 }) 209 210 Context("when more than one peer address is provided", func() { 211 BeforeEach(func() { 212 queryInstalledCmd.SetArgs([]string{ 213 "--peerAddresses=queryinstalledpeer1", 214 "--tlsRootCertFiles=tls1", 215 "--peerAddresses=queryinstalledpeer2", 216 "--tlsRootCertFiles=tls2", 217 }) 218 }) 219 220 It("returns an error", func() { 221 err := queryInstalledCmd.Execute() 222 Expect(err).To(MatchError(ContainSubstring("failed to validate peer connection parameters"))) 223 }) 224 }) 225 }) 226 })