github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/localconfig/config_test.go (about)

     1  // Copyright hechain. All Rights Reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package localconfig
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/hechain20/hechain/core/config/configtest"
    15  	"github.com/mitchellh/mapstructure"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestLoadGoodConfig(t *testing.T) {
    20  	cleanup := configtest.SetDevFabricConfigPath(t)
    21  	defer cleanup()
    22  	cc := &configCache{}
    23  	cfg, err := cc.load()
    24  	require.NoError(t, err)
    25  	require.NotNil(t, cfg, "Could not load config")
    26  	require.Nil(t, err, "Load good config returned unexpected error")
    27  }
    28  
    29  func TestMissingConfigValueOverridden(t *testing.T) {
    30  	t.Run("when the value is missing and not overridden", func(t *testing.T) {
    31  		cleanup := configtest.SetDevFabricConfigPath(t)
    32  		defer cleanup()
    33  		cc := &configCache{}
    34  		cfg, err := cc.load()
    35  		require.NotNil(t, cfg, "Could not load config")
    36  		require.NoError(t, err, "Load good config returned unexpected error")
    37  		require.Nil(t, cfg.Kafka.TLS.ClientRootCAs)
    38  	})
    39  
    40  	t.Run("when the value is missing and is overridden", func(t *testing.T) {
    41  		os.Setenv("ORDERER_KAFKA_TLS_CLIENTROOTCAS", "msp/tlscacerts/tlsroot.pem")
    42  		cleanup := configtest.SetDevFabricConfigPath(t)
    43  		defer cleanup()
    44  		cache := &configCache{}
    45  		cfg, err := cache.load()
    46  		require.NotNil(t, cfg, "Could not load config")
    47  		require.NoError(t, err, "Load good config returned unexpected error")
    48  		require.NotNil(t, cfg.Kafka.TLS.ClientRootCAs)
    49  	})
    50  }
    51  
    52  func TestLoadCached(t *testing.T) {
    53  	cleanup := configtest.SetDevFabricConfigPath(t)
    54  	defer cleanup()
    55  
    56  	// Load the initial config, update the environment, and load again.
    57  	// With the caching behavior, the update should not be reflected
    58  	initial, err := Load()
    59  	require.NoError(t, err)
    60  	os.Setenv("ORDERER_KAFKA_RETRY_SHORTINTERVAL", "120s")
    61  	updated, err := Load()
    62  	require.NoError(t, err)
    63  	require.Equal(t, initial, updated, "expected %#v to equal %#v", updated, initial)
    64  
    65  	// Change the configuration we got back and load again.
    66  	// The new value should not contain the update to the initial
    67  	initial.General.LocalMSPDir = "/test/bad/mspDir"
    68  	updated, err = Load()
    69  	require.NoError(t, err)
    70  	require.NotEqual(t, initial, updated, "expected %#v to not equal %#v", updated, initial)
    71  }
    72  
    73  func TestLoadMissingConfigFile(t *testing.T) {
    74  	envVar1 := "FABRIC_CFG_PATH"
    75  	envVal1 := "invalid fabric cfg path"
    76  	os.Setenv(envVar1, envVal1)
    77  	defer os.Unsetenv(envVar1)
    78  
    79  	cc := &configCache{}
    80  	cfg, err := cc.load()
    81  	require.Nil(t, cfg, "Loaded missing config file")
    82  	require.NotNil(t, err, "Loaded missing config file without error")
    83  }
    84  
    85  func TestLoadMalformedConfigFile(t *testing.T) {
    86  	name, err := ioutil.TempDir("", "hyperledger_fabric")
    87  	require.Nil(t, err, "Error creating temp dir: %s", err)
    88  	defer func() {
    89  		err = os.RemoveAll(name)
    90  		require.Nil(t, os.RemoveAll(name), "Error removing temp dir: %s", err)
    91  	}()
    92  
    93  	// Create a malformed orderer.yaml file in temp dir
    94  	f, err := os.OpenFile(filepath.Join(name, "orderer.yaml"), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
    95  	require.Nil(t, err, "Error creating file: %s", err)
    96  	f.WriteString("General: 42")
    97  	require.NoError(t, f.Close(), "Error closing file")
    98  
    99  	envVar1 := "FABRIC_CFG_PATH"
   100  	envVal1 := name
   101  	os.Setenv(envVar1, envVal1)
   102  	defer os.Unsetenv(envVar1)
   103  
   104  	cc := &configCache{}
   105  	cfg, err := cc.load()
   106  	require.Nil(t, cfg, "Loaded missing config file")
   107  	require.NotNil(t, err, "Loaded missing config file without error")
   108  }
   109  
   110  // TestEnvInnerVar verifies that with the Unmarshal function that
   111  // the environmental overrides still work on internal vars.  This was
   112  // a bug in the original viper implementation that is worked around in
   113  // the Load codepath for now
   114  func TestEnvInnerVar(t *testing.T) {
   115  	envVar1 := "ORDERER_GENERAL_LISTENPORT"
   116  	envVal1 := uint16(80)
   117  	envVar2 := "ORDERER_KAFKA_RETRY_SHORTINTERVAL"
   118  	envVal2 := "42s"
   119  	os.Setenv(envVar1, fmt.Sprintf("%d", envVal1))
   120  	os.Setenv(envVar2, envVal2)
   121  	defer os.Unsetenv(envVar1)
   122  	defer os.Unsetenv(envVar2)
   123  	cleanup := configtest.SetDevFabricConfigPath(t)
   124  	defer cleanup()
   125  
   126  	cc := &configCache{}
   127  	config, err := cc.load()
   128  	require.NoError(t, err)
   129  
   130  	require.NotNil(t, config, "Could not load config")
   131  	require.Equal(t, config.General.ListenPort, envVal1, "Environmental override of inner config test 1 did not work")
   132  
   133  	v2, _ := time.ParseDuration(envVal2)
   134  	require.Equal(t, config.Kafka.Retry.ShortInterval, v2, "Environmental override of inner config test 2 did not work")
   135  }
   136  
   137  func TestKafkaTLSConfig(t *testing.T) {
   138  	testCases := []struct {
   139  		name        string
   140  		tls         TLS
   141  		shouldPanic bool
   142  	}{
   143  		{"Disabled", TLS{Enabled: false}, false},
   144  		{"EnabledNoPrivateKey", TLS{Enabled: true, Certificate: "public.key"}, true},
   145  		{"EnabledNoPublicKey", TLS{Enabled: true, PrivateKey: "private.key"}, true},
   146  		{"EnabledNoTrustedRoots", TLS{Enabled: true, PrivateKey: "private.key", Certificate: "public.key"}, true},
   147  	}
   148  	for _, tc := range testCases {
   149  		t.Run(tc.name, func(t *testing.T) {
   150  			uconf := &TopLevel{Kafka: Kafka{TLS: tc.tls}}
   151  			if tc.shouldPanic {
   152  				require.Panics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should panic")
   153  			} else {
   154  				require.NotPanics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should not panic")
   155  			}
   156  		})
   157  	}
   158  }
   159  
   160  func TestKafkaSASLPlain(t *testing.T) {
   161  	testCases := []struct {
   162  		name        string
   163  		sasl        SASLPlain
   164  		shouldPanic bool
   165  	}{
   166  		{"Disabled", SASLPlain{Enabled: false}, false},
   167  		{"EnabledUserPassword", SASLPlain{Enabled: true, User: "user", Password: "pwd"}, false},
   168  		{"EnabledNoUserPassword", SASLPlain{Enabled: true}, true},
   169  		{"EnabledNoUser", SASLPlain{Enabled: true, Password: "pwd"}, true},
   170  		{"EnabledNoPassword", SASLPlain{Enabled: true, User: "user"}, true},
   171  	}
   172  	for _, tc := range testCases {
   173  		t.Run(tc.name, func(t *testing.T) {
   174  			uconf := &TopLevel{Kafka: Kafka{SASLPlain: tc.sasl}}
   175  			if tc.shouldPanic {
   176  				require.Panics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should panic")
   177  			} else {
   178  				require.NotPanics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should not panic")
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  func TestAdminTLSConfig(t *testing.T) {
   185  	testCases := []struct {
   186  		name        string
   187  		tls         TLS
   188  		shouldPanic bool
   189  	}{
   190  		{
   191  			name: "no TLS",
   192  			tls: TLS{
   193  				Enabled:            false,
   194  				ClientAuthRequired: false,
   195  			},
   196  			shouldPanic: false,
   197  		},
   198  		{
   199  			name: "TLS enabled and ClientAuthRequired",
   200  			tls: TLS{
   201  				Enabled:            true,
   202  				ClientAuthRequired: true,
   203  			},
   204  			shouldPanic: false,
   205  		},
   206  		{
   207  			name: "TLS enabled and ClientAuthRequired set to false",
   208  			tls: TLS{
   209  				Enabled:            true,
   210  				ClientAuthRequired: false,
   211  			},
   212  			shouldPanic: true,
   213  		},
   214  	}
   215  	for _, tc := range testCases {
   216  		t.Run(tc.name, func(t *testing.T) {
   217  			uconf := &TopLevel{Admin: Admin{TLS: tc.tls}}
   218  			if tc.shouldPanic {
   219  				require.PanicsWithValue(t, "Admin.TLS.ClientAuthRequired must be set to true if Admin.TLS.Enabled is set to true", func() { uconf.completeInitialization("/dummy/path") })
   220  			} else {
   221  				require.NotPanics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should not panic")
   222  			}
   223  		})
   224  	}
   225  }
   226  
   227  func TestClusterDefaults(t *testing.T) {
   228  	cleanup := configtest.SetDevFabricConfigPath(t)
   229  	defer cleanup()
   230  
   231  	cc := &configCache{}
   232  	cfg, err := cc.load()
   233  	require.NoError(t, err)
   234  	require.Equal(t, cfg.General.Cluster.ReplicationMaxRetries, Defaults.General.Cluster.ReplicationMaxRetries)
   235  }
   236  
   237  func TestConsensusConfig(t *testing.T) {
   238  	name, err := ioutil.TempDir("", "hyperledger_fabric")
   239  	require.Nil(t, err, "Error creating temp dir: %s", err)
   240  	defer func() {
   241  		err = os.RemoveAll(name)
   242  		require.Nil(t, os.RemoveAll(name), "Error removing temp dir: %s", err)
   243  	}()
   244  
   245  	content := `---
   246  Consensus:
   247    Foo: bar
   248    Hello:
   249      World: 42
   250  `
   251  
   252  	f, err := os.OpenFile(filepath.Join(name, "orderer.yaml"), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
   253  	require.Nil(t, err, "Error creating file: %s", err)
   254  	f.WriteString(content)
   255  	require.NoError(t, f.Close(), "Error closing file")
   256  
   257  	envVar1 := "FABRIC_CFG_PATH"
   258  	envVal1 := name
   259  	os.Setenv(envVar1, envVal1)
   260  	defer os.Unsetenv(envVar1)
   261  
   262  	cc := &configCache{}
   263  	conf, err := cc.load()
   264  	require.NoError(t, err, "Load good config returned unexpected error")
   265  	require.NotNil(t, conf, "Could not load config")
   266  
   267  	consensus := conf.Consensus
   268  	require.IsType(t, map[string]interface{}{}, consensus, "Expected Consensus to be of type map[string]interface{}")
   269  
   270  	foo := &struct {
   271  		Foo   string
   272  		Hello struct {
   273  			World int
   274  		}
   275  	}{}
   276  	err = mapstructure.Decode(consensus, foo)
   277  	require.NoError(t, err, "Failed to decode Consensus to struct")
   278  	require.Equal(t, foo.Foo, "bar")
   279  	require.Equal(t, foo.Hello.World, 42)
   280  }
   281  
   282  func TestConnectionTimeout(t *testing.T) {
   283  	t.Run("without connection timeout overridden", func(t *testing.T) {
   284  		cleanup := configtest.SetDevFabricConfigPath(t)
   285  		defer cleanup()
   286  		cc := &configCache{}
   287  		cfg, err := cc.load()
   288  		require.NotNil(t, cfg, "Could not load config")
   289  		require.NoError(t, err, "Load good config returned unexpected error")
   290  		require.Equal(t, cfg.General.ConnectionTimeout, time.Duration(0))
   291  	})
   292  
   293  	t.Run("with connection timeout overridden", func(t *testing.T) {
   294  		os.Setenv("ORDERER_GENERAL_CONNECTIONTIMEOUT", "10s")
   295  		defer os.Unsetenv("ORDERER_GENERAL_CONNECTIONTIMEOUT")
   296  		cleanup := configtest.SetDevFabricConfigPath(t)
   297  		defer cleanup()
   298  
   299  		cc := &configCache{}
   300  		cfg, err := cc.load()
   301  		require.NotNil(t, cfg, "Could not load config")
   302  		require.NoError(t, err, "Load good config returned unexpected error")
   303  		require.Equal(t, cfg.General.ConnectionTimeout, 10*time.Second)
   304  	})
   305  }
   306  
   307  func TestChannelParticipationDefaults(t *testing.T) {
   308  	cleanup := configtest.SetDevFabricConfigPath(t)
   309  	defer cleanup()
   310  
   311  	cc := &configCache{}
   312  	cfg, err := cc.load()
   313  	require.NoError(t, err)
   314  	require.Equal(t, cfg.ChannelParticipation.Enabled, Defaults.ChannelParticipation.Enabled)
   315  	require.Equal(t, cfg.ChannelParticipation.MaxRequestBodySize, Defaults.ChannelParticipation.MaxRequestBodySize)
   316  }