github.com/binyushen/fabric@v2.1.1+incompatible/core/peer/config_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  package peer
     7  
     8  import (
     9  	"crypto/tls"
    10  	"fmt"
    11  	"net"
    12  	"os"
    13  	"path/filepath"
    14  	"runtime"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/hyperledger/fabric/internal/pkg/comm"
    19  	"github.com/spf13/viper"
    20  	"github.com/stretchr/testify/assert"
    21  )
    22  
    23  func TestCacheConfigurationNegative(t *testing.T) {
    24  	// set a bad peer.address
    25  	viper.Set("peer.addressAutoDetect", true)
    26  	viper.Set("peer.address", "testing.com")
    27  	_, err := GlobalConfig()
    28  	assert.Error(t, err, "Expected error for bad configuration")
    29  
    30  	viper.Set("peer.addressAutoDetect", false)
    31  	viper.Set("peer.address", "")
    32  	_, err = GlobalConfig()
    33  	assert.Error(t, err, "Expected error for bad configuration")
    34  
    35  	viper.Set("peer.address", "wrongAddress")
    36  	_, err = GlobalConfig()
    37  	assert.Error(t, err, "Expected error for bad configuration")
    38  
    39  }
    40  
    41  func TestConfiguration(t *testing.T) {
    42  	// get the interface addresses
    43  	addresses, err := net.InterfaceAddrs()
    44  	if err != nil {
    45  		t.Fatal("Failed to get interface addresses")
    46  	}
    47  
    48  	var ips []string
    49  	for _, address := range addresses {
    50  		// eliminate loopback interfaces
    51  		if ip, ok := address.(*net.IPNet); ok && !ip.IP.IsLoopback() {
    52  			ips = append(ips, ip.IP.String()+":7051")
    53  			t.Logf("found interface address [%s]", ip.IP.String())
    54  		}
    55  	}
    56  
    57  	// There is a flake where sometimes this returns no IP address.
    58  	localIP, err := comm.GetLocalIP()
    59  	assert.NoError(t, err)
    60  
    61  	var tests = []struct {
    62  		name                string
    63  		settings            map[string]interface{}
    64  		validAddresses      []string
    65  		invalidAddresses    []string
    66  		expectedPeerAddress string
    67  	}{
    68  		{
    69  			name: "test1",
    70  			settings: map[string]interface{}{
    71  				"peer.addressAutoDetect": false,
    72  				"peer.address":           "testing.com:7051",
    73  				"peer.id":                "testPeer",
    74  			},
    75  			validAddresses:      []string{"testing.com:7051"},
    76  			invalidAddresses:    ips,
    77  			expectedPeerAddress: "testing.com:7051",
    78  		},
    79  		{
    80  			name: "test2",
    81  			settings: map[string]interface{}{
    82  				"peer.addressAutoDetect": true,
    83  				"peer.address":           "testing.com:7051",
    84  				"peer.id":                "testPeer",
    85  			},
    86  			validAddresses:      ips,
    87  			invalidAddresses:    []string{"testing.com:7051"},
    88  			expectedPeerAddress: net.JoinHostPort(localIP, "7051"),
    89  		},
    90  		{
    91  			name: "test3",
    92  			settings: map[string]interface{}{
    93  				"peer.addressAutoDetect": false,
    94  				"peer.address":           "0.0.0.0:7051",
    95  				"peer.id":                "testPeer",
    96  			},
    97  			validAddresses:      []string{fmt.Sprintf("%s:7051", localIP)},
    98  			invalidAddresses:    []string{"0.0.0.0:7051"},
    99  			expectedPeerAddress: net.JoinHostPort(localIP, "7051"),
   100  		},
   101  	}
   102  
   103  	for _, test := range tests {
   104  		test := test
   105  		t.Run(test.name, func(t *testing.T) {
   106  			for k, v := range test.settings {
   107  				viper.Set(k, v)
   108  			}
   109  			// load Config file
   110  			_, err := GlobalConfig()
   111  			assert.NoError(t, err, "GlobalConfig returned unexpected error")
   112  		})
   113  	}
   114  }
   115  
   116  func TestGetServerConfig(t *testing.T) {
   117  	// good config without TLS
   118  	viper.Set("peer.tls.enabled", false)
   119  	viper.Set("peer.connectiontimeout", "7s")
   120  	sc, _ := GetServerConfig()
   121  	assert.Equal(t, false, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be false")
   122  	assert.Equal(t, sc.ConnectionTimeout, 7*time.Second, "ServerConfig.ConnectionTimeout should be 7 seconds")
   123  
   124  	// keepalive options
   125  	assert.Equal(t, comm.DefaultKeepaliveOptions, sc.KaOpts, "ServerConfig.KaOpts should be set to default values")
   126  	viper.Set("peer.keepalive.interval", "60m")
   127  	sc, _ = GetServerConfig()
   128  	assert.Equal(t, time.Duration(60)*time.Minute, sc.KaOpts.ServerInterval, "ServerConfig.KaOpts.ServerInterval should be set to 60 min")
   129  	viper.Set("peer.keepalive.timeout", "30s")
   130  	sc, _ = GetServerConfig()
   131  	assert.Equal(t, time.Duration(30)*time.Second, sc.KaOpts.ServerTimeout, "ServerConfig.KaOpts.ServerTimeout should be set to 30 sec")
   132  	viper.Set("peer.keepalive.minInterval", "2m")
   133  	sc, _ = GetServerConfig()
   134  	assert.Equal(t, time.Duration(2)*time.Minute, sc.KaOpts.ServerMinInterval, "ServerConfig.KaOpts.ServerMinInterval should be set to 2 min")
   135  
   136  	// good config with TLS
   137  	viper.Set("peer.tls.enabled", true)
   138  	viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
   139  	viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
   140  	viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org1-cert.pem"))
   141  	sc, _ = GetServerConfig()
   142  	assert.Equal(t, true, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be true")
   143  	assert.Equal(t, false, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be false")
   144  	viper.Set("peer.tls.clientAuthRequired", true)
   145  	viper.Set("peer.tls.clientRootCAs.files", []string{
   146  		filepath.Join("testdata", "Org1-cert.pem"),
   147  		filepath.Join("testdata", "Org2-cert.pem"),
   148  	})
   149  	sc, _ = GetServerConfig()
   150  	assert.Equal(t, true, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be true")
   151  	assert.Equal(t, 2, len(sc.SecOpts.ClientRootCAs), "ServerConfig.SecOpts.ClientRootCAs should contain 2 entries")
   152  
   153  	// bad config with TLS
   154  	viper.Set("peer.tls.rootcert.file", filepath.Join("testdata", "Org11-cert.pem"))
   155  	_, err := GetServerConfig()
   156  	assert.Error(t, err, "GetServerConfig should return error with bad root cert path")
   157  	viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org11-cert.pem"))
   158  	_, err = GetServerConfig()
   159  	assert.Error(t, err, "GetServerConfig should return error with bad tls cert path")
   160  
   161  	// disable TLS for remaining tests
   162  	viper.Set("peer.tls.enabled", false)
   163  	viper.Set("peer.tls.clientAuthRequired", false)
   164  }
   165  
   166  func TestGetClientCertificate(t *testing.T) {
   167  	viper.Set("peer.tls.key.file", "")
   168  	viper.Set("peer.tls.cert.file", "")
   169  	viper.Set("peer.tls.clientKey.file", "")
   170  	viper.Set("peer.tls.clientCert.file", "")
   171  
   172  	// neither client nor server key pairs set - expect error
   173  	_, err := GetClientCertificate()
   174  	assert.Error(t, err)
   175  
   176  	viper.Set("peer.tls.key.file", "")
   177  	viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
   178  	// missing server key file - expect error
   179  	_, err = GetClientCertificate()
   180  	assert.Error(t, err)
   181  
   182  	viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
   183  	viper.Set("peer.tls.cert.file", "")
   184  	// missing server cert file - expect error
   185  	_, err = GetClientCertificate()
   186  	assert.Error(t, err)
   187  
   188  	// set server TLS settings to ensure we get the client TLS settings
   189  	// when they are set properly
   190  	viper.Set("peer.tls.key.file", filepath.Join("testdata", "Org1-server1-key.pem"))
   191  	viper.Set("peer.tls.cert.file", filepath.Join("testdata", "Org1-server1-cert.pem"))
   192  
   193  	// peer.tls.clientCert.file not set - expect error
   194  	viper.Set("peer.tls.clientKey.file", filepath.Join("testdata", "Org2-server1-key.pem"))
   195  	_, err = GetClientCertificate()
   196  	assert.Error(t, err)
   197  
   198  	// peer.tls.clientKey.file not set - expect error
   199  	viper.Set("peer.tls.clientKey.file", "")
   200  	viper.Set("peer.tls.clientCert.file", filepath.Join("testdata", "Org2-server1-cert.pem"))
   201  	_, err = GetClientCertificate()
   202  	assert.Error(t, err)
   203  
   204  	// client auth required and clientKey/clientCert set
   205  	expected, err := tls.LoadX509KeyPair(
   206  		filepath.Join("testdata", "Org2-server1-cert.pem"),
   207  		filepath.Join("testdata", "Org2-server1-key.pem"),
   208  	)
   209  	if err != nil {
   210  		t.Fatalf("Failed to load test certificate (%s)", err)
   211  	}
   212  	viper.Set("peer.tls.clientKey.file", filepath.Join("testdata", "Org2-server1-key.pem"))
   213  	cert, err := GetClientCertificate()
   214  	assert.NoError(t, err)
   215  	assert.Equal(t, expected, cert)
   216  
   217  	// client auth required and clientKey/clientCert not set - expect
   218  	// client cert to be the server cert
   219  	viper.Set("peer.tls.clientKey.file", "")
   220  	viper.Set("peer.tls.clientCert.file", "")
   221  	expected, err = tls.LoadX509KeyPair(
   222  		filepath.Join("testdata", "Org1-server1-cert.pem"),
   223  		filepath.Join("testdata", "Org1-server1-key.pem"),
   224  	)
   225  	if err != nil {
   226  		t.Fatalf("Failed to load test certificate (%s)", err)
   227  	}
   228  	cert, err = GetClientCertificate()
   229  	assert.NoError(t, err)
   230  	assert.Equal(t, expected, cert)
   231  }
   232  
   233  func TestGlobalConfig(t *testing.T) {
   234  	defer viper.Reset()
   235  	cwd, err := os.Getwd()
   236  	assert.NoError(t, err, "failed to get current working directory")
   237  	viper.SetConfigFile(filepath.Join(cwd, "core.yaml"))
   238  
   239  	//Capture the configuration from viper
   240  	viper.Set("peer.addressAutoDetect", false)
   241  	viper.Set("peer.address", "localhost:8080")
   242  	viper.Set("peer.id", "testPeerID")
   243  	viper.Set("peer.localMspId", "SampleOrg")
   244  	viper.Set("peer.listenAddress", "0.0.0.0:7051")
   245  	viper.Set("peer.authentication.timewindow", "15m")
   246  	viper.Set("peer.tls.enabled", "false")
   247  	viper.Set("peer.networkId", "testNetwork")
   248  	viper.Set("peer.limits.concurrency.endorserService", 2500)
   249  	viper.Set("peer.limits.concurrency.deliverService", 2500)
   250  	viper.Set("peer.discovery.enabled", true)
   251  	viper.Set("peer.profile.enabled", false)
   252  	viper.Set("peer.profile.listenAddress", "peer.authentication.timewindow")
   253  	viper.Set("peer.discovery.orgMembersAllowedAccess", false)
   254  	viper.Set("peer.discovery.authCacheEnabled", true)
   255  	viper.Set("peer.discovery.authCacheMaxSize", 1000)
   256  	viper.Set("peer.discovery.authCachePurgeRetentionRatio", 0.75)
   257  	viper.Set("peer.chaincodeListenAddress", "0.0.0.0:7052")
   258  	viper.Set("peer.chaincodeAddress", "0.0.0.0:7052")
   259  	viper.Set("peer.validatorPoolSize", 1)
   260  
   261  	viper.Set("vm.endpoint", "unix:///var/run/docker.sock")
   262  	viper.Set("vm.docker.tls.enabled", false)
   263  	viper.Set("vm.docker.attachStdout", false)
   264  	viper.Set("vm.docker.hostConfig.NetworkMode", "TestingHost")
   265  	viper.Set("vm.docker.tls.cert.file", "test/vm/tls/cert/file")
   266  	viper.Set("vm.docker.tls.key.file", "test/vm/tls/key/file")
   267  	viper.Set("vm.docker.tls.ca.file", "test/vm/tls/ca/file")
   268  
   269  	viper.Set("operations.listenAddress", "127.0.0.1:9443")
   270  	viper.Set("operations.tls.enabled", false)
   271  	viper.Set("operations.tls.cert.file", "test/tls/cert/file")
   272  	viper.Set("operations.tls.key.file", "test/tls/key/file")
   273  	viper.Set("operations.tls.clientAuthRequired", false)
   274  	viper.Set("operations.tls.clientRootCAs.files", []string{"relative/file1", "/absolute/file2"})
   275  
   276  	viper.Set("metrics.provider", "disabled")
   277  	viper.Set("metrics.statsd.network", "udp")
   278  	viper.Set("metrics.statsd.address", "127.0.0.1:8125")
   279  	viper.Set("metrics.statsd.writeInterval", "10s")
   280  	viper.Set("metrics.statsd.prefix", "testPrefix")
   281  
   282  	viper.Set("chaincode.pull", false)
   283  	viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{
   284  		{
   285  			Path: "relative/plugin_dir",
   286  			Name: "relative",
   287  		},
   288  		{
   289  			Path: "/absolute/plugin_dir",
   290  			Name: "absolute",
   291  		},
   292  	})
   293  
   294  	coreConfig, err := GlobalConfig()
   295  	assert.NoError(t, err)
   296  
   297  	expectedConfig := &Config{
   298  		LocalMSPID:                            "SampleOrg",
   299  		ListenAddress:                         "0.0.0.0:7051",
   300  		AuthenticationTimeWindow:              15 * time.Minute,
   301  		PeerTLSEnabled:                        false,
   302  		PeerAddress:                           "localhost:8080",
   303  		PeerID:                                "testPeerID",
   304  		NetworkID:                             "testNetwork",
   305  		LimitsConcurrencyEndorserService:      2500,
   306  		LimitsConcurrencyDeliverService:       2500,
   307  		DiscoveryEnabled:                      true,
   308  		ProfileEnabled:                        false,
   309  		ProfileListenAddress:                  "peer.authentication.timewindow",
   310  		DiscoveryOrgMembersAllowed:            false,
   311  		DiscoveryAuthCacheEnabled:             true,
   312  		DiscoveryAuthCacheMaxSize:             1000,
   313  		DiscoveryAuthCachePurgeRetentionRatio: 0.75,
   314  		ChaincodeListenAddress:                "0.0.0.0:7052",
   315  		ChaincodeAddress:                      "0.0.0.0:7052",
   316  		ValidatorPoolSize:                     1,
   317  		DeliverClientKeepaliveOptions:         comm.DefaultKeepaliveOptions,
   318  
   319  		VMEndpoint:           "unix:///var/run/docker.sock",
   320  		VMDockerTLSEnabled:   false,
   321  		VMDockerAttachStdout: false,
   322  		VMNetworkMode:        "TestingHost",
   323  
   324  		ChaincodePull: false,
   325  		ExternalBuilders: []ExternalBuilder{
   326  			{
   327  				Path: "relative/plugin_dir",
   328  				Name: "relative",
   329  			},
   330  			{
   331  				Path: "/absolute/plugin_dir",
   332  				Name: "absolute",
   333  			},
   334  		},
   335  		OperationsListenAddress:         "127.0.0.1:9443",
   336  		OperationsTLSEnabled:            false,
   337  		OperationsTLSCertFile:           filepath.Join(cwd, "test/tls/cert/file"),
   338  		OperationsTLSKeyFile:            filepath.Join(cwd, "test/tls/key/file"),
   339  		OperationsTLSClientAuthRequired: false,
   340  		OperationsTLSClientRootCAs: []string{
   341  			filepath.Join(cwd, "relative", "file1"),
   342  			"/absolute/file2",
   343  		},
   344  
   345  		MetricsProvider:     "disabled",
   346  		StatsdNetwork:       "udp",
   347  		StatsdAaddress:      "127.0.0.1:8125",
   348  		StatsdWriteInterval: 10 * time.Second,
   349  		StatsdPrefix:        "testPrefix",
   350  
   351  		DockerCert: filepath.Join(cwd, "test/vm/tls/cert/file"),
   352  		DockerKey:  filepath.Join(cwd, "test/vm/tls/key/file"),
   353  		DockerCA:   filepath.Join(cwd, "test/vm/tls/ca/file"),
   354  	}
   355  
   356  	assert.Equal(t, coreConfig, expectedConfig)
   357  }
   358  
   359  func TestGlobalConfigDefault(t *testing.T) {
   360  	defer viper.Reset()
   361  	viper.Set("peer.address", "localhost:8080")
   362  
   363  	coreConfig, err := GlobalConfig()
   364  	assert.NoError(t, err)
   365  
   366  	expectedConfig := &Config{
   367  		AuthenticationTimeWindow:      15 * time.Minute,
   368  		PeerAddress:                   "localhost:8080",
   369  		ValidatorPoolSize:             runtime.NumCPU(),
   370  		VMNetworkMode:                 "host",
   371  		DeliverClientKeepaliveOptions: comm.DefaultKeepaliveOptions,
   372  	}
   373  
   374  	assert.Equal(t, expectedConfig, coreConfig)
   375  }
   376  
   377  func TestMissingExternalBuilderPath(t *testing.T) {
   378  	defer viper.Reset()
   379  	viper.Set("peer.address", "localhost:8080")
   380  	viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{
   381  		{
   382  			Name: "testName",
   383  		},
   384  	})
   385  	_, err := GlobalConfig()
   386  	assert.EqualError(t, err, "invalid external builder configuration, path attribute missing in one or more builders")
   387  }
   388  
   389  func TestMissingExternalBuilderName(t *testing.T) {
   390  	defer viper.Reset()
   391  	viper.Set("peer.address", "localhost:8080")
   392  	viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{
   393  		{
   394  			Path: "relative/plugin_dir",
   395  		},
   396  	})
   397  	_, err := GlobalConfig()
   398  	assert.EqualError(t, err, "external builder at path relative/plugin_dir has no name attribute")
   399  }