github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/vsphere/config_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package vsphere_test
     5  
     6  import (
     7  	stdcontext "context"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/cloud"
    13  	"github.com/juju/juju/environs"
    14  	environscloudspec "github.com/juju/juju/environs/cloudspec"
    15  	"github.com/juju/juju/environs/config"
    16  	"github.com/juju/juju/provider/vsphere"
    17  	"github.com/juju/juju/testing"
    18  )
    19  
    20  func fakeConfig(c *gc.C, attrs ...testing.Attrs) *config.Config {
    21  	cfg, err := testing.ModelConfig(c).Apply(fakeConfigAttrs(attrs...))
    22  	c.Assert(err, jc.ErrorIsNil)
    23  	return cfg
    24  }
    25  
    26  func fakeConfigAttrs(attrs ...testing.Attrs) testing.Attrs {
    27  	merged := testing.FakeConfig().Merge(testing.Attrs{
    28  		"type":                      "vsphere",
    29  		"uuid":                      "2d02eeac-9dbb-11e4-89d3-123b93f75cba",
    30  		"external-network":          "",
    31  		"enable-disk-uuid":          true,
    32  		"force-vm-hardware-version": 0,
    33  		"disk-provisioning-type":    "",
    34  	})
    35  	for _, attrs := range attrs {
    36  		merged = merged.Merge(attrs)
    37  	}
    38  	return merged
    39  }
    40  
    41  func fakeCloudSpec() environscloudspec.CloudSpec {
    42  	cred := fakeCredential()
    43  	return environscloudspec.CloudSpec{
    44  		Type:       "vsphere",
    45  		Name:       "vsphere",
    46  		Region:     "/datacenter1",
    47  		Endpoint:   "host1",
    48  		Credential: &cred,
    49  	}
    50  }
    51  
    52  func fakeCredential() cloud.Credential {
    53  	return cloud.NewCredential(cloud.UserPassAuthType, map[string]string{
    54  		"user":     "user1",
    55  		"password": "password1",
    56  	})
    57  }
    58  
    59  type ConfigSuite struct {
    60  	testing.BaseSuite
    61  	config   *config.Config
    62  	provider environs.EnvironProvider
    63  }
    64  
    65  var _ = gc.Suite(&ConfigSuite{})
    66  
    67  func (s *ConfigSuite) SetUpTest(c *gc.C) {
    68  	s.BaseSuite.SetUpTest(c)
    69  	s.config = fakeConfig(c)
    70  	s.provider = vsphere.NewEnvironProvider(vsphere.EnvironProviderConfig{})
    71  }
    72  
    73  // configTestSpec defines a subtest to run in a table driven test.
    74  type configTestSpec struct {
    75  	// info describes the subtest.
    76  	info string
    77  	// insert holds attrs that should be merged into the config.
    78  	insert testing.Attrs
    79  	// remove has the names of attrs that should be removed.
    80  	remove []string
    81  	// expect defines the expected attributes in a success case.
    82  	expect testing.Attrs
    83  	// err is the error message to expect in a failure case.
    84  	err string
    85  }
    86  
    87  func (ts configTestSpec) checkSuccess(c *gc.C, value interface{}, err error) {
    88  	if !c.Check(err, jc.ErrorIsNil) {
    89  		return
    90  	}
    91  
    92  	var cfg *config.Config
    93  	switch typed := value.(type) {
    94  	case *config.Config:
    95  		cfg = typed
    96  	case environs.Environ:
    97  		cfg = typed.Config()
    98  	}
    99  
   100  	attrs := cfg.AllAttrs()
   101  	for field, value := range ts.expect {
   102  		c.Check(attrs[field], gc.Equals, value)
   103  	}
   104  }
   105  
   106  func (ts configTestSpec) checkFailure(c *gc.C, err error, msg string) {
   107  	c.Check(err, gc.ErrorMatches, msg+": "+ts.err)
   108  }
   109  
   110  func (ts configTestSpec) checkAttrs(c *gc.C, attrs map[string]interface{}, cfg *config.Config) {
   111  	for field, value := range cfg.UnknownAttrs() {
   112  		c.Check(attrs[field], gc.Equals, value)
   113  	}
   114  }
   115  
   116  func (ts configTestSpec) attrs() testing.Attrs {
   117  	return fakeConfigAttrs().Merge(ts.insert).Delete(ts.remove...)
   118  }
   119  
   120  func (ts configTestSpec) newConfig(c *gc.C) *config.Config {
   121  	attrs := ts.attrs()
   122  	cfg, err := testing.ModelConfig(c).Apply(attrs)
   123  	c.Assert(err, jc.ErrorIsNil)
   124  	return cfg
   125  }
   126  
   127  var newConfigTests = []configTestSpec{
   128  	{
   129  		info:   "unknown field is not touched",
   130  		insert: testing.Attrs{"unknown-field": "12345"},
   131  		expect: testing.Attrs{"unknown-field": "12345"},
   132  	},
   133  	{
   134  		info:   "use thick disk provisioning",
   135  		insert: testing.Attrs{"disk-provisioning-type": "thick"},
   136  		expect: testing.Attrs{"disk-provisioning-type": "thick"},
   137  	},
   138  	{
   139  		info:   "set invalid disk provisioning",
   140  		insert: testing.Attrs{"disk-provisioning-type": "eroneous"},
   141  		err:    "\"disk-provisioning-type\" must be one of.*",
   142  	},
   143  }
   144  
   145  func (*ConfigSuite) TestNewModelConfig(c *gc.C) {
   146  	for i, test := range newConfigTests {
   147  		c.Logf("test %d: %s", i, test.info)
   148  
   149  		fakeConfig := test.newConfig(c)
   150  		environ, err := environs.New(stdcontext.TODO(), environs.OpenParams{
   151  			Cloud:  fakeCloudSpec(),
   152  			Config: fakeConfig,
   153  		})
   154  
   155  		// Check the result
   156  		if test.err != "" {
   157  			test.checkFailure(c, err, "invalid config")
   158  		} else {
   159  			test.checkSuccess(c, environ, err)
   160  		}
   161  	}
   162  }
   163  
   164  func (s *ConfigSuite) TestValidateNewConfig(c *gc.C) {
   165  	for i, test := range newConfigTests {
   166  		c.Logf("test %d: %s", i, test.info)
   167  
   168  		fakeConfig := test.newConfig(c)
   169  		validatedConfig, err := s.provider.Validate(fakeConfig, nil)
   170  
   171  		// Check the result
   172  		if test.err != "" {
   173  			test.checkFailure(c, err, "invalid config")
   174  		} else {
   175  			c.Check(validatedConfig, gc.NotNil)
   176  			test.checkSuccess(c, validatedConfig, err)
   177  		}
   178  	}
   179  }
   180  
   181  func (s *ConfigSuite) TestValidateOldConfig(c *gc.C) {
   182  	for i, test := range newConfigTests {
   183  		c.Logf("test %d: %s", i, test.info)
   184  
   185  		oldcfg := test.newConfig(c)
   186  		newcfg := s.config
   187  		expected := fakeConfigAttrs()
   188  
   189  		// Validate the new config (relative to the old one) using the
   190  		// provider.
   191  		validatedConfig, err := s.provider.Validate(newcfg, oldcfg)
   192  
   193  		// Check the result.
   194  		if test.err != "" {
   195  			test.checkFailure(c, err, "invalid base config")
   196  		} else {
   197  			if test.remove != nil {
   198  				// No defaults are set on the old config.
   199  				c.Check(err, gc.ErrorMatches, "invalid base config: .*")
   200  				continue
   201  			}
   202  
   203  			c.Assert(err, jc.ErrorIsNil)
   204  			// We verify that Validate filled in the defaults
   205  			// appropriately.
   206  			c.Check(validatedConfig, gc.NotNil)
   207  			test.checkAttrs(c, expected, validatedConfig)
   208  		}
   209  	}
   210  }
   211  
   212  var changeConfigTests = []configTestSpec{{
   213  	info:   "no change, no error",
   214  	expect: fakeConfigAttrs(),
   215  }, {
   216  	info:   "can insert unknown field",
   217  	insert: testing.Attrs{"unknown": "ignoti"},
   218  	expect: testing.Attrs{"unknown": "ignoti"},
   219  }}
   220  
   221  func (s *ConfigSuite) TestValidateChange(c *gc.C) {
   222  	for i, test := range changeConfigTests {
   223  		c.Logf("test %d: %s", i, test.info)
   224  
   225  		fakeConfig := test.newConfig(c)
   226  		validatedConfig, err := s.provider.Validate(fakeConfig, s.config)
   227  
   228  		// Check the result.
   229  		if test.err != "" {
   230  			test.checkFailure(c, err, "invalid config change")
   231  		} else {
   232  			test.checkSuccess(c, validatedConfig, err)
   233  		}
   234  	}
   235  }
   236  
   237  func (s *ConfigSuite) TestSetConfig(c *gc.C) {
   238  	for i, test := range changeConfigTests {
   239  		c.Logf("test %d: %s", i, test.info)
   240  
   241  		environ, err := environs.New(stdcontext.TODO(), environs.OpenParams{
   242  			Cloud:  fakeCloudSpec(),
   243  			Config: s.config,
   244  		})
   245  		c.Assert(err, jc.ErrorIsNil)
   246  
   247  		fakeConfig := test.newConfig(c)
   248  		err = environ.SetConfig(fakeConfig)
   249  
   250  		// Check the result.
   251  		if test.err != "" {
   252  			test.checkFailure(c, err, "invalid config change")
   253  			test.checkAttrs(c, environ.Config().AllAttrs(), s.config)
   254  		} else {
   255  			test.checkSuccess(c, environ.Config(), err)
   256  		}
   257  	}
   258  }
   259  
   260  func (s *ConfigSuite) TestSchema(c *gc.C) {
   261  	ps, ok := s.provider.(environs.ProviderSchema)
   262  	c.Assert(ok, jc.IsTrue)
   263  
   264  	fields := ps.Schema()
   265  
   266  	globalFields, err := config.Schema(nil)
   267  	c.Assert(err, gc.IsNil)
   268  	for name, field := range globalFields {
   269  		c.Check(fields[name], jc.DeepEquals, field)
   270  	}
   271  }