go_study/fabric-main/common/viperutil/config_test.go

339 lines
8.8 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package viperutil
import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"time"
"github.com/hyperledger/fabric/bccsp/factory"
"github.com/hyperledger/fabric/orderer/mocks/util"
"github.com/stretchr/testify/require"
)
const (
testConfigName = "viperutil"
testEnvPrefix = "VIPERUTIL"
)
func TestEnvSlice(t *testing.T) {
type testSlice struct {
Inner struct {
Slice []string
}
}
envVar := testEnvPrefix + "_INNER_SLICE"
t.Setenv(envVar, "[a, b, c]")
data := "---\nInner:\n Slice: [d,e,f]"
config := New()
config.SetConfigName(testConfigName)
err := config.ReadConfig(strings.NewReader(data))
require.NoError(t, err, "error reading %s plugin config", testConfigName)
var uconf testSlice
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
expected := []string{"a", "b", "c"}
require.Exactly(t, expected, uconf.Inner.Slice, "did not get the expected slice")
}
type testByteSize struct {
Inner struct {
ByteSize uint32
}
}
func TestByteSize(t *testing.T) {
testCases := []struct {
data string
expected uint32
}{
{"", 0},
{"42", 42},
{"42k", 42 * 1024},
{"42kb", 42 * 1024},
{"42K", 42 * 1024},
{"42KB", 42 * 1024},
{"42 K", 42 * 1024},
{"42 KB", 42 * 1024},
{"42m", 42 * 1024 * 1024},
{"42mb", 42 * 1024 * 1024},
{"42M", 42 * 1024 * 1024},
{"42MB", 42 * 1024 * 1024},
{"42 M", 42 * 1024 * 1024},
{"42 MB", 42 * 1024 * 1024},
{"3g", 3 * 1024 * 1024 * 1024},
{"3gb", 3 * 1024 * 1024 * 1024},
{"3G", 3 * 1024 * 1024 * 1024},
{"3GB", 3 * 1024 * 1024 * 1024},
{"3 G", 3 * 1024 * 1024 * 1024},
{"3 GB", 3 * 1024 * 1024 * 1024},
}
for _, tc := range testCases {
t.Run(tc.data, func(t *testing.T) {
data := fmt.Sprintf("---\nInner:\n ByteSize: %s", tc.data)
config := New()
err := config.ReadConfig(strings.NewReader(data))
require.NoError(t, err, "error reading config")
var uconf testByteSize
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
require.Exactly(t, tc.expected, uconf.Inner.ByteSize, "incorrect byte size")
})
}
}
func TestByteSizeOverflow(t *testing.T) {
data := "---\nInner:\n ByteSize: 4GB"
config := New()
err := config.ReadConfig(strings.NewReader(data))
require.NoError(t, err, "error reading config")
var uconf testByteSize
err = config.EnhancedExactUnmarshal(&uconf)
require.Error(t, err)
require.Contains(t, err.Error(), "Inner.ByteSize")
require.Contains(t, err.Error(), "value '4GB' overflows uint32")
}
type stringFromFileConfig struct {
Inner struct {
Single string
Multiple []string
}
}
func TestStringNotFromFile(t *testing.T) {
yaml := "---\nInner:\n Single: expected_value\n"
config := New()
err := config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
require.Equal(t, "expected_value", uconf.Inner.Single)
}
func TestStringFromFile(t *testing.T) {
file, err := ioutil.TempFile(os.TempDir(), "test")
require.NoError(t, err, "failed to create temp file")
defer os.Remove(file.Name())
expectedValue := "this is the text in the file"
err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0o644)
require.NoError(t, err, "uname to write temp file")
yaml := fmt.Sprintf("---\nInner:\n Single:\n File: %s", file.Name())
config := New()
err = config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "unmarshal failed")
require.Equal(t, expectedValue, uconf.Inner.Single)
}
func TestPEMBlocksFromFile(t *testing.T) {
file, err := ioutil.TempFile(os.TempDir(), "test")
require.NoError(t, err, "failed to create temp file")
defer os.Remove(file.Name())
var pems []byte
for i := 0; i < 3; i++ {
publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
pems = append(pems, publicKeyCert...)
}
err = ioutil.WriteFile(file.Name(), pems, 0o644)
require.NoError(t, err, "failed to write temp file")
yaml := fmt.Sprintf("---\nInner:\n Multiple:\n File: %s", file.Name())
config := New()
err = config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
require.Len(t, uconf.Inner.Multiple, 3)
}
func TestPEMBlocksFromFileEnv(t *testing.T) {
file, err := ioutil.TempFile(os.TempDir(), "test")
require.NoError(t, err, "failed to create temp file")
defer os.Remove(file.Name())
var pems []byte
for i := 0; i < 3; i++ {
publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
pems = append(pems, publicKeyCert...)
}
err = ioutil.WriteFile(file.Name(), pems, 0o644)
require.NoError(t, err, "failed to write temp file")
envVar := testEnvPrefix + "_INNER_MULTIPLE_FILE"
t.Setenv(envVar, file.Name())
testCases := []struct {
name string
data string
}{
{"Override", "---\nInner:\n Multiple:\n File: wrong_file"},
{"NoFileElement", "---\nInner:\n Multiple:\n"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
config := New()
config.SetConfigName(testConfigName)
err := config.ReadConfig(strings.NewReader(tc.data))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
require.Len(t, uconf.Inner.Multiple, 3)
})
}
}
func TestStringFromFileNotSpecified(t *testing.T) {
yaml := "---\nInner:\n Single:\n File:\n"
config := New()
err := config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.Error(t, err, "umarshal should fail")
}
func TestStringFromFileEnv(t *testing.T) {
expectedValue := "this is the text in the file"
file, err := ioutil.TempFile(os.TempDir(), "test")
require.NoError(t, err, "failed to create temp file")
defer os.Remove(file.Name())
err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0o644)
require.NoError(t, err, "failed to write temp file")
envVar := testEnvPrefix + "_INNER_SINGLE_FILE"
t.Setenv(envVar, file.Name())
testCases := []struct {
name string
data string
}{
{"Override", "---\nInner:\n Single:\n File: wrong_file"},
{"NoFileElement", "---\nInner:\n Single:\n"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
config := New()
config.SetConfigName(testConfigName)
err := config.ReadConfig(strings.NewReader(tc.data))
require.NoError(t, err, "error reading config")
var uconf stringFromFileConfig
err = config.EnhancedExactUnmarshal(&uconf)
require.NoError(t, err, "failed to unmarshal")
require.Exactly(t, expectedValue, uconf.Inner.Single)
})
}
}
func TestDecodeOpaqueField(t *testing.T) {
yaml := "---\nFoo: bar\nHello:\n World: 42\n"
config := New()
err := config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var conf struct {
Foo string
Hello struct{ World int }
}
err = config.EnhancedExactUnmarshal(&conf)
require.NoError(t, err, "failed to unmarshal")
require.Equal(t, "bar", conf.Foo)
require.Equal(t, 42, conf.Hello.World)
}
func TestBCCSPDecodeHookOverride(t *testing.T) {
yaml := "---\nBCCSP:\n Default: default-provider\n SW:\n Security: 999\n"
overrideVar := testEnvPrefix + "_BCCSP_SW_SECURITY"
t.Setenv(overrideVar, "1111")
config := New()
config.SetConfigName(testConfigName)
err := config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var tc struct {
BCCSP *factory.FactoryOpts
}
err = config.EnhancedExactUnmarshal(&tc)
require.NoError(t, err, "failed to unmarshal")
require.NotNil(t, tc.BCCSP)
require.NotNil(t, tc.BCCSP.SW)
require.Equal(t, 1111, tc.BCCSP.SW.Security)
}
func TestDurationDecode(t *testing.T) {
tests := []struct {
input string
expected time.Duration
}{
{"", 0},
{"100", 100 * time.Nanosecond},
{"1s", time.Second},
{"1m", time.Minute},
{"1m1s", 61 * time.Second},
{"90s", 90 * time.Second},
}
for _, tt := range tests {
t.Run(tt.expected.String(), func(t *testing.T) {
yaml := fmt.Sprintf("---\nDuration: %s\n", tt.input)
config := New()
config.SetConfigName(testConfigName)
err := config.ReadConfig(strings.NewReader(yaml))
require.NoError(t, err, "error reading config")
var conf struct{ Duration time.Duration }
err = config.EnhancedExactUnmarshal(&conf)
require.NoError(t, err, "failed to unmarshal")
require.Equal(t, tt.expected, conf.Duration)
})
}
}