@@ -20,6 +20,9 @@ import (
20
20
"archive/tar"
21
21
"bytes"
22
22
"compress/gzip"
23
+ "errors"
24
+ "io/ioutil"
25
+ "path/filepath"
23
26
"testing"
24
27
25
28
"os"
@@ -67,10 +70,15 @@ func buildPackage(name string, path string, version string, initArgs [][]byte) (
67
70
}
68
71
69
72
type mockCCInfoFSStorageMgrImpl struct {
70
- CCMap map [string ]CCPackage
73
+ CCMap map [string ]CCPackage
74
+ putchaincodeErr bool
71
75
}
72
76
73
77
func (m * mockCCInfoFSStorageMgrImpl ) PutChaincode (depSpec * peer.ChaincodeDeploymentSpec ) (CCPackage , error ) {
78
+ if m .putchaincodeErr {
79
+ return nil , errors .New ("Error putting the chaincode" )
80
+ }
81
+
74
82
buf , err := proto .Marshal (depSpec )
75
83
if err != nil {
76
84
return nil , err
@@ -145,6 +153,63 @@ func TestCCInfoCache(t *testing.T) {
145
153
assert .NotNil (t , cd2 )
146
154
}
147
155
156
+ func TestPutChaincode (t * testing.T ) {
157
+ ccname := ""
158
+ ccver := "1.0"
159
+ ccpath := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
160
+
161
+ ccinfoFs := & mockCCInfoFSStorageMgrImpl {CCMap : map [string ]CCPackage {}}
162
+ cccache := NewCCInfoCache (ccinfoFs )
163
+
164
+ // Error case 1: ccname is empty
165
+ // create a dep spec to put
166
+ ds , err := getDepSpec (ccname , ccpath , ccver , [][]byte {[]byte ("init" ), []byte ("a" ), []byte ("100" ), []byte ("b" ), []byte ("200" )})
167
+ assert .NoError (t , err )
168
+ _ , err = cccache .PutChaincode (ds )
169
+ assert .Error (t , err )
170
+ assert .Equal (t , "the chaincode name cannot be an empty string" , err .Error (), "Unexpected error received" )
171
+
172
+ // Error case 2: ccver is empty
173
+ ccname = "foo"
174
+ ccver = ""
175
+ ds , err = getDepSpec (ccname , ccpath , ccver , [][]byte {[]byte ("init" ), []byte ("a" ), []byte ("100" ), []byte ("b" ), []byte ("200" )})
176
+ assert .NoError (t , err )
177
+ _ , err = cccache .PutChaincode (ds )
178
+ assert .Error (t , err )
179
+ assert .Equal (t , "the chaincode version cannot be an empty string" , err .Error (), "Unexpected error received" )
180
+
181
+ // Error case 3: ccfs.PutChainCode returns an error
182
+ ccinfoFs = & mockCCInfoFSStorageMgrImpl {CCMap : map [string ]CCPackage {}, putchaincodeErr : true }
183
+ cccache = NewCCInfoCache (ccinfoFs )
184
+
185
+ ccname = "foo"
186
+ ccver = "1.0"
187
+ ds , err = getDepSpec (ccname , ccpath , ccver , [][]byte {[]byte ("init" ), []byte ("a" ), []byte ("100" ), []byte ("b" ), []byte ("200" )})
188
+ assert .NoError (t , err )
189
+ _ , err = cccache .PutChaincode (ds )
190
+ assert .Error (t , err )
191
+ assert .Contains (t , err .Error (), "PutChaincodeIntoFS failed" , "Unexpected error received" )
192
+ }
193
+
194
+ // here we test the peer's built-in cache after enabling it
195
+ func TestCCInfoFSPeerInstance (t * testing.T ) {
196
+ ccname := "bar"
197
+ ccver := "1.0"
198
+ ccpath := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
199
+
200
+ // the cc data is not yet in the cache
201
+ _ , err := GetChaincodeFromFS (ccname , ccver )
202
+ assert .Error (t , err )
203
+
204
+ // create a dep spec to put
205
+ ds , err := getDepSpec (ccname , ccpath , ccver , [][]byte {[]byte ("init" ), []byte ("a" ), []byte ("100" ), []byte ("b" ), []byte ("200" )})
206
+ assert .NoError (t , err )
207
+
208
+ // put it
209
+ err = PutChaincodeIntoFS (ds )
210
+ assert .NoError (t , err )
211
+ }
212
+
148
213
// here we test the peer's built-in cache after enabling it
149
214
func TestCCInfoCachePeerInstance (t * testing.T ) {
150
215
// enable the cache first: it's disabled by default
@@ -166,18 +231,108 @@ func TestCCInfoCachePeerInstance(t *testing.T) {
166
231
err = PutChaincodeIntoFS (ds )
167
232
assert .NoError (t , err )
168
233
234
+ // Check if chain code package exists
235
+ exists , err := ChaincodePackageExists (ccname , ccver )
236
+ assert .NoError (t , err )
237
+ assert .True (t , exists , "ChaincodePackageExists should have returned true for an existing package" )
238
+
239
+ // Get all installed chaincodes, it should not return 0 chain codes
240
+ resp , err := GetInstalledChaincodes ()
241
+ assert .NoError (t , err )
242
+ assert .NotNil (t , resp )
243
+ assert .NotZero (t , len (resp .Chaincodes ), "GetInstalledChaincodes should not have returned 0 chain codes" )
244
+
169
245
// expect it to be in the cache
170
246
cd , err := GetChaincodeFromFS (ccname , ccver )
171
247
assert .NoError (t , err )
172
248
assert .NotNil (t , cd )
173
249
}
174
250
251
+ func TestGetInstalledChaincodesErrorPaths (t * testing.T ) {
252
+ // Get the existing chaincode install path value and set it
253
+ // back after we are done with the test
254
+ cip := chaincodeInstallPath
255
+ defer SetChaincodesPath (cip )
256
+
257
+ // Create a temp dir and remove it at the end
258
+ dir , err := ioutil .TempDir (os .TempDir (), "chaincodes" )
259
+ assert .NoError (t , err )
260
+ defer os .RemoveAll (dir )
261
+
262
+ // Set the above created directory as the chain code install path
263
+ SetChaincodesPath (dir )
264
+ err = ioutil .WriteFile (filepath .Join (dir , "idontexist.1.0" ), []byte ("test" ), 0777 )
265
+ assert .NoError (t , err )
266
+ resp , err := GetInstalledChaincodes ()
267
+ assert .NoError (t , err )
268
+ assert .Equal (t , 0 , len (resp .Chaincodes ),
269
+ "Expected 0 chain codes but GetInstalledChaincodes returned %s chain codes" , len (resp .Chaincodes ))
270
+ }
271
+
272
+ func TestNewCCContext (t * testing.T ) {
273
+ ccctx := NewCCContext ("foo" , "foo" , "1.0" , "" , false , nil , nil )
274
+ assert .NotNil (t , ccctx )
275
+ canName := ccctx .GetCanonicalName ()
276
+ assert .NotEmpty (t , canName )
277
+
278
+ assert .Panics (t , func () {
279
+ NewCCContext ("foo" , "foo" , "" , "" , false , nil , nil )
280
+ }, "NewCCContext should have paniced if version is empty" )
281
+
282
+ ccctx = & CCContext {"foo" , "foo" , "1.0" , "" , false , nil , nil , "" }
283
+ assert .Panics (t , func () {
284
+ ccctx .GetCanonicalName ()
285
+ }, "GetConnonicalName should have paniced if cannonical name is empty" )
286
+ }
287
+
288
+ func TestChaincodePackageExists (t * testing.T ) {
289
+ _ , err := ChaincodePackageExists ("foo1" , "1.0" )
290
+ assert .Error (t , err )
291
+ }
292
+
293
+ func TestSetChaincodesPath (t * testing.T ) {
294
+ dir , err := ioutil .TempDir (os .TempDir (), "setchaincodes" )
295
+ if err != nil {
296
+ assert .Fail (t , err .Error (), "Unable to create temp dir" )
297
+ }
298
+ defer os .RemoveAll (dir )
299
+ t .Logf ("created temp dir %s" , dir )
300
+
301
+ // Get the existing chaincode install path value and set it
302
+ // back after we are done with the test
303
+ cip := chaincodeInstallPath
304
+ defer SetChaincodesPath (cip )
305
+
306
+ f , err := ioutil .TempFile (dir , "chaincodes" )
307
+ assert .NoError (t , err )
308
+ assert .Panics (t , func () {
309
+ SetChaincodesPath (f .Name ())
310
+ }, "SetChaincodesPath should have paniced if a file is passed to it" )
311
+
312
+ // Following code works on mac but does not work in CI
313
+ // // Make the directory read only
314
+ // err = os.Chmod(dir, 0444)
315
+ // assert.NoError(t, err)
316
+ // cdir := filepath.Join(dir, "chaincodesdir")
317
+ // assert.Panics(t, func() {
318
+ // SetChaincodesPath(cdir)
319
+ // }, "SetChaincodesPath should have paniced if it is not able to stat the dir")
320
+
321
+ // // Make the directory read and execute
322
+ // err = os.Chmod(dir, 0555)
323
+ // assert.NoError(t, err)
324
+ // assert.Panics(t, func() {
325
+ // SetChaincodesPath(cdir)
326
+ // }, "SetChaincodesPath should have paniced if it is not able to create the dir")
327
+ }
328
+
175
329
var ccinfocachetestpath = "/tmp/ccinfocachetest"
176
330
177
331
func TestMain (m * testing.M ) {
178
332
os .RemoveAll (ccinfocachetestpath )
179
- defer os .RemoveAll (ccinfocachetestpath )
180
333
181
334
SetChaincodesPath (ccinfocachetestpath )
182
- os .Exit (m .Run ())
335
+ rc := m .Run ()
336
+ os .RemoveAll (ccinfocachetestpath )
337
+ os .Exit (rc )
183
338
}
0 commit comments