github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/cloudsigma/config_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloudsigma
     5  
     6  import (
     7  	"github.com/juju/schema"
     8  	gc "gopkg.in/check.v1"
     9  
    10  	"github.com/juju/juju/environs"
    11  	"github.com/juju/juju/environs/config"
    12  	"github.com/juju/juju/testing"
    13  )
    14  
    15  func newConfig(c *gc.C, attrs testing.Attrs) *config.Config {
    16  	attrs = testing.FakeConfig().Merge(attrs)
    17  	cfg, err := config.New(config.NoDefaults, attrs)
    18  	c.Assert(err, gc.IsNil)
    19  	return cfg
    20  }
    21  
    22  func validAttrs() testing.Attrs {
    23  	return testing.FakeConfig().Merge(testing.Attrs{
    24  		"type":     "cloudsigma",
    25  		"username": "user",
    26  		"password": "password",
    27  		"region":   "zrh",
    28  		"endpoint": "https://0.1.2.3:2000/api/2.0/",
    29  		"uuid":     "f54aac3a-9dcd-4a0c-86b5-24091478478c",
    30  	})
    31  }
    32  
    33  type configSuite struct {
    34  	testing.BaseSuite
    35  }
    36  
    37  func (s *configSuite) SetUpSuite(c *gc.C) {
    38  	s.BaseSuite.SetUpSuite(c)
    39  }
    40  
    41  func (s *configSuite) SetUpTest(c *gc.C) {
    42  	s.BaseSuite.SetUpTest(c)
    43  	// speed up tests, do not create heavy stuff inside providers created withing this test suite
    44  	s.PatchValue(&newClient, func(cfg *environConfig) (*environClient, error) {
    45  		return nil, nil
    46  	})
    47  }
    48  
    49  var _ = gc.Suite(&configSuite{})
    50  
    51  func (s *configSuite) TestNewModelConfig(c *gc.C) {
    52  
    53  	type checker struct {
    54  		checker gc.Checker
    55  		value   interface{}
    56  	}
    57  
    58  	var newConfigTests = []struct {
    59  		info   string
    60  		insert testing.Attrs
    61  		remove []string
    62  		expect testing.Attrs
    63  		err    string
    64  	}{{
    65  		info:   "username is required",
    66  		remove: []string{"username"},
    67  		err:    "username: must not be empty",
    68  	}, {
    69  		info:   "username cannot be empty",
    70  		insert: testing.Attrs{"username": ""},
    71  		err:    "username: must not be empty",
    72  	}, {
    73  		info:   "password is required",
    74  		remove: []string{"password"},
    75  		err:    "password: must not be empty",
    76  	}, {
    77  		info:   "password cannot be empty",
    78  		insert: testing.Attrs{"password": ""},
    79  		err:    "password: must not be empty",
    80  	}, {
    81  		info:   "region is inserted if missing",
    82  		remove: []string{"region"},
    83  		expect: testing.Attrs{"region": "zrh"},
    84  	}, {
    85  		info:   "region must not be empty",
    86  		insert: testing.Attrs{"region": ""},
    87  		err:    "region: must not be empty",
    88  	}}
    89  
    90  	for i, test := range newConfigTests {
    91  		c.Logf("test %d: %s", i, test.info)
    92  		attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
    93  		testConfig := newConfig(c, attrs)
    94  		environ, err := environs.New(testConfig)
    95  		if test.err == "" {
    96  			c.Check(err, gc.IsNil)
    97  			attrs := environ.Config().AllAttrs()
    98  			for field, value := range test.expect {
    99  				if chk, ok := value.(checker); ok {
   100  					c.Check(attrs[field], chk.checker, chk.value)
   101  				} else {
   102  					c.Check(attrs[field], gc.Equals, value)
   103  				}
   104  			}
   105  		} else {
   106  			c.Check(environ, gc.IsNil)
   107  			c.Check(err, gc.ErrorMatches, test.err)
   108  		}
   109  	}
   110  }
   111  
   112  var changeConfigTests = []struct {
   113  	info   string
   114  	insert testing.Attrs
   115  	remove []string
   116  	expect testing.Attrs
   117  	err    string
   118  }{{
   119  	info:   "no change, no error",
   120  	expect: validAttrs(),
   121  }, {
   122  	info:   "can change username",
   123  	insert: testing.Attrs{"username": "cloudsigma_user"},
   124  	expect: testing.Attrs{"username": "cloudsigma_user"},
   125  }, {
   126  	info:   "can not change username to empty",
   127  	insert: testing.Attrs{"username": ""},
   128  	err:    "username: must not be empty",
   129  }, {
   130  	info:   "can change password",
   131  	insert: testing.Attrs{"password": "cloudsigma_password"},
   132  	expect: testing.Attrs{"password": "cloudsigma_password"},
   133  }, {
   134  	info:   "can not change password to empty",
   135  	insert: testing.Attrs{"password": ""},
   136  	err:    "password: must not be empty",
   137  }, {
   138  	info:   "can change region",
   139  	insert: testing.Attrs{"region": "lvs"},
   140  	err:    "region: cannot change from .* to .*",
   141  }}
   142  
   143  func (s *configSuite) TestValidateChange(c *gc.C) {
   144  	baseConfig := newConfig(c, validAttrs())
   145  	for i, test := range changeConfigTests {
   146  		c.Logf("test %d: %s", i, test.info)
   147  		attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
   148  		testConfig := newConfig(c, attrs)
   149  		validatedConfig, err := providerInstance.Validate(testConfig, baseConfig)
   150  		if test.err == "" {
   151  			c.Check(err, gc.IsNil)
   152  			attrs := validatedConfig.AllAttrs()
   153  			for field, value := range test.expect {
   154  				c.Check(attrs[field], gc.Equals, value)
   155  			}
   156  		} else {
   157  			c.Check(validatedConfig, gc.IsNil)
   158  			c.Check(err, gc.ErrorMatches, "invalid config.*: "+test.err)
   159  		}
   160  
   161  		// reverse change
   162  		validatedConfig, err = providerInstance.Validate(baseConfig, testConfig)
   163  		if test.err == "" {
   164  			c.Check(err, gc.IsNil)
   165  			attrs := validatedConfig.AllAttrs()
   166  			for field, value := range validAttrs() {
   167  				c.Check(attrs[field], gc.Equals, value)
   168  			}
   169  		} else {
   170  			c.Check(validatedConfig, gc.IsNil)
   171  			c.Check(err, gc.ErrorMatches, "invalid .*config.*: "+test.err)
   172  		}
   173  	}
   174  }
   175  
   176  func (s *configSuite) TestSetConfig(c *gc.C) {
   177  	baseConfig := newConfig(c, validAttrs())
   178  	for i, test := range changeConfigTests {
   179  		c.Logf("test %d: %s", i, test.info)
   180  		environ, err := environs.New(baseConfig)
   181  		c.Assert(err, gc.IsNil)
   182  		attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
   183  		testConfig := newConfig(c, attrs)
   184  		err = environ.SetConfig(testConfig)
   185  		newAttrs := environ.Config().AllAttrs()
   186  		if test.err == "" {
   187  			c.Check(err, gc.IsNil)
   188  			for field, value := range test.expect {
   189  				c.Check(newAttrs[field], gc.Equals, value)
   190  			}
   191  		} else {
   192  			c.Check(err, gc.ErrorMatches, test.err)
   193  			for field, value := range baseConfig.UnknownAttrs() {
   194  				c.Check(newAttrs[field], gc.Equals, value)
   195  			}
   196  		}
   197  	}
   198  }
   199  
   200  func (s *configSuite) TestConfigName(c *gc.C) {
   201  	baseConfig := newConfig(c, validAttrs().Merge(testing.Attrs{"name": "testname"}))
   202  	environ, err := environs.New(baseConfig)
   203  	c.Assert(err, gc.IsNil)
   204  	c.Check(environ.Config().Name(), gc.Equals, "testname")
   205  }
   206  
   207  func (s *configSuite) TestModelConfig(c *gc.C) {
   208  	testConfig := newConfig(c, validAttrs())
   209  	ecfg, err := validateConfig(testConfig, nil)
   210  	c.Assert(ecfg, gc.NotNil)
   211  	c.Assert(err, gc.IsNil)
   212  	c.Check(ecfg.username(), gc.Equals, "user")
   213  	c.Check(ecfg.password(), gc.Equals, "password")
   214  	c.Check(ecfg.region(), gc.Equals, "zrh")
   215  }
   216  
   217  func (s *configSuite) TestInvalidConfigChange(c *gc.C) {
   218  	oldAttrs := validAttrs().Merge(testing.Attrs{"name": "123"})
   219  	oldConfig := newConfig(c, oldAttrs)
   220  	newAttrs := validAttrs().Merge(testing.Attrs{"name": "321"})
   221  	newConfig := newConfig(c, newAttrs)
   222  
   223  	oldecfg, _ := providerInstance.Validate(oldConfig, nil)
   224  	c.Assert(oldecfg, gc.NotNil)
   225  
   226  	newecfg, err := providerInstance.Validate(newConfig, oldecfg)
   227  	c.Assert(newecfg, gc.IsNil)
   228  	c.Assert(err, gc.NotNil)
   229  }
   230  
   231  var secretAttrsConfigTests = []struct {
   232  	info   string
   233  	insert testing.Attrs
   234  	remove []string
   235  	expect map[string]string
   236  	err    string
   237  }{{
   238  	info:   "no change, no error",
   239  	expect: map[string]string{"password": "password"},
   240  }, {
   241  	info:   "invalid config",
   242  	insert: testing.Attrs{"username": ""},
   243  	err:    ".* must not be empty.*",
   244  }}
   245  
   246  func (s *configSuite) TestSecretAttrs(c *gc.C) {
   247  	for i, test := range secretAttrsConfigTests {
   248  		c.Logf("test %d: %s", i, test.info)
   249  		attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
   250  		testConfig := newConfig(c, attrs)
   251  		sa, err := providerInstance.SecretAttrs(testConfig)
   252  		if test.err == "" {
   253  			c.Check(sa, gc.HasLen, len(test.expect))
   254  			for field, value := range test.expect {
   255  				c.Check(sa[field], gc.Equals, value)
   256  			}
   257  			c.Check(err, gc.IsNil)
   258  		} else {
   259  			c.Check(sa, gc.IsNil)
   260  			c.Check(err, gc.ErrorMatches, test.err)
   261  		}
   262  	}
   263  }
   264  
   265  func (s *configSuite) TestSecretAttrsAreStrings(c *gc.C) {
   266  	for i, field := range configSecretFields {
   267  		c.Logf("test %d: %s", i, field)
   268  		attrs := validAttrs().Merge(testing.Attrs{field: 0})
   269  
   270  		if v, ok := configFields[field]; ok {
   271  			configFields[field] = schema.ForceInt()
   272  			defer func(c schema.Checker) {
   273  				configFields[field] = c
   274  			}(v)
   275  		} else {
   276  			c.Errorf("secrect field %s not found in configFields", field)
   277  			continue
   278  		}
   279  
   280  		testConfig := newConfig(c, attrs)
   281  		sa, err := providerInstance.SecretAttrs(testConfig)
   282  		c.Check(sa, gc.IsNil)
   283  		c.Check(err, gc.ErrorMatches, "secret .* field must have a string value; got .*")
   284  	}
   285  }
   286  
   287  func (s *configSuite) TestClientConfigChanged(c *gc.C) {
   288  	ecfg := &environConfig{
   289  		Config: newConfig(c, testing.Attrs{"name": "client-test"}),
   290  		attrs: map[string]interface{}{
   291  			"region":   "https://testing.invalid",
   292  			"username": "user",
   293  			"password": "password",
   294  		},
   295  	}
   296  
   297  	oldConfig := &environConfig{
   298  		Config: newConfig(c, testing.Attrs{"name": "client-test"}),
   299  		attrs: map[string]interface{}{
   300  			"region":   "https://testing.invalid",
   301  			"username": "user",
   302  			"password": "password",
   303  		},
   304  	}
   305  
   306  	rc := oldConfig.clientConfigChanged(ecfg)
   307  	c.Check(rc, gc.Equals, false)
   308  
   309  	ecfg.attrs["region"] = ""
   310  	rc = oldConfig.clientConfigChanged(ecfg)
   311  	c.Check(rc, gc.Equals, true)
   312  
   313  	ecfg.attrs["region"] = "https://testing.invalid"
   314  	ecfg.attrs["username"] = "user1"
   315  	rc = oldConfig.clientConfigChanged(ecfg)
   316  	c.Check(rc, gc.Equals, true)
   317  
   318  	ecfg.attrs["username"] = "user"
   319  	ecfg.attrs["password"] = "password1"
   320  	rc = oldConfig.clientConfigChanged(ecfg)
   321  	c.Check(rc, gc.Equals, true)
   322  }