1
# Copyright 2014 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Tests for the `download_descriptions` module."""
6
from __future__ import (
17
from maastesting.factory import factory
18
from maastesting.matchers import MockAnyCall
19
from maastesting.testcase import MAASTestCase
20
from provisioningserver.import_images import download_descriptions
21
from provisioningserver.import_images.boot_image_mapping import (
24
from provisioningserver.import_images.testing.factory import (
30
class TestValuePassesFilterList(MAASTestCase):
31
"""Tests for `value_passes_filter_list`."""
33
def test_nothing_passes_empty_list(self):
35
download_descriptions.value_passes_filter_list(
36
[], factory.make_name('value')))
38
def test_unmatched_value_does_not_pass(self):
40
download_descriptions.value_passes_filter_list(
41
[factory.make_name('filter')], factory.make_name('value')))
43
def test_matched_value_passes(self):
44
value = factory.make_name('value')
46
download_descriptions.value_passes_filter_list([value], value))
48
def test_value_passes_if_matched_anywhere_in_filter(self):
49
value = factory.make_name('value')
51
download_descriptions.value_passes_filter_list(
53
factory.make_name('filter'),
55
factory.make_name('filter'),
59
def test_any_value_passes_asterisk(self):
61
download_descriptions.value_passes_filter_list(
62
['*'], factory.make_name('value')))
65
class TestValuePassesFilter(MAASTestCase):
66
"""Tests for `value_passes_filter`."""
68
def test_unmatched_value_does_not_pass(self):
70
download_descriptions.value_passes_filter(
71
factory.make_name('filter'), factory.make_name('value')))
73
def test_matching_value_passes(self):
74
value = factory.make_name('value')
76
download_descriptions.value_passes_filter(value, value))
78
def test_any_value_matches_asterisk(self):
80
download_descriptions.value_passes_filter(
81
'*', factory.make_name('value')))
84
class TestImagePassesFilter(MAASTestCase):
85
"""Tests for `image_passes_filter`."""
87
def make_filter_from_image(self, image_spec=None):
88
"""Create a filter dict that matches the given `ImageSpec`.
90
If `image_spec` is not given, creates a random value.
92
if image_spec is None:
93
image_spec = make_image_spec()
95
'arches': [image_spec.arch],
96
'subarches': [image_spec.subarch],
97
'release': image_spec.release,
98
'labels': [image_spec.label],
101
def test_any_image_passes_none_filter(self):
102
arch, subarch, release, label = make_image_spec()
104
download_descriptions.image_passes_filter(
105
None, arch, subarch, release, label))
107
def test_any_image_passes_empty_filter(self):
108
arch, subarch, release, label = make_image_spec()
110
download_descriptions.image_passes_filter(
111
[], arch, subarch, release, label))
113
def test_image_passes_matching_filter(self):
114
image = make_image_spec()
116
download_descriptions.image_passes_filter(
117
[self.make_filter_from_image(image)],
118
image.arch, image.subarch, image.release, image.label))
120
def test_image_does_not_pass_nonmatching_filter(self):
121
image = make_image_spec()
123
download_descriptions.image_passes_filter(
124
[self.make_filter_from_image()],
125
image.arch, image.subarch, image.release, image.label))
127
def test_image_passes_if_one_filter_matches(self):
128
image = make_image_spec()
130
download_descriptions.image_passes_filter(
132
self.make_filter_from_image(),
133
self.make_filter_from_image(image),
134
self.make_filter_from_image(),
135
], image.arch, image.subarch, image.release, image.label))
137
def test_filter_checks_release(self):
138
image = make_image_spec()
140
download_descriptions.image_passes_filter(
142
self.make_filter_from_image(image._replace(
143
release=factory.make_name('other-release')))
144
], image.arch, image.subarch, image.release, image.label))
146
def test_filter_checks_arches(self):
147
image = make_image_spec()
149
download_descriptions.image_passes_filter(
151
self.make_filter_from_image(image._replace(
152
arch=factory.make_name('other-arch')))
153
], image.arch, image.subarch, image.release, image.label))
155
def test_filter_checks_subarches(self):
156
image = make_image_spec()
158
download_descriptions.image_passes_filter(
160
self.make_filter_from_image(image._replace(
161
subarch=factory.make_name('other-subarch')))
162
], image.arch, image.subarch, image.release, image.label))
164
def test_filter_checks_labels(self):
165
image = make_image_spec()
167
download_descriptions.image_passes_filter(
169
self.make_filter_from_image(image._replace(
170
label=factory.make_name('other-label')))
171
], image.arch, image.subarch, image.release, image.label))
174
class TestBootMerge(MAASTestCase):
175
"""Tests for `boot_merge`."""
177
def test_integrates(self):
178
# End-to-end scenario for boot_merge: start with an empty boot
179
# resources dict, and receive one resource from Simplestreams.
180
total_resources = BootImageMapping()
181
resources_from_repo = set_resource()
182
download_descriptions.boot_merge(total_resources, resources_from_repo)
183
# Since we started with an empty dict, the result contains the same
184
# item that we got from Simplestreams, and nothing else.
185
self.assertEqual(resources_from_repo.mapping, total_resources.mapping)
187
def test_obeys_filters(self):
190
'arches': [factory.make_name('other-arch')],
191
'subarches': [factory.make_name('other-subarch')],
192
'release': factory.make_name('other-release'),
193
'label': [factory.make_name('other-label')],
196
total_resources = BootImageMapping()
197
resources_from_repo = set_resource()
198
download_descriptions.boot_merge(
199
total_resources, resources_from_repo, filters=filters)
200
self.assertEqual({}, total_resources.mapping)
202
def test_does_not_overwrite_existing_entry(self):
203
image = make_image_spec()
204
total_resources = set_resource(
205
resource="Original resource", image_spec=image)
206
original_resources = total_resources.mapping.copy()
207
resources_from_repo = set_resource(
208
resource="New resource", image_spec=image)
209
download_descriptions.boot_merge(total_resources, resources_from_repo)
210
self.assertEqual(original_resources, total_resources.mapping)
213
class TestDownloadImageDescriptions(MAASTestCase):
215
def test_warns_if_no_resources_found(self):
216
self.patch(download_descriptions, 'logger')
217
# Stop the RepoDumper from finding any boot resources at all.
218
self.patch(download_descriptions, 'RepoDumper')
219
path = factory.make_name('path')
220
download_descriptions.download_image_descriptions(path)
222
download_descriptions.logger.warn,
224
"No resources found in Simplestreams repository %r. "
225
"Is it correctly configured?",