github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/container/kvm/wrappedcmds_test.go (about) 1 // Copyright 2014-2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package kvm_test 5 6 import ( 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/pkg/errors" 14 gc "gopkg.in/check.v1" 15 16 . "github.com/juju/juju/container/kvm" 17 "github.com/juju/juju/environs/imagedownloads" 18 "github.com/juju/juju/environs/simplestreams" 19 coretesting "github.com/juju/juju/testing" 20 ) 21 22 type LibVertSuite struct { 23 coretesting.BaseSuite 24 ContainerDir string 25 RemovedDir string 26 } 27 28 var _ = gc.Suite(&LibVertSuite{}) 29 30 func (s *LibVertSuite) SetUpTest(c *gc.C) { 31 s.BaseSuite.SetUpTest(c) 32 } 33 34 type testSyncParams struct { 35 arch, series, ftype string 36 srcFunc func() simplestreams.DataSource 37 onevalErr error 38 success bool 39 } 40 41 func (p testSyncParams) One() (*imagedownloads.Metadata, error) { 42 if p.success { 43 return &imagedownloads.Metadata{ 44 Arch: p.arch, 45 Release: p.series, 46 }, nil 47 } 48 return nil, p.onevalErr 49 } 50 51 func (p testSyncParams) sourceURL() (string, error) { 52 return p.srcFunc().URL("") 53 } 54 55 // Test that the call to SyncImages utilizes the defined source 56 func (s *LibVertSuite) TestSyncImagesUtilizesSimpleStreamsSource(c *gc.C) { 57 58 const ( 59 series = "mocked-series" 60 arch = "mocked-arch" 61 source = "mocked-url" 62 ) 63 p := testSyncParams{ 64 arch: arch, 65 series: series, 66 srcFunc: func() simplestreams.DataSource { return imagedownloads.NewDataSource(source) }, 67 success: true, 68 } 69 err := Sync(p, fakeFetcher{}, nil) 70 c.Assert(err, jc.ErrorIsNil) 71 72 url, err := p.sourceURL() 73 c.Check(err, jc.ErrorIsNil) 74 c.Check(url, jc.DeepEquals, source+"/") 75 76 res, err := p.One() 77 c.Check(err, jc.ErrorIsNil) 78 79 c.Check(res.Arch, jc.DeepEquals, arch) 80 c.Check(res.Release, jc.DeepEquals, series) 81 } 82 83 // gocheck boilerplate. 84 type commandWrapperSuite struct { 85 testing.IsolationSuite 86 } 87 88 var _ = gc.Suite(&commandWrapperSuite{}) 89 90 func (commandWrapperSuite) TestCreateNoHostname(c *gc.C) { 91 stub := NewRunStub("exit before this", nil) 92 p := CreateMachineParams{} 93 err := CreateMachine(p) 94 c.Assert(len(stub.Calls()) == 0, jc.IsTrue) 95 c.Assert(err, gc.ErrorMatches, "hostname is required") 96 } 97 98 func (commandWrapperSuite) TestCreateMachineSuccess(c *gc.C) { 99 stub := NewRunStub("success", nil) 100 101 tmpDir, err := ioutil.TempDir("", "juju-libvirtSuite-") 102 c.Check(err, jc.ErrorIsNil) 103 err = os.MkdirAll(filepath.Join(tmpDir, "kvm", "guests"), 0755) 104 c.Check(err, jc.ErrorIsNil) 105 cloudInitPath := filepath.Join(tmpDir, "cloud-init") 106 userDataPath := filepath.Join(tmpDir, "user-data") 107 networkConfigPath := filepath.Join(tmpDir, "network-config") 108 err = ioutil.WriteFile(cloudInitPath, []byte("#cloud-init\nEOF\n"), 0755) 109 c.Assert(err, jc.ErrorIsNil) 110 111 defer func() { 112 err := os.RemoveAll(tmpDir) 113 if err != nil { 114 c.Errorf("failed removing %q in test %s", tmpDir, err) 115 } 116 }() 117 pathfinder := func(s string) (string, error) { 118 return tmpDir, nil 119 } 120 121 hostname := "host00" 122 params := CreateMachineParams{ 123 Hostname: hostname, 124 Series: "precise", 125 UserDataFile: cloudInitPath, 126 NetworkConfigData: "this-is-network-config", 127 CpuCores: 1, 128 RootDisk: 8, 129 } 130 131 MakeCreateMachineParamsTestable(¶ms, pathfinder, stub.Run, "arm64") 132 err = CreateMachine(params) 133 c.Assert(err, jc.ErrorIsNil) 134 135 _, err = os.Stat(cloudInitPath) 136 c.Assert(os.IsNotExist(err), jc.IsTrue) 137 138 b, err := ioutil.ReadFile(userDataPath) 139 c.Assert(err, jc.ErrorIsNil) 140 c.Assert(string(b), jc.Contains, "#cloud-init") 141 142 b, err = ioutil.ReadFile(networkConfigPath) 143 c.Assert(err, jc.ErrorIsNil) 144 c.Assert(string(b), gc.Equals, "this-is-network-config") 145 146 c.Check(len(stub.Calls()), gc.Equals, 4) 147 want := []string{ 148 `genisoimage -output \/tmp\/juju-libvirtSuite-\d+\/kvm\/guests\/host00-ds\.iso -volid cidata -joliet -rock user-data meta-data network-config`, 149 `qemu-img create -b \/tmp/juju-libvirtSuite-\d+\/kvm\/guests\/precise-arm64-backing-file.qcow -f qcow2 \/tmp\/juju-libvirtSuite-\d+\/kvm\/guests\/host00.qcow 8G`, 150 `virsh define \/tmp\/juju-libvirtSuite-\d+\/host00.xml`, 151 "virsh start host00", 152 } 153 154 for i, cmd := range stub.Calls() { 155 c.Assert(cmd, gc.Matches, want[i]) 156 } 157 } 158 159 func (commandWrapperSuite) TestDestroyMachineSuccess(c *gc.C) { 160 tmpDir, err := ioutil.TempDir("", "juju-libvirtSuite-") 161 c.Check(err, jc.ErrorIsNil) 162 guestBase := filepath.Join(tmpDir, "kvm", "guests") 163 err = os.MkdirAll(guestBase, 0700) 164 c.Check(err, jc.ErrorIsNil) 165 166 err = ioutil.WriteFile(filepath.Join(guestBase, "aname.qcow"), []byte("diskcontents"), 0700) 167 c.Check(err, jc.ErrorIsNil) 168 err = ioutil.WriteFile(filepath.Join(guestBase, "aname-ds.iso"), []byte("diskcontents"), 0700) 169 c.Check(err, jc.ErrorIsNil) 170 171 pathfinder := func(_ string) (string, error) { 172 return tmpDir, nil 173 } 174 175 stub := NewRunStub("success", nil) 176 container := NewTestContainer("aname", stub.Run, pathfinder) 177 err = DestroyMachine(container) 178 c.Assert(err, jc.ErrorIsNil) 179 c.Assert(stub.Calls(), jc.DeepEquals, []string{ 180 "virsh destroy aname", 181 "virsh undefine --nvram aname", 182 }) 183 } 184 185 func (commandWrapperSuite) TestDestroyMachineFails(c *gc.C) { 186 stub := NewRunStub("", errors.Errorf("Boom")) 187 container := NewTestContainer("aname", stub.Run, nil) 188 err := DestroyMachine(container) 189 c.Check(stub.Calls(), jc.DeepEquals, []string{ 190 "virsh destroy aname", 191 "virsh undefine --nvram aname", 192 }) 193 log := c.GetTestLog() 194 c.Check(log, jc.Contains, "`virsh destroy aname` failed") 195 c.Check(log, jc.Contains, "`virsh undefine --nvram aname` failed") 196 c.Assert(err, jc.ErrorIsNil) 197 198 } 199 200 func (commandWrapperSuite) TestAutostartMachineSuccess(c *gc.C) { 201 stub := NewRunStub("success", nil) 202 container := NewTestContainer("aname", stub.Run, nil) 203 err := AutostartMachine(container) 204 c.Assert(stub.Calls(), jc.DeepEquals, []string{"virsh autostart aname"}) 205 c.Assert(err, jc.ErrorIsNil) 206 } 207 208 func (commandWrapperSuite) TestAutostartMachineFails(c *gc.C) { 209 stub := NewRunStub("", errors.Errorf("Boom")) 210 container := NewTestContainer("aname", stub.Run, nil) 211 err := AutostartMachine(container) 212 c.Assert(stub.Calls(), jc.DeepEquals, []string{"virsh autostart aname"}) 213 c.Check(err, gc.ErrorMatches, `failed to autostart domain "aname": Boom`) 214 } 215 216 func (commandWrapperSuite) TestListMachinesSuccess(c *gc.C) { 217 output := ` 218 Id Name State 219 ---------------------------------------------------- 220 0 Domain-0 running 221 2 ubuntu paused 222 `[1:] 223 stub := NewRunStub(output, nil) 224 got, err := ListMachines(stub.Run) 225 226 c.Check(err, jc.ErrorIsNil) 227 c.Check(stub.Calls(), jc.DeepEquals, []string{"virsh -q list --all"}) 228 c.Assert(got, jc.DeepEquals, map[string]string{ 229 "Domain-0": "running", 230 "ubuntu": "paused", 231 }) 232 233 } 234 235 func (commandWrapperSuite) TestListMachinesFails(c *gc.C) { 236 stub := NewRunStub("", errors.Errorf("Boom")) 237 got, err := ListMachines(stub.Run) 238 c.Check(err, gc.ErrorMatches, "Boom") 239 c.Check(stub.Calls(), jc.DeepEquals, []string{"virsh -q list --all"}) 240 c.Assert(got, gc.IsNil) 241 }