launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/container/lxc/lxc_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package lxc_test
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	stdtesting "testing"
    13  
    14  	"github.com/loggo/loggo"
    15  	gc "launchpad.net/gocheck"
    16  	"launchpad.net/golxc"
    17  	"launchpad.net/goyaml"
    18  
    19  	"launchpad.net/juju-core/container"
    20  	"launchpad.net/juju-core/container/lxc"
    21  	lxctesting "launchpad.net/juju-core/container/lxc/testing"
    22  	containertesting "launchpad.net/juju-core/container/testing"
    23  	instancetest "launchpad.net/juju-core/instance/testing"
    24  	jc "launchpad.net/juju-core/testing/checkers"
    25  	"launchpad.net/juju-core/testing/testbase"
    26  )
    27  
    28  func Test(t *stdtesting.T) {
    29  	gc.TestingT(t)
    30  }
    31  
    32  type LxcSuite struct {
    33  	lxctesting.TestSuite
    34  }
    35  
    36  var _ = gc.Suite(&LxcSuite{})
    37  
    38  func (s *LxcSuite) SetUpTest(c *gc.C) {
    39  	s.TestSuite.SetUpTest(c)
    40  	loggo.GetLogger("juju.container.lxc").SetLogLevel(loggo.TRACE)
    41  }
    42  
    43  func (s *LxcSuite) TestStartContainer(c *gc.C) {
    44  	manager := lxc.NewContainerManager(container.ManagerConfig{})
    45  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
    46  
    47  	name := string(instance.Id())
    48  	// Check our container config files.
    49  	lxcConfContents, err := ioutil.ReadFile(filepath.Join(s.ContainerDir, name, "lxc.conf"))
    50  	c.Assert(err, gc.IsNil)
    51  	c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42")
    52  
    53  	cloudInitFilename := filepath.Join(s.ContainerDir, name, "cloud-init")
    54  	data := containertesting.AssertCloudInit(c, cloudInitFilename)
    55  
    56  	x := make(map[interface{}]interface{})
    57  	err = goyaml.Unmarshal(data, &x)
    58  	c.Assert(err, gc.IsNil)
    59  
    60  	var scripts []string
    61  	for _, s := range x["runcmd"].([]interface{}) {
    62  		scripts = append(scripts, s.(string))
    63  	}
    64  
    65  	c.Assert(scripts[len(scripts)-2:], gc.DeepEquals, []string{
    66  		"start jujud-machine-1-lxc-0",
    67  		"ifconfig",
    68  	})
    69  
    70  	// Check the mount point has been created inside the container.
    71  	c.Assert(filepath.Join(s.LxcDir, name, "rootfs/var/log/juju"), jc.IsDirectory)
    72  	// Check that the config file is linked in the restart dir.
    73  	expectedLinkLocation := filepath.Join(s.RestartDir, name+".conf")
    74  	expectedTarget := filepath.Join(s.LxcDir, name, "config")
    75  	linkInfo, err := os.Lstat(expectedLinkLocation)
    76  	c.Assert(err, gc.IsNil)
    77  	c.Assert(linkInfo.Mode()&os.ModeSymlink, gc.Equals, os.ModeSymlink)
    78  
    79  	location, err := os.Readlink(expectedLinkLocation)
    80  	c.Assert(err, gc.IsNil)
    81  	c.Assert(location, gc.Equals, expectedTarget)
    82  }
    83  
    84  func (s *LxcSuite) TestContainerState(c *gc.C) {
    85  	manager := lxc.NewContainerManager(container.ManagerConfig{})
    86  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
    87  
    88  	// The mock container will be immediately "running".
    89  	c.Assert(instance.Status(), gc.Equals, string(golxc.StateRunning))
    90  
    91  	// StopContainer stops and then destroys the container, putting it
    92  	// into "unknown" state.
    93  	err := manager.StopContainer(instance)
    94  	c.Assert(err, gc.IsNil)
    95  	c.Assert(instance.Status(), gc.Equals, string(golxc.StateUnknown))
    96  }
    97  
    98  func (s *LxcSuite) TestStopContainer(c *gc.C) {
    99  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   100  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   101  
   102  	err := manager.StopContainer(instance)
   103  	c.Assert(err, gc.IsNil)
   104  
   105  	name := string(instance.Id())
   106  	// Check that the container dir is no longer in the container dir
   107  	c.Assert(filepath.Join(s.ContainerDir, name), jc.DoesNotExist)
   108  	// but instead, in the removed container dir
   109  	c.Assert(filepath.Join(s.RemovedDir, name), jc.IsDirectory)
   110  }
   111  
   112  func (s *LxcSuite) TestStopContainerNameClash(c *gc.C) {
   113  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   114  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   115  
   116  	name := string(instance.Id())
   117  	targetDir := filepath.Join(s.RemovedDir, name)
   118  	err := os.MkdirAll(targetDir, 0755)
   119  	c.Assert(err, gc.IsNil)
   120  
   121  	err = manager.StopContainer(instance)
   122  	c.Assert(err, gc.IsNil)
   123  
   124  	// Check that the container dir is no longer in the container dir
   125  	c.Assert(filepath.Join(s.ContainerDir, name), jc.DoesNotExist)
   126  	// but instead, in the removed container dir with a ".1" suffix as there was already a directory there.
   127  	c.Assert(filepath.Join(s.RemovedDir, fmt.Sprintf("%s.1", name)), jc.IsDirectory)
   128  }
   129  
   130  func (s *LxcSuite) TestNamedManagerPrefix(c *gc.C) {
   131  	manager := lxc.NewContainerManager(container.ManagerConfig{Name: "eric"})
   132  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   133  	c.Assert(string(instance.Id()), gc.Equals, "eric-machine-1-lxc-0")
   134  }
   135  
   136  func (s *LxcSuite) TestListContainers(c *gc.C) {
   137  	foo := lxc.NewContainerManager(container.ManagerConfig{Name: "foo"})
   138  	bar := lxc.NewContainerManager(container.ManagerConfig{Name: "bar"})
   139  
   140  	foo1 := containertesting.StartContainer(c, foo, "1/lxc/0")
   141  	foo2 := containertesting.StartContainer(c, foo, "1/lxc/1")
   142  	foo3 := containertesting.StartContainer(c, foo, "1/lxc/2")
   143  
   144  	bar1 := containertesting.StartContainer(c, bar, "1/lxc/0")
   145  	bar2 := containertesting.StartContainer(c, bar, "1/lxc/1")
   146  
   147  	result, err := foo.ListContainers()
   148  	c.Assert(err, gc.IsNil)
   149  	instancetest.MatchInstances(c, result, foo1, foo2, foo3)
   150  
   151  	result, err = bar.ListContainers()
   152  	c.Assert(err, gc.IsNil)
   153  	instancetest.MatchInstances(c, result, bar1, bar2)
   154  }
   155  
   156  func (s *LxcSuite) TestStartContainerAutostarts(c *gc.C) {
   157  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   158  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   159  	autostartLink := lxc.RestartSymlink(string(instance.Id()))
   160  	c.Assert(autostartLink, jc.IsSymlink)
   161  }
   162  
   163  func (s *LxcSuite) TestStartContainerNoRestartDir(c *gc.C) {
   164  	err := os.Remove(s.RestartDir)
   165  	c.Assert(err, gc.IsNil)
   166  
   167  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   168  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   169  	autostartLink := lxc.RestartSymlink(string(instance.Id()))
   170  
   171  	config := lxc.NetworkConfigTemplate("foo", "bar")
   172  	expected := `
   173  lxc.network.type = foo
   174  lxc.network.link = bar
   175  lxc.network.flags = up
   176  lxc.start.auto = 1
   177  `
   178  	c.Assert(config, gc.Equals, expected)
   179  	c.Assert(autostartLink, jc.DoesNotExist)
   180  }
   181  
   182  func (s *LxcSuite) TestStopContainerRemovesAutostartLink(c *gc.C) {
   183  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   184  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   185  	err := manager.StopContainer(instance)
   186  	c.Assert(err, gc.IsNil)
   187  	autostartLink := lxc.RestartSymlink(string(instance.Id()))
   188  	c.Assert(autostartLink, jc.SymlinkDoesNotExist)
   189  }
   190  
   191  func (s *LxcSuite) TestStopContainerNoRestartDir(c *gc.C) {
   192  	err := os.Remove(s.RestartDir)
   193  	c.Assert(err, gc.IsNil)
   194  
   195  	manager := lxc.NewContainerManager(container.ManagerConfig{})
   196  	instance := containertesting.StartContainer(c, manager, "1/lxc/0")
   197  	err = manager.StopContainer(instance)
   198  	c.Assert(err, gc.IsNil)
   199  }
   200  
   201  type NetworkSuite struct {
   202  	testbase.LoggingSuite
   203  }
   204  
   205  var _ = gc.Suite(&NetworkSuite{})
   206  
   207  func (*NetworkSuite) TestGenerateNetworkConfig(c *gc.C) {
   208  	for _, test := range []struct {
   209  		config *container.NetworkConfig
   210  		net    string
   211  		link   string
   212  	}{{
   213  		config: nil,
   214  		net:    "veth",
   215  		link:   "lxcbr0",
   216  	}, {
   217  		config: lxc.DefaultNetworkConfig(),
   218  		net:    "veth",
   219  		link:   "lxcbr0",
   220  	}, {
   221  		config: container.BridgeNetworkConfig("foo"),
   222  		net:    "veth",
   223  		link:   "foo",
   224  	}, {
   225  		config: container.PhysicalNetworkConfig("foo"),
   226  		net:    "phys",
   227  		link:   "foo",
   228  	}} {
   229  		config := lxc.GenerateNetworkConfig(test.config)
   230  		c.Assert(config, jc.Contains, fmt.Sprintf("lxc.network.type = %s\n", test.net))
   231  		c.Assert(config, jc.Contains, fmt.Sprintf("lxc.network.link = %s\n", test.link))
   232  	}
   233  }
   234  
   235  func (*NetworkSuite) TestNetworkConfigTemplate(c *gc.C) {
   236  	config := lxc.NetworkConfigTemplate("foo", "bar")
   237  	//In the past, the entire lxc.conf file was just networking. With the addition
   238  	//of the auto start, we now have to have better isolate this test. As such, we
   239  	//parse the conf template results and just get the results that start with
   240  	//'lxc.network' as that is what the test cares about.
   241  	obtained := []string{}
   242  	for _, value := range strings.Split(config, "\n") {
   243  		if strings.HasPrefix(value, "lxc.network") {
   244  			obtained = append(obtained, value)
   245  		}
   246  	}
   247  	expected := []string{
   248  		"lxc.network.type = foo",
   249  		"lxc.network.link = bar",
   250  		"lxc.network.flags = up",
   251  	}
   252  	c.Assert(obtained, gc.DeepEquals, expected)
   253  }