238 lines
7.2 KiB
Go
238 lines
7.2 KiB
Go
// Copyright IBM Corp. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package localconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hyperledger/fabric/core/config/configtest"
|
|
"github.com/mitchellh/mapstructure"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLoadGoodConfig(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, cfg, "Could not load config")
|
|
require.Nil(t, err, "Load good config returned unexpected error")
|
|
}
|
|
|
|
func TestMissingConfigValueOverridden(t *testing.T) {
|
|
t.Run("when the value is missing and not overridden", func(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NotNil(t, cfg, "Could not load config")
|
|
require.NoError(t, err, "Load good config returned unexpected error")
|
|
require.Nil(t, cfg.General.TLS.ClientRootCAs)
|
|
})
|
|
|
|
t.Run("when the value is missing and is overridden", func(t *testing.T) {
|
|
t.Setenv("ORDERER_GENERAL_TLS_CLIENTROOTCAS", "msp/tlscacerts/tlsroot.pem")
|
|
configtest.SetDevFabricConfigPath(t)
|
|
cache := &configCache{}
|
|
cfg, err := cache.load()
|
|
require.NotNil(t, cfg, "Could not load config")
|
|
require.NoError(t, err, "Load good config returned unexpected error")
|
|
require.NotNil(t, cfg.Admin.TLS.ClientRootCAs)
|
|
})
|
|
}
|
|
|
|
func TestLoadCached(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
|
|
// Load the initial config, update the environment, and load again.
|
|
// With the caching behavior, the update should not be reflected
|
|
initial, err := Load()
|
|
require.NoError(t, err)
|
|
t.Setenv("ORDERER_GENERAL_KEEPALIVE_SERVERTIMEOUT", "120s")
|
|
updated, err := Load()
|
|
require.NoError(t, err)
|
|
require.Equal(t, initial, updated, "expected %#v to equal %#v", updated, initial)
|
|
|
|
// Change the configuration we got back and load again.
|
|
// The new value should not contain the update to the initial
|
|
initial.General.LocalMSPDir = "/test/bad/mspDir"
|
|
updated, err = Load()
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, initial, updated, "expected %#v to not equal %#v", updated, initial)
|
|
}
|
|
|
|
func TestLoadMissingConfigFile(t *testing.T) {
|
|
t.Setenv("FABRIC_CFG_PATH", "invalid fabric cfg path")
|
|
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.Nil(t, cfg, "Loaded missing config file")
|
|
require.NotNil(t, err, "Loaded missing config file without error")
|
|
}
|
|
|
|
func TestLoadMalformedConfigFile(t *testing.T) {
|
|
name := t.TempDir()
|
|
|
|
// Create a malformed orderer.yaml file in temp dir
|
|
f, err := os.OpenFile(filepath.Join(name, "orderer.yaml"), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
|
|
require.Nil(t, err, "Error creating file: %s", err)
|
|
f.WriteString("General: 42")
|
|
require.NoError(t, f.Close(), "Error closing file")
|
|
|
|
t.Setenv("FABRIC_CFG_PATH", name)
|
|
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.Nil(t, cfg, "Loaded missing config file")
|
|
require.NotNil(t, err, "Loaded missing config file without error")
|
|
}
|
|
|
|
// TestEnvInnerVar verifies that with the Unmarshal function that
|
|
// the environmental overrides still work on internal vars. This was
|
|
// a bug in the original viper implementation that is worked around in
|
|
// the Load codepath for now
|
|
func TestEnvInnerVar(t *testing.T) {
|
|
envVar1 := "ORDERER_GENERAL_LISTENPORT"
|
|
envVal1 := uint16(80)
|
|
envVar2 := "ORDERER_GENERAL_KEEPALIVE_SERVERTIMEOUT"
|
|
envVal2 := "42s"
|
|
t.Setenv(envVar1, fmt.Sprintf("%d", envVal1))
|
|
t.Setenv(envVar2, envVal2)
|
|
configtest.SetDevFabricConfigPath(t)
|
|
|
|
cc := &configCache{}
|
|
config, err := cc.load()
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, config, "Could not load config")
|
|
require.Equal(t, config.General.ListenPort, envVal1, "Environmental override of inner config test 1 did not work")
|
|
|
|
v2, _ := time.ParseDuration(envVal2)
|
|
require.Equal(t, config.General.Keepalive.ServerTimeout, v2, "Environmental override of inner config test 2 did not work")
|
|
}
|
|
|
|
func TestAdminTLSConfig(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
tls TLS
|
|
shouldPanic bool
|
|
}{
|
|
{
|
|
name: "no TLS",
|
|
tls: TLS{
|
|
Enabled: false,
|
|
ClientAuthRequired: false,
|
|
},
|
|
shouldPanic: false,
|
|
},
|
|
{
|
|
name: "TLS enabled and ClientAuthRequired",
|
|
tls: TLS{
|
|
Enabled: true,
|
|
ClientAuthRequired: true,
|
|
},
|
|
shouldPanic: false,
|
|
},
|
|
{
|
|
name: "TLS enabled and ClientAuthRequired set to false",
|
|
tls: TLS{
|
|
Enabled: true,
|
|
ClientAuthRequired: false,
|
|
},
|
|
shouldPanic: true,
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
uconf := &TopLevel{Admin: Admin{TLS: tc.tls}}
|
|
if tc.shouldPanic {
|
|
require.PanicsWithValue(t, "Admin.TLS.ClientAuthRequired must be set to true if Admin.TLS.Enabled is set to true", func() { uconf.completeInitialization("/dummy/path") })
|
|
} else {
|
|
require.NotPanics(t, func() { uconf.completeInitialization("/dummy/path") }, "Should not panic")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestClusterDefaults(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NoError(t, err)
|
|
require.Equal(t, cfg.General.Cluster.ReplicationMaxRetries, Defaults.General.Cluster.ReplicationMaxRetries)
|
|
}
|
|
|
|
func TestConsensusConfig(t *testing.T) {
|
|
name := t.TempDir()
|
|
|
|
content := `---
|
|
Consensus:
|
|
Foo: bar
|
|
Hello:
|
|
World: 42
|
|
`
|
|
|
|
f, err := os.OpenFile(filepath.Join(name, "orderer.yaml"), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)
|
|
require.Nil(t, err, "Error creating file: %s", err)
|
|
f.WriteString(content)
|
|
require.NoError(t, f.Close(), "Error closing file")
|
|
|
|
t.Setenv("FABRIC_CFG_PATH", name)
|
|
|
|
cc := &configCache{}
|
|
conf, err := cc.load()
|
|
require.NoError(t, err, "Load good config returned unexpected error")
|
|
require.NotNil(t, conf, "Could not load config")
|
|
|
|
consensus := conf.Consensus
|
|
require.IsType(t, map[string]interface{}{}, consensus, "Expected Consensus to be of type map[string]interface{}")
|
|
|
|
foo := &struct {
|
|
Foo string
|
|
Hello struct {
|
|
World int
|
|
}
|
|
}{}
|
|
err = mapstructure.Decode(consensus, foo)
|
|
require.NoError(t, err, "Failed to decode Consensus to struct")
|
|
require.Equal(t, foo.Foo, "bar")
|
|
require.Equal(t, foo.Hello.World, 42)
|
|
}
|
|
|
|
func TestConnectionTimeout(t *testing.T) {
|
|
t.Run("without connection timeout overridden", func(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NotNil(t, cfg, "Could not load config")
|
|
require.NoError(t, err, "Load good config returned unexpected error")
|
|
require.Equal(t, cfg.General.ConnectionTimeout, time.Duration(0))
|
|
})
|
|
|
|
t.Run("with connection timeout overridden", func(t *testing.T) {
|
|
t.Setenv("ORDERER_GENERAL_CONNECTIONTIMEOUT", "10s")
|
|
configtest.SetDevFabricConfigPath(t)
|
|
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NotNil(t, cfg, "Could not load config")
|
|
require.NoError(t, err, "Load good config returned unexpected error")
|
|
require.Equal(t, cfg.General.ConnectionTimeout, 10*time.Second)
|
|
})
|
|
}
|
|
|
|
func TestChannelParticipationDefaults(t *testing.T) {
|
|
configtest.SetDevFabricConfigPath(t)
|
|
|
|
cc := &configCache{}
|
|
cfg, err := cc.load()
|
|
require.NoError(t, err)
|
|
require.Equal(t, cfg.ChannelParticipation.Enabled, Defaults.ChannelParticipation.Enabled)
|
|
require.Equal(t, cfg.ChannelParticipation.MaxRequestBodySize, Defaults.ChannelParticipation.MaxRequestBodySize)
|
|
}
|