|
| 1 | +/* |
| 2 | +Copyright IBM Corp. 2017 All Rights Reserved. |
| 3 | +
|
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +*/ |
| 16 | + |
| 17 | +package ccprovider |
| 18 | + |
| 19 | +import ( |
| 20 | + "archive/tar" |
| 21 | + "bytes" |
| 22 | + "compress/gzip" |
| 23 | + "testing" |
| 24 | + |
| 25 | + "os" |
| 26 | + |
| 27 | + "github.com/golang/protobuf/proto" |
| 28 | + "github.com/hyperledger/fabric/core/container/util" |
| 29 | + "github.com/hyperledger/fabric/protos/peer" |
| 30 | + "github.com/stretchr/testify/assert" |
| 31 | +) |
| 32 | + |
| 33 | +func getDepSpec(name string, path string, version string, initArgs [][]byte) (*peer.ChaincodeDeploymentSpec, error) { |
| 34 | + spec := &peer.ChaincodeSpec{Type: 1, ChaincodeId: &peer.ChaincodeID{Name: name, Path: path, Version: version}, Input: &peer.ChaincodeInput{Args: initArgs}} |
| 35 | + |
| 36 | + codePackageBytes := bytes.NewBuffer(nil) |
| 37 | + gz := gzip.NewWriter(codePackageBytes) |
| 38 | + tw := tar.NewWriter(gz) |
| 39 | + |
| 40 | + err := util.WriteBytesToPackage("src/garbage.go", []byte(name+path+version), tw) |
| 41 | + if err != nil { |
| 42 | + return nil, err |
| 43 | + } |
| 44 | + |
| 45 | + tw.Close() |
| 46 | + gz.Close() |
| 47 | + |
| 48 | + return &peer.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes.Bytes()}, nil |
| 49 | +} |
| 50 | + |
| 51 | +func buildPackage(name string, path string, version string, initArgs [][]byte) (CCPackage, error) { |
| 52 | + depSpec, err := getDepSpec(name, path, version, initArgs) |
| 53 | + if err != nil { |
| 54 | + return nil, err |
| 55 | + } |
| 56 | + |
| 57 | + buf, err := proto.Marshal(depSpec) |
| 58 | + if err != nil { |
| 59 | + return nil, err |
| 60 | + } |
| 61 | + cccdspack := &CDSPackage{} |
| 62 | + if _, err := cccdspack.InitFromBuffer(buf); err != nil { |
| 63 | + return nil, err |
| 64 | + } |
| 65 | + |
| 66 | + return cccdspack, nil |
| 67 | +} |
| 68 | + |
| 69 | +type mockCCInfoFSStorageMgrImpl struct { |
| 70 | + CCMap map[string]CCPackage |
| 71 | +} |
| 72 | + |
| 73 | +func (m *mockCCInfoFSStorageMgrImpl) PutChaincode(depSpec *peer.ChaincodeDeploymentSpec) (CCPackage, error) { |
| 74 | + buf, err := proto.Marshal(depSpec) |
| 75 | + if err != nil { |
| 76 | + return nil, err |
| 77 | + } |
| 78 | + cccdspack := &CDSPackage{} |
| 79 | + if _, err := cccdspack.InitFromBuffer(buf); err != nil { |
| 80 | + return nil, err |
| 81 | + } |
| 82 | + |
| 83 | + m.CCMap[depSpec.ChaincodeSpec.ChaincodeId.Name+depSpec.ChaincodeSpec.ChaincodeId.Version] = cccdspack |
| 84 | + |
| 85 | + return cccdspack, nil |
| 86 | +} |
| 87 | + |
| 88 | +func (m *mockCCInfoFSStorageMgrImpl) GetChaincode(ccname string, ccversion string) (CCPackage, error) { |
| 89 | + return m.CCMap[ccname+ccversion], nil |
| 90 | +} |
| 91 | + |
| 92 | +// here we test the cache implementation itself |
| 93 | +func TestCCInfoCache(t *testing.T) { |
| 94 | + ccname := "foo" |
| 95 | + ccver := "1.0" |
| 96 | + ccpath := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" |
| 97 | + |
| 98 | + ccinfoFs := &mockCCInfoFSStorageMgrImpl{CCMap: map[string]CCPackage{}} |
| 99 | + cccache := NewCCInfoCache(ccinfoFs) |
| 100 | + |
| 101 | + // test the get side |
| 102 | + |
| 103 | + // the cc data is not yet in the cache |
| 104 | + _, err := cccache.GetChaincode(ccname, ccver) |
| 105 | + assert.Error(t, err) |
| 106 | + |
| 107 | + // put it in the file system |
| 108 | + pack, err := buildPackage(ccname, ccpath, ccver, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}) |
| 109 | + assert.NoError(t, err) |
| 110 | + ccinfoFs.CCMap[ccname+ccver] = pack |
| 111 | + |
| 112 | + // expect it to be in the cache now |
| 113 | + cd1, err := cccache.GetChaincode(ccname, ccver) |
| 114 | + assert.NoError(t, err) |
| 115 | + |
| 116 | + // it should still be in the cache |
| 117 | + cd2, err := cccache.GetChaincode(ccname, ccver) |
| 118 | + assert.NoError(t, err) |
| 119 | + |
| 120 | + // they are not null |
| 121 | + assert.NotNil(t, cd1) |
| 122 | + assert.NotNil(t, cd2) |
| 123 | + |
| 124 | + // test the put side now.. |
| 125 | + ccver = "2.0" |
| 126 | + |
| 127 | + // create a dep spec to put |
| 128 | + ds, err := getDepSpec(ccname, ccpath, ccver, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}) |
| 129 | + assert.NoError(t, err) |
| 130 | + |
| 131 | + // put it |
| 132 | + _, err = cccache.PutChaincode(ds) |
| 133 | + assert.NoError(t, err) |
| 134 | + |
| 135 | + // expect it to be in the cache |
| 136 | + cd1, err = cccache.GetChaincode(ccname, ccver) |
| 137 | + assert.NoError(t, err) |
| 138 | + |
| 139 | + // it should still be in the cache |
| 140 | + cd2, err = cccache.GetChaincode(ccname, ccver) |
| 141 | + assert.NoError(t, err) |
| 142 | + |
| 143 | + // they are not null |
| 144 | + assert.NotNil(t, cd1) |
| 145 | + assert.NotNil(t, cd2) |
| 146 | +} |
| 147 | + |
| 148 | +// here we test the peer's built-in cache after enabling it |
| 149 | +func TestCCInfoCachePeerInstance(t *testing.T) { |
| 150 | + // enable the cache first: it's disabled by default |
| 151 | + EnableCCInfoCache() |
| 152 | + |
| 153 | + ccname := "foo" |
| 154 | + ccver := "1.0" |
| 155 | + ccpath := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" |
| 156 | + |
| 157 | + // the cc data is not yet in the cache |
| 158 | + _, err := GetChaincodeFromFS(ccname, ccver) |
| 159 | + assert.Error(t, err) |
| 160 | + |
| 161 | + // create a dep spec to put |
| 162 | + ds, err := getDepSpec(ccname, ccpath, ccver, [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}) |
| 163 | + assert.NoError(t, err) |
| 164 | + |
| 165 | + // put it |
| 166 | + err = PutChaincodeIntoFS(ds) |
| 167 | + assert.NoError(t, err) |
| 168 | + |
| 169 | + // expect it to be in the cache |
| 170 | + cd, err := GetChaincodeFromFS(ccname, ccver) |
| 171 | + assert.NoError(t, err) |
| 172 | + assert.NotNil(t, cd) |
| 173 | +} |
| 174 | + |
| 175 | +var ccinfocachetestpath = "/tmp/ccinfocachetest" |
| 176 | + |
| 177 | +func TestMain(m *testing.M) { |
| 178 | + os.RemoveAll(ccinfocachetestpath) |
| 179 | + defer os.RemoveAll(ccinfocachetestpath) |
| 180 | + |
| 181 | + SetChaincodesPath(ccinfocachetestpath) |
| 182 | + os.Exit(m.Run()) |
| 183 | +} |
0 commit comments