github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/localconfig/config_test.go (about)

     1  // Copyright IBM Corp. 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/hyperledger/fabric/core/config/configtest"
    15  	"github.com/mitchellh/mapstructure"
    16  	"github.com/stretchr/testify/assert"
    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  	assert.NoError(t, err)
    25  	assert.NotNil(t, cfg, "Could not load config")
    26  	assert.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  		assert.NotNil(t, cfg, "Could not load config")
    36  		assert.NoError(t, err, "Load good config returned unexpected error")
    37  		assert.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  		assert.NotNil(t, cfg, "Could not load config")
    47  		assert.NoError(t, err, "Load good config returned unexpected error")
    48  		assert.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  	assert.NoError(t, err)
    60  	os.Setenv("ORDERER_KAFKA_RETRY_SHORTINTERVAL", "120s")
    61  	updated, err := Load()
    62  	assert.NoError(t, err)
    63  	assert.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  	assert.NoError(t, err)
    70  	assert.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  	assert.Nil(t, cfg, "Loaded missing config file")
    82  	assert.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  	assert.Nil(t, err, "Error creating temp dir: %s", err)
    88  	defer func() {
    89  		err = os.RemoveAll(name)
    90  		assert.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, 0600)
    95  	assert.Nil(t, err, "Error creating file: %s", err)
    96  	f.WriteString("General: 42")
    97  	assert.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  	assert.Nil(t, cfg, "Loaded missing config file")
   107  	assert.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  	assert.NoError(t, err)
   129  
   130  	assert.NotNil(t, config, "Could not load config")
   131  	assert.Equal(t, config.General.ListenPort, envVal1, "Environmental override of inner config test 1 did not work")
   132  
   133  	v2, _ := time.ParseDuration(envVal2)
   134  	assert.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  				assert.Panics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should panic")
   153  			} else {
   154  				assert.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  				assert.Panics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should panic")
   177  			} else {
   178  				assert.NotPanics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should not panic")
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  func TestClusterDefaults(t *testing.T) {
   185  	cleanup := configtest.SetDevFabricConfigPath(t)
   186  	defer cleanup()
   187  
   188  	cc := &configCache{}
   189  	cfg, err := cc.load()
   190  	assert.NoError(t, err)
   191  	assert.Equal(t, cfg.General.Cluster.ReplicationMaxRetries, Defaults.General.Cluster.ReplicationMaxRetries)
   192  }
   193  
   194  func TestConsensusConfig(t *testing.T) {
   195  	name, err := ioutil.TempDir("", "hyperledger_fabric")
   196  	assert.Nil(t, err, "Error creating temp dir: %s", err)
   197  	defer func() {
   198  		err = os.RemoveAll(name)
   199  		assert.Nil(t, os.RemoveAll(name), "Error removing temp dir: %s", err)
   200  	}()
   201  
   202  	content := `---
   203  Consensus:
   204    Foo: bar
   205    Hello:
   206      World: 42
   207  `
   208  
   209  	f, err := os.OpenFile(filepath.Join(name, "orderer.yaml"), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
   210  	assert.Nil(t, err, "Error creating file: %s", err)
   211  	f.WriteString(content)
   212  	assert.NoError(t, f.Close(), "Error closing file")
   213  
   214  	envVar1 := "FABRIC_CFG_PATH"
   215  	envVal1 := name
   216  	os.Setenv(envVar1, envVal1)
   217  	defer os.Unsetenv(envVar1)
   218  
   219  	cc := &configCache{}
   220  	conf, err := cc.load()
   221  	assert.NoError(t, err, "Load good config returned unexpected error")
   222  	assert.NotNil(t, conf, "Could not load config")
   223  
   224  	consensus := conf.Consensus
   225  	assert.IsType(t, map[string]interface{}{}, consensus, "Expected Consensus to be of type map[string]interface{}")
   226  
   227  	foo := &struct {
   228  		Foo   string
   229  		Hello struct {
   230  			World int
   231  		}
   232  	}{}
   233  	err = mapstructure.Decode(consensus, foo)
   234  	assert.NoError(t, err, "Failed to decode Consensus to struct")
   235  	assert.Equal(t, foo.Foo, "bar")
   236  	assert.Equal(t, foo.Hello.World, 42)
   237  }
   238  
   239  func TestConnectionTimeout(t *testing.T) {
   240  	t.Run("without connection timeout overridden", func(t *testing.T) {
   241  		cleanup := configtest.SetDevFabricConfigPath(t)
   242  		defer cleanup()
   243  		cc := &configCache{}
   244  		cfg, err := cc.load()
   245  		assert.NotNil(t, cfg, "Could not load config")
   246  		assert.NoError(t, err, "Load good config returned unexpected error")
   247  		assert.Equal(t, cfg.General.ConnectionTimeout, time.Duration(0))
   248  	})
   249  
   250  	t.Run("with connection timeout overridden", func(t *testing.T) {
   251  		os.Setenv("ORDERER_GENERAL_CONNECTIONTIMEOUT", "10s")
   252  		defer os.Unsetenv("ORDERER_GENERAL_CONNECTIONTIMEOUT")
   253  		cleanup := configtest.SetDevFabricConfigPath(t)
   254  		defer cleanup()
   255  
   256  		cc := &configCache{}
   257  		cfg, err := cc.load()
   258  		assert.NotNil(t, cfg, "Could not load config")
   259  		assert.NoError(t, err, "Load good config returned unexpected error")
   260  		assert.Equal(t, cfg.General.ConnectionTimeout, 10*time.Second)
   261  	})
   262  }