github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/provider/local/environ_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package local_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	gc "launchpad.net/gocheck"
    13  
    14  	coreCloudinit "launchpad.net/juju-core/cloudinit"
    15  	"launchpad.net/juju-core/constraints"
    16  	"launchpad.net/juju-core/environs"
    17  	"launchpad.net/juju-core/environs/cloudinit"
    18  	"launchpad.net/juju-core/environs/config"
    19  	"launchpad.net/juju-core/environs/jujutest"
    20  	envtesting "launchpad.net/juju-core/environs/testing"
    21  	"launchpad.net/juju-core/environs/tools"
    22  	"launchpad.net/juju-core/juju/osenv"
    23  	"launchpad.net/juju-core/provider/local"
    24  	"launchpad.net/juju-core/state/api/params"
    25  	coretesting "launchpad.net/juju-core/testing"
    26  	jc "launchpad.net/juju-core/testing/checkers"
    27  )
    28  
    29  const echoCommandScript = "#!/bin/sh\necho $0 \"$@\" >> $0.args"
    30  
    31  type environSuite struct {
    32  	baseProviderSuite
    33  	envtesting.ToolsFixture
    34  }
    35  
    36  var _ = gc.Suite(&environSuite{})
    37  
    38  func (s *environSuite) SetUpTest(c *gc.C) {
    39  	s.baseProviderSuite.SetUpTest(c)
    40  	s.ToolsFixture.SetUpTest(c)
    41  }
    42  
    43  func (s *environSuite) TearDownTest(c *gc.C) {
    44  	s.ToolsFixture.TearDownTest(c)
    45  	s.baseProviderSuite.TearDownTest(c)
    46  }
    47  
    48  func (*environSuite) TestOpenFailsWithProtectedDirectories(c *gc.C) {
    49  	testConfig := minimalConfig(c)
    50  	testConfig, err := testConfig.Apply(map[string]interface{}{
    51  		"root-dir": "/usr/lib/juju",
    52  	})
    53  	c.Assert(err, gc.IsNil)
    54  
    55  	environ, err := local.Provider.Open(testConfig)
    56  	c.Assert(err, gc.ErrorMatches, "mkdir .* permission denied")
    57  	c.Assert(environ, gc.IsNil)
    58  }
    59  
    60  func (s *environSuite) TestNameAndStorage(c *gc.C) {
    61  	testConfig := minimalConfig(c)
    62  	environ, err := local.Provider.Open(testConfig)
    63  	c.Assert(err, gc.IsNil)
    64  	c.Assert(environ.Name(), gc.Equals, "test")
    65  	c.Assert(environ.Storage(), gc.NotNil)
    66  }
    67  
    68  func (s *environSuite) TestGetToolsMetadataSources(c *gc.C) {
    69  	testConfig := minimalConfig(c)
    70  	environ, err := local.Provider.Open(testConfig)
    71  	c.Assert(err, gc.IsNil)
    72  	sources, err := tools.GetMetadataSources(environ)
    73  	c.Assert(err, gc.IsNil)
    74  	c.Assert(len(sources), gc.Equals, 1)
    75  	url, err := sources[0].URL("")
    76  	c.Assert(err, gc.IsNil)
    77  	c.Assert(strings.Contains(url, "/tools"), jc.IsTrue)
    78  }
    79  
    80  type localJujuTestSuite struct {
    81  	baseProviderSuite
    82  	jujutest.Tests
    83  	restoreRootCheck   func()
    84  	oldUpstartLocation string
    85  	testPath           string
    86  	dbServiceName      string
    87  	fakesudo           string
    88  }
    89  
    90  func (s *localJujuTestSuite) SetUpTest(c *gc.C) {
    91  	s.baseProviderSuite.SetUpTest(c)
    92  	// Construct the directories first.
    93  	err := local.CreateDirs(c, minimalConfig(c))
    94  	c.Assert(err, gc.IsNil)
    95  	s.testPath = c.MkDir()
    96  	s.fakesudo = filepath.Join(s.testPath, "sudo")
    97  	s.PatchEnvPathPrepend(s.testPath)
    98  
    99  	// Write a fake "sudo" which records its args to sudo.args.
   100  	err = ioutil.WriteFile(s.fakesudo, []byte(echoCommandScript), 0755)
   101  	c.Assert(err, gc.IsNil)
   102  
   103  	// Add in an admin secret
   104  	s.Tests.TestConfig["admin-secret"] = "sekrit"
   105  	s.restoreRootCheck = local.SetRootCheckFunction(func() bool { return false })
   106  	s.Tests.SetUpTest(c)
   107  
   108  	cfg, err := config.New(config.NoDefaults, s.TestConfig)
   109  	c.Assert(err, gc.IsNil)
   110  	s.dbServiceName = "juju-db-" + local.ConfigNamespace(cfg)
   111  }
   112  
   113  func (s *localJujuTestSuite) TearDownTest(c *gc.C) {
   114  	s.Tests.TearDownTest(c)
   115  	s.restoreRootCheck()
   116  	s.baseProviderSuite.TearDownTest(c)
   117  }
   118  
   119  func (s *localJujuTestSuite) MakeTool(c *gc.C, name, script string) {
   120  	path := filepath.Join(s.testPath, name)
   121  	script = "#!/bin/bash\n" + script
   122  	err := ioutil.WriteFile(path, []byte(script), 0755)
   123  	c.Assert(err, gc.IsNil)
   124  }
   125  
   126  func (s *localJujuTestSuite) StoppedStatus(c *gc.C) {
   127  	s.MakeTool(c, "status", `echo "some-service stop/waiting"`)
   128  }
   129  
   130  func (s *localJujuTestSuite) RunningStatus(c *gc.C) {
   131  	s.MakeTool(c, "status", `echo "some-service start/running, process 123"`)
   132  }
   133  
   134  var _ = gc.Suite(&localJujuTestSuite{
   135  	Tests: jujutest.Tests{
   136  		TestConfig: minimalConfigValues(),
   137  	},
   138  })
   139  
   140  func (s *localJujuTestSuite) TestStartStop(c *gc.C) {
   141  	c.Skip("StartInstance not implemented yet.")
   142  }
   143  
   144  func (s *localJujuTestSuite) testBootstrap(c *gc.C) (env environs.Environ) {
   145  	testConfig := minimalConfig(c)
   146  	ctx := coretesting.Context(c)
   147  	environ, err := local.Provider.Prepare(ctx, testConfig)
   148  	c.Assert(err, gc.IsNil)
   149  	envtesting.UploadFakeTools(c, environ.Storage())
   150  	defer environ.Storage().RemoveAll()
   151  	err = environ.Bootstrap(ctx, constraints.Value{})
   152  	c.Assert(err, gc.IsNil)
   153  	return environ
   154  }
   155  
   156  func (s *localJujuTestSuite) TestBootstrap(c *gc.C) {
   157  	s.PatchValue(local.FinishBootstrap, func(mcfg *cloudinit.MachineConfig, cloudcfg *coreCloudinit.Config, ctx environs.BootstrapContext) error {
   158  		c.Assert(cloudcfg.AptUpdate(), jc.IsFalse)
   159  		c.Assert(cloudcfg.AptUpgrade(), jc.IsFalse)
   160  		c.Assert(cloudcfg.Packages(), gc.HasLen, 0)
   161  		c.Assert(mcfg.AgentEnvironment, gc.Not(gc.IsNil))
   162  		// local does not allow machine-0 to host units
   163  		c.Assert(mcfg.Jobs, gc.DeepEquals, []params.MachineJob{params.JobManageEnviron})
   164  		return nil
   165  	})
   166  	s.testBootstrap(c)
   167  }
   168  
   169  func (s *localJujuTestSuite) TestDestroy(c *gc.C) {
   170  	s.PatchValue(local.FinishBootstrap, func(mcfg *cloudinit.MachineConfig, cloudcfg *coreCloudinit.Config, ctx environs.BootstrapContext) error {
   171  		return nil
   172  	})
   173  	env := s.testBootstrap(c)
   174  	err := env.Destroy()
   175  	// Succeeds because there's no "agents" directory,
   176  	// so destroy will just return without attempting
   177  	// sudo or anything.
   178  	c.Assert(err, gc.IsNil)
   179  	c.Assert(s.fakesudo+".args", jc.DoesNotExist)
   180  }
   181  
   182  func (s *localJujuTestSuite) TestDestroyCallSudo(c *gc.C) {
   183  	s.PatchValue(local.FinishBootstrap, func(mcfg *cloudinit.MachineConfig, cloudcfg *coreCloudinit.Config, ctx environs.BootstrapContext) error {
   184  		return nil
   185  	})
   186  	env := s.testBootstrap(c)
   187  	rootDir := env.Config().AllAttrs()["root-dir"].(string)
   188  	agentsDir := filepath.Join(rootDir, "agents")
   189  	err := os.Mkdir(agentsDir, 0755)
   190  	c.Assert(err, gc.IsNil)
   191  	err = env.Destroy()
   192  	c.Assert(err, gc.IsNil)
   193  	data, err := ioutil.ReadFile(s.fakesudo + ".args")
   194  	c.Assert(err, gc.IsNil)
   195  	expected := []string{
   196  		s.fakesudo,
   197  		"JUJU_HOME=" + osenv.JujuHome(),
   198  		os.Args[0],
   199  		"destroy-environment",
   200  		"-y",
   201  		"--force",
   202  		env.Config().Name(),
   203  	}
   204  	c.Assert(string(data), gc.Equals, strings.Join(expected, " ")+"\n")
   205  }