github.com/elfadel/cilium@v1.6.12/pkg/option/option_test.go (about) 1 // Copyright 2016-2017 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package option 18 19 import ( 20 "fmt" 21 "testing" 22 23 "github.com/cilium/cilium/api/v1/models" 24 "github.com/cilium/cilium/pkg/checker" 25 26 . "gopkg.in/check.v1" 27 ) 28 29 // Hook up gocheck into the "go test" runner. 30 func Test(t *testing.T) { 31 TestingT(t) 32 } 33 34 type OptionSuite struct{} 35 36 var _ = Suite(&OptionSuite{}) 37 38 func (s *OptionSuite) TestGetValue(c *C) { 39 k1, k2 := "foo", "bar" 40 v1 := OptionSetting(7) 41 42 o := IntOptions{ 43 Opts: OptionMap{ 44 k1: v1, 45 k2: OptionEnabled, 46 }, 47 } 48 49 c.Assert(o.GetValue(k1), Equals, v1) 50 c.Assert(o.GetValue(k2), Equals, OptionEnabled) 51 c.Assert(o.GetValue("unknown"), Equals, OptionDisabled) 52 } 53 54 func (s *OptionSuite) TestIsEnabled(c *C) { 55 k1, k2 := "foo", "bar" 56 57 o := IntOptions{ 58 Opts: OptionMap{ 59 k1: OptionEnabled, 60 k2: OptionDisabled, 61 }, 62 } 63 64 c.Assert(o.IsEnabled(k1), Equals, true) 65 c.Assert(o.IsEnabled(k2), Equals, false) 66 c.Assert(o.IsEnabled("unknown"), Equals, false) 67 } 68 69 func (s *OptionSuite) TestSetValidated(c *C) { 70 k1, k2 := "foo", "bar" 71 72 o := IntOptions{ 73 Opts: OptionMap{ 74 k1: OptionEnabled, 75 }, 76 } 77 78 c.Assert(o.IsEnabled(k1), Equals, true) 79 c.Assert(o.IsEnabled(k2), Equals, false) 80 81 o.SetValidated(k1, OptionDisabled) 82 o.SetValidated(k2, OptionEnabled) 83 c.Assert(o.IsEnabled(k1), Equals, false) 84 c.Assert(o.IsEnabled(k2), Equals, true) 85 } 86 87 func (s *OptionSuite) TestSetBool(c *C) { 88 k1, k2, k3 := "foo", "bar", "baz" 89 90 o := IntOptions{ 91 Opts: OptionMap{ 92 k1: OptionEnabled, 93 k2: OptionDisabled, 94 }, 95 } 96 97 o.SetBool(k1, false) 98 o.SetBool(k2, true) 99 o.SetBool(k3, true) 100 c.Assert(o.GetValue(k1), Equals, OptionDisabled) 101 c.Assert(o.GetValue(k2), Equals, OptionEnabled) 102 c.Assert(o.GetValue(k3), Equals, OptionEnabled) 103 } 104 105 func (s *OptionSuite) TestDelete(c *C) { 106 k1, k2 := "foo", "bar" 107 108 o := IntOptions{ 109 Opts: OptionMap{ 110 k1: OptionEnabled, 111 k2: OptionEnabled, 112 }, 113 } 114 115 o.Delete(k1) 116 c.Assert(o.GetValue(k1), Equals, OptionDisabled) 117 c.Assert(o.GetValue(k2), Equals, OptionEnabled) 118 } 119 120 func (s *OptionSuite) TestSetIfUnset(c *C) { 121 k1, k2 := "foo", "bar" 122 123 o := IntOptions{ 124 Opts: OptionMap{ 125 k1: OptionDisabled, 126 }, 127 } 128 129 o.SetIfUnset(k1, OptionEnabled) 130 o.SetIfUnset(k2, OptionEnabled) 131 c.Assert(o.GetValue(k1), Equals, OptionDisabled) 132 c.Assert(o.GetValue(k2), Equals, OptionEnabled) 133 } 134 135 func (s *OptionSuite) TestInheritDefault(c *C) { 136 k := "foo" 137 138 o := IntOptions{ 139 Opts: OptionMap{}, 140 } 141 parent := IntOptions{ 142 Opts: OptionMap{ 143 k: OptionEnabled, 144 }, 145 } 146 147 c.Assert(o.GetValue(k), Equals, OptionDisabled) 148 o.InheritDefault(&parent, k) 149 c.Assert(o.GetValue(k), Equals, OptionEnabled) 150 } 151 152 func (s *OptionSuite) TestParseKeyValueWithDefaultParseFunc(c *C) { 153 k := "foo" 154 155 l := OptionLibrary{ 156 k: &Option{ 157 Define: "TEST_DEFINE", 158 Description: "This is a test", 159 }, 160 } 161 162 _, res, err := ParseKeyValue(&l, k, "on") 163 c.Assert(err, IsNil) 164 c.Assert(res, Equals, OptionEnabled) 165 } 166 167 func (s *OptionSuite) TestParseKeyValue(c *C) { 168 k := "foo" 169 170 l := OptionLibrary{ 171 k: &Option{ 172 Define: "TEST_DEFINE", 173 Description: "This is a test", 174 Parse: func(value string) (OptionSetting, error) { 175 if value == "yes" { 176 return OptionEnabled, nil 177 } 178 return OptionDisabled, fmt.Errorf("invalid option value %s", value) 179 }, 180 }, 181 } 182 183 _, _, err := ParseKeyValue(&l, k, "true") 184 c.Assert(err, NotNil) 185 186 _, res, err := ParseKeyValue(&l, k, "yes") 187 c.Assert(err, IsNil) 188 c.Assert(res, Equals, OptionEnabled) 189 190 _, _, err = ParseKeyValue(&l, "unknown", "yes") 191 c.Assert(err, NotNil) 192 } 193 194 func (s *OptionSuite) TestParseOption(c *C) { 195 k := "foo" 196 arg := k + "=enabled" 197 198 OptionTest := Option{ 199 Define: "TEST_DEFINE", 200 Description: "This is a test", 201 } 202 203 l := OptionLibrary{ 204 k: &OptionTest, 205 } 206 207 _, _, err := ParseOption(k+":enabled", &l) 208 c.Assert(err, NotNil) 209 210 _, res, err := ParseOption(arg, &l) 211 c.Assert(err, IsNil) 212 c.Assert(res, Equals, OptionEnabled) 213 214 _, _, err = ParseOption("!"+arg, &l) 215 c.Assert(err, NotNil) 216 217 OptionTest.Immutable = true 218 _, _, err = ParseOption(arg, &l) 219 c.Assert(err, NotNil) 220 OptionTest.Immutable = false 221 } 222 223 func (s *OptionSuite) TestGetFmtOpts(c *C) { 224 OptionTest := Option{ 225 Define: "TEST_DEFINE", 226 Description: "This is a test", 227 } 228 229 o := IntOptions{ 230 Opts: OptionMap{ 231 "test": OptionEnabled, 232 "BAR": OptionDisabled, 233 "foo": OptionEnabled, 234 "bar": OptionDisabled, 235 }, 236 Library: &OptionLibrary{ 237 "test": &OptionTest, 238 }, 239 } 240 241 fmtList := o.GetFmtList() 242 fmtList2 := o.GetFmtList() 243 244 // Both strings should be equal because the formatted options should be sorted. 245 c.Assert(fmtList, Equals, fmtList2) 246 247 o2 := IntOptions{ 248 Opts: OptionMap{ 249 "foo": OptionEnabled, 250 "BAR": OptionDisabled, 251 "bar": OptionDisabled, 252 "test": OptionEnabled, 253 }, 254 Library: &OptionLibrary{ 255 "test": &OptionTest, 256 }, 257 } 258 259 fmtListO := o.GetFmtList() 260 fmtListO2 := o2.GetFmtList() 261 262 // Both strings should be equal because the formatted options should be sorted. 263 c.Assert(fmtListO, Equals, fmtListO2) 264 } 265 266 func (s *OptionSuite) TestGetFmtOpt(c *C) { 267 OptionTest := Option{ 268 Define: "TEST_DEFINE", 269 Description: "This is a test", 270 } 271 272 o := IntOptions{ 273 Opts: OptionMap{ 274 "test": OptionEnabled, 275 "BAR": OptionDisabled, 276 "alice": 2, 277 }, 278 Library: &OptionLibrary{ 279 "test": &OptionTest, 280 "alice": &OptionTest, 281 }, 282 } 283 o.optsMU.Lock() 284 c.Assert(o.getFmtOpt("test"), Equals, "#define TEST_DEFINE 1") 285 c.Assert(o.getFmtOpt("BAR"), Equals, "#undef BAR") 286 c.Assert(o.getFmtOpt("BAZ"), Equals, "#undef BAZ") 287 c.Assert(o.getFmtOpt("alice"), Equals, "#define TEST_DEFINE 2") 288 o.optsMU.Unlock() 289 } 290 291 func (s *OptionSuite) TestGetImmutableModel(c *C) { 292 k := "foo" 293 294 OptionTest := Option{ 295 Define: "TEST_DEFINE", 296 Description: "This is a test", 297 } 298 299 o := IntOptions{ 300 Opts: OptionMap{ 301 k: OptionEnabled, 302 }, 303 Library: &OptionLibrary{ 304 k: &OptionTest, 305 }, 306 } 307 308 cfg := o.GetImmutableModel() 309 c.Assert(cfg, NotNil) 310 c.Assert(cfg, checker.DeepEquals, &models.ConfigurationMap{}) 311 } 312 313 func (s *OptionSuite) TestGetMutableModel(c *C) { 314 k1, k2, k3 := "foo", "bar", "baz" 315 316 OptionDefaultFormat := Option{ 317 Define: "TEST_DEFINE", 318 Description: "This is a test", 319 } 320 OptionCustomFormat := Option{ 321 Define: "TEST_DEFINE", 322 Description: "This is a test", 323 Format: func(value OptionSetting) string { 324 return "ok" 325 }, 326 } 327 328 o := IntOptions{ 329 Opts: OptionMap{ 330 k1: OptionEnabled, 331 k2: OptionDisabled, 332 k3: OptionEnabled, 333 }, 334 Library: &OptionLibrary{ 335 k1: &OptionDefaultFormat, 336 k2: &OptionDefaultFormat, 337 k3: &OptionCustomFormat, 338 }, 339 } 340 341 cfg := o.GetMutableModel() 342 c.Assert(cfg, NotNil) 343 c.Assert(cfg, checker.DeepEquals, &models.ConfigurationMap{ 344 k1: "Enabled", 345 k2: "Disabled", 346 k3: "ok", 347 }) 348 349 o2 := IntOptions{} 350 cfg2 := o2.GetMutableModel() 351 c.Assert(cfg2, NotNil) 352 c.Assert(cfg2, checker.DeepEquals, &models.ConfigurationMap{}) 353 } 354 355 func (s *OptionSuite) TestValidate(c *C) { 356 k1, k2, k3, k4 := "foo", "bar", "baz", "qux" 357 358 OptionTest := Option{ 359 Define: "TEST_DEFINE", 360 Description: "This is a test", 361 } 362 OptionCustomVerify := Option{ 363 Define: "TEST_DEFINE", 364 Description: "This is a test", 365 Verify: func(key string, value string) error { 366 return fmt.Errorf("invalid key value %s %s", key, value) 367 368 }, 369 } 370 OptionImmutable := Option{ 371 Define: "TEST_DEFINE", 372 Description: "This is a test", 373 Immutable: true, 374 } 375 376 o := IntOptions{ 377 Opts: OptionMap{ 378 k1: OptionEnabled, 379 k2: OptionEnabled, 380 k3: OptionDisabled, 381 k4: OptionEnabled, 382 }, 383 Library: &OptionLibrary{ 384 k1: &OptionTest, 385 k2: &OptionCustomVerify, 386 k3: &OptionCustomVerify, 387 k4: &OptionImmutable, 388 }, 389 } 390 391 c.Assert(o.Validate(models.ConfigurationMap{k1: "on"}), IsNil) 392 c.Assert(o.Validate(models.ConfigurationMap{"unknown": "on"}), NotNil) 393 c.Assert(o.Validate(models.ConfigurationMap{k4: "on"}), NotNil) 394 c.Assert(o.Validate(models.ConfigurationMap{k1: "on", k2: "on"}), IsNil) 395 c.Assert(o.Validate(models.ConfigurationMap{k1: "on", k3: "on"}), NotNil) 396 } 397 398 func (s *OptionSuite) TestApplyValidated(c *C) { 399 k1, k2, k3, k4, k5, k6 := "foo", "bar", "baz", "qux", "quux", "corge" 400 401 OptionDefault := Option{ 402 Define: "TEST_DEFINE", 403 Description: "This is a test", 404 } 405 Option2 := Option{ 406 Define: "TEST_DEFINE", 407 Description: "This is a test", 408 Requires: []string{k1}, 409 } 410 Option3 := Option{ 411 Define: "TEST_DEFINE", 412 Description: "This is a test", 413 Requires: []string{k4}, 414 } 415 416 o := IntOptions{ 417 Opts: OptionMap{ 418 k1: OptionEnabled, 419 k2: OptionEnabled, 420 k3: OptionDisabled, 421 k4: OptionDisabled, 422 k5: OptionDisabled, 423 }, 424 Library: &OptionLibrary{ 425 k1: &OptionDefault, 426 k2: &Option2, 427 k3: &Option3, 428 k4: &OptionDefault, 429 k5: &OptionDefault, 430 k6: &OptionDefault, 431 }, 432 } 433 434 cfg := models.ConfigurationMap{ 435 k1: "off", 436 k3: "on", 437 k5: "off", 438 k6: "on", 439 } 440 c.Assert(o.Validate(cfg), IsNil) 441 442 expectedChanges := OptionMap{ 443 k1: OptionDisabled, 444 k3: OptionEnabled, 445 k6: OptionEnabled, 446 } 447 actualChanges := OptionMap{} 448 var changed ChangedFunc = func(key string, value OptionSetting, data interface{}) { 449 c.Assert(data, Equals, &cfg) 450 actualChanges[key] = value 451 } 452 453 om, err := o.Library.ValidateConfigurationMap(cfg) 454 c.Assert(err, IsNil) 455 c.Assert(o.ApplyValidated(om, changed, &cfg), Equals, len(expectedChanges)) 456 c.Assert(actualChanges, checker.DeepEquals, expectedChanges) 457 458 expectedOpts := OptionMap{ 459 k1: OptionDisabled, 460 k2: OptionDisabled, 461 k3: OptionEnabled, 462 k4: OptionEnabled, 463 k5: OptionDisabled, 464 k6: OptionEnabled, 465 } 466 for k, v := range expectedOpts { 467 c.Assert(o.GetValue(k), Equals, v) 468 } 469 }