Skip to content

Commit 2a91d0e

Browse files
author
Anil Ambati
committed
[FAB-4183]: Add unit tests to ccprovider pkg
Added additional tests to ccprovider package Change-Id: Ida624943badb5d51802ff4d732b1fafe0a0f7a44 Signed-off-by: Anil Ambati <[email protected]>
1 parent a28a10c commit 2a91d0e

File tree

4 files changed

+373
-27
lines changed

4 files changed

+373
-27
lines changed

core/common/ccprovider/ccinfocache.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ func (c *ccInfoCacheImpl) PutChaincode(depSpec *peer.ChaincodeDeploymentSpec) (C
7575
ccversion := depSpec.ChaincodeSpec.ChaincodeId.Version
7676

7777
if ccname == "" {
78-
return nil, fmt.Errorf("the chaincode name cannot be an emoty string")
78+
return nil, fmt.Errorf("the chaincode name cannot be an empty string")
7979
}
8080

8181
if ccversion == "" {
82-
return nil, fmt.Errorf("the chaincode version cannot be an emoty string")
82+
return nil, fmt.Errorf("the chaincode version cannot be an empty string")
8383
}
8484

8585
key := ccname + "/" + ccversion

core/common/ccprovider/ccinfocache_test.go

+158-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import (
2020
"archive/tar"
2121
"bytes"
2222
"compress/gzip"
23+
"errors"
24+
"io/ioutil"
25+
"path/filepath"
2326
"testing"
2427

2528
"os"
@@ -67,10 +70,15 @@ func buildPackage(name string, path string, version string, initArgs [][]byte) (
6770
}
6871

6972
type mockCCInfoFSStorageMgrImpl struct {
70-
CCMap map[string]CCPackage
73+
CCMap map[string]CCPackage
74+
putchaincodeErr bool
7175
}
7276

7377
func (m *mockCCInfoFSStorageMgrImpl) PutChaincode(depSpec *peer.ChaincodeDeploymentSpec) (CCPackage, error) {
78+
if m.putchaincodeErr {
79+
return nil, errors.New("Error putting the chaincode")
80+
}
81+
7482
buf, err := proto.Marshal(depSpec)
7583
if err != nil {
7684
return nil, err
@@ -145,6 +153,63 @@ func TestCCInfoCache(t *testing.T) {
145153
assert.NotNil(t, cd2)
146154
}
147155

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+
148213
// here we test the peer's built-in cache after enabling it
149214
func TestCCInfoCachePeerInstance(t *testing.T) {
150215
// enable the cache first: it's disabled by default
@@ -166,18 +231,108 @@ func TestCCInfoCachePeerInstance(t *testing.T) {
166231
err = PutChaincodeIntoFS(ds)
167232
assert.NoError(t, err)
168233

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+
169245
// expect it to be in the cache
170246
cd, err := GetChaincodeFromFS(ccname, ccver)
171247
assert.NoError(t, err)
172248
assert.NotNil(t, cd)
173249
}
174250

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+
175329
var ccinfocachetestpath = "/tmp/ccinfocachetest"
176330

177331
func TestMain(m *testing.M) {
178332
os.RemoveAll(ccinfocachetestpath)
179-
defer os.RemoveAll(ccinfocachetestpath)
180333

181334
SetChaincodesPath(ccinfocachetestpath)
182-
os.Exit(m.Run())
335+
rc := m.Run()
336+
os.RemoveAll(ccinfocachetestpath)
337+
os.Exit(rc)
183338
}

core/common/ccprovider/cdspackage_test.go

+45-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
pb "github.com/hyperledger/fabric/protos/peer"
2626
"github.com/hyperledger/fabric/protos/utils"
27+
"github.com/stretchr/testify/assert"
2728
)
2829

2930
func setupccdir() string {
@@ -75,7 +76,8 @@ func TestPutCDSErrorPaths(t *testing.T) {
7576
ccdir := setupccdir()
7677
defer os.RemoveAll(ccdir)
7778

78-
cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
79+
cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
80+
Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
7981

8082
ccpack, b, _, err := processCDS(cds, true)
8183
if err != nil {
@@ -174,3 +176,45 @@ func TestCDSSwitchChaincodes(t *testing.T) {
174176
return
175177
}
176178
}
179+
180+
func TestPutChaincodeToFSErrorPaths(t *testing.T) {
181+
ccpack := &CDSPackage{}
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+
cpack := &CDSPackage{}
210+
ccdata := &ChaincodeData{}
211+
err := cpack.ValidateCC(ccdata)
212+
assert.Error(t, err)
213+
assert.Contains(t, err.Error(), "uninitialized package", "Unexpected error returned")
214+
215+
cpack.depSpec = &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "testcc", Version: "0"},
216+
Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("")}}}, CodePackage: []byte("code")}
217+
err = cpack.ValidateCC(ccdata)
218+
assert.Error(t, err)
219+
assert.Contains(t, err.Error(), "nil data", "Unexpected error returned")
220+
}

0 commit comments

Comments
 (0)