github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/peer/config_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package peer 7 8 import ( 9 "crypto/tls" 10 "io/ioutil" 11 "net" 12 "os" 13 "path/filepath" 14 "runtime" 15 "testing" 16 "time" 17 18 "github.com/hechain20/hechain/common/crypto/tlsgen" 19 "github.com/hechain20/hechain/internal/pkg/comm" 20 "github.com/hechain20/hechain/internal/pkg/gateway/config" 21 "github.com/spf13/viper" 22 "github.com/stretchr/testify/require" 23 ) 24 25 func TestCacheConfigurationNegative(t *testing.T) { 26 // set a bad peer.address 27 viper.Set("peer.addressAutoDetect", true) 28 viper.Set("peer.address", "testing.com") 29 _, err := GlobalConfig() 30 require.Error(t, err, "Expected error for bad configuration") 31 32 viper.Set("peer.addressAutoDetect", false) 33 viper.Set("peer.address", "") 34 _, err = GlobalConfig() 35 require.Error(t, err, "Expected error for bad configuration") 36 37 viper.Set("peer.address", "wrongAddress") 38 _, err = GlobalConfig() 39 require.Error(t, err, "Expected error for bad configuration") 40 } 41 42 func TestPeerAddress(t *testing.T) { 43 localIP, err := getLocalIP() 44 require.NoError(t, err) 45 46 tests := []struct { 47 name string 48 settings map[string]interface{} 49 expectedPeerAddress string 50 }{ 51 { 52 name: "test1", 53 settings: map[string]interface{}{ 54 "peer.addressAutoDetect": false, 55 "peer.address": "testing.com:7051", 56 }, 57 expectedPeerAddress: "testing.com:7051", 58 }, 59 { 60 name: "test2", 61 settings: map[string]interface{}{ 62 "peer.addressAutoDetect": true, 63 "peer.address": "testing.com:7051", 64 }, 65 expectedPeerAddress: net.JoinHostPort(localIP, "7051"), 66 }, 67 { 68 name: "test3", 69 settings: map[string]interface{}{ 70 "peer.addressAutoDetect": false, 71 "peer.address": "0.0.0.0:7051", 72 }, 73 expectedPeerAddress: net.JoinHostPort(localIP, "7051"), 74 }, 75 { 76 name: "test4", 77 settings: map[string]interface{}{ 78 "peer.addressAutoDetect": true, 79 "peer.address": "127.0.0.1:7051", 80 }, 81 expectedPeerAddress: net.JoinHostPort(localIP, "7051"), 82 }, 83 } 84 85 for _, test := range tests { 86 test := test 87 t.Run(test.name, func(t *testing.T) { 88 for k, v := range test.settings { 89 viper.Set(k, v) 90 } 91 c, err := GlobalConfig() 92 require.NoError(t, err, "GlobalConfig returned unexpected error") 93 require.Equal(t, test.expectedPeerAddress, c.PeerAddress) 94 }) 95 } 96 } 97 98 func TestGetServerConfig(t *testing.T) { 99 tempdir, err := ioutil.TempDir("", "peer-clientcert") 100 require.NoError(t, err) 101 defer os.RemoveAll(tempdir) 102 103 // good config without TLS 104 viper.Set("peer.tls.enabled", false) 105 viper.Set("peer.connectiontimeout", "7s") 106 sc, err := GetServerConfig() 107 require.NoError(t, err) 108 require.Equal(t, false, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be false") 109 require.Equal(t, sc.ConnectionTimeout, 7*time.Second, "ServerConfig.ConnectionTimeout should be 7 seconds") 110 111 // keepalive options 112 require.Equal(t, comm.DefaultKeepaliveOptions, sc.KaOpts, "ServerConfig.KaOpts should be set to default values") 113 viper.Set("peer.keepalive.interval", "60m") 114 sc, _ = GetServerConfig() 115 require.Equal(t, time.Duration(60)*time.Minute, sc.KaOpts.ServerInterval, "ServerConfig.KaOpts.ServerInterval should be set to 60 min") 116 viper.Set("peer.keepalive.timeout", "30s") 117 sc, _ = GetServerConfig() 118 require.Equal(t, time.Duration(30)*time.Second, sc.KaOpts.ServerTimeout, "ServerConfig.KaOpts.ServerTimeout should be set to 30 sec") 119 viper.Set("peer.keepalive.minInterval", "2m") 120 sc, _ = GetServerConfig() 121 require.Equal(t, time.Duration(2)*time.Minute, sc.KaOpts.ServerMinInterval, "ServerConfig.KaOpts.ServerMinInterval should be set to 2 min") 122 123 // good config with TLS 124 org1CA, err := tlsgen.NewCA() 125 require.NoError(t, err) 126 err = ioutil.WriteFile(filepath.Join(tempdir, "org1-ca-cert.pem"), org1CA.CertBytes(), 0o644) 127 require.NoError(t, err) 128 org2CA, err := tlsgen.NewCA() 129 require.NoError(t, err) 130 err = ioutil.WriteFile(filepath.Join(tempdir, "org2-ca-cert.pem"), org2CA.CertBytes(), 0o644) 131 require.NoError(t, err) 132 133 org1ServerKP, err := org1CA.NewServerCertKeyPair("localhost") 134 require.NoError(t, err) 135 err = ioutil.WriteFile(filepath.Join(tempdir, "org1-server1-cert.pem"), org1ServerKP.Cert, 0o644) 136 require.NoError(t, err) 137 err = ioutil.WriteFile(filepath.Join(tempdir, "org1-server1-key.pem"), org1ServerKP.Key, 0o600) 138 require.NoError(t, err) 139 140 viper.Set("peer.tls.enabled", true) 141 viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "org1-server1-cert.pem")) 142 viper.Set("peer.tls.key.file", filepath.Join(tempdir, "org1-server1-key.pem")) 143 viper.Set("peer.tls.rootcert.file", filepath.Join(tempdir, "org1-ca-cert.pem")) 144 145 sc, err = GetServerConfig() 146 require.NoError(t, err, "failed to build server config") 147 require.Equal(t, true, sc.SecOpts.UseTLS, "ServerConfig.SecOpts.UseTLS should be true") 148 require.Equal(t, false, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be false") 149 viper.Set("peer.tls.clientAuthRequired", true) 150 viper.Set("peer.tls.clientRootCAs.files", []string{ 151 filepath.Join(tempdir, "org1-ca-cert.pem"), 152 filepath.Join(tempdir, "org2-ca-cert.pem"), 153 }) 154 sc, _ = GetServerConfig() 155 require.Equal(t, true, sc.SecOpts.RequireClientCert, "ServerConfig.SecOpts.RequireClientCert should be true") 156 require.Equal(t, 2, len(sc.SecOpts.ClientRootCAs), "ServerConfig.SecOpts.ClientRootCAs should contain 2 entries") 157 158 // GRPC max message size options 159 require.Equal(t, comm.DefaultMaxRecvMsgSize, sc.MaxRecvMsgSize, "ServerConfig.MaxRecvMsgSize should be set to default value %v", comm.DefaultMaxRecvMsgSize) 160 require.Equal(t, comm.DefaultMaxSendMsgSize, sc.MaxSendMsgSize, "ServerConfig.MaxSendMsgSize should be set to default value %v", comm.DefaultMaxSendMsgSize) 161 viper.Set("peer.maxRecvMsgSize", "1024") 162 viper.Set("peer.maxSendMsgSize", "1024") 163 sc, _ = GetServerConfig() 164 require.Equal(t, 1024, sc.MaxRecvMsgSize, "ServerConfig.MaxRecvMsgSize should be set to custom value 1024") 165 require.Equal(t, 1024, sc.MaxSendMsgSize, "ServerConfig.MaxSendMsgSize should be set to custom value 1024") 166 167 // bad config with TLS 168 viper.Set("peer.tls.rootcert.file", "non-existent-file.pem") 169 _, err = GetServerConfig() 170 require.Error(t, err, "GetServerConfig should return error with bad root cert path") 171 172 viper.Set("peer.tls.rootcert.file", filepath.Join(tempdir, "org1-ca-cert.pem")) 173 viper.Set("peer.tls.cert.file", "non-existent-file.pem") 174 _, err = GetServerConfig() 175 require.Error(t, err, "GetServerConfig should return error with bad tls cert path") 176 177 // disable TLS for remaining tests 178 viper.Set("peer.tls.enabled", false) 179 viper.Set("peer.tls.clientAuthRequired", false) 180 } 181 182 func TestGetClientCertificate(t *testing.T) { 183 tempdir, err := ioutil.TempDir("", "peer-clientcert") 184 require.NoError(t, err) 185 defer os.RemoveAll(tempdir) 186 187 ca, err := tlsgen.NewCA() 188 require.NoError(t, err) 189 kp, err := ca.NewServerCertKeyPair("localhost") 190 require.NoError(t, err) 191 err = ioutil.WriteFile(filepath.Join(tempdir, "server1-cert.pem"), kp.Cert, 0o644) 192 require.NoError(t, err) 193 err = ioutil.WriteFile(filepath.Join(tempdir, "server1-key.pem"), kp.Key, 0o600) 194 require.NoError(t, err) 195 196 viper.Set("peer.tls.key.file", "") 197 viper.Set("peer.tls.cert.file", "") 198 viper.Set("peer.tls.clientKey.file", "") 199 viper.Set("peer.tls.clientCert.file", "") 200 201 // neither client nor server key pairs set - expect error 202 _, err = GetClientCertificate() 203 require.Error(t, err) 204 205 viper.Set("peer.tls.key.file", "") 206 viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "server1-cert.pem")) 207 // missing server key file - expect error 208 _, err = GetClientCertificate() 209 require.Error(t, err) 210 211 viper.Set("peer.tls.key.file", filepath.Join(tempdir, "server1-key.pem")) 212 viper.Set("peer.tls.cert.file", "") 213 // missing server cert file - expect error 214 _, err = GetClientCertificate() 215 require.Error(t, err) 216 217 // set server TLS settings to ensure we get the client TLS settings 218 // when they are set properly 219 viper.Set("peer.tls.key.file", filepath.Join(tempdir, "server1-key.pem")) 220 viper.Set("peer.tls.cert.file", filepath.Join(tempdir, "server1-cert.pem")) 221 222 // peer.tls.clientCert.file not set - expect error 223 viper.Set("peer.tls.clientKey.file", filepath.Join(tempdir, "server1-key.pem")) 224 _, err = GetClientCertificate() 225 require.Error(t, err) 226 227 // peer.tls.clientKey.file not set - expect error 228 viper.Set("peer.tls.clientKey.file", "") 229 viper.Set("peer.tls.clientCert.file", filepath.Join(tempdir, "server1-cert.pem")) 230 _, err = GetClientCertificate() 231 require.Error(t, err) 232 233 // client auth required and clientKey/clientCert set 234 expected, err := tls.LoadX509KeyPair( 235 filepath.Join(tempdir, "server1-cert.pem"), 236 filepath.Join(tempdir, "server1-key.pem"), 237 ) 238 if err != nil { 239 t.Fatalf("Failed to load test certificate (%s)", err) 240 } 241 viper.Set("peer.tls.clientKey.file", filepath.Join(tempdir, "server1-key.pem")) 242 cert, err := GetClientCertificate() 243 require.NoError(t, err) 244 require.Equal(t, expected, cert) 245 246 // client auth required and clientKey/clientCert not set - expect 247 // client cert to be the server cert 248 viper.Set("peer.tls.clientKey.file", "") 249 viper.Set("peer.tls.clientCert.file", "") 250 expected, err = tls.LoadX509KeyPair( 251 filepath.Join(tempdir, "server1-cert.pem"), 252 filepath.Join(tempdir, "server1-key.pem"), 253 ) 254 require.NoError(t, err, "failed to load test certificate") 255 cert, err = GetClientCertificate() 256 require.NoError(t, err) 257 require.Equal(t, expected, cert) 258 } 259 260 func TestGlobalConfig(t *testing.T) { 261 defer viper.Reset() 262 cwd, err := os.Getwd() 263 require.NoError(t, err, "failed to get current working directory") 264 viper.SetConfigFile(filepath.Join(cwd, "core.yaml")) 265 266 // Capture the configuration from viper 267 viper.Set("peer.addressAutoDetect", false) 268 viper.Set("peer.address", "localhost:8080") 269 viper.Set("peer.id", "testPeerID") 270 viper.Set("peer.localMspId", "SampleOrg") 271 viper.Set("peer.listenAddress", "0.0.0.0:7051") 272 viper.Set("peer.authentication.timewindow", "15m") 273 viper.Set("peer.tls.enabled", "false") 274 viper.Set("peer.networkId", "testNetwork") 275 viper.Set("peer.limits.concurrency.endorserService", 2500) 276 viper.Set("peer.limits.concurrency.deliverService", 2500) 277 viper.Set("peer.limits.concurrency.gatewayService", 500) 278 viper.Set("peer.discovery.enabled", true) 279 viper.Set("peer.profile.enabled", false) 280 viper.Set("peer.profile.listenAddress", "peer.authentication.timewindow") 281 viper.Set("peer.discovery.orgMembersAllowedAccess", false) 282 viper.Set("peer.discovery.authCacheEnabled", true) 283 viper.Set("peer.discovery.authCacheMaxSize", 1000) 284 viper.Set("peer.discovery.authCachePurgeRetentionRatio", 0.75) 285 viper.Set("peer.chaincodeListenAddress", "0.0.0.0:7052") 286 viper.Set("peer.chaincodeAddress", "0.0.0.0:7052") 287 viper.Set("peer.validatorPoolSize", 1) 288 viper.Set("peer.gateway.enabled", true) 289 viper.Set("peer.gateway.endorsementTimeout", 10*time.Second) 290 viper.Set("peer.gateway.dialTimeout", 60*time.Second) 291 292 viper.Set("vm.endpoint", "unix:///var/run/docker.sock") 293 viper.Set("vm.docker.tls.enabled", false) 294 viper.Set("vm.docker.attachStdout", false) 295 viper.Set("vm.docker.hostConfig.NetworkMode", "TestingHost") 296 viper.Set("vm.docker.tls.cert.file", "test/vm/tls/cert/file") 297 viper.Set("vm.docker.tls.key.file", "test/vm/tls/key/file") 298 viper.Set("vm.docker.tls.ca.file", "test/vm/tls/ca/file") 299 300 viper.Set("operations.listenAddress", "127.0.0.1:9443") 301 viper.Set("operations.tls.enabled", false) 302 viper.Set("operations.tls.cert.file", "test/tls/cert/file") 303 viper.Set("operations.tls.key.file", "test/tls/key/file") 304 viper.Set("operations.tls.clientAuthRequired", false) 305 viper.Set("operations.tls.clientRootCAs.files", []string{"relative/file1", "/absolute/file2"}) 306 307 viper.Set("metrics.provider", "disabled") 308 viper.Set("metrics.statsd.network", "udp") 309 viper.Set("metrics.statsd.address", "127.0.0.1:8125") 310 viper.Set("metrics.statsd.writeInterval", "10s") 311 viper.Set("metrics.statsd.prefix", "testPrefix") 312 313 viper.Set("chaincode.pull", false) 314 viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{ 315 { 316 Path: "relative/plugin_dir", 317 Name: "relative", 318 }, 319 { 320 Path: "/absolute/plugin_dir", 321 Name: "absolute", 322 }, 323 }) 324 325 coreConfig, err := GlobalConfig() 326 require.NoError(t, err) 327 328 expectedConfig := &Config{ 329 LocalMSPID: "SampleOrg", 330 ListenAddress: "0.0.0.0:7051", 331 AuthenticationTimeWindow: 15 * time.Minute, 332 PeerTLSEnabled: false, 333 PeerAddress: "localhost:8080", 334 PeerID: "testPeerID", 335 NetworkID: "testNetwork", 336 LimitsConcurrencyEndorserService: 2500, 337 LimitsConcurrencyDeliverService: 2500, 338 LimitsConcurrencyGatewayService: 500, 339 DiscoveryEnabled: true, 340 ProfileEnabled: false, 341 ProfileListenAddress: "peer.authentication.timewindow", 342 DiscoveryOrgMembersAllowed: false, 343 DiscoveryAuthCacheEnabled: true, 344 DiscoveryAuthCacheMaxSize: 1000, 345 DiscoveryAuthCachePurgeRetentionRatio: 0.75, 346 ChaincodeListenAddress: "0.0.0.0:7052", 347 ChaincodeAddress: "0.0.0.0:7052", 348 ValidatorPoolSize: 1, 349 DeliverClientKeepaliveOptions: comm.DefaultKeepaliveOptions, 350 351 VMEndpoint: "unix:///var/run/docker.sock", 352 VMDockerTLSEnabled: false, 353 VMDockerAttachStdout: false, 354 VMNetworkMode: "TestingHost", 355 356 ChaincodePull: false, 357 ExternalBuilders: []ExternalBuilder{ 358 { 359 Path: "relative/plugin_dir", 360 Name: "relative", 361 }, 362 { 363 Path: "/absolute/plugin_dir", 364 Name: "absolute", 365 }, 366 }, 367 OperationsListenAddress: "127.0.0.1:9443", 368 OperationsTLSEnabled: false, 369 OperationsTLSCertFile: filepath.Join(cwd, "test/tls/cert/file"), 370 OperationsTLSKeyFile: filepath.Join(cwd, "test/tls/key/file"), 371 OperationsTLSClientAuthRequired: false, 372 OperationsTLSClientRootCAs: []string{ 373 filepath.Join(cwd, "relative", "file1"), 374 "/absolute/file2", 375 }, 376 377 MetricsProvider: "disabled", 378 StatsdNetwork: "udp", 379 StatsdAaddress: "127.0.0.1:8125", 380 StatsdWriteInterval: 10 * time.Second, 381 StatsdPrefix: "testPrefix", 382 383 DockerCert: filepath.Join(cwd, "test/vm/tls/cert/file"), 384 DockerKey: filepath.Join(cwd, "test/vm/tls/key/file"), 385 DockerCA: filepath.Join(cwd, "test/vm/tls/ca/file"), 386 387 GatewayOptions: config.Options{ 388 Enabled: true, 389 EndorsementTimeout: 10 * time.Second, 390 DialTimeout: 60 * time.Second, 391 }, 392 } 393 394 require.Equal(t, coreConfig, expectedConfig) 395 } 396 397 func TestGlobalConfigDefault(t *testing.T) { 398 defer viper.Reset() 399 viper.Set("peer.address", "localhost:8080") 400 401 coreConfig, err := GlobalConfig() 402 require.NoError(t, err) 403 404 expectedConfig := &Config{ 405 AuthenticationTimeWindow: 15 * time.Minute, 406 PeerAddress: "localhost:8080", 407 ValidatorPoolSize: runtime.NumCPU(), 408 VMNetworkMode: "host", 409 DeliverClientKeepaliveOptions: comm.DefaultKeepaliveOptions, 410 GatewayOptions: config.GetOptions(viper.GetViper()), 411 } 412 413 require.Equal(t, expectedConfig, coreConfig) 414 } 415 416 func TestPropagateEnvironment(t *testing.T) { 417 defer viper.Reset() 418 viper.Set("peer.address", "localhost:8080") 419 viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{ 420 { 421 Name: "testName", 422 Environment: []string{"KEY=VALUE"}, 423 Path: "/testPath", 424 }, 425 { 426 Name: "testName", 427 PropagateEnvironment: []string{"KEY=VALUE"}, 428 Path: "/testPath", 429 }, 430 { 431 Name: "testName", 432 Environment: []string{"KEY=VALUE"}, 433 PropagateEnvironment: []string{"KEY=VALUE2"}, 434 Path: "/testPath", 435 }, 436 }) 437 coreConfig, err := GlobalConfig() 438 require.NoError(t, err) 439 440 expectedConfig := &Config{ 441 AuthenticationTimeWindow: 15 * time.Minute, 442 PeerAddress: "localhost:8080", 443 ValidatorPoolSize: runtime.NumCPU(), 444 VMNetworkMode: "host", 445 DeliverClientKeepaliveOptions: comm.DefaultKeepaliveOptions, 446 ExternalBuilders: []ExternalBuilder{ 447 { 448 Name: "testName", 449 Environment: []string{"KEY=VALUE"}, 450 PropagateEnvironment: []string{"KEY=VALUE"}, 451 Path: "/testPath", 452 }, 453 { 454 Name: "testName", 455 PropagateEnvironment: []string{"KEY=VALUE"}, 456 Path: "/testPath", 457 }, 458 { 459 Name: "testName", 460 Environment: []string{"KEY=VALUE"}, 461 PropagateEnvironment: []string{"KEY=VALUE2"}, 462 Path: "/testPath", 463 }, 464 }, 465 GatewayOptions: config.GetOptions(viper.GetViper()), 466 } 467 require.Equal(t, expectedConfig, coreConfig) 468 } 469 470 func TestExternalBuilderConfigAsEnvVar(t *testing.T) { 471 defer viper.Reset() 472 viper.Set("peer.address", "localhost:8080") 473 viper.Set("chaincode.externalBuilders", "[{name: relative, path: relative/plugin_dir, propagateEnvironment: [ENVVAR_NAME_TO_PROPAGATE_FROM_PEER, GOPROXY]}, {name: absolute, path: /absolute/plugin_dir}]") 474 coreConfig, err := GlobalConfig() 475 require.NoError(t, err) 476 477 require.Equal(t, []ExternalBuilder{ 478 { 479 Path: "relative/plugin_dir", 480 Name: "relative", 481 PropagateEnvironment: []string{"ENVVAR_NAME_TO_PROPAGATE_FROM_PEER", "GOPROXY"}, 482 }, 483 { 484 Path: "/absolute/plugin_dir", 485 Name: "absolute", 486 }, 487 }, coreConfig.ExternalBuilders) 488 } 489 490 func TestMissingExternalBuilderPath(t *testing.T) { 491 defer viper.Reset() 492 viper.Set("peer.address", "localhost:8080") 493 viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{ 494 { 495 Name: "testName", 496 }, 497 }) 498 _, err := GlobalConfig() 499 require.EqualError(t, err, "invalid external builder configuration, path attribute missing in one or more builders") 500 } 501 502 func TestMissingExternalBuilderName(t *testing.T) { 503 defer viper.Reset() 504 viper.Set("peer.address", "localhost:8080") 505 viper.Set("chaincode.externalBuilders", &[]ExternalBuilder{ 506 { 507 Path: "relative/plugin_dir", 508 }, 509 }) 510 _, err := GlobalConfig() 511 require.EqualError(t, err, "external builder at path relative/plugin_dir has no name attribute") 512 }