~twom/launchpad-buildd/close-directory-tar

« back to all changes in this revision

Viewing changes to lpbuildd/target/tests/test_lxd.py

  • Committer: Colin Watson
  • Date: 2019-11-26 12:21:42 UTC
  • mfrom: (401.1.10 lp-1852518-again)
  • Revision ID: cjwatson@canonical.com-20191126122142-86okgi2fl8zoelg9
[r=cjwatson] Do not make assumptions about what device major number the device mapper is using. (LP: #1852518)

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
from contextlib import closing
10
10
import io
11
11
import json
12
 
import os.path
 
12
import os
 
13
import random
 
14
import stat
13
15
import tarfile
14
16
from textwrap import dedent
15
17
import time
27
29
from pylxd.exceptions import LXDAPIException
28
30
import six
29
31
from systemfixtures import (
30
 
    FakeFilesystem,
 
32
    FakeFilesystem as _FakeFilesystem,
31
33
    FakeProcesses,
32
34
    )
 
35
from systemfixtures._overlay import Overlay
33
36
from testtools import TestCase
34
37
from testtools.matchers import (
35
38
    DirContains,
91
94
        return {"stdout": io.BytesIO((output + "\n").encode("UTF-8"))}
92
95
 
93
96
 
 
97
class FakeFilesystem(_FakeFilesystem):
 
98
    # Add support for os.mknod to the upstream implementation.
 
99
 
 
100
    def _setUp(self):
 
101
        super(FakeFilesystem, self)._setUp()
 
102
        self._devices = {}
 
103
        self.useFixture(
 
104
            Overlay("os.mknod", self._mknod, self._is_fake_path))
 
105
 
 
106
    def _stat(self, real, path, *args, **kwargs):
 
107
        r = super(FakeFilesystem, self)._stat(real, path, *args, **kwargs)
 
108
        if path in self._devices:
 
109
            r = os.stat_result(list(r), {"st_rdev": self._devices[path]})
 
110
        return r
 
111
 
 
112
    def _mknod(self, real, path, mode=0o600, device=None):
 
113
        fd = os.open(path, os.O_CREAT | os.O_EXCL, mode & 0o777)
 
114
        os.close(fd)
 
115
        if mode & (stat.S_IFBLK | stat.S_IFCHR):
 
116
            self._devices[path] = device
 
117
 
 
118
 
94
119
class TestLXD(TestCase):
95
120
 
96
121
    def make_chroot_tarball(self, output_path):
287
312
                        driver_version=driver_version or "3.0"
288
313
                        )
289
314
 
290
 
    def test_start(self):
 
315
    def fakeFS(self):
291
316
        fs_fixture = self.useFixture(FakeFilesystem())
292
317
        fs_fixture.add("/sys")
 
318
        fs_fixture.add("/dev")
 
319
        os.mkdir("/dev")
293
320
        fs_fixture.add("/run")
294
321
        os.makedirs("/run/launchpad-buildd")
295
322
        fs_fixture.add("/etc")
297
324
        with open("/etc/resolv.conf", "w") as f:
298
325
            print("host resolv.conf", file=f)
299
326
        os.chmod("/etc/resolv.conf", 0o644)
 
327
 
 
328
    def test_start(self, with_dm0=True):
 
329
        self.fakeFS()
 
330
        DM_BLOCK_MAJOR = random.randrange(128, 255)
 
331
        if with_dm0:
 
332
            os.mknod(
 
333
                "/dev/dm-0", 0o660 | stat.S_IFBLK,
 
334
                os.makedev(DM_BLOCK_MAJOR, 0))
300
335
        self.useFixture(MockPatch("pylxd.Client"))
301
336
        client = pylxd.Client()
302
337
        client.profiles.get.side_effect = FakeLXDAPIException
313
348
        processes_fixture = self.useFixture(FakeProcesses())
314
349
        processes_fixture.add(lambda _: {}, name="sudo")
315
350
        processes_fixture.add(lambda _: {}, name="lxc")
 
351
 
 
352
        def fake_dmsetup(args):
 
353
            command = args["args"][1]
 
354
            if command == "create":
 
355
                os.mknod(
 
356
                    "/dev/dm-0", 0o660 | stat.S_IFBLK,
 
357
                    os.makedev(DM_BLOCK_MAJOR, 0))
 
358
            elif command == "remove":
 
359
                os.remove("/dev/dm-0")
 
360
            else:
 
361
                self.fail("unexpected dmsetup command %r" % (command,))
 
362
            return {}
 
363
 
 
364
        processes_fixture.add(fake_dmsetup, name="dmsetup")
316
365
        processes_fixture.add(
317
366
            FakeHostname("example", "example.buildd"), name="hostname")
318
367
        LXD("1", "xenial", "amd64").start()
363
412
                    lxc +
364
413
                    ["mknod", "-m", "0660", "/dev/loop%d" % minor,
365
414
                     "b", "7", str(minor)]))
 
