pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/knf/knf_test.go (about) 1 package knf 2 3 // ////////////////////////////////////////////////////////////////////////////////// // 4 // // 5 // Copyright (c) 2022 ESSENTIAL KAOS // 6 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 7 // // 8 // ////////////////////////////////////////////////////////////////////////////////// // 9 10 import ( 11 "fmt" 12 "io/ioutil" 13 "os" 14 "strings" 15 "sync" 16 "testing" 17 "time" 18 19 check "pkg.re/essentialkaos/check.v1" 20 ) 21 22 // ////////////////////////////////////////////////////////////////////////////////// // 23 24 const _CONFIG_DATA = ` 25 [formating] 26 test1: 1 27 test2:2 28 29 test3: 3 30 31 [string] 32 test1: test 33 test2: true 34 test3: 4500 35 test4: !$%^& 36 test5: long long long long text for test 37 test6: 38 39 [boolean] 40 test1: true 41 test2: false 42 test3: 0 43 test4: 1 44 test5: 45 test6: example for test 46 test7: no 47 48 [integer] 49 test1: 1 50 test2: -5 51 test3: 10000000 52 test4: A 53 test5: 0xFF 54 test6: 123.4 55 test7: 123.456789 56 test8: 0xZZYY 57 test9: ABCD 58 59 [file-mode] 60 test1: 644 61 test2: 0644 62 test3: 0 63 test4: ABC 64 test5: true 65 66 [duration] 67 test1: 0 68 test2: 60 69 test3: ABC 70 test4: true 71 72 [comment] 73 test1: 100 74 # test2: 100 75 76 [macro] 77 test1: 100 78 test2: {macro:test1}.50 79 test3: Value is {macro:test2} 80 test4: "{macro:test3}" 81 test5: {ABC} 82 test6: {} 83 84 [k] 85 t: 1 86 ` 87 88 const _CONFIG_MALF_DATA = ` 89 test1: 123 90 test2: 111 91 ` 92 93 const ( 94 _CONFIG_FILE_NAME = "knf-config-test.conf" 95 _CONFIG_EMPTY_FILE_NAME = "knf-config-test-empty.conf" 96 _CONFIG_MALFORMED_FILE_NAME = "knf-config-test-malf.conf" 97 ) 98 99 // ////////////////////////////////////////////////////////////////////////////////// // 100 101 type KNFSuite struct { 102 ConfigPath string 103 EmptyConfigPath string 104 MalformedConfigPath string 105 NonReadableConfigPath string 106 } 107 108 // ////////////////////////////////////////////////////////////////////////////////// // 109 110 var _ = check.Suite(&KNFSuite{}) 111 112 // ////////////////////////////////////////////////////////////////////////////////// // 113 114 func Test(t *testing.T) { 115 check.TestingT(t) 116 } 117 118 // ////////////////////////////////////////////////////////////////////////////////// // 119 120 func (s *KNFSuite) SetUpSuite(c *check.C) { 121 tmpdir := c.MkDir() 122 123 s.ConfigPath = tmpdir + "/" + _CONFIG_FILE_NAME 124 s.EmptyConfigPath = tmpdir + "/" + _CONFIG_EMPTY_FILE_NAME 125 s.MalformedConfigPath = tmpdir + "/" + _CONFIG_MALFORMED_FILE_NAME 126 s.NonReadableConfigPath = "/etc/sudoers" 127 128 err := ioutil.WriteFile(s.ConfigPath, []byte(_CONFIG_DATA), 0644) 129 130 if err != nil { 131 c.Fatal(err.Error()) 132 } 133 134 err = ioutil.WriteFile(s.EmptyConfigPath, []byte(""), 0644) 135 136 if err != nil { 137 c.Fatal(err.Error()) 138 } 139 140 err = ioutil.WriteFile(s.MalformedConfigPath, []byte(_CONFIG_MALF_DATA), 0644) 141 142 if err != nil { 143 c.Fatal(err.Error()) 144 } 145 } 146 147 func (s *KNFSuite) TestErrors(c *check.C) { 148 global = nil 149 150 err := Global("/_not_exists_") 151 c.Assert(err, check.NotNil) 152 153 err = Global(s.EmptyConfigPath) 154 c.Assert(err, check.NotNil) 155 156 err = Global(s.NonReadableConfigPath) 157 c.Assert(err, check.NotNil) 158 159 err = Global(s.MalformedConfigPath) 160 161 c.Assert(err, check.NotNil) 162 c.Assert(err.Error(), check.Equals, "Error at line 2: Data defined before section") 163 164 updated, err := Reload() 165 166 c.Assert(err, check.NotNil) 167 c.Assert(err, check.DeepEquals, ErrConfigIsNil) 168 c.Assert(updated, check.IsNil) 169 170 c.Assert(GetS("test"), check.Equals, "") 171 c.Assert(GetI("test"), check.Equals, 0) 172 c.Assert(GetI("test"), check.Equals, 0) 173 c.Assert(GetU("test"), check.Equals, uint(0)) 174 c.Assert(GetI64("test"), check.Equals, int64(0)) 175 c.Assert(GetU64("test"), check.Equals, uint64(0)) 176 c.Assert(GetF("test"), check.Equals, 0.0) 177 c.Assert(GetB("test"), check.Equals, false) 178 c.Assert(GetM("test"), check.Equals, os.FileMode(0)) 179 c.Assert(GetD("test"), check.Equals, time.Duration(0)) 180 c.Assert(HasSection("test"), check.Equals, false) 181 c.Assert(HasProp("test"), check.Equals, false) 182 c.Assert(Sections(), check.HasLen, 0) 183 c.Assert(Props("test"), check.HasLen, 0) 184 c.Assert(Validate([]*Validator{}), check.DeepEquals, []error{ErrConfigIsNil}) 185 186 config := &Config{mx: &sync.RWMutex{}} 187 188 c.Assert(config.GetS("test"), check.Equals, "") 189 c.Assert(config.GetI("test"), check.Equals, 0) 190 c.Assert(config.GetF("test"), check.Equals, 0.0) 191 c.Assert(config.GetB("test"), check.Equals, false) 192 c.Assert(config.GetM("test"), check.Equals, os.FileMode(0)) 193 c.Assert(config.GetD("test"), check.Equals, time.Duration(0)) 194 c.Assert(config.HasSection("test"), check.Equals, false) 195 c.Assert(config.HasProp("test"), check.Equals, false) 196 c.Assert(config.Sections(), check.HasLen, 0) 197 c.Assert(config.Props("test"), check.HasLen, 0) 198 c.Assert(config.Validate([]*Validator{}), check.HasLen, 0) 199 200 updated, err = config.Reload() 201 202 c.Assert(updated, check.IsNil) 203 c.Assert(err, check.NotNil) 204 c.Assert(err, check.DeepEquals, ErrFileNotSet) 205 206 config = &Config{file: "/_not_exists_", mx: &sync.RWMutex{}} 207 208 updated, err = config.Reload() 209 210 c.Assert(updated, check.IsNil) 211 c.Assert(err, check.NotNil) 212 } 213 214 func (s *KNFSuite) TestParsing(c *check.C) { 215 err := Global(s.ConfigPath) 216 217 c.Assert(err, check.IsNil) 218 219 _, err = Reload() 220 221 c.Assert(err, check.IsNil) 222 } 223 224 func (s *KNFSuite) TestSections(c *check.C) { 225 var err error 226 227 err = Global(s.ConfigPath) 228 229 c.Assert(global, check.NotNil) 230 c.Assert(err, check.IsNil) 231 232 sections := Sections() 233 234 c.Assert(sections, check.HasLen, 9) 235 c.Assert( 236 sections, 237 check.DeepEquals, 238 []string{ 239 "formating", 240 "string", 241 "boolean", 242 "integer", 243 "file-mode", 244 "duration", 245 "comment", 246 "macro", 247 "k", 248 }, 249 ) 250 } 251 252 func (s *KNFSuite) TestProps(c *check.C) { 253 var err error 254 255 err = Global(s.ConfigPath) 256 257 c.Assert(global, check.NotNil) 258 c.Assert(err, check.IsNil) 259 260 props := Props("file-mode") 261 262 c.Assert(props, check.HasLen, 5) 263 c.Assert( 264 props, 265 check.DeepEquals, 266 []string{"test1", "test2", "test3", "test4", "test5"}, 267 ) 268 } 269 270 func (s *KNFSuite) TestCheckers(c *check.C) { 271 var err error 272 273 err = Global(s.ConfigPath) 274 275 c.Assert(global, check.NotNil) 276 c.Assert(err, check.IsNil) 277 278 c.Assert(HasSection("string"), check.Equals, true) 279 c.Assert(HasSection("strings"), check.Equals, false) 280 281 c.Assert(HasProp("string:test1"), check.Equals, true) 282 c.Assert(HasProp("string:test6"), check.Equals, false) 283 c.Assert(HasProp("strings:test6"), check.Equals, false) 284 } 285 286 func (s *KNFSuite) TestFormating(c *check.C) { 287 var err error 288 289 err = Global(s.ConfigPath) 290 291 c.Assert(global, check.NotNil) 292 c.Assert(err, check.IsNil) 293 294 c.Assert(GetI("formating:test1"), check.Equals, 1) 295 c.Assert(GetI("formating:test2"), check.Equals, 2) 296 c.Assert(GetI("formating:test3"), check.Equals, 3) 297 } 298 299 func (s *KNFSuite) TestStrings(c *check.C) { 300 var err error 301 302 err = Global(s.ConfigPath) 303 304 c.Assert(global, check.NotNil) 305 c.Assert(err, check.IsNil) 306 307 c.Assert(GetS("string:test1"), check.Equals, "test") 308 c.Assert(GetS("string:test2"), check.Equals, "true") 309 c.Assert(GetS("string:test3"), check.Equals, "4500") 310 c.Assert(GetS("string:test4"), check.Equals, "!$%^&") 311 c.Assert(GetS("string:test5"), check.Equals, "long long long long text for test") 312 } 313 314 func (s *KNFSuite) TestBoolean(c *check.C) { 315 var err error 316 317 err = Global(s.ConfigPath) 318 319 c.Assert(global, check.NotNil) 320 c.Assert(err, check.IsNil) 321 322 c.Assert(GetB("boolean:test1"), check.Equals, true) 323 c.Assert(GetB("boolean:test2"), check.Equals, false) 324 c.Assert(GetB("boolean:test3"), check.Equals, false) 325 c.Assert(GetB("boolean:test4"), check.Equals, true) 326 c.Assert(GetB("boolean:test5"), check.Equals, false) 327 c.Assert(GetB("boolean:test6"), check.Equals, true) 328 c.Assert(GetB("boolean:test7"), check.Equals, false) 329 } 330 331 func (s *KNFSuite) TestInteger(c *check.C) { 332 var err error 333 334 err = Global(s.ConfigPath) 335 336 c.Assert(global, check.NotNil) 337 c.Assert(err, check.IsNil) 338 339 c.Assert(GetI("integer:test1"), check.Equals, 1) 340 c.Assert(GetI("integer:test2"), check.Equals, -5) 341 c.Assert(GetI("integer:test3"), check.Equals, 10000000) 342 c.Assert(GetI("integer:test4"), check.Equals, 0) 343 c.Assert(GetI("integer:test5"), check.Equals, 0xFF) 344 c.Assert(GetF("integer:test6"), check.Equals, 123.4) 345 c.Assert(GetF("integer:test7"), check.Equals, 123.456789) 346 c.Assert(GetF("integer:test8"), check.Equals, 0.0) 347 c.Assert(GetI("integer:test8"), check.Equals, 0) 348 c.Assert(GetF("integer:test9"), check.Equals, 0.0) 349 350 c.Assert(GetU("integer:test1"), check.Equals, uint(1)) 351 c.Assert(GetI64("integer:test1"), check.Equals, int64(1)) 352 c.Assert(GetU64("integer:test1"), check.Equals, uint64(1)) 353 } 354 355 func (s *KNFSuite) TestFileMode(c *check.C) { 356 var err error 357 358 err = Global(s.ConfigPath) 359 360 c.Assert(global, check.NotNil) 361 c.Assert(err, check.IsNil) 362 363 c.Assert(GetM("file-mode:test1"), check.Equals, os.FileMode(0644)) 364 c.Assert(GetM("file-mode:test2"), check.Equals, os.FileMode(0644)) 365 c.Assert(GetM("file-mode:test3"), check.Equals, os.FileMode(0)) 366 c.Assert(GetM("file-mode:test4"), check.Equals, os.FileMode(0)) 367 c.Assert(GetM("file-mode:test5"), check.Equals, os.FileMode(0)) 368 } 369 370 func (s *KNFSuite) TestDuration(c *check.C) { 371 var err error 372 373 err = Global(s.ConfigPath) 374 375 c.Assert(global, check.NotNil) 376 c.Assert(err, check.IsNil) 377 378 c.Assert(GetD("duration:test1"), check.Equals, time.Duration(0)) 379 c.Assert(GetD("duration:test2"), check.Equals, time.Minute) 380 c.Assert(GetD("duration:test3"), check.Equals, time.Duration(0)) 381 c.Assert(GetD("duration:test4"), check.Equals, time.Duration(0)) 382 } 383 384 func (s *KNFSuite) TestComments(c *check.C) { 385 var err error 386 387 err = Global(s.ConfigPath) 388 389 c.Assert(global, check.NotNil) 390 c.Assert(err, check.IsNil) 391 392 c.Assert(GetI("comment:test1"), check.Equals, 100) 393 c.Assert(GetI("comment:test2"), check.Not(check.Equals), 100) 394 c.Assert(HasProp("comment:test2"), check.Equals, false) 395 } 396 397 func (s *KNFSuite) TestMacro(c *check.C) { 398 var err error 399 400 err = Global(s.ConfigPath) 401 402 c.Assert(global, check.NotNil) 403 c.Assert(err, check.IsNil) 404 405 c.Assert(GetS("macro:test1"), check.Equals, "100") 406 c.Assert(GetI("macro:test1"), check.Equals, 100) 407 c.Assert(GetS("macro:test2"), check.Equals, "100.50") 408 c.Assert(GetS("macro:test3"), check.Equals, "Value is 100.50") 409 c.Assert(GetS("macro:test4"), check.Equals, "\"Value is 100.50\"") 410 c.Assert(GetS("macro:test5"), check.Equals, "{ABC}") 411 c.Assert(GetS("macro:test6"), check.Equals, "{}") 412 } 413 414 func (s *KNFSuite) TestNil(c *check.C) { 415 var nilConf *Config 416 417 c.Assert(nilConf.GetS("formating:test1"), check.Equals, "") 418 c.Assert(nilConf.GetI("formating:test1"), check.Equals, 0) 419 c.Assert(nilConf.GetF("formating:test1"), check.Equals, 0.0) 420 c.Assert(nilConf.GetB("formating:test1"), check.Equals, false) 421 c.Assert(nilConf.GetM("formating:test1"), check.Equals, os.FileMode(0)) 422 c.Assert(nilConf.GetD("formating:test1"), check.Equals, time.Duration(0)) 423 c.Assert(nilConf.HasSection("formating"), check.Equals, false) 424 c.Assert(nilConf.HasProp("formating:test1"), check.Equals, false) 425 c.Assert(nilConf.Sections(), check.HasLen, 0) 426 c.Assert(nilConf.Props("formating"), check.HasLen, 0) 427 428 _, err := nilConf.Reload() 429 430 c.Assert(err, check.NotNil) 431 c.Assert(err, check.DeepEquals, ErrConfigIsNil) 432 433 errs := nilConf.Validate([]*Validator{}) 434 435 c.Assert(errs, check.Not(check.HasLen), 0) 436 c.Assert(errs, check.DeepEquals, []error{ErrConfigIsNil}) 437 } 438 439 func (s *KNFSuite) TestDefault(c *check.C) { 440 var err error 441 442 global = nil 443 444 c.Assert(GetS("string:test100", "fail"), check.Equals, "fail") 445 c.Assert(GetB("boolean:test100", true), check.Equals, true) 446 c.Assert(GetI("integer:test100", 9999), check.Equals, 9999) 447 c.Assert(GetU("integer:test100", 9999), check.Equals, uint(9999)) 448 c.Assert(GetI64("integer:test100", 9999), check.Equals, int64(9999)) 449 c.Assert(GetU64("integer:test100", 9999), check.Equals, uint64(9999)) 450 c.Assert(GetF("integer:test100", 123.45), check.Equals, 123.45) 451 c.Assert(GetM("file-mode:test100", 0755), check.Equals, os.FileMode(0755)) 452 c.Assert(GetD("duration:test100", time.Minute), check.Equals, time.Minute) 453 c.Assert(GetS("string:test6", "fail"), check.Equals, "fail") 454 455 err = Global(s.ConfigPath) 456 457 c.Assert(global, check.NotNil) 458 c.Assert(err, check.IsNil) 459 460 c.Assert(GetS("string:test100", "fail"), check.Equals, "fail") 461 c.Assert(GetB("boolean:test100", true), check.Equals, true) 462 c.Assert(GetI("integer:test100", 9999), check.Equals, 9999) 463 c.Assert(GetU("integer:test100", 9999), check.Equals, uint(9999)) 464 c.Assert(GetI64("integer:test100", 9999), check.Equals, int64(9999)) 465 c.Assert(GetU64("integer:test100", 9999), check.Equals, uint64(9999)) 466 c.Assert(GetF("integer:test100", 123.45), check.Equals, 123.45) 467 c.Assert(GetM("file-mode:test100", 0755), check.Equals, os.FileMode(0755)) 468 c.Assert(GetD("duration:test100", time.Minute), check.Equals, time.Minute) 469 c.Assert(GetS("string:test6", "fail"), check.Equals, "fail") 470 471 var nc *Config 472 473 c.Assert(nc.GetS("string:test100", "fail"), check.Equals, "fail") 474 c.Assert(nc.GetB("boolean:test100", true), check.Equals, true) 475 c.Assert(nc.GetI("integer:test100", 9999), check.Equals, 9999) 476 c.Assert(nc.GetU("integer:test100", 9999), check.Equals, uint(9999)) 477 c.Assert(nc.GetI64("integer:test100", 9999), check.Equals, int64(9999)) 478 c.Assert(nc.GetU64("integer:test100", 9999), check.Equals, uint64(9999)) 479 c.Assert(nc.GetF("integer:test100", 123.45), check.Equals, 123.45) 480 c.Assert(nc.GetM("file-mode:test100", 0755), check.Equals, os.FileMode(0755)) 481 c.Assert(nc.GetD("duration:test100", time.Minute), check.Equals, time.Minute) 482 c.Assert(nc.GetS("string:test6", "fail"), check.Equals, "fail") 483 } 484 485 func (s *KNFSuite) TestSimpleValidator(c *check.C) { 486 err := Global(s.ConfigPath) 487 488 c.Assert(global, check.NotNil) 489 c.Assert(err, check.IsNil) 490 491 var simpleValidator = func(config *Config, prop string, value interface{}) error { 492 if prop == "string:test2" { 493 return fmt.Errorf("ERROR") 494 } 495 496 return nil 497 } 498 499 errs := Validate([]*Validator{ 500 {"string:test2", simpleValidator, nil}, 501 }) 502 503 c.Assert(errs, check.HasLen, 1) 504 } 505 506 func (s *KNFSuite) TestKNFParserExceptions(c *check.C) { 507 r := strings.NewReader(` 508 [section] 509 ABCD 510 `) 511 512 _, err := readKNFData(r) 513 c.Assert(err.Error(), check.Equals, "Error at line 3: Property must have \":\" as a delimiter") 514 515 r = strings.NewReader(` 516 [section] 517 A: 1 518 A: 2 519 `) 520 521 _, err = readKNFData(r) 522 c.Assert(err.Error(), check.Equals, "Error at line 4: Property \"A\" defined more than once") 523 524 r = strings.NewReader(` 525 [section] 526 A: {abcd:test} 527 `) 528 529 _, err = readKNFData(r) 530 c.Assert(err.Error(), check.Equals, "Error at line 3: Unknown property {abcd:test}") 531 }