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