github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/common/ccprovider/ccprovider_test.go (about)

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