github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/viperutil/config_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package viperutil 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "os" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/Shopify/sarama" 18 "github.com/hechain20/hechain/bccsp/factory" 19 "github.com/hechain20/hechain/orderer/mocks/util" 20 "github.com/stretchr/testify/require" 21 ) 22 23 const ( 24 testConfigName = "viperutil" 25 testEnvPrefix = "VIPERUTIL" 26 ) 27 28 func TestEnvSlice(t *testing.T) { 29 type testSlice struct { 30 Inner struct { 31 Slice []string 32 } 33 } 34 35 envVar := testEnvPrefix + "_INNER_SLICE" 36 os.Setenv(envVar, "[a, b, c]") 37 defer os.Unsetenv(envVar) 38 39 data := "---\nInner:\n Slice: [d,e,f]" 40 41 config := New() 42 config.SetConfigName(testConfigName) 43 err := config.ReadConfig(strings.NewReader(data)) 44 require.NoError(t, err, "error reading %s plugin config", testConfigName) 45 46 var uconf testSlice 47 err = config.EnhancedExactUnmarshal(&uconf) 48 require.NoError(t, err, "failed to unmarshal") 49 50 expected := []string{"a", "b", "c"} 51 require.Exactly(t, expected, uconf.Inner.Slice, "did not get the expected slice") 52 } 53 54 func TestKafkaVersionDecode(t *testing.T) { 55 type testKafkaVersion struct { 56 Inner struct { 57 Version sarama.KafkaVersion 58 } 59 } 60 61 testCases := []struct { 62 data string 63 expected sarama.KafkaVersion 64 errExpected bool 65 }{ 66 {"0.8", sarama.KafkaVersion{}, true}, 67 {"0.8.2.0", sarama.V0_8_2_0, false}, 68 {"0.8.2.1", sarama.V0_8_2_1, false}, 69 {"0.8.2.2", sarama.V0_8_2_2, false}, 70 {"0.9.0.0", sarama.V0_9_0_0, false}, 71 {"0.9", sarama.V0_9_0_0, false}, 72 {"0.9.0", sarama.V0_9_0_0, false}, 73 {"0.9.0.1", sarama.V0_9_0_1, false}, 74 {"0.9.0.3", sarama.V0_9_0_1, false}, 75 {"0.10.0.0", sarama.V0_10_0_0, false}, 76 {"0.10", sarama.V0_10_0_0, false}, 77 {"0.10.0", sarama.V0_10_0_0, false}, 78 {"0.10.0.1", sarama.V0_10_0_1, false}, 79 {"0.10.1.0", sarama.V0_10_1_0, false}, 80 {"0.10.2.0", sarama.V0_10_2_0, false}, 81 {"0.10.2.1", sarama.V0_10_2_0, false}, 82 {"0.10.2.2", sarama.V0_10_2_0, false}, 83 {"0.10.2.3", sarama.V0_10_2_0, false}, 84 {"0.11", sarama.V0_11_0_0, false}, 85 {"0.11.0", sarama.V0_11_0_0, false}, 86 {"0.11.0.0", sarama.V0_11_0_0, false}, 87 {"1", sarama.V1_0_0_0, false}, 88 {"1.0", sarama.V1_0_0_0, false}, 89 {"1.0.0", sarama.V1_0_0_0, false}, 90 {"1.0.1", sarama.V1_0_0_0, false}, 91 {"2.0.0", sarama.V1_0_0_0, false}, 92 {"Malformed", sarama.KafkaVersion{}, true}, 93 } 94 95 for _, tc := range testCases { 96 t.Run(tc.data, func(t *testing.T) { 97 data := fmt.Sprintf("---\nInner:\n Version: '%s'", tc.data) 98 99 config := New() 100 err := config.ReadConfig(strings.NewReader(data)) 101 require.NoError(t, err, "error reading config") 102 103 var uconf testKafkaVersion 104 err = config.EnhancedExactUnmarshal(&uconf) 105 if tc.errExpected { 106 require.Error(t, err, "unmarshal did not fail") 107 } else { 108 require.NoError(t, err, "unmarshal failed") 109 require.Exactly(t, tc.expected, uconf.Inner.Version, "incorrect kafka version") 110 } 111 }) 112 } 113 } 114 115 type testByteSize struct { 116 Inner struct { 117 ByteSize uint32 118 } 119 } 120 121 func TestByteSize(t *testing.T) { 122 testCases := []struct { 123 data string 124 expected uint32 125 }{ 126 {"", 0}, 127 {"42", 42}, 128 {"42k", 42 * 1024}, 129 {"42kb", 42 * 1024}, 130 {"42K", 42 * 1024}, 131 {"42KB", 42 * 1024}, 132 {"42 K", 42 * 1024}, 133 {"42 KB", 42 * 1024}, 134 {"42m", 42 * 1024 * 1024}, 135 {"42mb", 42 * 1024 * 1024}, 136 {"42M", 42 * 1024 * 1024}, 137 {"42MB", 42 * 1024 * 1024}, 138 {"42 M", 42 * 1024 * 1024}, 139 {"42 MB", 42 * 1024 * 1024}, 140 {"3g", 3 * 1024 * 1024 * 1024}, 141 {"3gb", 3 * 1024 * 1024 * 1024}, 142 {"3G", 3 * 1024 * 1024 * 1024}, 143 {"3GB", 3 * 1024 * 1024 * 1024}, 144 {"3 G", 3 * 1024 * 1024 * 1024}, 145 {"3 GB", 3 * 1024 * 1024 * 1024}, 146 } 147 148 for _, tc := range testCases { 149 t.Run(tc.data, func(t *testing.T) { 150 data := fmt.Sprintf("---\nInner:\n ByteSize: %s", tc.data) 151 152 config := New() 153 err := config.ReadConfig(strings.NewReader(data)) 154 require.NoError(t, err, "error reading config") 155 156 var uconf testByteSize 157 err = config.EnhancedExactUnmarshal(&uconf) 158 require.NoError(t, err, "failed to unmarshal") 159 require.Exactly(t, tc.expected, uconf.Inner.ByteSize, "incorrect byte size") 160 }) 161 } 162 } 163 164 func TestByteSizeOverflow(t *testing.T) { 165 data := "---\nInner:\n ByteSize: 4GB" 166 167 config := New() 168 err := config.ReadConfig(strings.NewReader(data)) 169 require.NoError(t, err, "error reading config") 170 171 var uconf testByteSize 172 err = config.EnhancedExactUnmarshal(&uconf) 173 require.Error(t, err) 174 require.Contains(t, err.Error(), "Inner.ByteSize") 175 require.Contains(t, err.Error(), "value '4GB' overflows uint32") 176 } 177 178 type stringFromFileConfig struct { 179 Inner struct { 180 Single string 181 Multiple []string 182 } 183 } 184 185 func TestStringNotFromFile(t *testing.T) { 186 yaml := "---\nInner:\n Single: expected_value\n" 187 188 config := New() 189 err := config.ReadConfig(strings.NewReader(yaml)) 190 require.NoError(t, err, "error reading config") 191 192 var uconf stringFromFileConfig 193 err = config.EnhancedExactUnmarshal(&uconf) 194 require.NoError(t, err, "failed to unmarshal") 195 require.Equal(t, "expected_value", uconf.Inner.Single) 196 } 197 198 func TestStringFromFile(t *testing.T) { 199 file, err := ioutil.TempFile(os.TempDir(), "test") 200 require.NoError(t, err, "failed to create temp file") 201 defer os.Remove(file.Name()) 202 203 expectedValue := "this is the text in the file" 204 205 err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0o644) 206 require.NoError(t, err, "uname to write temp file") 207 208 yaml := fmt.Sprintf("---\nInner:\n Single:\n File: %s", file.Name()) 209 210 config := New() 211 err = config.ReadConfig(strings.NewReader(yaml)) 212 require.NoError(t, err, "error reading config") 213 214 var uconf stringFromFileConfig 215 err = config.EnhancedExactUnmarshal(&uconf) 216 require.NoError(t, err, "unmarshal failed") 217 require.Equal(t, expectedValue, uconf.Inner.Single) 218 } 219 220 func TestPEMBlocksFromFile(t *testing.T) { 221 file, err := ioutil.TempFile(os.TempDir(), "test") 222 require.NoError(t, err, "failed to create temp file") 223 defer os.Remove(file.Name()) 224 225 var pems []byte 226 for i := 0; i < 3; i++ { 227 publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true) 228 pems = append(pems, publicKeyCert...) 229 } 230 231 err = ioutil.WriteFile(file.Name(), pems, 0o644) 232 require.NoError(t, err, "failed to write temp file") 233 234 yaml := fmt.Sprintf("---\nInner:\n Multiple:\n File: %s", file.Name()) 235 236 config := New() 237 err = config.ReadConfig(strings.NewReader(yaml)) 238 require.NoError(t, err, "error reading config") 239 240 var uconf stringFromFileConfig 241 err = config.EnhancedExactUnmarshal(&uconf) 242 require.NoError(t, err, "failed to unmarshal") 243 require.Len(t, uconf.Inner.Multiple, 3) 244 } 245 246 func TestPEMBlocksFromFileEnv(t *testing.T) { 247 file, err := ioutil.TempFile(os.TempDir(), "test") 248 require.NoError(t, err, "failed to create temp file") 249 defer os.Remove(file.Name()) 250 251 var pems []byte 252 for i := 0; i < 3; i++ { 253 publicKeyCert, _, _ := util.GenerateMockPublicPrivateKeyPairPEM(true) 254 pems = append(pems, publicKeyCert...) 255 } 256 257 err = ioutil.WriteFile(file.Name(), pems, 0o644) 258 require.NoError(t, err, "failed to write temp file") 259 260 envVar := testEnvPrefix + "_INNER_MULTIPLE_FILE" 261 defer os.Unsetenv(envVar) 262 os.Setenv(envVar, file.Name()) 263 264 testCases := []struct { 265 name string 266 data string 267 }{ 268 {"Override", "---\nInner:\n Multiple:\n File: wrong_file"}, 269 {"NoFileElement", "---\nInner:\n Multiple:\n"}, 270 } 271 272 for _, tc := range testCases { 273 t.Run(tc.name, func(t *testing.T) { 274 config := New() 275 config.SetConfigName(testConfigName) 276 277 err := config.ReadConfig(strings.NewReader(tc.data)) 278 require.NoError(t, err, "error reading config") 279 280 var uconf stringFromFileConfig 281 err = config.EnhancedExactUnmarshal(&uconf) 282 require.NoError(t, err, "failed to unmarshal") 283 require.Len(t, uconf.Inner.Multiple, 3) 284 }) 285 } 286 } 287 288 func TestStringFromFileNotSpecified(t *testing.T) { 289 yaml := "---\nInner:\n Single:\n File:\n" 290 291 config := New() 292 err := config.ReadConfig(strings.NewReader(yaml)) 293 require.NoError(t, err, "error reading config") 294 295 var uconf stringFromFileConfig 296 err = config.EnhancedExactUnmarshal(&uconf) 297 require.Error(t, err, "umarshal should fail") 298 } 299 300 func TestStringFromFileEnv(t *testing.T) { 301 expectedValue := "this is the text in the file" 302 303 file, err := ioutil.TempFile(os.TempDir(), "test") 304 require.NoError(t, err, "failed to create temp file") 305 defer os.Remove(file.Name()) 306 307 err = ioutil.WriteFile(file.Name(), []byte(expectedValue), 0o644) 308 require.NoError(t, err, "failed to write temp file") 309 310 envVar := testEnvPrefix + "_INNER_SINGLE_FILE" 311 defer os.Unsetenv(envVar) 312 os.Setenv(envVar, file.Name()) 313 314 testCases := []struct { 315 name string 316 data string 317 }{ 318 {"Override", "---\nInner:\n Single:\n File: wrong_file"}, 319 {"NoFileElement", "---\nInner:\n Single:\n"}, 320 } 321 322 for _, tc := range testCases { 323 t.Run(tc.name, func(t *testing.T) { 324 config := New() 325 config.SetConfigName(testConfigName) 326 327 err := config.ReadConfig(strings.NewReader(tc.data)) 328 require.NoError(t, err, "error reading config") 329 330 var uconf stringFromFileConfig 331 err = config.EnhancedExactUnmarshal(&uconf) 332 require.NoError(t, err, "failed to unmarshal") 333 require.Exactly(t, expectedValue, uconf.Inner.Single) 334 }) 335 } 336 } 337 338 func TestDecodeOpaqueField(t *testing.T) { 339 yaml := "---\nFoo: bar\nHello:\n World: 42\n" 340 341 config := New() 342 err := config.ReadConfig(strings.NewReader(yaml)) 343 require.NoError(t, err, "error reading config") 344 345 var conf struct { 346 Foo string 347 Hello struct{ World int } 348 } 349 err = config.EnhancedExactUnmarshal(&conf) 350 require.NoError(t, err, "failed to unmarshal") 351 require.Equal(t, "bar", conf.Foo) 352 require.Equal(t, 42, conf.Hello.World) 353 } 354 355 func TestBCCSPDecodeHookOverride(t *testing.T) { 356 yaml := "---\nBCCSP:\n Default: default-provider\n SW:\n Security: 999\n" 357 358 overrideVar := testEnvPrefix + "_BCCSP_SW_SECURITY" 359 os.Setenv(overrideVar, "1111") 360 defer os.Unsetenv(overrideVar) 361 362 config := New() 363 config.SetConfigName(testConfigName) 364 err := config.ReadConfig(strings.NewReader(yaml)) 365 require.NoError(t, err, "error reading config") 366 367 var tc struct { 368 BCCSP *factory.FactoryOpts 369 } 370 err = config.EnhancedExactUnmarshal(&tc) 371 require.NoError(t, err, "failed to unmarshal") 372 require.NotNil(t, tc.BCCSP) 373 require.NotNil(t, tc.BCCSP.SW) 374 require.Equal(t, 1111, tc.BCCSP.SW.Security) 375 } 376 377 func TestDurationDecode(t *testing.T) { 378 tests := []struct { 379 input string 380 expected time.Duration 381 }{ 382 {"", 0}, 383 {"100", 100 * time.Nanosecond}, 384 {"1s", time.Second}, 385 {"1m", time.Minute}, 386 {"1m1s", 61 * time.Second}, 387 {"90s", 90 * time.Second}, 388 } 389 for _, tt := range tests { 390 t.Run(tt.expected.String(), func(t *testing.T) { 391 yaml := fmt.Sprintf("---\nDuration: %s\n", tt.input) 392 393 config := New() 394 config.SetConfigName(testConfigName) 395 err := config.ReadConfig(strings.NewReader(yaml)) 396 require.NoError(t, err, "error reading config") 397 398 var conf struct{ Duration time.Duration } 399 err = config.EnhancedExactUnmarshal(&conf) 400 require.NoError(t, err, "failed to unmarshal") 401 require.Equal(t, tt.expected, conf.Duration) 402 }) 403 } 404 }