github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/internal/peer/common/common_test.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package common_test
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"path"
    14  	"path/filepath"
    15  	"strings"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/hechain20/hechain/bccsp/factory"
    20  	"github.com/hechain20/hechain/bccsp/sw"
    21  	"github.com/hechain20/hechain/common/channelconfig"
    22  	"github.com/hechain20/hechain/common/crypto/tlsgen"
    23  	"github.com/hechain20/hechain/common/flogging"
    24  	"github.com/hechain20/hechain/common/util"
    25  	"github.com/hechain20/hechain/core/config/configtest"
    26  	"github.com/hechain20/hechain/internal/configtxgen/encoder"
    27  	"github.com/hechain20/hechain/internal/configtxgen/genesisconfig"
    28  	"github.com/hechain20/hechain/internal/peer/common"
    29  	"github.com/hechain20/hechain/internal/pkg/comm"
    30  	"github.com/hechain20/hechain/msp"
    31  	msptesttools "github.com/hechain20/hechain/msp/mgmt/testtools"
    32  	"github.com/hechain20/hechain/protoutil"
    33  	cb "github.com/hyperledger/fabric-protos-go/common"
    34  	pb "github.com/hyperledger/fabric-protos-go/peer"
    35  	"github.com/pkg/errors"
    36  	"github.com/spf13/cobra"
    37  	"github.com/spf13/viper"
    38  	"github.com/stretchr/testify/require"
    39  )
    40  
    41  func TestInitConfig(t *testing.T) {
    42  	cleanup := configtest.SetDevFabricConfigPath(t)
    43  	defer cleanup()
    44  
    45  	type args struct {
    46  		cmdRoot string
    47  	}
    48  	tests := []struct {
    49  		name    string
    50  		args    args
    51  		wantErr bool
    52  	}{
    53  		{
    54  			name:    "Empty command root",
    55  			args:    args{cmdRoot: ""},
    56  			wantErr: true,
    57  		},
    58  		{
    59  			name:    "Bad command root",
    60  			args:    args{cmdRoot: "cre"},
    61  			wantErr: true,
    62  		},
    63  		{
    64  			name:    "Good command root",
    65  			args:    args{cmdRoot: "core"},
    66  			wantErr: false,
    67  		},
    68  	}
    69  	for _, tt := range tests {
    70  		t.Run(tt.name, func(t *testing.T) {
    71  			if err := common.InitConfig(tt.args.cmdRoot); (err != nil) != tt.wantErr {
    72  				t.Errorf("InitConfig() error = %v, wantErr %v", err, tt.wantErr)
    73  			}
    74  		})
    75  	}
    76  }
    77  
    78  func TestInitCryptoMissingDir(t *testing.T) {
    79  	dir := path.Join(os.TempDir(), util.GenerateUUID())
    80  	err := common.InitCrypto(dir, "SampleOrg", msp.ProviderTypeToString(msp.FABRIC))
    81  	require.Error(t, err, "Should not be able to initialize crypto with non-existing directory")
    82  	require.Contains(t, err.Error(), fmt.Sprintf("specified path \"%s\" does not exist", dir))
    83  }
    84  
    85  func TestInitCryptoFileNotDir(t *testing.T) {
    86  	file := path.Join(os.TempDir(), util.GenerateUUID())
    87  	err := ioutil.WriteFile(file, []byte{}, 0o644)
    88  	require.Nil(t, err, "Failed to create test file")
    89  	defer os.Remove(file)
    90  	err = common.InitCrypto(file, "SampleOrg", msp.ProviderTypeToString(msp.FABRIC))
    91  	require.Error(t, err, "Should not be able to initialize crypto with a file instead of a directory")
    92  	require.Contains(t, err.Error(), fmt.Sprintf("specified path \"%s\" is not a directory", file))
    93  }
    94  
    95  func TestInitCrypto(t *testing.T) {
    96  	mspConfigPath := configtest.GetDevMspDir()
    97  	localMspId := "SampleOrg"
    98  	err := common.InitCrypto(mspConfigPath, localMspId, msp.ProviderTypeToString(msp.FABRIC))
    99  	require.NoError(t, err, "Unexpected error [%s] calling InitCrypto()", err)
   100  	localMspId = ""
   101  	err = common.InitCrypto(mspConfigPath, localMspId, msp.ProviderTypeToString(msp.FABRIC))
   102  	require.Error(t, err, fmt.Sprintf("Expected error [%s] calling InitCrypto()", err))
   103  }
   104  
   105  func TestSetBCCSPKeystorePath(t *testing.T) {
   106  	cfgKey := "peer.BCCSP.SW.FileKeyStore.KeyStore"
   107  	cfgPath := "./testdata"
   108  	absPath, err := filepath.Abs(cfgPath)
   109  	require.NoError(t, err)
   110  
   111  	keystorePath := "/msp/keystore"
   112  	defer os.Unsetenv("FABRIC_CFG_PATH")
   113  
   114  	os.Setenv("FABRIC_CFG_PATH", cfgPath)
   115  	viper.Reset()
   116  	err = common.InitConfig("notset")
   117  	require.NoError(t, err)
   118  	common.SetBCCSPKeystorePath()
   119  	t.Log(viper.GetString(cfgKey))
   120  	require.Equal(t, "", viper.GetString(cfgKey))
   121  	require.Nil(t, viper.Get(cfgKey))
   122  
   123  	viper.Reset()
   124  	err = common.InitConfig("absolute")
   125  	require.NoError(t, err)
   126  	common.SetBCCSPKeystorePath()
   127  	t.Log(viper.GetString(cfgKey))
   128  	require.Equal(t, keystorePath, viper.GetString(cfgKey))
   129  
   130  	viper.Reset()
   131  	err = common.InitConfig("relative")
   132  	require.NoError(t, err)
   133  	common.SetBCCSPKeystorePath()
   134  	t.Log(viper.GetString(cfgKey))
   135  	require.Equal(t, filepath.Join(absPath, keystorePath), viper.GetString(cfgKey))
   136  
   137  	viper.Reset()
   138  }
   139  
   140  func TestCheckLogLevel(t *testing.T) {
   141  	type args struct {
   142  		level string
   143  	}
   144  	tests := []struct {
   145  		name    string
   146  		args    args
   147  		wantErr bool
   148  	}{
   149  		{
   150  			name:    "Empty level",
   151  			args:    args{level: ""},
   152  			wantErr: true,
   153  		},
   154  		{
   155  			name:    "Valid level",
   156  			args:    args{level: "warning"},
   157  			wantErr: false,
   158  		},
   159  		{
   160  			name:    "Invalid level",
   161  			args:    args{level: "foobaz"},
   162  			wantErr: true,
   163  		},
   164  		{
   165  			name:    "Valid level",
   166  			args:    args{level: "error"},
   167  			wantErr: false,
   168  		},
   169  		{
   170  			name:    "Valid level",
   171  			args:    args{level: "info"},
   172  			wantErr: false,
   173  		},
   174  	}
   175  	for _, tt := range tests {
   176  		t.Run(tt.name, func(t *testing.T) {
   177  			if err := common.CheckLogLevel(tt.args.level); (err != nil) != tt.wantErr {
   178  				t.Errorf("CheckLogLevel() args = %v error = %v, wantErr %v", tt.args, err, tt.wantErr)
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  func TestGetDefaultSigner(t *testing.T) {
   185  	tests := []struct {
   186  		name    string
   187  		want    msp.SigningIdentity
   188  		wantErr bool
   189  	}{
   190  		{
   191  			name:    "Should return DefaultSigningIdentity",
   192  			want:    nil,
   193  			wantErr: false,
   194  		},
   195  	}
   196  	for _, tt := range tests {
   197  		t.Run(tt.name, func(t *testing.T) {
   198  			_, err := common.GetDefaultSigner()
   199  			if (err != nil) != tt.wantErr {
   200  				t.Errorf("GetDefaultSigner() error = %v, wantErr %v", err, tt.wantErr)
   201  				return
   202  			}
   203  		})
   204  	}
   205  }
   206  
   207  func TestInitCmd(t *testing.T) {
   208  	cleanup := configtest.SetDevFabricConfigPath(t)
   209  	defer cleanup()
   210  	defer viper.Reset()
   211  
   212  	// test that InitCmd doesn't remove existing loggers from the logger levels map
   213  	flogging.MustGetLogger("test")
   214  	flogging.ActivateSpec("test=error")
   215  	require.Equal(t, "error", flogging.LoggerLevel("test"))
   216  	flogging.MustGetLogger("chaincode")
   217  	require.Equal(t, flogging.DefaultLevel(), flogging.LoggerLevel("chaincode"))
   218  	flogging.MustGetLogger("test.test2")
   219  	flogging.ActivateSpec("test.test2=warn")
   220  	require.Equal(t, "warn", flogging.LoggerLevel("test.test2"))
   221  
   222  	origEnvValue := os.Getenv("FABRIC_LOGGING_SPEC")
   223  	os.Setenv("FABRIC_LOGGING_SPEC", "chaincode=debug:test.test2=fatal:abc=error")
   224  	common.InitCmd(&cobra.Command{}, nil)
   225  	require.Equal(t, "debug", flogging.LoggerLevel("chaincode"))
   226  	require.Equal(t, "info", flogging.LoggerLevel("test"))
   227  	require.Equal(t, "fatal", flogging.LoggerLevel("test.test2"))
   228  	require.Equal(t, "error", flogging.LoggerLevel("abc"))
   229  	os.Setenv("FABRIC_LOGGING_SPEC", origEnvValue)
   230  }
   231  
   232  func TestInitCmdWithoutInitCrypto(t *testing.T) {
   233  	cleanup := configtest.SetDevFabricConfigPath(t)
   234  	defer cleanup()
   235  	defer viper.Reset()
   236  
   237  	peerCmd := &cobra.Command{
   238  		Use: "peer",
   239  	}
   240  	lifecycleCmd := &cobra.Command{
   241  		Use: "lifecycle",
   242  	}
   243  	chaincodeCmd := &cobra.Command{
   244  		Use: "chaincode",
   245  	}
   246  	packageCmd := &cobra.Command{
   247  		Use: "package",
   248  	}
   249  	// peer lifecycle chaincode package
   250  	chaincodeCmd.AddCommand(packageCmd)
   251  	lifecycleCmd.AddCommand(chaincodeCmd)
   252  	peerCmd.AddCommand(lifecycleCmd)
   253  
   254  	// MSPCONFIGPATH is default value
   255  	common.InitCmd(packageCmd, nil)
   256  
   257  	// set MSPCONFIGPATH to be a missing dir, the function InitCrypto will fail
   258  	// confirm that 'peer lifecycle chaincode package' mandates does not require MSPCONFIG information
   259  	viper.SetEnvPrefix("core")
   260  	viper.AutomaticEnv()
   261  	replacer := strings.NewReplacer(".", "_")
   262  	viper.SetEnvKeyReplacer(replacer)
   263  	dir := os.TempDir() + "/" + util.GenerateUUID()
   264  	os.Setenv("CORE_PEER_MSPCONFIGPATH", dir)
   265  
   266  	common.InitCmd(packageCmd, nil)
   267  }
   268  
   269  func TestGetOrdererEndpointFromConfigTx(t *testing.T) {
   270  	require.NoError(t, msptesttools.LoadMSPSetupForTesting())
   271  	signer, err := common.GetDefaultSigner()
   272  	require.NoError(t, err)
   273  	factory.InitFactories(nil)
   274  	cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
   275  	require.NoError(t, err)
   276  
   277  	t.Run("green-path", func(t *testing.T) {
   278  		profile := genesisconfig.Load(genesisconfig.SampleInsecureSoloProfile, configtest.GetDevConfigDir())
   279  		channelGroup, err := encoder.NewChannelGroup(profile)
   280  		require.NoError(t, err)
   281  		channelConfig := &cb.Config{ChannelGroup: channelGroup}
   282  
   283  		ordererAddresses := channelconfig.OrdererAddressesValue([]string{"order-1-endpoint", "order-2-end-point"})
   284  		channelConfig.ChannelGroup.Values[ordererAddresses.Key()] = &cb.ConfigValue{
   285  			Value: protoutil.MarshalOrPanic(ordererAddresses.Value()),
   286  		}
   287  
   288  		mockEndorserClient := common.GetMockEndorserClient(
   289  			&pb.ProposalResponse{
   290  				Response:    &pb.Response{Status: 200, Payload: protoutil.MarshalOrPanic(channelConfig)},
   291  				Endorsement: &pb.Endorsement{},
   292  			},
   293  			nil,
   294  		)
   295  
   296  		ordererEndpoints, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   297  		require.NoError(t, err)
   298  		require.Equal(t, []string{"order-1-endpoint", "order-2-end-point"}, ordererEndpoints)
   299  	})
   300  
   301  	t.Run("error-invoking-CSCC", func(t *testing.T) {
   302  		mockEndorserClient := common.GetMockEndorserClient(
   303  			nil,
   304  			errors.Errorf("cscc-invocation-error"),
   305  		)
   306  		_, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   307  		require.EqualError(t, err, "error endorsing GetChannelConfig: cscc-invocation-error")
   308  	})
   309  
   310  	t.Run("nil-response", func(t *testing.T) {
   311  		mockEndorserClient := common.GetMockEndorserClient(
   312  			nil,
   313  			nil,
   314  		)
   315  		_, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   316  		require.EqualError(t, err, "received nil proposal response")
   317  	})
   318  
   319  	t.Run("bad-status-code-from-cscc", func(t *testing.T) {
   320  		mockEndorserClient := common.GetMockEndorserClient(
   321  			&pb.ProposalResponse{
   322  				Response:    &pb.Response{Status: 404, Payload: []byte{}},
   323  				Endorsement: &pb.Endorsement{},
   324  			},
   325  			nil,
   326  		)
   327  		_, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   328  		require.EqualError(t, err, "error bad proposal response 404: ")
   329  	})
   330  
   331  	t.Run("unmarshalable-config", func(t *testing.T) {
   332  		mockEndorserClient := common.GetMockEndorserClient(
   333  			&pb.ProposalResponse{
   334  				Response:    &pb.Response{Status: 200, Payload: []byte("unmarshalable-config")},
   335  				Endorsement: &pb.Endorsement{},
   336  			},
   337  			nil,
   338  		)
   339  		_, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   340  		require.EqualError(t, err, "error unmarshalling channel config: unexpected EOF")
   341  	})
   342  
   343  	t.Run("unloadable-config", func(t *testing.T) {
   344  		mockEndorserClient := common.GetMockEndorserClient(
   345  			&pb.ProposalResponse{
   346  				Response:    &pb.Response{Status: 200, Payload: []byte{}},
   347  				Endorsement: &pb.Endorsement{},
   348  			},
   349  			nil,
   350  		)
   351  		_, err := common.GetOrdererEndpointOfChain("test-channel", signer, mockEndorserClient, cryptoProvider)
   352  		require.EqualError(t, err, "error loading channel config: config must contain a channel group")
   353  	})
   354  }
   355  
   356  func TestConfigFromEnv(t *testing.T) {
   357  	tempdir, err := ioutil.TempDir("", "peer-clientcert")
   358  	require.NoError(t, err)
   359  	defer os.RemoveAll(tempdir)
   360  
   361  	// peer client config
   362  	address, clientConfig, err := common.ConfigFromEnv("peer")
   363  	require.NoError(t, err)
   364  	require.Equal(t, "", address, "ClientConfig.address by default not set")
   365  	require.Equal(t, common.DefaultConnTimeout, clientConfig.DialTimeout, "ClientConfig.DialTimeout should be set to default value of %v", common.DefaultConnTimeout)
   366  	require.Equal(t, false, clientConfig.SecOpts.UseTLS, "ClientConfig.SecOpts.UseTLS default value should be false")
   367  	require.Equal(t, comm.DefaultMaxRecvMsgSize, clientConfig.MaxRecvMsgSize, "ServerConfig.MaxRecvMsgSize should be set to default value %v", comm.DefaultMaxRecvMsgSize)
   368  	require.Equal(t, comm.DefaultMaxSendMsgSize, clientConfig.MaxSendMsgSize, "ServerConfig.MaxSendMsgSize should be set to default value %v", comm.DefaultMaxSendMsgSize)
   369  
   370  	viper.Set("peer.address", "127.0.0.1")
   371  	viper.Set("peer.client.connTimeout", "30s")
   372  	viper.Set("peer.maxRecvMsgSize", "1024")
   373  	viper.Set("peer.maxSendMsgSize", "2048")
   374  	address, clientConfig, err = common.ConfigFromEnv("peer")
   375  	require.NoError(t, err)
   376  	require.Equal(t, "127.0.0.1", address, "ClientConfig.address should be set to 127.0.0.1")
   377  	require.Equal(t, 30*time.Second, clientConfig.DialTimeout, "ClientConfig.DialTimeout should be set to default value of 30s")
   378  	require.Equal(t, 1024, clientConfig.MaxRecvMsgSize, "ClientConfig.MaxRecvMsgSize should be set to 1024")
   379  	require.Equal(t, 2048, clientConfig.MaxSendMsgSize, "ClientConfig.maxSendMsgSize should be set to 2048")
   380  
   381  	viper.Set("peer.tls.enabled", true)
   382  	viper.Set("peer.tls.rootcert.file", "./filenotfound.pem")
   383  	_, _, err = common.ConfigFromEnv("peer")
   384  	require.Error(t, err, "ClientConfig should return with bad root cert file path")
   385  
   386  	viper.Set("peer.tls.enabled", false)
   387  	viper.Set("peer.tls.clientAuthRequired", true)
   388  	viper.Set("peer.tls.clientKey.file", "./filenotfound.pem")
   389  	_, clientConfig, err = common.ConfigFromEnv("peer")
   390  	require.Equal(t, false, clientConfig.SecOpts.UseTLS, "ClientConfig.SecOpts.UseTLS should be false")
   391  	require.Error(t, err, "ClientConfig should return with client key file path")
   392  
   393  	org1CA, err := tlsgen.NewCA()
   394  	require.NoError(t, err)
   395  	err = ioutil.WriteFile(filepath.Join(tempdir, "org1-ca-cert.pem"), org1CA.CertBytes(), 0o644)
   396  	require.NoError(t, err)
   397  	org1ServerKP, err := org1CA.NewServerCertKeyPair("localhost")
   398  	require.NoError(t, err)
   399  	err = ioutil.WriteFile(filepath.Join(tempdir, "org1-peer1-cert.pem"), org1ServerKP.Cert, 0o644)
   400  	require.NoError(t, err)
   401  	err = ioutil.WriteFile(filepath.Join(tempdir, "org1-peer1-key.pem"), org1ServerKP.Key, 0o600)
   402  	require.NoError(t, err)
   403  
   404  	viper.Set("peer.tls.enabled", true)
   405  	viper.Set("peer.tls.clientAuthRequired", true)
   406  	viper.Set("peer.tls.rootcert.file", filepath.Join(tempdir, "org1-ca-cert.pem"))
   407  	viper.Set("peer.tls.clientCert.file", filepath.Join(tempdir, "org1-peer1-cert.pem"))
   408  	viper.Set("peer.tls.clientKey.file", filepath.Join(tempdir, "org1-peer1-key.pem"))
   409  	_, clientConfig, err = common.ConfigFromEnv("peer")
   410  	require.NoError(t, err)
   411  	require.Equal(t, 1, len(clientConfig.SecOpts.ServerRootCAs), "ClientConfig.SecOpts.ServerRootCAs should contain 1 entries")
   412  	require.Equal(t, org1ServerKP.Key, clientConfig.SecOpts.Key, "Client.SecOpts.Key should be set to configured key")
   413  	require.Equal(t, org1ServerKP.Cert, clientConfig.SecOpts.Certificate, "Client.SecOpts.Certificate shoulbe bet set to configured certificate")
   414  }