github.com/lzy4123/fabric@v2.1.1+incompatible/internal/peer/lifecycle/chaincode/package_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 "archive/tar" 11 "bytes" 12 "compress/gzip" 13 "io" 14 "io/ioutil" 15 "os" 16 "path/filepath" 17 18 "github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode" 19 "github.com/hyperledger/fabric/internal/peer/lifecycle/chaincode/mock" 20 "github.com/pkg/errors" 21 "github.com/spf13/cobra" 22 23 . "github.com/onsi/ginkgo" 24 . "github.com/onsi/gomega" 25 ) 26 27 var _ = Describe("Package", func() { 28 Describe("Packager", func() { 29 var ( 30 mockPlatformRegistry *mock.PlatformRegistry 31 mockWriter *mock.Writer 32 input *chaincode.PackageInput 33 packager *chaincode.Packager 34 ) 35 36 BeforeEach(func() { 37 mockPlatformRegistry = &mock.PlatformRegistry{} 38 mockPlatformRegistry.NormalizePathReturns("normalizedPath", nil) 39 40 input = &chaincode.PackageInput{ 41 OutputFile: "testDir/testPackage", 42 Path: "testPath", 43 Type: "testType", 44 Label: "testLabel", 45 } 46 47 mockWriter = &mock.Writer{} 48 49 packager = &chaincode.Packager{ 50 PlatformRegistry: mockPlatformRegistry, 51 Writer: mockWriter, 52 Input: input, 53 } 54 }) 55 56 It("packages chaincodes", func() { 57 err := packager.Package() 58 Expect(err).NotTo(HaveOccurred()) 59 60 Expect(mockPlatformRegistry.NormalizePathCallCount()).To(Equal(1)) 61 ccType, path := mockPlatformRegistry.NormalizePathArgsForCall(0) 62 Expect(ccType).To(Equal("TESTTYPE")) 63 Expect(path).To(Equal("testPath")) 64 65 Expect(mockPlatformRegistry.GetDeploymentPayloadCallCount()).To(Equal(1)) 66 ccType, path = mockPlatformRegistry.GetDeploymentPayloadArgsForCall(0) 67 Expect(ccType).To(Equal("TESTTYPE")) 68 Expect(path).To(Equal("testPath")) 69 70 Expect(mockWriter.WriteFileCallCount()).To(Equal(1)) 71 dir, name, pkgTarGzBytes := mockWriter.WriteFileArgsForCall(0) 72 wd, err := os.Getwd() 73 Expect(err).NotTo(HaveOccurred()) 74 Expect(dir).To(Equal(filepath.Join(wd, "testDir"))) 75 Expect(name).To(Equal("testPackage")) 76 Expect(pkgTarGzBytes).NotTo(BeNil()) 77 78 metadata, err := readMetadataFromBytes(pkgTarGzBytes) 79 Expect(err).NotTo(HaveOccurred()) 80 Expect(metadata).To(MatchJSON(`{"path":"normalizedPath","type":"testType","label":"testLabel"}`)) 81 }) 82 83 Context("when the path is not provided", func() { 84 BeforeEach(func() { 85 input.Path = "" 86 }) 87 88 It("returns an error", func() { 89 err := packager.Package() 90 Expect(err).To(MatchError("chaincode path must be specified")) 91 }) 92 }) 93 94 Context("when the type is not provided", func() { 95 BeforeEach(func() { 96 input.Type = "" 97 }) 98 99 It("returns an error", func() { 100 err := packager.Package() 101 Expect(err).To(MatchError("chaincode language must be specified")) 102 }) 103 }) 104 105 Context("when the output file is not provided", func() { 106 BeforeEach(func() { 107 input.OutputFile = "" 108 }) 109 110 It("returns an error", func() { 111 err := packager.Package() 112 Expect(err).To(MatchError("output file must be specified")) 113 }) 114 }) 115 116 Context("when the label is not provided", func() { 117 BeforeEach(func() { 118 input.Label = "" 119 }) 120 121 It("returns an error", func() { 122 err := packager.Package() 123 Expect(err).To(MatchError("package label must be specified")) 124 }) 125 }) 126 127 Context("when the label is invalid", func() { 128 BeforeEach(func() { 129 input.Label = "label with spaces" 130 }) 131 132 It("returns an error", func() { 133 err := packager.Package() 134 Expect(err).To(MatchError("invalid label 'label with spaces'. Label must be non-empty, can only consist of alphanumerics, symbols from '.+-_', and can only begin with alphanumerics")) 135 }) 136 }) 137 138 Context("when the platform registry fails to normalize the path", func() { 139 BeforeEach(func() { 140 mockPlatformRegistry.NormalizePathReturns("", errors.New("cortado")) 141 }) 142 143 It("returns an error", func() { 144 err := packager.Package() 145 Expect(err).To(MatchError("failed to normalize chaincode path: cortado")) 146 }) 147 }) 148 149 Context("when the platform registry fails to get the deployment payload", func() { 150 BeforeEach(func() { 151 mockPlatformRegistry.GetDeploymentPayloadReturns(nil, errors.New("americano")) 152 }) 153 154 It("returns an error", func() { 155 err := packager.Package() 156 Expect(err).To(MatchError("error getting chaincode bytes: americano")) 157 }) 158 }) 159 160 Context("when writing the file fails", func() { 161 BeforeEach(func() { 162 mockWriter.WriteFileReturns(errors.New("espresso")) 163 }) 164 165 It("returns an error", func() { 166 err := packager.Package() 167 Expect(err).To(MatchError("error writing chaincode package to testDir/testPackage: espresso")) 168 }) 169 }) 170 }) 171 172 Describe("PackageCmd", func() { 173 var ( 174 packageCmd *cobra.Command 175 ) 176 177 BeforeEach(func() { 178 packageCmd = chaincode.PackageCmd(nil) 179 packageCmd.SetArgs([]string{ 180 "testPackage", 181 "--path=testPath", 182 "--lang=golang", 183 "--label=testLabel", 184 }) 185 }) 186 187 It("sets up the packager and attempts to package the chaincode", func() { 188 err := packageCmd.Execute() 189 Expect(err).To(MatchError(ContainSubstring("error getting chaincode bytes"))) 190 }) 191 192 Context("when more than one argument is provided", func() { 193 BeforeEach(func() { 194 packageCmd = chaincode.PackageCmd(nil) 195 packageCmd.SetArgs([]string{ 196 "testPackage", 197 "whatthe", 198 }) 199 }) 200 201 It("returns an error", func() { 202 err := packageCmd.Execute() 203 Expect(err).To(MatchError("invalid number of args. expected only the output file")) 204 }) 205 }) 206 207 Context("when no argument is provided", func() { 208 BeforeEach(func() { 209 packageCmd = chaincode.PackageCmd(nil) 210 packageCmd.SetArgs([]string{}) 211 }) 212 213 It("returns an error", func() { 214 err := packageCmd.Execute() 215 Expect(err).To(MatchError("invalid number of args. expected only the output file")) 216 }) 217 }) 218 }) 219 }) 220 221 func readMetadataFromBytes(pkgTarGzBytes []byte) ([]byte, error) { 222 buffer := bytes.NewBuffer(pkgTarGzBytes) 223 gzr, err := gzip.NewReader(buffer) 224 Expect(err).NotTo(HaveOccurred()) 225 defer gzr.Close() 226 tr := tar.NewReader(gzr) 227 for { 228 header, err := tr.Next() 229 if err == io.EOF { 230 break 231 } 232 if err != nil { 233 return nil, err 234 } 235 if header.Name == "metadata.json" { 236 return ioutil.ReadAll(tr) 237 } 238 } 239 return nil, errors.New("metadata.json not found") 240 }