github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/provider/maas/environ_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas_test
     5  
     6  import (
     7  	"io"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	stdtesting "testing"
    11  
    12  	"github.com/juju/gomaasapi"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/utils/set"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/errors"
    18  	"github.com/juju/juju/cloud"
    19  	"github.com/juju/juju/environs"
    20  	"github.com/juju/juju/environs/config"
    21  	envtesting "github.com/juju/juju/environs/testing"
    22  	"github.com/juju/juju/provider/maas"
    23  	coretesting "github.com/juju/juju/testing"
    24  )
    25  
    26  type environSuite struct {
    27  	coretesting.BaseSuite
    28  	envtesting.ToolsFixture
    29  	restoreTimeouts func()
    30  }
    31  
    32  var _ = gc.Suite(&environSuite{})
    33  
    34  func TestMAAS(t *stdtesting.T) {
    35  	gc.TestingT(t)
    36  }
    37  
    38  // TDOO: jam 2013-12-06 This is copied from the providerSuite which is in a
    39  // whitebox package maas. Either move that into a whitebox test so it can be
    40  // shared, or into a 'testing' package so we can use it here.
    41  func (s *environSuite) SetUpSuite(c *gc.C) {
    42  	s.restoreTimeouts = envtesting.PatchAttemptStrategies(maas.ShortAttempt)
    43  	s.BaseSuite.SetUpSuite(c)
    44  }
    45  
    46  func (s *environSuite) SetUpTest(c *gc.C) {
    47  	s.BaseSuite.SetUpTest(c)
    48  	s.ToolsFixture.SetUpTest(c)
    49  
    50  	mockCapabilities := func(*gomaasapi.MAASObject, string) (set.Strings, error) {
    51  		return set.NewStrings("network-deployment-ubuntu"), nil
    52  	}
    53  	mockGetController := func(string, string) (gomaasapi.Controller, error) {
    54  		return nil, gomaasapi.NewUnsupportedVersionError("oops")
    55  	}
    56  	s.PatchValue(&maas.GetCapabilities, mockCapabilities)
    57  	s.PatchValue(&maas.GetMAAS2Controller, mockGetController)
    58  }
    59  
    60  func (s *environSuite) TearDownTest(c *gc.C) {
    61  	s.ToolsFixture.TearDownTest(c)
    62  	s.BaseSuite.TearDownTest(c)
    63  }
    64  
    65  func (s *environSuite) TearDownSuite(c *gc.C) {
    66  	s.restoreTimeouts()
    67  	s.BaseSuite.TearDownSuite(c)
    68  }
    69  
    70  func getSimpleTestConfig(c *gc.C, extraAttrs coretesting.Attrs) *config.Config {
    71  	attrs := coretesting.FakeConfig()
    72  	attrs["type"] = "maas"
    73  	attrs["bootstrap-timeout"] = "1200"
    74  	for k, v := range extraAttrs {
    75  		attrs[k] = v
    76  	}
    77  	cfg, err := config.New(config.NoDefaults, attrs)
    78  	c.Assert(err, jc.ErrorIsNil)
    79  	return cfg
    80  }
    81  
    82  func getSimpleCloudSpec() environs.CloudSpec {
    83  	cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
    84  		"maas-oauth": "a:b:c",
    85  	})
    86  	return environs.CloudSpec{
    87  		Type:       "maas",
    88  		Name:       "maas",
    89  		Endpoint:   "http://maas.testing.invalid",
    90  		Credential: &cred,
    91  	}
    92  }
    93  
    94  func (*environSuite) TestSetConfigValidatesFirst(c *gc.C) {
    95  	// SetConfig() validates the config change and disallows, for example,
    96  	// changes in the environment name.
    97  	oldCfg := getSimpleTestConfig(c, coretesting.Attrs{"name": "old-name"})
    98  	newCfg := getSimpleTestConfig(c, coretesting.Attrs{"name": "new-name"})
    99  	env, err := maas.NewEnviron(getSimpleCloudSpec(), oldCfg)
   100  	c.Assert(err, jc.ErrorIsNil)
   101  
   102  	// SetConfig() fails, even though both the old and the new config are
   103  	// individually valid.
   104  	err = env.SetConfig(newCfg)
   105  	c.Assert(err, gc.NotNil)
   106  	c.Check(err, gc.ErrorMatches, ".*cannot change name.*")
   107  
   108  	// The old config is still in place.  The new config never took effect.
   109  	c.Check(env.Config().Name(), gc.Equals, "old-name")
   110  }
   111  
   112  func (*environSuite) TestSetConfigUpdatesConfig(c *gc.C) {
   113  	origAttrs := coretesting.Attrs{
   114  		"apt-mirror": "http://testing1.invalid",
   115  	}
   116  	cfg := getSimpleTestConfig(c, origAttrs)
   117  	env, err := maas.NewEnviron(getSimpleCloudSpec(), cfg)
   118  	c.Check(err, jc.ErrorIsNil)
   119  	c.Check(env.Config().Name(), gc.Equals, "testenv")
   120  
   121  	newAttrs := coretesting.Attrs{
   122  		"apt-mirror": "http://testing2.invalid",
   123  	}
   124  	cfg2 := getSimpleTestConfig(c, newAttrs)
   125  	errSetConfig := env.SetConfig(cfg2)
   126  	c.Check(errSetConfig, gc.IsNil)
   127  	c.Check(env.Config().Name(), gc.Equals, "testenv")
   128  	c.Check(env.Config().AptMirror(), gc.Equals, "http://testing2.invalid")
   129  }
   130  
   131  func (*environSuite) TestNewEnvironSetsConfig(c *gc.C) {
   132  	cfg := getSimpleTestConfig(c, nil)
   133  
   134  	env, err := maas.NewEnviron(getSimpleCloudSpec(), cfg)
   135  
   136  	c.Check(err, jc.ErrorIsNil)
   137  	c.Check(env.Config().Name(), gc.Equals, "testenv")
   138  }
   139  
   140  var expectedCloudinitConfig = []string{
   141  	"set -xe",
   142  	"mkdir -p '/var/lib/juju'\ncat > '/var/lib/juju/MAASmachine.txt' << 'EOF'\n'hostname: testing.invalid\n'\nEOF\nchmod 0755 '/var/lib/juju/MAASmachine.txt'",
   143  }
   144  
   145  func (*environSuite) TestNewCloudinitConfig(c *gc.C) {
   146  	cfg := getSimpleTestConfig(c, nil)
   147  	env, err := maas.NewEnviron(getSimpleCloudSpec(), cfg)
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	modifyNetworkScript := maas.RenderEtcNetworkInterfacesScript("eth0", "eth1")
   150  	script := expectedCloudinitConfig
   151  	script = append(script, modifyNetworkScript)
   152  	cloudcfg, err := maas.NewCloudinitConfig(env, "testing.invalid", "quantal", []string{"eth0", "eth1"})
   153  	c.Assert(err, jc.ErrorIsNil)
   154  	c.Assert(cloudcfg.SystemUpdate(), jc.IsTrue)
   155  	c.Assert(cloudcfg.RunCmds(), jc.DeepEquals, script)
   156  }
   157  
   158  func (*environSuite) TestNewCloudinitConfigWithDisabledNetworkManagement(c *gc.C) {
   159  	attrs := coretesting.Attrs{
   160  		"disable-network-management": true,
   161  	}
   162  	cfg := getSimpleTestConfig(c, attrs)
   163  	env, err := maas.NewEnviron(getSimpleCloudSpec(), cfg)
   164  	c.Assert(err, jc.ErrorIsNil)
   165  	cloudcfg, err := maas.NewCloudinitConfig(env, "testing.invalid", "quantal", nil)
   166  	c.Assert(err, jc.ErrorIsNil)
   167  	c.Assert(cloudcfg.SystemUpdate(), jc.IsTrue)
   168  	c.Assert(cloudcfg.RunCmds(), jc.DeepEquals, expectedCloudinitConfig)
   169  }
   170  
   171  func (*environSuite) TestRenderEtcNetworkInterfacesScriptMultipleNames(c *gc.C) {
   172  	script := maas.RenderEtcNetworkInterfacesScript("eth0", "eth0:1", "eth2", "eth1")
   173  	c.Check(script, jc.Contains, `--interfaces-to-bridge="eth0 eth0:1 eth2 eth1"`)
   174  	c.Check(script, jc.Contains, `--bridge-prefix="br-"`)
   175  }
   176  
   177  func (*environSuite) TestRenderEtcNetworkInterfacesScriptSingleName(c *gc.C) {
   178  	script := maas.RenderEtcNetworkInterfacesScript("eth0")
   179  	c.Check(script, jc.Contains, `--interfaces-to-bridge="eth0"`)
   180  	c.Check(script, jc.Contains, `--bridge-prefix="br-"`)
   181  }
   182  
   183  type badEndpointSuite struct {
   184  	coretesting.BaseSuite
   185  
   186  	fakeServer *httptest.Server
   187  	cloudSpec  environs.CloudSpec
   188  }
   189  
   190  var _ = gc.Suite(&badEndpointSuite{})
   191  
   192  func (s *badEndpointSuite) SetUpSuite(c *gc.C) {
   193  	s.BaseSuite.SetUpSuite(c)
   194  	always404 := func(w http.ResponseWriter, req *http.Request) {
   195  		w.WriteHeader(http.StatusNotFound)
   196  		io.WriteString(w, "uh-oh")
   197  	}
   198  	s.fakeServer = httptest.NewServer(http.HandlerFunc(always404))
   199  }
   200  
   201  func (s *badEndpointSuite) SetUpTest(c *gc.C) {
   202  	s.BaseSuite.SetUpTest(c)
   203  	cred := cloud.NewCredential(cloud.OAuth1AuthType, map[string]string{
   204  		"maas-oauth": "a:b:c",
   205  	})
   206  	s.cloudSpec = environs.CloudSpec{
   207  		Type:       "maas",
   208  		Name:       "maas",
   209  		Endpoint:   s.fakeServer.URL,
   210  		Credential: &cred,
   211  	}
   212  }
   213  
   214  func (s *badEndpointSuite) TestBadEndpointMessageNoMAAS(c *gc.C) {
   215  	cfg := getSimpleTestConfig(c, coretesting.Attrs{})
   216  	env, err := maas.NewEnviron(s.cloudSpec, cfg)
   217  	c.Assert(env, gc.IsNil)
   218  	c.Assert(err, gc.ErrorMatches, `could not connect to MAAS controller - check the endpoint is correct \(it normally ends with /MAAS\)`)
   219  	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
   220  }
   221  
   222  func (s *badEndpointSuite) TestBadEndpointMessageWithMAAS(c *gc.C) {
   223  	cfg := getSimpleTestConfig(c, coretesting.Attrs{})
   224  	s.cloudSpec.Endpoint += "/MAAS"
   225  	env, err := maas.NewEnviron(s.cloudSpec, cfg)
   226  	c.Assert(env, gc.IsNil)
   227  	c.Assert(err, gc.ErrorMatches, `could not connect to MAAS controller - check the endpoint is correct`)
   228  	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
   229  }
   230  
   231  func (s *badEndpointSuite) TestBadEndpointMessageWithMAASAndSlash(c *gc.C) {
   232  	cfg := getSimpleTestConfig(c, coretesting.Attrs{})
   233  	s.cloudSpec.Endpoint += "/MAAS/"
   234  	env, err := maas.NewEnviron(s.cloudSpec, cfg)
   235  	c.Assert(env, gc.IsNil)
   236  	c.Assert(err, gc.ErrorMatches, `could not connect to MAAS controller - check the endpoint is correct`)
   237  	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
   238  }