github.com/bestchains/fabric-ca@v2.0.0-alpha+incompatible/util/flag_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 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 util_test
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/hyperledger/fabric-ca/lib"
    25  	. "github.com/hyperledger/fabric-ca/util"
    26  	"github.com/spf13/pflag"
    27  	"github.com/spf13/viper"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  // A test struct
    32  type A struct {
    33  	ADur        time.Duration     `help:"Duration"`
    34  	ASlice      []string          `help:"Slice description"`
    35  	AStr        string            `def:"defval" help:"Str1 description"`
    36  	AInt        int               `def:"10" help:"Int1 description"`
    37  	AB          B                 `help:"FB description"`
    38  	AStr2       string            `skip:"true"`
    39  	AIntArray   []int             `help:"IntArray description"`
    40  	AMap        map[string]string `skip:"true"`
    41  	ABPtr       *B                `help:"FBP description"`
    42  	AInterface  interface{}       `skip:"true"`
    43  	aUnexported string
    44  	ABad        ABad `skip:"true"`
    45  }
    46  
    47  // B test struct
    48  type B struct {
    49  	BStr  string `help:"Str description"`
    50  	BInt  int    `skip:"true"`
    51  	BCPtr *C
    52  }
    53  
    54  // C test struct
    55  type C struct {
    56  	CBool bool   `def:"true" help:"Bool description"`
    57  	CStr  string `help:"Str description"`
    58  }
    59  
    60  type ABad struct {
    61  }
    62  
    63  type DurBad struct {
    64  	ADur time.Duration `def:"xx" help:"Duration"`
    65  }
    66  
    67  type Int64Struct struct {
    68  	Int64Var int64 `def:"3546343826724305832" help:"int64"`
    69  }
    70  
    71  func printit(f *Field) error {
    72  	//fmt.Printf("%+v\n", f)
    73  	return nil
    74  }
    75  
    76  func TestRegisterFlags(t *testing.T) {
    77  	tags := map[string]string{
    78  		"help.fb.int": "This is an int field",
    79  	}
    80  	err := RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &A{}, tags)
    81  	if err != nil {
    82  		t.Errorf("Failed to register flags: %s", err)
    83  	}
    84  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &C{}, tags)
    85  	if err != nil {
    86  		t.Errorf("Failed to register flags: %s", err)
    87  	}
    88  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &Int64Struct{}, tags)
    89  	assert.NoError(t, err, "Failed to register int64 flag")
    90  }
    91  
    92  func TestParseObj(t *testing.T) {
    93  	err := ParseObj(&A{}, printit, nil)
    94  	if err != nil {
    95  		t.Errorf("Failed to parse foo: %s", err)
    96  	}
    97  	err = ParseObj(&A{}, nil, nil)
    98  	if err == nil {
    99  		t.Error("Should have failed to parse but didn't")
   100  	}
   101  }
   102  
   103  func TestCheckForMissingValues(t *testing.T) {
   104  
   105  	src := &A{
   106  		ADur:      time.Hour,
   107  		AStr:      "AStr",
   108  		AStr2:     "AStr2",
   109  		AIntArray: []int{1, 2, 3},
   110  		AMap:      map[string]string{"Key1": "Val1", "Key2": "Val2"},
   111  		AB: B{
   112  			BStr: "BStr",
   113  			BCPtr: &C{
   114  				CBool: true,
   115  				CStr:  "CStr",
   116  			},
   117  		},
   118  		ABPtr: &B{
   119  			BStr: "BStr",
   120  			BCPtr: &C{
   121  				CBool: false,
   122  				CStr:  "CStr",
   123  			},
   124  		},
   125  		AInterface: &C{
   126  			CStr: "CStr",
   127  		},
   128  	}
   129  
   130  	dst := &A{
   131  		AStr2: "dstAStr2",
   132  		AInt:  2,
   133  	}
   134  
   135  	CopyMissingValues(src, dst)
   136  
   137  	if src.AStr != dst.AStr {
   138  		t.Error("Failed to copy field AStr")
   139  	}
   140  
   141  	if src.AB.BStr != dst.AB.BStr {
   142  		t.Error("Failed to copy field AB.BStr")
   143  	}
   144  
   145  	if src.ABPtr.BStr != dst.ABPtr.BStr {
   146  		t.Error("Failed to copy field ABPtr.BStr")
   147  	}
   148  
   149  	if src.ABPtr.BCPtr.CStr != dst.ABPtr.BCPtr.CStr {
   150  		t.Error("Failed to copy field ABPtr.BCPtr.CStr")
   151  	}
   152  
   153  	if !reflect.DeepEqual(src.AMap, dst.AMap) {
   154  		t.Errorf("Failed to copy AMap: src=%+v, dst=%+v", src.AMap, dst.AMap)
   155  	}
   156  
   157  	for i := range src.AIntArray {
   158  		sv := src.AIntArray[i]
   159  		dv := dst.AIntArray[i]
   160  		if sv != dv {
   161  			t.Errorf("Failed to copy element %d of Int2 array (%d != %d)", i, sv, dv)
   162  		}
   163  	}
   164  
   165  	if dst.AStr2 != "dstAStr2" {
   166  		t.Errorf("Incorrectly replaced AStr2 with %s", dst.AStr2)
   167  	}
   168  
   169  	if dst.AInt != 2 {
   170  		t.Errorf("Incorrectly replaced AInt with %d", dst.AInt)
   171  	}
   172  }
   173  
   174  func TestViperUnmarshal(t *testing.T) {
   175  	var err error
   176  
   177  	cfg := &lib.CAConfig{}
   178  	vp := viper.New()
   179  	vp.SetConfigFile("../testdata/testviperunmarshal.yaml")
   180  	err = vp.ReadInConfig()
   181  	if err != nil {
   182  		t.Errorf("Failed to read config file: %s", err)
   183  	}
   184  
   185  	sliceFields := []string{
   186  		"db.tls",
   187  	}
   188  	err = ViperUnmarshal(cfg, sliceFields, vp)
   189  	if err == nil {
   190  		t.Error("Should have resulted in an error, as tls can't be casted to type string array")
   191  	}
   192  
   193  	sliceFields = []string{
   194  		"db.tls.certfiles",
   195  	}
   196  	err = ViperUnmarshal(cfg, sliceFields, vp)
   197  	if err != nil {
   198  		t.Error("Failed to correctly process valid path to be type string array: ", err)
   199  	}
   200  }
   201  
   202  func TestRegisterFlagsInvalidArgs(t *testing.T) {
   203  	data := struct{ Field string }{}
   204  	err := RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data, nil)
   205  	assert.Error(t, err)
   206  	assert.Contains(t, err.Error(), "Field is missing a help tag")
   207  
   208  	data2 := struct{ Field bool }{}
   209  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data2, nil)
   210  	assert.Error(t, err)
   211  	assert.Contains(t, err.Error(), "Field is missing a help tag")
   212  
   213  	data3 := struct{ Field int }{}
   214  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data3, nil)
   215  	assert.Error(t, err)
   216  	assert.Contains(t, err.Error(), "Field is missing a help tag")
   217  
   218  	data4 := struct{ Field []string }{}
   219  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data4, nil)
   220  	assert.Error(t, err)
   221  	assert.Contains(t, err.Error(), "Field is missing a help tag")
   222  
   223  	data5 := struct{ Field time.Duration }{}
   224  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data5, nil)
   225  	assert.Error(t, err)
   226  	assert.Contains(t, err.Error(), "Field is missing a help tag")
   227  
   228  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &DurBad{}, nil)
   229  	assert.Error(t, err)
   230  	assert.Contains(t, err.Error(), "Invalid duration value in 'def' tag")
   231  
   232  	data6 := struct{ Field float32 }{}
   233  	err = RegisterFlags(viper.GetViper(), &pflag.FlagSet{}, &data6, nil)
   234  	assert.NoError(t, err)
   235  }