github.com/hyperledger-labs/bdls@v2.1.1+incompatible/common/viperutil/config_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package viperutil
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"io/ioutil"
    13  	"os"
    14  	"reflect"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/Shopify/sarama"
    19  	"github.com/hyperledger/fabric/orderer/mocks/util"
    20  	"github.com/spf13/viper"
    21  )
    22  
    23  const Prefix = "VIPERUTIL"
    24  
    25  type testSlice struct {
    26  	Inner struct {
    27  		Slice []string
    28  	}
    29  }
    30  
    31  func TestEnvSlice(t *testing.T) {
    32  	envVar := "VIPERUTIL_INNER_SLICE"
    33  	envVal := "[a, b, c]"
    34  	os.Setenv(envVar, envVal)
    35  	defer os.Unsetenv(envVar)
    36  	config := viper.New()
    37  	config.SetEnvPrefix(Prefix)
    38  	config.AutomaticEnv()
    39  	replacer := strings.NewReplacer(".", "_")
    40  	config.SetEnvKeyReplacer(replacer)
    41  	config.SetConfigType("yaml")
    42  
    43  	data := "---\nInner:\n    Slice: [d,e,f]"
    44  
    45  	err := config.ReadConfig(bytes.NewReader([]byte(data)))
    46  
    47  	if err != nil {
    48  		t.Fatalf("Error reading %s plugin config: %s", Prefix, err)
    49  	}
    50  
    51  	var uconf testSlice
    52  
    53  	err = EnhancedExactUnmarshal(config, &uconf)
    54  	if err != nil {
    55  		t.Fatalf("Failed to unmarshal with: %s", err)
    56  	}
    57  
    58  	expected := []string{"a", "b", "c"}
    59  	if !reflect.DeepEqual(uconf.Inner.Slice, expected) {
    60  		t.Fatalf("Did not get back the right slice, expected: %v got %v", expected, uconf.Inner.Slice)
    61  	}
    62  }
    63  
    64  func TestKafkaVersionDecode(t *testing.T) {
    65  
    66  	type testKafkaVersion struct {
    67  		Inner struct {
    68  			Version sarama.KafkaVersion
    69  		}
    70  	}
    71  
    72  	config := viper.New()
    73  	config.SetConfigType("yaml")
    74  
    75  	testCases := []struct {
    76  		data        string
    77  		expected    sarama.KafkaVersion
    78  		errExpected bool
    79  	}{
    80  		{"0.8", sarama.KafkaVersion{}, true},
    81  		{"0.8.2.0", sarama.V0_8_2_0, false},
    82  		{"0.8.2.1", sarama.V0_8_2_1, false},
    83  		{"0.8.2.2", sarama.V0_8_2_2, false},
    84  		{"0.9.0.0", sarama.V0_9_0_0, false},
    85  		{"0.9", sarama.V0_9_0_0, false},
    86  		{"0.9.0", sarama.V0_9_0_0, false},
    87  		{"0.9.0.1", sarama.V0_9_0_1, false},
    88  		{"0.9.0.3", sarama.V0_9_0_1, false},
    89  		{"0.10.0.0", sarama.V0_10_0_0, false},
    90  		{"0.10", sarama.V0_10_0_0, false},
    91  		{"0.10.0", sarama.V0_10_0_0, false},
    92  		{"0.10.0.1", sarama.V0_10_0_1, false},
    93  		{"0.10.1.0", sarama.V0_10_1_0, false},
    94  		{"0.10.2.0", sarama.V0_10_2_0, false},
    95  		{"0.10.2.1", sarama.V0_10_2_0, false},
    96  		{"0.10.2.2", sarama.V0_10_2_0, false},
    97  		{"0.10.2.3", sarama.V0_10_2_0, false},
    98  		{"0.11", sarama.V0_11_0_0, false},
    99  		{"0.11.0", sarama.V0_11_0_0, false},
   100  		{"0.11.0.0", sarama.V0_11_0_0, false},
   101  		{"1", sarama.V1_0_0_0, false},
   102  		{"1.0", sarama.V1_0_0_0, false},
   103  		{"1.0.0", sarama.V1_0_0_0, false},
   104  		{"1.0.1", sarama.V1_0_0_0, false},
   105  		{"2.0.0", sarama.V1_0_0_0, false},
   106  		{"Malformed", sarama.KafkaVersion{}, true},
   107  	}
   108  
   109  	for _, tc := range testCases {
   110  		t.Run(tc.data, func(t *testing.T) {
   111  
   112  			data := fmt.Sprintf("---\nInner:\n    Version: '%s'", tc.data)
   113  			err := config.ReadConfig(bytes.NewReader([]byte(data)))
   114  			if err != nil {
   115  				t.Fatalf("Error reading config: %s", err)
   116  			}
   117  
   118  			var uconf testKafkaVersion
   119  			err = EnhancedExactUnmarshal(config, &uconf)
   120  
   121  			if tc.errExpected {
   122  				if err == nil {
   123  					t.Fatalf("Should have failed to unmarshal")
   124  				}
   125  			} else {
   126  				if err != nil {
   127  					t.Fatalf("Failed to unmarshal with: %s", err)
   128  				}
   129  				if uconf.Inner.Version != tc.expected {
   130  					t.Fatalf("Did not get back the right kafka version, expected: %v got %v", tc.expected, uconf.Inner.Version)
   131  				}
   132  			}
   133  
   134  		})
   135  	}
   136  
   137  }
   138  
   139  type testByteSize struct {
   140  	Inner struct {
   141  		ByteSize uint32
   142  	}
   143  }
   144  
   145  func TestByteSize(t *testing.T) {
   146  	config := viper.New()
   147  	config.SetConfigType("yaml")
   148  
   149  	testCases := []struct {
   150  		data     string
   151  		expected uint32
   152  	}{
   153  		{"", 0},
   154  		{"42", 42},
   155  		{"42k", 42 * 1024},
   156  		{"42kb", 42 * 1024},
   157  		{"42K", 42 * 1024},
   158  		{"42KB", 42 * 1024},
   159  		{"42 K", 42 * 1024},
   160  		{"42 KB", 42 * 1024},
   161  		{"42m", 42 * 1024 * 1024},
   162  		{"42mb", 42 * 1024 * 1024},
   163  		{"42M", 42 * 1024 * 1024},
   164  		{"42MB", 42 * 1024 * 1024},
   165  		{"42 M", 42 * 1024 * 1024},
   166  		{"42 MB", 42 * 1024 * 1024},
   167  		{"3g", 3 * 1024 * 1024 * 1024},
   168  		{"3gb", 3 * 1024 * 1024 * 1024},
   169  		{"3G", 3 * 1024 * 1024 * 1024},
   170  		{"3GB", 3 * 1024 * 1024 * 1024},
   171  		{"3 G", 3 * 1024 * 1024 * 1024},
   172  		{"3 GB", 3 * 1024 * 1024 * 1024},
   173  	}
   174  
   175  	for _, tc := range testCases {
   176  		t.Run(tc.data, func(t *testing.T) {
   177  			data := fmt.Sprintf("---\nInner:\n    ByteSize: %s", tc.data)
   178  			err := config.ReadConfig(bytes.NewReader([]byte(data)))
   179  			if err != nil {
   180  				t.Fatalf("Error reading config: %s", err)
   181  			}
   182  			var uconf testByteSize
   183  			err = EnhancedExactUnmarshal(config, &uconf)
   184  			if err != nil {
   185  				t.Fatalf("Failed to unmarshal with: %s", err)
   186  			}
   187  			if uconf.Inner.ByteSize != tc.expected {
   188  				t.Fatalf("Did not get back the right byte size, expected: %v got %v", tc.expected, uconf.Inner.ByteSize)
   189  			}
   190  		})
   191  	}
   192  }
   193  
   194  func TestByteSizeOverflow(t *testing.T) {
   195  	config := viper.New()
   196  	config.SetConfigType("yaml")
   197  
   198  	data := "---\nInner:\n    ByteSize: 4GB"
   199  	err := config.ReadConfig(bytes.NewReader([]byte(data)))
   200  	if err != nil {
   201  		t.Fatalf("Error reading config: %s", err)
   202  	}
   203  	var uconf testByteSize
   204  	err = EnhancedExactUnmarshal(config, &uconf)
   205  	if err == nil {
   206  		t.Fatalf("Should have failed to unmarshal")
   207  	}
   208  }
   209  
   210  type stringFromFileConfig struct {
   211  	Inner struct {
   212  		Single   string
   213  		Multiple []string
   214  	}
   215  }
   216  
   217  func TestStringNotFromFile(t *testing.T) {
   218  
   219  	expectedValue := "expected_value"
   220  	yaml := fmt.Sprintf("---\nInner:\n  Single: %s\n", expectedValue)
   221  
   222  	config := viper.New()
   223  	config.SetConfigType("yaml")
   224  
   225  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   226  		t.Fatalf("Error reading config: %s", err)
   227  	}
   228  
   229  	var uconf stringFromFileConfig
   230  	if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   231  		t.Fatalf("Failed to unmarshall: %s", err)
   232  	}
   233  
   234  	if uconf.Inner.Single != expectedValue {
   235  		t.Fatalf(`Expected: "%s", Actual: "%s"`, expectedValue, uconf.Inner.Single)
   236  	}
   237  
   238  }
   239  
   240  func TestStringFromFile(t *testing.T) {
   241  
   242  	expectedValue := "this is the text in the file"
   243  
   244  	// create temp file
   245  	file, err := ioutil.TempFile(os.TempDir(), "test")
   246  	if err != nil {
   247  		t.Fatalf("Unable to create temp file.")
   248  	}
   249  	defer os.Remove(file.Name())
   250  
   251  	// write temp file
   252  	if err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0777); err != nil {
   253  		t.Fatalf("Unable to write to temp file.")
   254  	}
   255  
   256  	yaml := fmt.Sprintf("---\nInner:\n  Single:\n    File: %s", file.Name())
   257  
   258  	config := viper.New()
   259  	config.SetConfigType("yaml")
   260  
   261  	if err = config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   262  		t.Fatalf("Error reading config: %s", err)
   263  	}
   264  	var uconf stringFromFileConfig
   265  	if err = EnhancedExactUnmarshal(config, &uconf); err != nil {
   266  		t.Fatalf("Failed to unmarshall: %s", err)
   267  	}
   268  
   269  	if uconf.Inner.Single != expectedValue {
   270  		t.Fatalf(`Expected: "%s", Actual: "%s"`, expectedValue, uconf.Inner.Single)
   271  	}
   272  }
   273  
   274  func TestPEMBlocksFromFile(t *testing.T) {
   275  
   276  	// create temp file
   277  	file, err := ioutil.TempFile(os.TempDir(), "test")
   278  	if err != nil {
   279  		t.Fatalf("Unable to create temp file.")
   280  	}
   281  	defer os.Remove(file.Name())
   282  
   283  	numberOfCertificates := 3
   284  	var pems []byte
   285  	for i := 0; i < numberOfCertificates; i++ {
   286  		publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
   287  		pems = append(pems, publicKeyCert...)
   288  	}
   289  
   290  	// write temp file
   291  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   292  		t.Fatalf("Unable to write to temp file: %v", err)
   293  	}
   294  
   295  	yaml := fmt.Sprintf("---\nInner:\n  Multiple:\n    File: %s", file.Name())
   296  
   297  	config := viper.New()
   298  	config.SetConfigType("yaml")
   299  
   300  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   301  		t.Fatalf("Error reading config: %v", err)
   302  	}
   303  	var uconf stringFromFileConfig
   304  	if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   305  		t.Fatalf("Failed to unmarshall: %v", err)
   306  	}
   307  
   308  	if len(uconf.Inner.Multiple) != 3 {
   309  		t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   310  	}
   311  }
   312  
   313  func TestPEMBlocksFromFileEnv(t *testing.T) {
   314  
   315  	// create temp file
   316  	file, err := ioutil.TempFile(os.TempDir(), "test")
   317  	if err != nil {
   318  		t.Fatalf("Unable to create temp file.")
   319  	}
   320  	defer os.Remove(file.Name())
   321  
   322  	numberOfCertificates := 3
   323  	var pems []byte
   324  	for i := 0; i < numberOfCertificates; i++ {
   325  		publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
   326  		pems = append(pems, publicKeyCert...)
   327  	}
   328  
   329  	// write temp file
   330  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   331  		t.Fatalf("Unable to write to temp file: %v", err)
   332  	}
   333  
   334  	testCases := []struct {
   335  		name string
   336  		data string
   337  	}{
   338  		{"Override", "---\nInner:\n  Multiple:\n    File: wrong_file"},
   339  		{"NoFileElement", "---\nInner:\n  Multiple:\n"},
   340  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   341  	}
   342  
   343  	for _, tc := range testCases {
   344  		t.Run(tc.name, func(t *testing.T) {
   345  
   346  			envVar := "VIPERUTIL_INNER_MULTIPLE_FILE"
   347  			envVal := file.Name()
   348  			os.Setenv(envVar, envVal)
   349  			defer os.Unsetenv(envVar)
   350  			config := viper.New()
   351  			config.SetEnvPrefix(Prefix)
   352  			config.AutomaticEnv()
   353  			replacer := strings.NewReplacer(".", "_")
   354  			config.SetEnvKeyReplacer(replacer)
   355  			config.SetConfigType("yaml")
   356  
   357  			if err := config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   358  				t.Fatalf("Error reading config: %v", err)
   359  			}
   360  			var uconf stringFromFileConfig
   361  			if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   362  				t.Fatalf("Failed to unmarshall: %v", err)
   363  			}
   364  
   365  			if len(uconf.Inner.Multiple) != 3 {
   366  				t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   367  			}
   368  		})
   369  	}
   370  }
   371  
   372  func TestStringFromFileNotSpecified(t *testing.T) {
   373  
   374  	yaml := fmt.Sprintf("---\nInner:\n  Single:\n    File:\n")
   375  
   376  	config := viper.New()
   377  	config.SetConfigType("yaml")
   378  
   379  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   380  		t.Fatalf("Error reading config: %s", err)
   381  	}
   382  	var uconf stringFromFileConfig
   383  	if err := EnhancedExactUnmarshal(config, &uconf); err == nil {
   384  		t.Fatalf("Should of failed to unmarshall.")
   385  	}
   386  
   387  }
   388  
   389  func TestStringFromFileEnv(t *testing.T) {
   390  
   391  	expectedValue := "this is the text in the file"
   392  
   393  	// create temp file
   394  	file, err := ioutil.TempFile(os.TempDir(), "test")
   395  	if err != nil {
   396  		t.Fatalf("Unable to create temp file.")
   397  	}
   398  	defer os.Remove(file.Name())
   399  
   400  	// write temp file
   401  	if err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0777); err != nil {
   402  		t.Fatalf("Unable to write to temp file.")
   403  	}
   404  
   405  	testCases := []struct {
   406  		name string
   407  		data string
   408  	}{
   409  		{"Override", "---\nInner:\n  Single:\n    File: wrong_file"},
   410  		{"NoFileElement", "---\nInner:\n  Single:\n"},
   411  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   412  	}
   413  
   414  	for _, tc := range testCases {
   415  		t.Run(tc.name, func(t *testing.T) {
   416  			envVar := "VIPERUTIL_INNER_SINGLE_FILE"
   417  			envVal := file.Name()
   418  			os.Setenv(envVar, envVal)
   419  			defer os.Unsetenv(envVar)
   420  			config := viper.New()
   421  			config.SetEnvPrefix(Prefix)
   422  			config.AutomaticEnv()
   423  			replacer := strings.NewReplacer(".", "_")
   424  			config.SetEnvKeyReplacer(replacer)
   425  			config.SetConfigType("yaml")
   426  
   427  			if err = config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   428  				t.Fatalf("Error reading %s plugin config: %s", Prefix, err)
   429  			}
   430  
   431  			var uconf stringFromFileConfig
   432  
   433  			err = EnhancedExactUnmarshal(config, &uconf)
   434  			if err != nil {
   435  				t.Fatalf("Failed to unmarshal with: %s", err)
   436  			}
   437  
   438  			t.Log(uconf.Inner.Single)
   439  
   440  			if !reflect.DeepEqual(uconf.Inner.Single, expectedValue) {
   441  				t.Fatalf(`Expected: "%v",  Actual: "%v"`, expectedValue, uconf.Inner.Single)
   442  			}
   443  		})
   444  	}
   445  
   446  }
   447  
   448  func TestDecodeOpaqueField(t *testing.T) {
   449  	yaml := `---
   450  Foo: bar
   451  Hello:
   452    World: 42
   453  `
   454  	config := viper.New()
   455  	config.SetConfigType("yaml")
   456  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   457  		t.Fatalf("Error reading config: %s", err)
   458  	}
   459  	var conf struct {
   460  		Foo   string
   461  		Hello struct{ World int }
   462  	}
   463  	if err := EnhancedExactUnmarshal(config, &conf); err != nil {
   464  		t.Fatalf("Error unmashalling: %s", err)
   465  	}
   466  
   467  	if conf.Foo != "bar" || conf.Hello.World != 42 {
   468  		t.Fatalf("Incorrect decoding")
   469  	}
   470  }