~ubuntu-branches/ubuntu/raring/maas/raring-proposed

« back to all changes in this revision

Viewing changes to src/provisioningserver/pxe/tests/test_install_image.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-07-17 08:28:36 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20120717082836-ucb2vou8tqg353eq
Tags: 0.1+bzr777+dfsg-0ubuntu1
* New upstream release
* Only run 'maas' command as root. (LP: #974046)
  - debian/extras/maas: Check id.
  - debian/maas.install: Install in 'sbin'.
* debian/maas.postinst:
  - restart apache2 after everything gets processed.
  - Update version to handle upgrades.
* debian/extras/maas-provision: Add wrapper to access 'maasprovisiong'
  command line.
* debian/patches/99_temporary_fix_path.patch: Dropped. No longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2012 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Tests for the install_pxe_image command."""
 
5
 
 
6
from __future__ import (
 
7
    absolute_import,
 
8
    print_function,
 
9
    unicode_literals,
 
10
    )
 
11
 
 
12
__metaclass__ = type
 
13
__all__ = []
 
14
 
 
15
import os
 
16
 
 
17
from maastesting.factory import factory
 
18
from maastesting.testcase import TestCase
 
19
import provisioningserver.pxe.install_image
 
20
from provisioningserver.pxe.install_image import (
 
21
    are_identical_dirs,
 
22
    install_dir,
 
23
    make_destination,
 
24
    )
 
25
from provisioningserver.pxe.tftppath import (
 
26
    compose_image_path,
 
27
    locate_tftp_path,
 
28
    )
 
29
from provisioningserver.testing.config import ConfigFixture
 
30
from provisioningserver.utils import MainScript
 
31
from testtools.matchers import (
 
32
    DirExists,
 
33
    FileContains,
 
34
    FileExists,
 
35
    Not,
 
36
    )
 
37
 
 
38
 
 
39
def make_arch_subarch_release_purpose():
 
40
    """Create arbitrary architecture/subarchitecture/release names.
 
41
 
 
42
    :return: A triplet of three identifiers for these respective items.
 
43
    """
 
44
    return tuple(
 
45
        factory.make_name(item)
 
46
        for item in ('arch', 'subarch', 'release', 'purpose'))
 
47
 
 
48
 
 
49
class TestInstallPXEImage(TestCase):
 
50
 
 
51
    def test_integration(self):
 
52
        tftproot = self.make_dir()
 
53
        config = {"tftp": {"root": tftproot}}
 
54
        config_fixture = ConfigFixture(config)
 
55
        self.useFixture(config_fixture)
 
56
 
 
57
        download_dir = self.make_dir()
 
58
        image_dir = os.path.join(download_dir, 'image')
 
59
        os.makedirs(image_dir)
 
60
        factory.make_file(image_dir, 'kernel')
 
61
        arch, subarch, release, purpose = make_arch_subarch_release_purpose()
 
62
 
 
63
        action = factory.make_name("action")
 
64
        script = MainScript(action)
 
65
        script.register(action, provisioningserver.pxe.install_image)
 
66
        script.execute(
 
67
            ("--config-file", config_fixture.filename, action, "--arch", arch,
 
68
             "--subarch", subarch, "--release", release, "--purpose", purpose,
 
69
             "--image", image_dir))
 
70
 
 
71
        self.assertThat(
 
72
            os.path.join(
 
73
                locate_tftp_path(
 
74
                    compose_image_path(arch, subarch, release, purpose),
 
75
                    tftproot=tftproot),
 
76
                'kernel'),
 
77
            FileExists())
 
78
 
 
79
    def test_make_destination_follows_pxe_path_conventions(self):
 
80
        # The directory that make_destination returns follows the PXE
 
81
        # directory hierarchy specified for MAAS:
 
82
        # /var/lib/tftproot/maas/<arch>/<subarch>/<release>/<purpose>
 
83
        # (Where the /var/lib/tftproot/ part is configurable, so we
 
84
        # can test this without overwriting system files).
 
85
        tftproot = self.make_dir()
 
86
        arch, subarch, release, purpose = make_arch_subarch_release_purpose()
 
87
        self.assertEqual(
 
88
            os.path.join(tftproot, 'maas', arch, subarch, release, purpose),
 
89
            make_destination(tftproot, arch, subarch, release, purpose))
 
90
 
 
91
    def test_make_destination_creates_directory_if_not_present(self):
 
92
        tftproot = self.make_dir()
 
93
        arch, subarch, release, purpose = make_arch_subarch_release_purpose()
 
94
        expected_destination = os.path.dirname(locate_tftp_path(
 
95
            compose_image_path(arch, subarch, release, purpose),
 
96
            tftproot=tftproot))
 
97
        make_destination(tftproot, arch, subarch, release, purpose)
 
98
        self.assertThat(expected_destination, DirExists())
 
99
 
 
100
    def test_make_destination_returns_existing_directory(self):
 
101
        tftproot = self.make_dir()
 
102
        arch, subarch, release, purpose = make_arch_subarch_release_purpose()
 
103
        expected_dest = locate_tftp_path(
 
104
            compose_image_path(arch, subarch, release, purpose),
 
105
            tftproot=tftproot)
 
106
        os.makedirs(expected_dest)
 
107
        contents = factory.getRandomString()
 
108
        testfile = factory.make_name('testfile')
 
109
        factory.make_file(expected_dest, contents=contents, name=testfile)
 
110
        dest = make_destination(tftproot, arch, subarch, release, purpose)
 
111
        self.assertThat(os.path.join(dest, testfile), FileContains(contents))
 
112
 
 
113
    def test_are_identical_dirs_sees_missing_old_dir_as_different(self):
 
114
        self.assertFalse(
 
115
            are_identical_dirs(
 
116
                os.path.join(self.make_dir(), factory.getRandomString()),
 
117
                os.path.dirname(self.make_file())))
 
118
 
 
119
    def test_are_identical_dirs_returns_true_if_identical(self):
 
120
        name = factory.getRandomString()
 
121
        contents = factory.getRandomString()
 
122
        self.assertTrue(are_identical_dirs(
 
123
            os.path.dirname(self.make_file(name=name, contents=contents)),
 
124
            os.path.dirname(self.make_file(name=name, contents=contents))))
 
125
 
 
126
    def test_are_identical_dirs_returns_false_if_file_has_changed(self):
 
127
        name = factory.getRandomString()
 
128
        old = os.path.dirname(self.make_file(name=name))
 
129
        new = os.path.dirname(self.make_file(name=name))
 
130
        self.assertFalse(are_identical_dirs(old, new))
 
131
 
 
132
    def test_are_identical_dirs_returns_false_if_file_was_added(self):
 
133
        shared_file = factory.getRandomString()
 
134
        contents = factory.getRandomString()
 
135
        old = os.path.dirname(
 
136
            self.make_file(name=shared_file, contents=contents))
 
137
        new = os.path.dirname(
 
138
            self.make_file(name=shared_file, contents=contents))
 
139
        factory.make_file(new)
 
140
        self.assertFalse(are_identical_dirs(old, new))
 
141
 
 
142
    def test_are_identical_dirs_returns_false_if_file_was_removed(self):
 
143
        shared_file = factory.getRandomString()
 
144
        contents = factory.getRandomString()
 
145
        old = os.path.dirname(
 
146
            self.make_file(name=shared_file, contents=contents))
 
147
        new = os.path.dirname(
 
148
            self.make_file(name=shared_file, contents=contents))
 
149
        factory.make_file(old)
 
150
        self.assertFalse(are_identical_dirs(old, new))
 
151
 
 
152
    def test_install_dir_moves_dir_into_place(self):
 
153
        download_image = os.path.join(self.make_dir(), 'download-image')
 
154
        published_image = os.path.join(self.make_dir(), 'published-image')
 
155
        contents = factory.getRandomString()
 
156
        os.makedirs(download_image)
 
157
        sample_file = factory.make_file(download_image, contents=contents)
 
158
        install_dir(download_image, published_image)
 
159
        self.assertThat(
 
160
            os.path.join(published_image, os.path.basename(sample_file)),
 
161
            FileContains(contents))
 
162
 
 
163
    def test_install_dir_replaces_existing_dir(self):
 
164
        download_image = os.path.join(self.make_dir(), 'download-image')
 
165
        published_image = os.path.join(self.make_dir(), 'published-image')
 
166
        os.makedirs(download_image)
 
167
        sample_file = factory.make_file(download_image)
 
168
        os.makedirs(published_image)
 
169
        obsolete_file = factory.make_file(published_image)
 
170
        install_dir(download_image, published_image)
 
171
        self.assertThat(
 
172
            os.path.join(published_image, os.path.basename(sample_file)),
 
173
            FileExists())
 
174
        self.assertThat(obsolete_file, Not(FileExists()))
 
175
 
 
176
    def test_install_dir_sweeps_aside_dot_new_and_dot_old_if_any(self):
 
177
        # If directories <old>.old or <old>.new already exist, they're
 
178
        # probably from an aborted previous run.  They won't stop
 
179
        # install_dir from doing its work.
 
180
        download_image = os.path.join(self.make_dir(), 'download-image')
 
181
        published_image = os.path.join(
 
182
            self.make_dir(), factory.getRandomString())
 
183
        contents = factory.getRandomString()
 
184
        os.makedirs(download_image)
 
185
        sample_file = factory.make_file(download_image, contents=contents)
 
186
        os.makedirs('%s.old' % published_image)
 
187
        os.makedirs('%s.new' % published_image)
 
188
        install_dir(download_image, published_image)
 
189
        self.assertThat(
 
190
            os.path.join(published_image, os.path.basename(sample_file)),
 
191
            FileContains(contents))
 
192
        self.assertThat('%s.old' % published_image, Not(DirExists()))
 
193
        self.assertThat('%s.new' % published_image, Not(DirExists()))