1
# Copyright 2012 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Test custom commissioning scripts."""
6
from __future__ import (
15
from io import BytesIO
21
from random import randint
25
from maasserver.testing.factory import factory
26
from maasserver.testing.testcase import TestCase
27
from maastesting.matchers import ContainsAll
28
from maastesting.utils import sample_binary_data
29
from metadataserver.fields import Bin
30
from metadataserver.models import (
32
commissioningscript as cs_module,
34
from metadataserver.models.commissioningscript import ARCHIVE_PREFIX
37
def open_tarfile(content):
38
"""Open tar file from raw binary data."""
39
return tarfile.open(fileobj=BytesIO(content))
42
def make_script_name(base_name=None, number=None):
43
"""Make up a name for a commissioning script."""
47
number = randint(0, 99)
48
return factory.make_name(
49
'%0.2d-%s' % (number, factory.make_name(base_name)))
52
class TestCommissioningScriptManager(TestCase):
54
def test_get_archive_wraps_scripts_in_tar(self):
55
script = factory.make_commissioning_script()
56
path = os.path.join(ARCHIVE_PREFIX, script.name)
57
archive = open_tarfile(CommissioningScript.objects.get_archive())
58
self.assertTrue(archive.getmember(path).isfile())
59
self.assertEqual(script.content, archive.extractfile(path).read())
61
def test_get_archive_wraps_all_scripts(self):
62
scripts = {factory.make_commissioning_script() for counter in range(3)}
63
archive = open_tarfile(CommissioningScript.objects.get_archive())
67
os.path.join(ARCHIVE_PREFIX, script.name)
71
def test_get_archive_supports_binary_scripts(self):
72
script = factory.make_commissioning_script(content=sample_binary_data)
73
path = os.path.join(ARCHIVE_PREFIX, script.name)
74
archive = open_tarfile(CommissioningScript.objects.get_archive())
75
self.assertEqual(script.content, archive.extractfile(path).read())
77
def test_get_archive_includes_builtin_scripts(self):
78
name = factory.make_name('00-maas')
79
path = os.path.join(ARCHIVE_PREFIX, name)
80
content = factory.getRandomString().encode('ascii')
81
self.patch(cs_module, 'BUILTIN_COMMISSIONING_SCRIPTS', {name: content})
82
archive = open_tarfile(CommissioningScript.objects.get_archive())
83
self.assertIn(path, archive.getnames())
84
self.assertEqual(content, archive.extractfile(path).read())
86
def test_get_archive_sets_sensible_mode(self):
87
for counter in range(3):
88
factory.make_commissioning_script()
89
archive = open_tarfile(CommissioningScript.objects.get_archive())
90
self.assertEqual({0755}, {info.mode for info in archive.getmembers()})
92
def test_get_archive_initializes_file_timestamps(self):
93
# The mtime on a file inside the tarball is reasonable.
94
# It would otherwise default to the Epoch, and GNU tar warns
95
# annoyingly about improbably old files.
96
start_time = floor(time.time())
97
script = factory.make_commissioning_script()
98
path = os.path.join(ARCHIVE_PREFIX, script.name)
99
archive = open_tarfile(CommissioningScript.objects.get_archive())
100
timestamp = archive.getmember(path).mtime
101
end_time = ceil(time.time())
102
self.assertGreaterEqual(timestamp, start_time)
103
self.assertLessEqual(timestamp, end_time)
106
class TestCommissioningScript(TestCase):
108
def test_scripts_may_be_binary(self):
109
name = make_script_name()
110
CommissioningScript.objects.create(
111
name=name, content=Bin(sample_binary_data))
112
stored_script = CommissioningScript.objects.get(name=name)
113
self.assertEqual(sample_binary_data, stored_script.content)