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  })