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

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package gce_test
     5  
     6  import (
     7  	jc "github.com/juju/testing/checkers"
     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/provider/gce"
    13  	"github.com/juju/juju/testing"
    14  )
    15  
    16  type ConfigSuite struct {
    17  	gce.BaseSuite
    18  
    19  	config *config.Config
    20  }
    21  
    22  var _ = gc.Suite(&ConfigSuite{})
    23  
    24  func (s *ConfigSuite) SetUpTest(c *gc.C) {
    25  	s.BaseSuite.SetUpTest(c)
    26  
    27  	cfg, err := testing.ModelConfig(c).Apply(gce.ConfigAttrs)
    28  	c.Assert(err, jc.ErrorIsNil)
    29  	s.config = cfg
    30  }
    31  
    32  // TODO(ericsnow) Each test only deals with a single field, so having
    33  // multiple values in insert and remove (in configTestSpec) is a little
    34  // misleading and unecessary.
    35  
    36  // configTestSpec defines a subtest to run in a table driven test.
    37  type configTestSpec struct {
    38  	// info describes the subtest.
    39  	info string
    40  	// insert holds attrs that should be merged into the config.
    41  	insert testing.Attrs
    42  	// remove has the names of attrs that should be removed.
    43  	remove []string
    44  	// expect defines the expected attributes in a success case.
    45  	expect testing.Attrs
    46  	// err is the error message to expect in a failure case.
    47  	err string
    48  }
    49  
    50  func (ts configTestSpec) checkSuccess(c *gc.C, value interface{}, err error) {
    51  	if !c.Check(err, jc.ErrorIsNil) {
    52  		return
    53  	}
    54  
    55  	var cfg *config.Config
    56  	switch typed := value.(type) {
    57  	case *config.Config:
    58  		cfg = typed
    59  	case environs.Environ:
    60  		cfg = typed.Config()
    61  	}
    62  
    63  	attrs := cfg.AllAttrs()
    64  	for field, value := range ts.expect {
    65  		c.Check(attrs[field], gc.Equals, value)
    66  	}
    67  }
    68  
    69  func (ts configTestSpec) checkFailure(c *gc.C, err error, msg string) {
    70  	c.Check(err, gc.ErrorMatches, msg+": "+ts.err)
    71  }
    72  
    73  func (ts configTestSpec) checkAttrs(c *gc.C, attrs map[string]interface{}, cfg *config.Config) {
    74  	for field, expected := range cfg.UnknownAttrs() {
    75  		value := attrs[field]
    76  		c.Check(value, gc.Equals, expected)
    77  	}
    78  }
    79  
    80  func (ts configTestSpec) attrs() testing.Attrs {
    81  	return gce.ConfigAttrs.Merge(ts.insert).Delete(ts.remove...)
    82  }
    83  
    84  func (ts configTestSpec) newConfig(c *gc.C) *config.Config {
    85  	attrs := ts.attrs()
    86  	cfg, err := testing.ModelConfig(c).Apply(attrs)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  	return cfg
    89  }
    90  
    91  func (ts configTestSpec) fixCfg(c *gc.C, cfg *config.Config) *config.Config {
    92  	newCfg, err := cfg.Apply(ts.insert)
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	return newCfg
    95  }
    96  
    97  func updateAttrs(attrs, updates testing.Attrs) testing.Attrs {
    98  	updated := make(testing.Attrs, len(attrs))
    99  	for k, v := range attrs {
   100  		updated[k] = v
   101  	}
   102  	for k, v := range updates {
   103  		updated[k] = v
   104  	}
   105  	return updated
   106  }
   107  
   108  var newConfigTests = []configTestSpec{{
   109  	info:   "client-id is required",
   110  	remove: []string{"client-id"},
   111  	err:    "client-id: expected string, got nothing",
   112  }, {
   113  	info:   "client-id cannot be empty",
   114  	insert: testing.Attrs{"client-id": ""},
   115  	err:    "client-id: must not be empty",
   116  }, {
   117  	info:   "private-key is required",
   118  	remove: []string{"private-key"},
   119  	err:    "private-key: expected string, got nothing",
   120  }, {
   121  	info:   "private-key cannot be empty",
   122  	insert: testing.Attrs{"private-key": ""},
   123  	err:    "private-key: must not be empty",
   124  }, {
   125  	info:   "client-email is required",
   126  	remove: []string{"client-email"},
   127  	err:    "client-email: expected string, got nothing",
   128  }, {
   129  	info:   "client-email cannot be empty",
   130  	insert: testing.Attrs{"client-email": ""},
   131  	err:    "client-email: must not be empty",
   132  }, {
   133  	info:   "region is optional",
   134  	remove: []string{"region"},
   135  	expect: testing.Attrs{"region": "us-central1"},
   136  }, {
   137  	info:   "region cannot be empty",
   138  	insert: testing.Attrs{"region": ""},
   139  	err:    "region: must not be empty",
   140  }, {
   141  	info:   "project-id is required",
   142  	remove: []string{"project-id"},
   143  	err:    "project-id: expected string, got nothing",
   144  }, {
   145  	info:   "project-id cannot be empty",
   146  	insert: testing.Attrs{"project-id": ""},
   147  	err:    "project-id: must not be empty",
   148  }, {
   149  	info:   "image-endpoint is inserted if missing",
   150  	remove: []string{"image-endpoint"},
   151  	expect: testing.Attrs{"image-endpoint": "https://www.googleapis.com"},
   152  }, {
   153  	info:   "image-endpoint cannot be empty",
   154  	insert: testing.Attrs{"image-endpoint": ""},
   155  	err:    "image-endpoint: must not be empty",
   156  }, {
   157  	info:   "unknown field is not touched",
   158  	insert: testing.Attrs{"unknown-field": 12345},
   159  	expect: testing.Attrs{"unknown-field": 12345},
   160  }}
   161  
   162  func (s *ConfigSuite) TestNewModelConfig(c *gc.C) {
   163  	for i, test := range newConfigTests {
   164  		c.Logf("test %d: %s", i, test.info)
   165  
   166  		testConfig := test.newConfig(c)
   167  		environ, err := environs.New(testConfig)
   168  
   169  		// Check the result
   170  		if test.err != "" {
   171  			test.checkFailure(c, err, "invalid config")
   172  		} else {
   173  			test.checkSuccess(c, environ, err)
   174  		}
   175  	}
   176  }
   177  
   178  // TODO(wwitzel3) refactor to provider_test file
   179  func (s *ConfigSuite) TestValidateNewConfig(c *gc.C) {
   180  	for i, test := range newConfigTests {
   181  		c.Logf("test %d: %s", i, test.info)
   182  
   183  		testConfig := test.newConfig(c)
   184  		validatedConfig, err := gce.Provider.Validate(testConfig, nil)
   185  
   186  		// Check the result
   187  		if test.err != "" {
   188  			test.checkFailure(c, err, "invalid config")
   189  		} else {
   190  			c.Check(validatedConfig, gc.NotNil)
   191  			test.checkSuccess(c, validatedConfig, err)
   192  		}
   193  	}
   194  }
   195  
   196  // TODO(wwitzel3) refactor to the provider_test file
   197  func (s *ConfigSuite) TestValidateOldConfig(c *gc.C) {
   198  	for i, test := range newConfigTests {
   199  		c.Logf("test %d: %s", i, test.info)
   200  
   201  		oldcfg := test.newConfig(c)
   202  		newcfg := test.fixCfg(c, s.config)
   203  		expected := updateAttrs(gce.ConfigAttrs, test.insert)
   204  
   205  		// Validate the new config (relative to the old one) using the
   206  		// provider.
   207  		validatedConfig, err := gce.Provider.Validate(newcfg, oldcfg)
   208  
   209  		// Check the result.
   210  		if test.err != "" {
   211  			test.checkFailure(c, err, "invalid base config")
   212  		} else {
   213  			if test.insert == nil && test.remove != nil {
   214  				// No defaults are set on the old config.
   215  				c.Check(err, gc.ErrorMatches, "invalid base config: .*")
   216  				continue
   217  			}
   218  
   219  			if !c.Check(err, jc.ErrorIsNil) {
   220  				continue
   221  			}
   222  			// We verify that Validate filled in the defaults
   223  			// appropriately.
   224  			c.Check(validatedConfig, gc.NotNil)
   225  			test.checkAttrs(c, expected, validatedConfig)
   226  		}
   227  	}
   228  }
   229  
   230  var changeConfigTests = []configTestSpec{{
   231  	info:   "no change, no error",
   232  	expect: gce.ConfigAttrs,
   233  }, {
   234  	info:   "cannot change private-key",
   235  	insert: testing.Attrs{"private-key": "okkult"},
   236  	err:    "private-key: cannot change from " + gce.PrivateKey + " to okkult",
   237  }, {
   238  	info:   "cannot change client-id",
   239  	insert: testing.Attrs{"client-id": "mutant"},
   240  	err:    "client-id: cannot change from " + gce.ClientID + " to mutant",
   241  }, {
   242  	info:   "cannot change client-email",
   243  	insert: testing.Attrs{"client-email": "spam@eggs.com"},
   244  	err:    "client-email: cannot change from " + gce.ClientEmail + " to spam@eggs.com",
   245  }, {
   246  	info:   "cannot change region",
   247  	insert: testing.Attrs{"region": "not home"},
   248  	err:    "region: cannot change from home to not home",
   249  }, {
   250  	info:   "cannot change project-id",
   251  	insert: testing.Attrs{"project-id": "your-juju"},
   252  	err:    "project-id: cannot change from my-juju to your-juju",
   253  }, {
   254  	info:   "can insert unknown field",
   255  	insert: testing.Attrs{"unknown": "ignoti"},
   256  	expect: testing.Attrs{"unknown": "ignoti"},
   257  }}
   258  
   259  // TODO(wwitzel3) refactor this to the provider_test file.
   260  func (s *ConfigSuite) TestValidateChange(c *gc.C) {
   261  	for i, test := range changeConfigTests {
   262  		c.Logf("test %d: %s", i, test.info)
   263  
   264  		testConfig := test.newConfig(c)
   265  		validatedConfig, err := gce.Provider.Validate(testConfig, s.config)
   266  
   267  		// Check the result.
   268  		if test.err != "" {
   269  			test.checkFailure(c, err, "invalid config change")
   270  		} else {
   271  			test.checkSuccess(c, validatedConfig, err)
   272  		}
   273  	}
   274  }
   275  
   276  func (s *ConfigSuite) TestSetConfig(c *gc.C) {
   277  	for i, test := range changeConfigTests {
   278  		c.Logf("test %d: %s", i, test.info)
   279  
   280  		environ, err := environs.New(s.config)
   281  		c.Assert(err, jc.ErrorIsNil)
   282  
   283  		testConfig := test.newConfig(c)
   284  		err = environ.SetConfig(testConfig)
   285  
   286  		// Check the result.
   287  		if test.err != "" {
   288  			test.checkFailure(c, err, "invalid config change")
   289  			test.checkAttrs(c, environ.Config().AllAttrs(), s.config)
   290  		} else {
   291  			test.checkSuccess(c, environ.Config(), err)
   292  		}
   293  	}
   294  }