github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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, expected: %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, expected: %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, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
   221  		pems = append(pems, publicKeyCert...)
   222  	}
   223  
   224  	// write temp file
   225  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   226  		t.Fatalf("Unable to write to temp file: %v", err)
   227  	}
   228  
   229  	yaml := fmt.Sprintf("---\nInner:\n  Multiple:\n    File: %s", file.Name())
   230  
   231  	config := viper.New()
   232  	config.SetConfigType("yaml")
   233  
   234  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   235  		t.Fatalf("Error reading config: %v", err)
   236  	}
   237  	var uconf stringFromFileConfig
   238  	if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   239  		t.Fatalf("Failed to unmarshall: %v", err)
   240  	}
   241  
   242  	if len(uconf.Inner.Multiple) != 3 {
   243  		t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   244  	}
   245  }
   246  
   247  func TestPEMBlocksFromFileEnv(t *testing.T) {
   248  
   249  	// create temp file
   250  	file, err := ioutil.TempFile(os.TempDir(), "test")
   251  	if err != nil {
   252  		t.Fatalf("Unable to create temp file.")
   253  	}
   254  	defer os.Remove(file.Name())
   255  
   256  	numberOfCertificates := 3
   257  	var pems []byte
   258  	for i := 0; i < numberOfCertificates; i++ {
   259  		publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true)
   260  		pems = append(pems, publicKeyCert...)
   261  	}
   262  
   263  	// write temp file
   264  	if err := ioutil.WriteFile(file.Name(), pems, 0666); err != nil {
   265  		t.Fatalf("Unable to write to temp file: %v", err)
   266  	}
   267  
   268  	testCases := []struct {
   269  		name string
   270  		data string
   271  	}{
   272  		{"Override", "---\nInner:\n  Multiple:\n    File: wrong_file"},
   273  		{"NoFileElement", "---\nInner:\n  Multiple:\n"},
   274  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   275  	}
   276  
   277  	for _, tc := range testCases {
   278  		t.Run(tc.name, func(t *testing.T) {
   279  
   280  			envVar := "VIPERUTIL_INNER_MULTIPLE_FILE"
   281  			envVal := file.Name()
   282  			os.Setenv(envVar, envVal)
   283  			defer os.Unsetenv(envVar)
   284  			config := viper.New()
   285  			config.SetEnvPrefix(Prefix)
   286  			config.AutomaticEnv()
   287  			replacer := strings.NewReplacer(".", "_")
   288  			config.SetEnvKeyReplacer(replacer)
   289  			config.SetConfigType("yaml")
   290  
   291  			if err := config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   292  				t.Fatalf("Error reading config: %v", err)
   293  			}
   294  			var uconf stringFromFileConfig
   295  			if err := EnhancedExactUnmarshal(config, &uconf); err != nil {
   296  				t.Fatalf("Failed to unmarshall: %v", err)
   297  			}
   298  
   299  			if len(uconf.Inner.Multiple) != 3 {
   300  				t.Fatalf(`Expected: "%v", Actual: "%v"`, numberOfCertificates, len(uconf.Inner.Multiple))
   301  			}
   302  		})
   303  	}
   304  }
   305  
   306  func TestStringFromFileNotSpecified(t *testing.T) {
   307  
   308  	yaml := fmt.Sprintf("---\nInner:\n  Single:\n    File:\n")
   309  
   310  	config := viper.New()
   311  	config.SetConfigType("yaml")
   312  
   313  	if err := config.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   314  		t.Fatalf("Error reading config: %s", err)
   315  	}
   316  	var uconf stringFromFileConfig
   317  	if err := EnhancedExactUnmarshal(config, &uconf); err == nil {
   318  		t.Fatalf("Should of failed to unmarshall.")
   319  	}
   320  
   321  }
   322  
   323  func TestStringFromFileEnv(t *testing.T) {
   324  
   325  	expectedValue := "this is the text in the file"
   326  
   327  	// create temp file
   328  	file, err := ioutil.TempFile(os.TempDir(), "test")
   329  	if err != nil {
   330  		t.Fatalf("Unable to create temp file.")
   331  	}
   332  	defer os.Remove(file.Name())
   333  
   334  	// write temp file
   335  	if err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0777); err != nil {
   336  		t.Fatalf("Unable to write to temp file.")
   337  	}
   338  
   339  	testCases := []struct {
   340  		name string
   341  		data string
   342  	}{
   343  		{"Override", "---\nInner:\n  Single:\n    File: wrong_file"},
   344  		{"NoFileElement", "---\nInner:\n  Single:\n"},
   345  		// {"NoElementAtAll", "---\nInner:\n"}, test case for another time
   346  	}
   347  
   348  	for _, tc := range testCases {
   349  		t.Run(tc.name, func(t *testing.T) {
   350  			envVar := "VIPERUTIL_INNER_SINGLE_FILE"
   351  			envVal := file.Name()
   352  			os.Setenv(envVar, envVal)
   353  			defer os.Unsetenv(envVar)
   354  			config := viper.New()
   355  			config.SetEnvPrefix(Prefix)
   356  			config.AutomaticEnv()
   357  			replacer := strings.NewReplacer(".", "_")
   358  			config.SetEnvKeyReplacer(replacer)
   359  			config.SetConfigType("yaml")
   360  
   361  			if err = config.ReadConfig(bytes.NewReader([]byte(tc.data))); err != nil {
   362  				t.Fatalf("Error reading %s plugin config: %s", Prefix, err)
   363  			}
   364  
   365  			var uconf stringFromFileConfig
   366  
   367  			err = EnhancedExactUnmarshal(config, &uconf)
   368  			if err != nil {
   369  				t.Fatalf("Failed to unmarshal with: %s", err)
   370  			}
   371  
   372  			t.Log(uconf.Inner.Single)
   373  
   374  			if !reflect.DeepEqual(uconf.Inner.Single, expectedValue) {
   375  				t.Fatalf(`Expected: "%v",  Actual: "%v"`, expectedValue, uconf.Inner.Single)
   376  			}
   377  		})
   378  	}
   379  
   380  }
   381  
   382  func TestEnhancedExactUnmarshalKey(t *testing.T) {
   383  	type Nested struct {
   384  		Key string
   385  	}
   386  
   387  	type nestedKey struct {
   388  		Nested Nested
   389  	}
   390  
   391  	yaml := "---\n" +
   392  		"Top:\n" +
   393  		"  Nested:\n" +
   394  		"    Nested:\n" +
   395  		"      Key: BAD\n"
   396  
   397  	envVar := "VIPERUTIL_TOP_NESTED_NESTED_KEY"
   398  	envVal := "GOOD"
   399  	os.Setenv(envVar, envVal)
   400  	defer os.Unsetenv(envVar)
   401  
   402  	viper.SetEnvPrefix(Prefix)
   403  	defer viper.Reset()
   404  	viper.AutomaticEnv()
   405  	replacer := strings.NewReplacer(".", "_")
   406  	viper.SetEnvKeyReplacer(replacer)
   407  	viper.SetConfigType("yaml")
   408  
   409  	if err := viper.ReadConfig(bytes.NewReader([]byte(yaml))); err != nil {
   410  		t.Fatalf("Error reading config: %s", err)
   411  	}
   412  
   413  	var uconf nestedKey
   414  	if err := EnhancedExactUnmarshalKey("top.Nested", &uconf); err != nil {
   415  		t.Fatalf("Failed to unmarshall: %s", err)
   416  	}
   417  
   418  	if uconf.Nested.Key != envVal {
   419  		t.Fatalf(`Expected: "%s", Actual: "%s"`, envVal, uconf.Nested.Key)
   420  	}
   421  
   422  }