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 }