github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/common/viperutil/config_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package viperutil
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"os"
    24  	"reflect"
    25  	"strings"
    26  	"testing"
    27  
    28  	"github.com/hyperledger/fabric/orderer/mocks/util"
    29  	"github.com/spf13/viper"
    30  )
    31  
    32  const Prefix = "VIPERUTIL"
    33  
    34  type testSlice struct {
    35  	Inner struct {
    36  		Slice []string
    37  	}
    38  }
    39  
    40  func TestEnvSlice(t *testing.T) {
    41  	envVar := "VIPERUTIL_INNER_SLICE"
    42  	envVal := "[a, b, c]"
    43  	os.Setenv(envVar, envVal)
    44  	defer os.Unsetenv(envVar)
    45  	config := viper.New()
    46  	config.SetEnvPrefix(Prefix)
    47  	config.AutomaticEnv()
    48  	replacer := strings.NewReplacer(".", "_")
    49  	config.SetEnvKeyReplacer(replacer)
    50  	config.SetConfigType("yaml")
    51  
    52  	data := "---\nInner:\n    Slice: [d,e,f]"
    53  
    54  	err := config.ReadConfig(bytes.NewReader([]byte(data)))
    55  
    56  	if err != nil {
    57  		t.Fatalf("Error reading %s plugin config: %s", Prefix, err)
    58  	}
    59  
    60  	var uconf testSlice
    61  
    62  	err = EnhancedExactUnmarshal(config, &uconf)
    63  	if err != nil {
    64  		t.Fatalf("Failed to unmarshal with: %s", err)
    65  	}
    66  
    67  	expected := []string{"a", "b", "c"}
    68  	if !reflect.DeepEqual(uconf.Inner.Slice, expected) {
    69  		t.Fatalf("Did not get back the right slice, expeced: %v got %v", expected, uconf.Inner.Slice)
    70  	}
    71  }
    72  
    73  type testByteSize struct {
    74  	Inner struct {
    75  		ByteSize uint32
    76  	}
    77  }
    78  
    79  func TestByteSize(t *testing.T) {
    80  	config := viper.New()
    81  	config.SetConfigType("yaml")
    82  
    83  	testCases := []struct {
    84  		data     string
    85  		expected uint32
    86  	}{
    87  		{"", 0},
    88  		{"42", 42},
    89  		{"42k", 42 * 1024},
    90  		{"42kb", 42 * 1024},
    91  		{"42K", 42 * 1024},
    92  		{"42KB", 42 * 1024},
    93  		{"42 K", 42 * 1024},
    94  		{"42 KB", 42 * 1024},
    95  		{"42m", 42 * 1024 * 1024},
    96  		{"42mb", 42 * 1024 * 1024},
    97  		{"42M", 42 * 1024 * 1024},
    98  		{"42MB", 42 * 1024 * 1024},
    99  		{"42 M", 42 * 1024 * 1024},
   100  		{"42 MB", 42 * 1024 * 1024},
   101  		{"3g", 3 * 1024 * 1024 * 1024},
   102  		{"3gb", 3 * 1024 * 1024 * 1024},
   103  		{"3G", 3 * 1024 * 1024 * 1024},
   104  		{"3GB", 3 * 1024 * 1024 * 1024},
   105  		{"3 G", 3 * 1024 * 1024 * 1024},
   106  		{"3 GB", 3 * 1024 * 1024 * 1024},
   107  	}
   108  
   109  	for _, tc := range testCases {
   110  		t.Run(tc.data, func(t *testing.T) {
   111  			data := fmt.Sprintf("---\nInner:\n    ByteSize: %s", tc.data)
   112  			err := config.ReadConfig(bytes.NewReader([]byte(data)))
   113  			if err != nil {
   114  				t.Fatalf("Error reading config: %s", err)
   115  			}
   116  			var uconf testByteSize
   117  			err = EnhancedExactUnmarshal(config, &uconf)
   118  			if err != nil {
   119  				t.Fatalf("Failed to unmarshal with: %s", err)
   120  			}
   121  			if uconf.Inner.ByteSize != tc.expected {
   122  				t.Fatalf("Did not get back the right byte size, expeced: %v got %v", tc.expected, uconf.Inner.ByteSize)
   123  			}
   124  		})
   125  	}
   126  }
   127  
   128  func TestByteSizeOverflow(t *testing.T) {
   129  	config := viper.New()
   130  	config.SetConfigType("yaml")
   131  
   132  	data := "---\nInner:\n    ByteSize: 4GB"
   133  	err := config.ReadConfig(bytes.NewReader([]byte(data)))
   134  	if err != nil {
   135  		t.Fatalf("Error reading config: %s", err)
   136  	}
   137  	var uconf testByteSize
   138  	err = EnhancedExactUnmarshal(config, &uconf)
   139  	if err == nil {
   140  		t.Fatalf("Should have failed to unmarshal")
   141  	}
   142  }
   143  
   144  type stringFromFileConfig struct {
   145  	Inner struct {
   146  		Single   string
   147  		Multiple []string
   148  	}
   149  }
   150  
   151  func TestStringNotFromFile(t *testing.T) {
   152  
   153  	expectedValue := "expected_value"
   154  	yaml := fmt.Sprintf("---\nInner:\n  Single: %s\n", expectedValue)
   155  
   156  	config := viper.New()
   157  	config.SetConfigType("yaml")
   158  
   159  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   160  		t.Fatalf("Error reading config: %s", err)
   161  	}
   162  
   163  	var uconf stringFromFileConfig
   164  	if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   165  		t.Fatalf("Failed to unmarshall: %s", err)
   166  	}
   167  
   168  	if uconf.Inner.Single != expectedValue {
   169  		t.Fatalf(`Expected: "%s", Actual: "%s"`, expectedValue, uconf.Inner.Single)
   170  	}
   171  
   172  }
   173  
   174  func TestStringFromFile(t *testing.T) {
   175  
   176  	expectedValue := "this is the text in the file"
   177  
   178  	// create temp file
   179  	file, err := ioutil.TempFile(os.TempDir(), "test")
   180  	if err != nil {
   181  		t.Fatalf("Unable to create temp file.")
   182  	}
   183  	defer os.Remove(file.Name())
   184  
   185  	// write temp file
   186  	if err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0777); err != nil {
   187  		t.Fatalf("Unable to write to temp file.")
   188  	}
   189  
   190  	yaml := fmt.Sprintf("---\nInner:\n  Single:\n    File: %s", file.Name())
   191  
   192  	config := viper.New()
   193  	config.SetConfigType("yaml")
   194  
   195  	if err = config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   196  		t.Fatalf("Error reading config: %s", err)
   197  	}
   198  	var uconf stringFromFileConfig
   199  	if err = EnhancedExactUnmarshal(config, &uconf); err != nil {
   200  		t.Fatalf("Failed to unmarshall: %s", err)
   201  	}
   202  
   203  	if uconf.Inner.Single != expectedValue {
   204  		t.Fatalf(`Expected: "%s", Actual: "%s"`, expectedValue, uconf.Inner.Single)
   205  	}
   206  }
   207  
   208  func TestPEMBlocksFromFile(t *testing.T) {
   209  
   210  	// create temp file
   211  	file, err := ioutil.TempFile(os.TempDir(), "test")
   212  	if err != nil {
   213  		t.Fatalf("Unable to create temp file.")
   214  	}
   215  	defer os.Remove(file.Name())
   216  
   217  	numberOfCertificates := 3
   218  	var pems []byte
   219  	for i := 0; i < numberOfCertificates; i++ {
   220  		publicKeyCert, _, err := util.GenerateMockPublicPrivateKeyPairPEM(true)
   221  		if err != nil {
   222  			t.Fatalf("Enable to generate a signer certificate: %v", err)
   223  		}
   224  		pems = append(pems, publicKeyCert...)
   225  	}
   226  
   227  	// write temp file
   228  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   229  		t.Fatalf("Unable to write to temp file: %v", err)
   230  	}
   231  
   232  	yaml := fmt.Sprintf("---\nInner:\n  Multiple:\n    File: %s", file.Name())
   233  
   234  	config := viper.New()
   235  	config.SetConfigType("yaml")
   236  
   237  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   238  		t.Fatalf("Error reading config: %v", err)
   239  	}
   240  	var uconf stringFromFileConfig
   241  	if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   242  		t.Fatalf("Failed to unmarshall: %v", err)
   243  	}
   244  
   245  	if len(uconf.Inner.Multiple) != 3 {
   246  		t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   247  	}
   248  }
   249  
   250  func TestPEMBlocksFromFileEnv(t *testing.T) {
   251  
   252  	// create temp file
   253  	file, err := ioutil.TempFile(os.TempDir(), "test")
   254  	if err != nil {
   255  		t.Fatalf("Unable to create temp file.")
   256  	}
   257  	defer os.Remove(file.Name())
   258  
   259  	numberOfCertificates := 3
   260  	var pems []byte
   261  	for i := 0; i < numberOfCertificates; i++ {
   262  		publicKeyCert, _, err := util.GenerateMockPublicPrivateKeyPairPEM(true)
   263  		if err != nil {
   264  			t.Fatalf("Enable to generate a signer certificate: %v", err)
   265  		}
   266  		pems = append(pems, publicKeyCert...)
   267  	}
   268  
   269  	// write temp file
   270  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   271  		t.Fatalf("Unable to write to temp file: %v", err)
   272  	}
   273  
   274  	testCases := []struct {
   275  		name string
   276  		data string
   277  	}{
   278  		{"Override", "---\nInner:\n  Multiple:\n    File: wrong_file"},
   279  		{"NoFileElement", "---\nInner:\n  Multiple:\n"},
   280  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   281  	}
   282  
   283  	for _, tc := range testCases {
   284  		t.Run(tc.name, func(t *testing.T) {
   285  
   286  			envVar := "VIPERUTIL_INNER_MULTIPLE_FILE"
   287  			envVal := file.Name()
   288  			os.Setenv(envVar, envVal)
   289  			defer os.Unsetenv(envVar)
   290  			config := viper.New()
   291  			config.SetEnvPrefix(Prefix)
   292  			config.AutomaticEnv()
   293  			replacer := strings.NewReplacer(".", "_")
   294  			config.SetEnvKeyReplacer(replacer)
   295  			config.SetConfigType("yaml")
   296  
   297  			if err := config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   298  				t.Fatalf("Error reading config: %v", err)
   299  			}
   300  			var uconf stringFromFileConfig
   301  			if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   302  				t.Fatalf("Failed to unmarshall: %v", err)
   303  			}
   304  
   305  			if len(uconf.Inner.Multiple) != 3 {
   306  				t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   307  			}
   308  		})
   309  	}
   310  }
   311  
   312  func TestStringFromFileNotSpecified(t *testing.T) {
   313  
   314  	yaml := fmt.Sprintf("---\nInner:\n  Single:\n    File:\n")
   315  
   316  	config := viper.New()
   317  	config.SetConfigType("yaml")
   318  
   319  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   320  		t.Fatalf("Error reading config: %s", err)
   321  	}
   322  	var uconf stringFromFileConfig
   323  	if err := EnhancedExactUnmarshal(config, &uconf); err == nil {
   324  		t.Fatalf("Should of failed to unmarshall.")
   325  	}
   326  
   327  }
   328  
   329  func TestStringFromFileEnv(t *testing.T) {
   330  
   331  	expectedValue := "this is the text in the file"
   332  
   333  	// create temp file
   334  	file, err := ioutil.TempFile(os.TempDir(), "test")
   335  	if err != nil {
   336  		t.Fatalf("Unable to create temp file.")
   337  	}
   338  	defer os.Remove(file.Name())
   339  
   340  	// write temp file
   341  	if err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0777); err != nil {
   342  		t.Fatalf("Unable to write to temp file.")
   343  	}
   344  
   345  	testCases := []struct {
   346  		name string
   347  		data string
   348  	}{
   349  		{"Override", "---\nInner:\n  Single:\n    File: wrong_file"},
   350  		{"NoFileElement", "---\nInner:\n  Single:\n"},
   351  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   352  	}
   353  
   354  	for _, tc := range testCases {
   355  		t.Run(tc.name, func(t *testing.T) {
   356  			envVar := "VIPERUTIL_INNER_SINGLE_FILE"
   357  			envVal := file.Name()
   358  			os.Setenv(envVar, envVal)
   359  			defer os.Unsetenv(envVar)
   360  			config := viper.New()
   361  			config.SetEnvPrefix(Prefix)
   362  			config.AutomaticEnv()
   363  			replacer := strings.NewReplacer(".", "_")
   364  			config.SetEnvKeyReplacer(replacer)
   365  			config.SetConfigType("yaml")
   366  
   367  			if err = config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   368  				t.Fatalf("Error reading %s plugin config: %s", Prefix, err)
   369  			}
   370  
   371  			var uconf stringFromFileConfig
   372  
   373  			err = EnhancedExactUnmarshal(config, &uconf)
   374  			if err != nil {
   375  				t.Fatalf("Failed to unmarshal with: %s", err)
   376  			}
   377  
   378  			t.Log(uconf.Inner.Single)
   379  
   380  			if !reflect.DeepEqual(uconf.Inner.Single, expectedValue) {
   381  				t.Fatalf(`Expected: "%v",  Actual: "%v"`, expectedValue, uconf.Inner.Single)
   382  			}
   383  		})
   384  	}
   385  
   386  }
   387  
   388  func TestEnhancedExactUnmarshalKey(t *testing.T) {
   389  	type Nested struct {
   390  		Key string
   391  	}
   392  
   393  	type nestedKey struct {
   394  		Nested Nested
   395  	}
   396  
   397  	yaml := "---\n" +
   398  		"Top:\n" +
   399  		"  Nested:\n" +
   400  		"    Nested:\n" +
   401  		"      Key: BAD\n"
   402  
   403  	envVar := "VIPERUTIL_TOP_NESTED_NESTED_KEY"
   404  	envVal := "GOOD"
   405  	os.Setenv(envVar, envVal)
   406  	defer os.Unsetenv(envVar)
   407  
   408  	viper.SetEnvPrefix(Prefix)
   409  	defer viper.Reset()
   410  	viper.AutomaticEnv()
   411  	replacer := strings.NewReplacer(".", "_")
   412  	viper.SetEnvKeyReplacer(replacer)
   413  	viper.SetConfigType("yaml")
   414  
   415  	if err := viper.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   416  		t.Fatalf("Error reading config: %s", err)
   417  	}
   418  
   419  	var uconf nestedKey
   420  	if err := EnhancedExactUnmarshalKey("top.Nested", &uconf); err != nil {
   421  		t.Fatalf("Failed to unmarshall: %s", err)
   422  	}
   423  
   424  	if uconf.Nested.Key != envVal {
   425  		t.Fatalf(`Expected: "%s", Actual: "%s"`, envVal, uconf.Nested.Key)
   426  	}
   427  
   428  }