github.com/cloudwego/kitex@v0.9.0/internal/configutil/config_test.go (about)

     1  /*
     2   * Copyright 2021 CloudWeGo Authors
     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 configutil
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/cloudwego/kitex/internal/test"
    24  )
    25  
    26  type mockConfig struct {
    27  	data map[interface{}]interface{}
    28  }
    29  
    30  func (c *mockConfig) Get(key string) (interface{}, bool) {
    31  	ret, ok := c.data[key]
    32  	return ret, ok
    33  }
    34  
    35  func TestConfigs_Get(t *testing.T) {
    36  	// empty config
    37  	emptyConfigs := configs{}
    38  	val, ok := emptyConfigs.Get("key")
    39  	test.Assert(t, val == nil)
    40  	test.Assert(t, ok == false)
    41  	val, ok = emptyConfigs.Get("")
    42  	test.Assert(t, val == nil)
    43  	test.Assert(t, ok == false)
    44  
    45  	// contain single config
    46  	singleCfg := configs{
    47  		sources: []Config{
    48  			&mockConfig{
    49  				data: map[interface{}]interface{}{
    50  					"key": "val",
    51  				},
    52  			},
    53  		},
    54  	}
    55  	val, ok = singleCfg.Get("key")
    56  	test.Assert(t, val == "val")
    57  	test.Assert(t, ok == true)
    58  	val, ok = singleCfg.Get("not_exist_key")
    59  	test.Assert(t, val == nil)
    60  	test.Assert(t, ok == false)
    61  	val, ok = singleCfg.Get("")
    62  	test.Assert(t, val == nil)
    63  	test.Assert(t, ok == false)
    64  
    65  	// contain multi configs
    66  	multiCfgs := configs{
    67  		sources: []Config{
    68  			&mockConfig{
    69  				data: map[interface{}]interface{}{
    70  					"key1": "val1",
    71  				},
    72  			},
    73  			&mockConfig{
    74  				data: map[interface{}]interface{}{
    75  					"key2": "val2",
    76  				},
    77  			},
    78  			&mockConfig{
    79  				data: map[interface{}]interface{}{
    80  					"key2": "val3",
    81  				},
    82  			},
    83  		},
    84  	}
    85  	val, ok = multiCfgs.Get("key2")
    86  	test.Assert(t, val == "val3")
    87  	test.Assert(t, ok == true)
    88  	val, ok = multiCfgs.Get("key1")
    89  	test.Assert(t, val == "val1")
    90  	test.Assert(t, ok == true)
    91  	val, ok = multiCfgs.Get("key")
    92  	test.Assert(t, val == nil)
    93  	test.Assert(t, ok == false)
    94  	val, ok = multiCfgs.Get("")
    95  	test.Assert(t, val == nil)
    96  	test.Assert(t, ok == false)
    97  }
    98  
    99  func TestConfigs_AddPriorSource(t *testing.T) {
   100  	invalidCfgs := &configs{}
   101  	invalidCfgs.AddPriorSource(nil)
   102  	nilVal := invalidCfgs.sources[0]
   103  	test.Assert(t, nilVal == nil)
   104  
   105  	cfgs := &configs{}
   106  	c1 := &mockConfig{
   107  		data: map[interface{}]interface{}{
   108  			"key": "val1",
   109  		},
   110  	}
   111  	cfgs.AddPriorSource(c1)
   112  	val, ok := cfgs.Get("key")
   113  	test.Assert(t, val == "val1", ok == true)
   114  
   115  	c2 := &mockConfig{
   116  		data: map[interface{}]interface{}{
   117  			"key": "val2",
   118  		},
   119  	}
   120  	cfgs.AddPriorSource(c2)
   121  	val, ok = cfgs.Get("key")
   122  	test.Assert(t, val == "val2", ok == true)
   123  }
   124  
   125  func TestDefaultConfig_Get(t *testing.T) {
   126  	// empty config
   127  	emptyCfg := &mockConfig{}
   128  	emptyDefCfg := NewDefaultConfig(emptyCfg)
   129  	val := emptyDefCfg.Get("key", "def_val")
   130  	test.Assert(t, val.(string) == "def_val")
   131  
   132  	// config contain element
   133  	cfg := &mockConfig{
   134  		data: map[interface{}]interface{}{
   135  			"key": "val",
   136  		},
   137  	}
   138  	defCfg := NewDefaultConfig(cfg)
   139  	val = defCfg.Get("key", "def_val")
   140  	test.Assert(t, val.(string) == "val")
   141  	val = defCfg.Get("not_exist_key", "def_val")
   142  	test.Assert(t, val.(string) == "def_val")
   143  	val = defCfg.Get("", "def_val")
   144  	test.Assert(t, val.(string) == "def_val")
   145  }
   146  
   147  func TestDummyConfig_Get(t *testing.T) {
   148  	emptyCfg := NewDummyConfig()
   149  	val, ok := emptyCfg.Get("key")
   150  	test.Assert(t, val == nil, ok == false)
   151  	val, ok = emptyCfg.Get("")
   152  	test.Assert(t, val == nil, ok == false)
   153  }
   154  
   155  func TestRichTypeConfig_GetBool(t *testing.T) {
   156  	// empty config
   157  	emptyCfg := &mockConfig{}
   158  	richCfg := NewRichTypeConfig(emptyCfg)
   159  	val, ok := richCfg.GetBool("key")
   160  	test.Assert(t, val == false, ok == false)
   161  	val, ok = richCfg.GetBool("")
   162  	test.Assert(t, val == false, ok == false)
   163  
   164  	// contain other type element
   165  	otherTypeCfg := &mockConfig{
   166  		data: map[interface{}]interface{}{
   167  			"key": "val",
   168  		},
   169  	}
   170  	richCfg = NewRichTypeConfig(otherTypeCfg)
   171  	val, ok = richCfg.GetBool("key")
   172  	test.Assert(t, val == false, ok == false)
   173  	val, ok = richCfg.GetBool("not_exist_key")
   174  	test.Assert(t, val == false, ok == false)
   175  	val, ok = richCfg.GetBool("")
   176  	test.Assert(t, val == false, ok == false)
   177  
   178  	// contain bool type element
   179  	boolTypeCfg := &mockConfig{
   180  		data: map[interface{}]interface{}{
   181  			"key": true,
   182  		},
   183  	}
   184  	richCfg = NewRichTypeConfig(boolTypeCfg)
   185  	val, ok = richCfg.GetBool("key")
   186  	test.Assert(t, val == true, ok == true)
   187  	val, ok = richCfg.GetBool("not_exist_key")
   188  	test.Assert(t, val == false, ok == false)
   189  	val, ok = richCfg.GetBool("")
   190  	test.Assert(t, val == false, ok == false)
   191  }
   192  
   193  func TestRichTypeConfig_GetDuration(t *testing.T) {
   194  	// empty config
   195  	emptyCfg := &mockConfig{}
   196  	richCfg := NewRichTypeConfig(emptyCfg)
   197  	val, ok := richCfg.GetDuration("key")
   198  	test.Assert(t, int64(val) == 0, ok == false)
   199  	val, ok = richCfg.GetDuration("")
   200  	test.Assert(t, int64(val) == 0, ok == false)
   201  
   202  	// contain other type element
   203  	otherTypeCfg := &mockConfig{
   204  		data: map[interface{}]interface{}{
   205  			"key": "val",
   206  		},
   207  	}
   208  	richCfg = NewRichTypeConfig(otherTypeCfg)
   209  	val, ok = richCfg.GetDuration("key")
   210  	test.Assert(t, int64(val) == 0, ok == false)
   211  	val, ok = richCfg.GetDuration("not_exist_key")
   212  	test.Assert(t, int64(val) == 0, ok == false)
   213  	val, ok = richCfg.GetDuration("")
   214  	test.Assert(t, int64(val) == 0, ok == false)
   215  
   216  	// contain bool type element
   217  	durationTypeCfg := &mockConfig{
   218  		data: map[interface{}]interface{}{
   219  			"key": time.Second,
   220  		},
   221  	}
   222  	richCfg = NewRichTypeConfig(durationTypeCfg)
   223  	val, ok = richCfg.GetDuration("key")
   224  	test.Assert(t, val == time.Second, ok == true)
   225  	val, ok = richCfg.GetDuration("not_exist_key")
   226  	test.Assert(t, int64(val) == 0, ok == false)
   227  	val, ok = richCfg.GetDuration("")
   228  	test.Assert(t, int64(val) == 0, ok == false)
   229  }
   230  
   231  func TestRichTypeConfig_GetFloat(t *testing.T) {
   232  	// empty config
   233  	emptyCfg := &mockConfig{}
   234  	richCfg := NewRichTypeConfig(emptyCfg)
   235  	val, ok := richCfg.GetFloat("key")
   236  	test.Assert(t, val == float64(0), ok == false)
   237  	val, ok = richCfg.GetFloat("")
   238  	test.Assert(t, val == float64(0), ok == false)
   239  
   240  	// contain other type element
   241  	otherTypeCfg := &mockConfig{
   242  		data: map[interface{}]interface{}{
   243  			"key": "val",
   244  		},
   245  	}
   246  	richCfg = NewRichTypeConfig(otherTypeCfg)
   247  	val, ok = richCfg.GetFloat("key")
   248  	test.Assert(t, val == float64(0), ok == false)
   249  	val, ok = richCfg.GetFloat("not_exist_key")
   250  	test.Assert(t, val == float64(0), ok == false)
   251  	val, ok = richCfg.GetFloat("")
   252  	test.Assert(t, val == float64(0), ok == false)
   253  
   254  	// contain bool type element
   255  	boolTypeCfg := &mockConfig{
   256  		data: map[interface{}]interface{}{
   257  			"key": float64(1.23),
   258  		},
   259  	}
   260  	richCfg = NewRichTypeConfig(boolTypeCfg)
   261  	val, ok = richCfg.GetFloat("key")
   262  	test.Assert(t, val == float64(1.23), ok == true)
   263  	val, ok = richCfg.GetFloat("not_exist_key")
   264  	test.Assert(t, val == float64(0), ok == false)
   265  	val, ok = richCfg.GetFloat("")
   266  	test.Assert(t, val == float64(0), ok == false)
   267  }
   268  
   269  func TestRichTypeConfig_GetInt(t *testing.T) {
   270  	// empty config
   271  	emptyCfg := &mockConfig{}
   272  	richCfg := NewRichTypeConfig(emptyCfg)
   273  	val, ok := richCfg.GetInt("key")
   274  	test.Assert(t, val == 0, ok == false)
   275  	val, ok = richCfg.GetInt("")
   276  	test.Assert(t, val == 0, ok == false)
   277  
   278  	// contain other type element
   279  	otherTypeCfg := &mockConfig{
   280  		data: map[interface{}]interface{}{
   281  			"key": "val",
   282  		},
   283  	}
   284  	richCfg = NewRichTypeConfig(otherTypeCfg)
   285  	val, ok = richCfg.GetInt("key")
   286  	test.Assert(t, val == 0, ok == false)
   287  	val, ok = richCfg.GetInt("not_exist_key")
   288  	test.Assert(t, val == 0, ok == false)
   289  	val, ok = richCfg.GetInt("")
   290  	test.Assert(t, val == 0, ok == false)
   291  
   292  	// contain bool type element
   293  	boolTypeCfg := &mockConfig{
   294  		data: map[interface{}]interface{}{
   295  			"key": 123,
   296  		},
   297  	}
   298  	richCfg = NewRichTypeConfig(boolTypeCfg)
   299  	val, ok = richCfg.GetInt("key")
   300  	test.Assert(t, val == 123, ok == true)
   301  	val, ok = richCfg.GetInt("not_exist_key")
   302  	test.Assert(t, val == 0, ok == false)
   303  	val, ok = richCfg.GetInt("")
   304  	test.Assert(t, val == 0, ok == false)
   305  }
   306  
   307  func TestRichTypeConfig_GetInt64(t *testing.T) {
   308  	// empty config
   309  	emptyCfg := &mockConfig{}
   310  	richCfg := NewRichTypeConfig(emptyCfg)
   311  	val, ok := richCfg.GetInt64("key")
   312  	test.Assert(t, val == int64(0), ok == false)
   313  	val, ok = richCfg.GetInt64("")
   314  	test.Assert(t, val == int64(0), ok == false)
   315  
   316  	// contain other type element
   317  	otherTypeCfg := &mockConfig{
   318  		data: map[interface{}]interface{}{
   319  			"key": "val",
   320  		},
   321  	}
   322  	richCfg = NewRichTypeConfig(otherTypeCfg)
   323  	val, ok = richCfg.GetInt64("key")
   324  	test.Assert(t, val == int64(0), ok == false)
   325  	val, ok = richCfg.GetInt64("not_exist_key")
   326  	test.Assert(t, val == int64(0), ok == false)
   327  	val, ok = richCfg.GetInt64("")
   328  	test.Assert(t, val == int64(0), ok == false)
   329  
   330  	// contain bool type element
   331  	boolTypeCfg := &mockConfig{
   332  		data: map[interface{}]interface{}{
   333  			"key": int64(123456),
   334  		},
   335  	}
   336  	richCfg = NewRichTypeConfig(boolTypeCfg)
   337  	val, ok = richCfg.GetInt64("key")
   338  	test.Assert(t, val == int64(123456), ok == true)
   339  	val, ok = richCfg.GetInt64("not_exist_key")
   340  	test.Assert(t, val == int64(0), ok == false)
   341  	val, ok = richCfg.GetInt64("")
   342  	test.Assert(t, val == int64(0), ok == false)
   343  }
   344  
   345  func TestRichTypeConfig_GetString(t *testing.T) {
   346  	// empty config
   347  	emptyCfg := &mockConfig{}
   348  	richCfg := NewRichTypeConfig(emptyCfg)
   349  	val, ok := richCfg.GetString("key")
   350  	test.Assert(t, val == "", ok == false)
   351  	val, ok = richCfg.GetString("")
   352  	test.Assert(t, val == "", ok == false)
   353  
   354  	// contain other type element
   355  	otherTypeCfg := &mockConfig{
   356  		data: map[interface{}]interface{}{
   357  			"key": true,
   358  		},
   359  	}
   360  	richCfg = NewRichTypeConfig(otherTypeCfg)
   361  	val, ok = richCfg.GetString("key")
   362  	test.Assert(t, val == "", ok == false)
   363  	val, ok = richCfg.GetString("not_exist_key")
   364  	test.Assert(t, val == "", ok == false)
   365  	val, ok = richCfg.GetString("")
   366  	test.Assert(t, val == "", ok == false)
   367  
   368  	// contain bool type element
   369  	boolTypeCfg := &mockConfig{
   370  		data: map[interface{}]interface{}{
   371  			"key": "val",
   372  		},
   373  	}
   374  	richCfg = NewRichTypeConfig(boolTypeCfg)
   375  	val, ok = richCfg.GetString("key")
   376  	test.Assert(t, val == "val", ok == true)
   377  	val, ok = richCfg.GetString("not_exist_key")
   378  	test.Assert(t, val == "", ok == false)
   379  	val, ok = richCfg.GetString("")
   380  	test.Assert(t, val == "", ok == false)
   381  }
   382  
   383  func TestRichTypeDefaultConfig_GetBool(t *testing.T) {
   384  	// empty config
   385  	emptyCfg := &mockConfig{}
   386  	richCfg := NewRichTypeConfig(emptyCfg)
   387  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   388  	val := emptyDefRichCfg.GetBool("key", true)
   389  	test.Assert(t, val == true)
   390  	val = emptyDefRichCfg.GetBool("", false)
   391  	test.Assert(t, val == false)
   392  
   393  	// contain other type element
   394  	otherTypeCfg := &mockConfig{
   395  		data: map[interface{}]interface{}{
   396  			"key": "val",
   397  		},
   398  	}
   399  	richCfg = NewRichTypeConfig(otherTypeCfg)
   400  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   401  	val = defRichCfg.GetBool("key", true)
   402  	test.Assert(t, val == true)
   403  	val = defRichCfg.GetBool("not_exist_key", true)
   404  	test.Assert(t, val == true)
   405  	val = defRichCfg.GetBool("", false)
   406  	test.Assert(t, val == false)
   407  
   408  	// contain bool type element
   409  	boolTypeCfg := &mockConfig{
   410  		data: map[interface{}]interface{}{
   411  			"key": true,
   412  		},
   413  	}
   414  	richCfg = NewRichTypeConfig(boolTypeCfg)
   415  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   416  	val = defRichCfg.GetBool("key", false)
   417  	test.Assert(t, val == true)
   418  	val = defRichCfg.GetBool("not_exist_key", true)
   419  	test.Assert(t, val == true)
   420  	val = defRichCfg.GetBool("", false)
   421  	test.Assert(t, val == false)
   422  }
   423  
   424  func TestRichTypeDefaultConfig_GetDuration(t *testing.T) {
   425  	// empty config
   426  	emptyCfg := &mockConfig{}
   427  	richCfg := NewRichTypeConfig(emptyCfg)
   428  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   429  	val := emptyDefRichCfg.GetDuration("key", time.Second)
   430  	test.Assert(t, val == time.Second)
   431  	val = emptyDefRichCfg.GetDuration("", time.Second)
   432  	test.Assert(t, val == time.Second)
   433  
   434  	// contain other type element
   435  	otherTypeCfg := &mockConfig{
   436  		data: map[interface{}]interface{}{
   437  			"key": "val",
   438  		},
   439  	}
   440  	richCfg = NewRichTypeConfig(otherTypeCfg)
   441  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   442  	val = defRichCfg.GetDuration("key", time.Second)
   443  	test.Assert(t, val == time.Second)
   444  	val = defRichCfg.GetDuration("not_exist_key", time.Second)
   445  	test.Assert(t, val == time.Second)
   446  	val = defRichCfg.GetDuration("", time.Second)
   447  	test.Assert(t, val == time.Second)
   448  
   449  	// contain bool type element
   450  	boolTypeCfg := &mockConfig{
   451  		data: map[interface{}]interface{}{
   452  			"key": time.Second,
   453  		},
   454  	}
   455  	richCfg = NewRichTypeConfig(boolTypeCfg)
   456  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   457  	val = defRichCfg.GetDuration("key", time.Minute)
   458  	test.Assert(t, val == time.Second)
   459  	val = defRichCfg.GetDuration("not_exist_key", time.Minute)
   460  	test.Assert(t, val == time.Minute)
   461  	val = defRichCfg.GetDuration("", time.Minute)
   462  	test.Assert(t, val == time.Minute)
   463  }
   464  
   465  func TestRichTypeDefaultConfig_GetFloat(t *testing.T) {
   466  	// empty config
   467  	emptyCfg := &mockConfig{}
   468  	richCfg := NewRichTypeConfig(emptyCfg)
   469  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   470  	val := emptyDefRichCfg.GetFloat("key", 1.23)
   471  	test.Assert(t, val == 1.23)
   472  	val = emptyDefRichCfg.GetFloat("", 2.34)
   473  	test.Assert(t, val == 2.34)
   474  
   475  	// contain other type element
   476  	otherTypeCfg := &mockConfig{
   477  		data: map[interface{}]interface{}{
   478  			"key": "val",
   479  		},
   480  	}
   481  	richCfg = NewRichTypeConfig(otherTypeCfg)
   482  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   483  	val = defRichCfg.GetFloat("key", 1.23)
   484  	test.Assert(t, val == 1.23)
   485  	val = defRichCfg.GetFloat("not_exist_key", 2.34)
   486  	test.Assert(t, val == 2.34)
   487  	val = defRichCfg.GetFloat("", 3.45)
   488  	test.Assert(t, val == 3.45)
   489  
   490  	// contain bool type element
   491  	boolTypeCfg := &mockConfig{
   492  		data: map[interface{}]interface{}{
   493  			"key": 0.01,
   494  		},
   495  	}
   496  	richCfg = NewRichTypeConfig(boolTypeCfg)
   497  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   498  	val = defRichCfg.GetFloat("key", 1.12)
   499  	test.Assert(t, val == 0.01)
   500  	val = defRichCfg.GetFloat("not_exist_key", 2.34)
   501  	test.Assert(t, val == 2.34)
   502  	val = defRichCfg.GetFloat("", 3.45)
   503  	test.Assert(t, val == 3.45)
   504  }
   505  
   506  func TestRichTypeDefaultConfig_GetInt(t *testing.T) {
   507  	// empty config
   508  	emptyCfg := &mockConfig{}
   509  	richCfg := NewRichTypeConfig(emptyCfg)
   510  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   511  	val := emptyDefRichCfg.GetInt("key", 1)
   512  	test.Assert(t, val == 1)
   513  	val = emptyDefRichCfg.GetInt("", 2)
   514  	test.Assert(t, val == 2)
   515  
   516  	// contain other type element
   517  	otherTypeCfg := &mockConfig{
   518  		data: map[interface{}]interface{}{
   519  			"key": "val",
   520  		},
   521  	}
   522  	richCfg = NewRichTypeConfig(otherTypeCfg)
   523  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   524  	val = defRichCfg.GetInt("key", 1)
   525  	test.Assert(t, val == 1)
   526  	val = defRichCfg.GetInt("not_exist_key", 2)
   527  	test.Assert(t, val == 2)
   528  	val = defRichCfg.GetInt("", 3)
   529  	test.Assert(t, val == 3)
   530  
   531  	// contain bool type element
   532  	boolTypeCfg := &mockConfig{
   533  		data: map[interface{}]interface{}{
   534  			"key": 123,
   535  		},
   536  	}
   537  	richCfg = NewRichTypeConfig(boolTypeCfg)
   538  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   539  	val = defRichCfg.GetInt("key", 456)
   540  	test.Assert(t, val == 123)
   541  	val = defRichCfg.GetInt("not_exist_key", 678)
   542  	test.Assert(t, val == 678)
   543  	val = defRichCfg.GetInt("", 789)
   544  	test.Assert(t, val == 789)
   545  }
   546  
   547  func TestRichTypeDefaultConfig_GetInt64(t *testing.T) {
   548  	// empty config
   549  	emptyCfg := &mockConfig{}
   550  	richCfg := NewRichTypeConfig(emptyCfg)
   551  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   552  	val := emptyDefRichCfg.GetInt64("key", 123456)
   553  	test.Assert(t, val == 123456)
   554  	val = emptyDefRichCfg.GetInt64("", 456789)
   555  	test.Assert(t, val == 456789)
   556  
   557  	// contain other type element
   558  	otherTypeCfg := &mockConfig{
   559  		data: map[interface{}]interface{}{
   560  			"key": "val",
   561  		},
   562  	}
   563  	richCfg = NewRichTypeConfig(otherTypeCfg)
   564  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   565  	val = defRichCfg.GetInt64("key", 123456)
   566  	test.Assert(t, val == 123456)
   567  	val = defRichCfg.GetInt64("not_exist_key", 23456)
   568  	test.Assert(t, val == 23456)
   569  	val = defRichCfg.GetInt64("", 45678)
   570  	test.Assert(t, val == 45678)
   571  
   572  	// contain bool type element
   573  	boolTypeCfg := &mockConfig{
   574  		data: map[interface{}]interface{}{
   575  			"key": 987654321,
   576  		},
   577  	}
   578  	richCfg = NewRichTypeConfig(boolTypeCfg)
   579  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   580  	val = defRichCfg.GetInt64("key", 123456789)
   581  	test.Assert(t, val == 987654321)
   582  	val = defRichCfg.GetInt64("not_exist_key", 123)
   583  	test.Assert(t, val == 123)
   584  	val = defRichCfg.GetInt64("", 456)
   585  	test.Assert(t, val == 456)
   586  }
   587  
   588  func TestRichTypeDefaultConfig_GetString(t *testing.T) {
   589  	// empty config
   590  	emptyCfg := &mockConfig{}
   591  	richCfg := NewRichTypeConfig(emptyCfg)
   592  	emptyDefRichCfg := NewRichTypeDefaultConfig(richCfg)
   593  	val := emptyDefRichCfg.GetString("key", "def_val")
   594  	test.Assert(t, val == "def_val")
   595  	val = emptyDefRichCfg.GetString("", "def_val")
   596  	test.Assert(t, val == "def_val")
   597  
   598  	// contain other type element
   599  	otherTypeCfg := &mockConfig{
   600  		data: map[interface{}]interface{}{
   601  			"key": true,
   602  		},
   603  	}
   604  	richCfg = NewRichTypeConfig(otherTypeCfg)
   605  	defRichCfg := NewRichTypeDefaultConfig(richCfg)
   606  	val = defRichCfg.GetString("key", "def_val")
   607  	test.Assert(t, val == "def_val")
   608  	val = defRichCfg.GetString("not_exist_key", "def_val")
   609  	test.Assert(t, val == "def_val")
   610  	val = defRichCfg.GetString("", "def_val")
   611  	test.Assert(t, val == "def_val")
   612  
   613  	// contain bool type element
   614  	boolTypeCfg := &mockConfig{
   615  		data: map[interface{}]interface{}{
   616  			"key": "val",
   617  		},
   618  	}
   619  	richCfg = NewRichTypeConfig(boolTypeCfg)
   620  	defRichCfg = NewRichTypeDefaultConfig(richCfg)
   621  	val = defRichCfg.GetString("key", "def_val")
   622  	test.Assert(t, val == "val")
   623  	val = defRichCfg.GetString("not_exist_key", "def_val")
   624  	test.Assert(t, val == "def_val")
   625  	val = defRichCfg.GetString("", "def_val")
   626  	test.Assert(t, val == "def_val")
   627  }