github.com/renegr87/renegr87@v2.1.1+incompatible/core/common/ccprovider/ccprovider_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package ccprovider_test 8 9 import ( 10 "crypto/sha256" 11 "io/ioutil" 12 "os" 13 "path" 14 "strings" 15 "testing" 16 17 "github.com/golang/protobuf/proto" 18 "github.com/hyperledger/fabric-protos-go/peer" 19 "github.com/hyperledger/fabric/bccsp/sw" 20 "github.com/hyperledger/fabric/common/chaincode" 21 "github.com/hyperledger/fabric/core/common/ccprovider" 22 "github.com/pkg/errors" 23 "github.com/stretchr/testify/assert" 24 ) 25 26 func TestInstalledCCs(t *testing.T) { 27 tmpDir, hashes := setupDirectoryStructure(t) 28 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 29 assert.NoError(t, err) 30 31 defer func() { 32 os.RemoveAll(tmpDir) 33 }() 34 35 testCases := []struct { 36 name string 37 directory string 38 expected []chaincode.InstalledChaincode 39 errorContains string 40 ls ccprovider.DirEnumerator 41 extractCCFromPath ccprovider.ChaincodeExtractor 42 }{ 43 { 44 name: "Non-empty directory", 45 ls: ioutil.ReadDir, 46 extractCCFromPath: ccprovider.LoadPackage, 47 expected: []chaincode.InstalledChaincode{ 48 { 49 Name: "example02", 50 Version: "1.0", 51 Hash: hashes["example02.1.0"], 52 }, 53 { 54 Name: "example04", 55 Version: "1", 56 Hash: hashes["example04.1"], 57 }, 58 }, 59 directory: "nonempty", 60 }, 61 { 62 name: "Nonexistent directory", 63 ls: ioutil.ReadDir, 64 extractCCFromPath: ccprovider.LoadPackage, 65 expected: nil, 66 directory: "nonexistent", 67 }, 68 { 69 name: "Empty directory", 70 ls: ioutil.ReadDir, 71 extractCCFromPath: ccprovider.LoadPackage, 72 expected: nil, 73 directory: "empty", 74 }, 75 { 76 name: "No permission to open directory", 77 ls: func(_ string) ([]os.FileInfo, error) { 78 return nil, errors.New("orange") 79 }, 80 extractCCFromPath: ccprovider.LoadPackage, 81 expected: nil, 82 directory: "nopermission", 83 errorContains: "orange", 84 }, 85 { 86 name: "No permission on chaincode files", 87 ls: ioutil.ReadDir, 88 extractCCFromPath: func(_ string, _ string, _ ccprovider.GetHasher) (ccprovider.CCPackage, error) { 89 return nil, errors.New("banana") 90 }, 91 expected: nil, 92 directory: "nopermissionforfiles", 93 errorContains: "banana", 94 }, 95 } 96 _ = testCases 97 98 for _, test := range testCases { 99 test := test 100 t.Run(test.name, func(t *testing.T) { 101 c := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider} 102 res, err := c.ListInstalledChaincodes(path.Join(tmpDir, test.directory), test.ls, test.extractCCFromPath) 103 assert.Equal(t, test.expected, res) 104 if test.errorContains == "" { 105 assert.NoError(t, err) 106 } else { 107 assert.Contains(t, err.Error(), test.errorContains) 108 } 109 }) 110 } 111 } 112 113 func TestGetChaincodeInstallPath(t *testing.T) { 114 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 115 assert.NoError(t, err) 116 c := &ccprovider.CCInfoFSImpl{GetHasher: cryptoProvider} 117 installPath := c.GetChaincodeInstallPath() 118 defer ccprovider.SetChaincodesPath(installPath) 119 120 ccprovider.SetChaincodesPath("blahblah") 121 assert.Equal(t, "blahblah", c.GetChaincodeInstallPath()) 122 } 123 124 func setupDirectoryStructure(t *testing.T) (string, map[string][]byte) { 125 files := []string{ 126 "example02.1.0", // Version contains the delimiter '.' is a valid case 127 "example03", // No version specified 128 "example04.1", // Version doesn't contain the '.' delimiter 129 } 130 hashes := map[string][]byte{} 131 tmp, err := ioutil.TempDir("", "test-installed-cc") 132 assert.NoError(t, err) 133 dir := path.Join(tmp, "empty") 134 assert.NoError(t, os.Mkdir(dir, 0755)) 135 dir = path.Join(tmp, "nonempty") 136 assert.NoError(t, os.Mkdir(dir, 0755)) 137 dir = path.Join(tmp, "nopermission") 138 assert.NoError(t, os.Mkdir(dir, 0755)) 139 dir = path.Join(tmp, "nopermissionforfiles") 140 assert.NoError(t, os.Mkdir(dir, 0755)) 141 noPermissionFile := path.Join(tmp, "nopermissionforfiles", "nopermission.1") 142 _, err = os.Create(noPermissionFile) 143 assert.NoError(t, err) 144 dir = path.Join(tmp, "nonempty") 145 assert.NoError(t, os.Mkdir(path.Join(tmp, "nonempty", "directory"), 0755)) 146 for _, f := range files { 147 var name, ver string 148 parts := strings.SplitN(f, ".", 2) 149 name = parts[0] 150 if len(parts) > 1 { 151 ver = parts[1] 152 } 153 file, err := os.Create(path.Join(dir, f)) 154 assert.NoError(t, err) 155 cds := &peer.ChaincodeDeploymentSpec{ 156 ChaincodeSpec: &peer.ChaincodeSpec{ 157 ChaincodeId: &peer.ChaincodeID{Name: name, Version: ver}, 158 }, 159 } 160 161 codehash := sha256.New() 162 codehash.Write(cds.CodePackage) 163 164 metahash := sha256.New() 165 metahash.Write([]byte(name)) 166 metahash.Write([]byte(ver)) 167 168 hash := sha256.New() 169 hash.Write(codehash.Sum(nil)) 170 hash.Write(metahash.Sum(nil)) 171 172 hashes[f] = hash.Sum(nil) 173 174 b, _ := proto.Marshal(cds) 175 file.Write(b) 176 file.Close() 177 } 178 179 return tmp, hashes 180 }