github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/common/ccprovider/cdspackage_test.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package ccprovider 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "os" 13 "testing" 14 15 pb "github.com/hyperledger/fabric-protos-go/peer" 16 "github.com/hyperledger/fabric/bccsp/sw" 17 "github.com/hyperledger/fabric/protoutil" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 func setupccdir() string { 22 tempDir, err := ioutil.TempDir("/tmp", "ccprovidertest") 23 if err != nil { 24 panic(err) 25 } 26 SetChaincodesPath(tempDir) 27 return tempDir 28 } 29 30 func processCDS(cds *pb.ChaincodeDeploymentSpec, tofs bool) (*CDSPackage, []byte, *ChaincodeData, error) { 31 b := protoutil.MarshalOrPanic(cds) 32 33 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 34 if err != nil { 35 return nil, nil, nil, fmt.Errorf("error creating bootBCCSP: %s", err) 36 } 37 ccpack := &CDSPackage{GetHasher: cryptoProvider} 38 cd, err := ccpack.InitFromBuffer(b) 39 if err != nil { 40 return nil, nil, nil, fmt.Errorf("error owner creating package %s", err) 41 } 42 43 if tofs { 44 if err = ccpack.PutChaincodeToFS(); err != nil { 45 return nil, nil, nil, fmt.Errorf("error putting package on the FS %s", err) 46 } 47 } 48 49 return ccpack, b, cd, nil 50 } 51 52 func TestPutCDSCC(t *testing.T) { 53 ccdir := setupccdir() 54 defer os.RemoveAll(ccdir) 55 56 cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")} 57 58 ccpack, _, cd, err := processCDS(cds, true) 59 if err != nil { 60 t.Fatalf("error putting CDS to FS %s", err) 61 return 62 } 63 64 if err = ccpack.ValidateCC(cd); err != nil { 65 t.Fatalf("error validating package %s", err) 66 return 67 } 68 } 69 70 func TestPutCDSErrorPaths(t *testing.T) { 71 ccdir := setupccdir() 72 defer os.RemoveAll(ccdir) 73 74 cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, 75 Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")} 76 77 ccpack, b, _, err := processCDS(cds, true) 78 if err != nil { 79 t.Fatalf("error putting CDS to FS %s", err) 80 return 81 } 82 83 //validate with invalid name 84 if err = ccpack.ValidateCC(&ChaincodeData{Name: "invalname", Version: "0"}); err == nil { 85 t.Fatalf("expected error validating package") 86 return 87 } 88 //remove the buffer 89 ccpack.buf = nil 90 if err = ccpack.PutChaincodeToFS(); err == nil { 91 t.Fatalf("expected error putting package on the FS") 92 return 93 } 94 95 //put back the buffer but remove the depspec 96 ccpack.buf = b 97 savDepSpec := ccpack.depSpec 98 ccpack.depSpec = nil 99 if err = ccpack.PutChaincodeToFS(); err == nil { 100 t.Fatalf("expected error putting package on the FS") 101 return 102 } 103 104 //put back dep spec 105 ccpack.depSpec = savDepSpec 106 107 //...but remove the chaincode directory 108 os.RemoveAll(ccdir) 109 if err = ccpack.PutChaincodeToFS(); err == nil { 110 t.Fatalf("expected error putting package on the FS") 111 return 112 } 113 } 114 115 func TestCDSGetCCPackage(t *testing.T) { 116 cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")} 117 118 b := protoutil.MarshalOrPanic(cds) 119 120 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 121 assert.NoError(t, err) 122 123 ccpack, err := GetCCPackage(b, cryptoProvider) 124 if err != nil { 125 t.Fatalf("failed to get CDS CCPackage %s", err) 126 return 127 } 128 129 cccdspack, ok := ccpack.(*CDSPackage) 130 if !ok || cccdspack == nil { 131 t.Fatalf("failed to get CDS CCPackage") 132 return 133 } 134 135 cds2 := cccdspack.GetDepSpec() 136 if cds2 == nil { 137 t.Fatalf("nil dep spec in CDS CCPackage") 138 return 139 } 140 141 if cds2.ChaincodeSpec.ChaincodeId.Name != cds.ChaincodeSpec.ChaincodeId.Name || cds2.ChaincodeSpec.ChaincodeId.Version != cds.ChaincodeSpec.ChaincodeId.Version { 142 t.Fatalf("dep spec in CDS CCPackage does not match %v != %v", cds, cds2) 143 return 144 } 145 } 146 147 //switch the chaincodes on the FS and validate 148 func TestCDSSwitchChaincodes(t *testing.T) { 149 ccdir := setupccdir() 150 defer os.RemoveAll(ccdir) 151 152 //someone modified the code on the FS with "badcode" 153 cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("badcode")} 154 155 //write the bad code to the fs 156 badccpack, _, _, err := processCDS(cds, true) 157 if err != nil { 158 t.Fatalf("error putting CDS to FS %s", err) 159 return 160 } 161 162 //mimic the good code ChaincodeData from the instantiate... 163 cds.CodePackage = []byte("goodcode") 164 165 //...and generate the CD for it (don't overwrite the bad code) 166 _, _, goodcd, err := processCDS(cds, false) 167 if err != nil { 168 t.Fatalf("error putting CDS to FS %s", err) 169 return 170 } 171 172 if err = badccpack.ValidateCC(goodcd); err == nil { 173 t.Fatalf("expected goodcd to fail against bad package but succeeded!") 174 return 175 } 176 } 177 178 func TestPutChaincodeToFSErrorPaths(t *testing.T) { 179 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 180 assert.NoError(t, err) 181 ccpack := &CDSPackage{GetHasher: cryptoProvider} 182 err = ccpack.PutChaincodeToFS() 183 assert.Error(t, err) 184 assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned") 185 186 ccpack.buf = []byte("hello") 187 err = ccpack.PutChaincodeToFS() 188 assert.Error(t, err) 189 assert.Contains(t, err.Error(), "id cannot be nil if buf is not nil", "Unexpected error returned") 190 191 ccpack.id = []byte("cc123") 192 err = ccpack.PutChaincodeToFS() 193 assert.Error(t, err) 194 assert.Contains(t, err.Error(), "depspec cannot be nil if buf is not nil", "Unexpected error returned") 195 196 ccpack.depSpec = &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, 197 Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")} 198 err = ccpack.PutChaincodeToFS() 199 assert.Error(t, err) 200 assert.Contains(t, err.Error(), "nil data", "Unexpected error returned") 201 202 ccpack.data = &CDSData{} 203 err = ccpack.PutChaincodeToFS() 204 assert.Error(t, err) 205 assert.Contains(t, err.Error(), "nil data bytes", "Unexpected error returned") 206 } 207 208 func TestValidateCCErrorPaths(t *testing.T) { 209 cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore()) 210 assert.NoError(t, err) 211 cpack := &CDSPackage{GetHasher: cryptoProvider} 212 ccdata := &ChaincodeData{} 213 err = cpack.ValidateCC(ccdata) 214 assert.Error(t, err) 215 assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned") 216 217 cpack.depSpec = &pb.ChaincodeDeploymentSpec{ 218 CodePackage: []byte("code"), 219 ChaincodeSpec: &pb.ChaincodeSpec{ 220 Type: 1, 221 ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, 222 Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}, 223 }, 224 } 225 err = cpack.ValidateCC(ccdata) 226 assert.Error(t, err) 227 assert.Contains(t, err.Error(), "nil data", "Unexpected error returned") 228 229 // invalid encoded name 230 cpack = &CDSPackage{GetHasher: cryptoProvider} 231 ccdata = &ChaincodeData{Name: "\027"} 232 cpack.depSpec = &pb.ChaincodeDeploymentSpec{ 233 CodePackage: []byte("code"), 234 ChaincodeSpec: &pb.ChaincodeSpec{ 235 ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"}, 236 }, 237 } 238 cpack.data = &CDSData{} 239 err = cpack.ValidateCC(ccdata) 240 assert.Error(t, err) 241 assert.Contains(t, err.Error(), `invalid chaincode name: "\x17"`) 242 243 // mismatched names 244 cpack = &CDSPackage{GetHasher: cryptoProvider} 245 ccdata = &ChaincodeData{Name: "Tom"} 246 cpack.depSpec = &pb.ChaincodeDeploymentSpec{ 247 CodePackage: []byte("code"), 248 ChaincodeSpec: &pb.ChaincodeSpec{ 249 ChaincodeId: &pb.ChaincodeID{Name: "Jerry", Version: "0"}, 250 }, 251 } 252 cpack.data = &CDSData{} 253 err = cpack.ValidateCC(ccdata) 254 assert.Error(t, err) 255 assert.Contains(t, err.Error(), `invalid chaincode data name:"Tom" (name:"Jerry" version:"0" )`) 256 257 // mismatched versions 258 cpack = &CDSPackage{GetHasher: cryptoProvider} 259 ccdata = &ChaincodeData{Name: "Tom", Version: "1"} 260 cpack.depSpec = &pb.ChaincodeDeploymentSpec{ 261 CodePackage: []byte("code"), 262 ChaincodeSpec: &pb.ChaincodeSpec{ 263 ChaincodeId: &pb.ChaincodeID{Name: ccdata.Name, Version: "0"}, 264 }, 265 } 266 cpack.data = &CDSData{} 267 err = cpack.ValidateCC(ccdata) 268 assert.Error(t, err) 269 assert.Contains(t, err.Error(), `invalid chaincode data name:"Tom" version:"1" (name:"Tom" version:"0" )`) 270 }