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  }