415
        if not with_dm0:
 
416
            expected_args.extend([
 
417
                Equals(["dmsetup", "create", "tmpdevice", "--notable"]),
 
418
                Equals(["dmsetup", "remove", "tmpdevice"]),
 
419
                ])
366
420
        for minor in range(8):
367
421
            expected_args.append(
368
422
                Equals(
369
423
                    lxc +
370
424
                    ["mknod", "-m", "0660", "/dev/dm-%d" % minor,
371
 
                     "b", "251", str(minor)]))
 
425
                     "b", str(DM_BLOCK_MAJOR), str(minor)]))
372
426
        expected_args.extend([
373
427
            Equals(
374
428
                lxc + ["mkdir", "-p", "/etc/systemd/system/snapd.service.d"]),
421
475
        container.start.assert_called_once_with(wait=True)
422
476
        self.assertEqual(LXD_RUNNING, container.status_code)
423
477
 
 
478
    def test_start_no_dm0(self):
 
479
        self.test_start(False)
 
480
 
424
481
    def test_start_missing_etc_hosts(self):
425
 
        fs_fixture = self.useFixture(FakeFilesystem())
426
 
        fs_fixture.add("/sys")
427
 
        fs_fixture.add("/run")
428
 
        os.makedirs("/run/launchpad-buildd")
429
 
        fs_fixture.add("/etc")
430
 
        os.mkdir("/etc")
431
 
        with open("/etc/resolv.conf", "w") as f:
432
 
            print("host resolv.conf", file=f)
433
 
        os.chmod("/etc/resolv.conf", 0o644)
 
482
        self.fakeFS()
 
483
        os.mknod("/dev/dm-0", 0o660 | stat.S_IFBLK, os.makedev(250, 0))
434
484
        self.useFixture(MockPatch("pylxd.Client"))
435
485
        client = pylxd.Client()
436
486
        client.profiles.get.side_effect = FakeLXDAPIException
460
510
            headers={"X-LXD-uid": "0", "X-LXD-gid": "0", "X-LXD-mode": "0644"})
461
511
 
462
512
    def test_start_with_mounted_dev_conf(self):
463
 
        fs_fixture = self.useFixture(FakeFilesystem())
464
 
        fs_fixture.add("/sys")
465
 
        fs_fixture.add("/run")
466
 
        os.makedirs("/run/launchpad-buildd")
467
 
        fs_fixture.add("/etc")
468
 
        os.mkdir("/etc")
469
 
        with open("/etc/resolv.conf", "w") as f:
470
 
            print("host resolv.conf", file=f)
471
 
        os.chmod("/etc/resolv.conf", 0o644)
 
513
        self.fakeFS()
 
514
        os.mknod("/dev/dm-0", 0o660 | stat.S_IFBLK, os.makedev(250, 0))
472
515
        self.useFixture(MockPatch("pylxd.Client"))
473
516
        client = pylxd.Client()
474
517
        client.profiles.get.side_effect = FakeLXDAPIException