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