3
from smart.cache import Package
3
from smart.cache import Package
5
# Smart is optional if AptFacade is being used.
5
8
from landscape.package.interface import (
6
9
install_landscape_interface, uninstall_landscape_interface)
8
from landscape.package.skeleton import build_skeleton, PackageTypeError
11
from landscape.package.facade import has_new_enough_apt
12
from landscape.package.skeleton import (
13
build_skeleton, PackageTypeError, build_skeleton_apt, DEB_PROVIDES,
14
DEB_NAME_PROVIDES, DEB_REQUIRES, DEB_OR_REQUIRES, DEB_UPGRADES,
10
from landscape.package.tests.helpers import SmartHelper, HASH1
17
from landscape.package.tests.helpers import (
18
AptFacadeHelper, SmartHelper, HASH1, create_simple_repository, create_deb,
19
PKGNAME_MINIMAL, PKGDEB_MINIMAL, HASH_MINIMAL, PKGNAME_SIMPLE_RELATIONS,
20
PKGDEB_SIMPLE_RELATIONS, HASH_SIMPLE_RELATIONS, PKGNAME_VERSION_RELATIONS,
21
PKGDEB_VERSION_RELATIONS, HASH_VERSION_RELATIONS,
22
PKGNAME_MULTIPLE_RELATIONS, PKGDEB_MULTIPLE_RELATIONS,
23
HASH_MULTIPLE_RELATIONS, PKGNAME_OR_RELATIONS, PKGDEB_OR_RELATIONS,
11
25
from landscape.tests.helpers import LandscapeTest
14
class SkeletonTest(LandscapeTest):
16
helpers = [SmartHelper]
28
class SkeletonTestHelper(object):
29
"""A helper to set up a repository for the skeleton tests."""
31
def set_up(self, test_case):
32
test_case.skeleton_repository_dir = test_case.makeDir()
33
create_simple_repository(test_case.skeleton_repository_dir)
35
test_case.skeleton_repository_dir, PKGNAME_MINIMAL, PKGDEB_MINIMAL)
37
test_case.skeleton_repository_dir, PKGNAME_SIMPLE_RELATIONS,
38
PKGDEB_SIMPLE_RELATIONS)
40
test_case.skeleton_repository_dir, PKGNAME_VERSION_RELATIONS,
41
PKGDEB_VERSION_RELATIONS)
43
test_case.skeleton_repository_dir, PKGNAME_MULTIPLE_RELATIONS,
44
PKGDEB_MULTIPLE_RELATIONS)
46
test_case.skeleton_repository_dir, PKGNAME_OR_RELATIONS,
50
class SkeletonTestMixin(object):
51
"""Tests for building a skeleton from a package.
53
This class should be mixed in to test different backends, like smart
56
The main test case classes need to implement C{get_package(name)} to
57
get a package by name, and C{build_skeleton(package, with_info,
58
with_unicode}, which builds the skeleton.
61
def test_build_skeleton(self):
63
C{build_skeleton} builds a C{PackageSkeleton} from a package. If
64
with_info isn't passed, C{section}, C{summary}, C{description},
65
C{size} and C{installed_size} will be C{None}.
67
pkg1 = self.get_package("name1")
68
skeleton = self.build_skeleton(pkg1)
69
self.assertEqual("name1", skeleton.name)
70
self.assertEqual("version1-release1", skeleton.version)
71
self.assertEqual(None, skeleton.section)
72
self.assertEqual(None, skeleton.summary)
73
self.assertEqual(None, skeleton.description)
74
self.assertEqual(None, skeleton.size)
75
self.assertEqual(None, skeleton.installed_size)
77
(DEB_PROVIDES, "providesname1"),
78
(DEB_NAME_PROVIDES, "name1 = version1-release1"),
79
(DEB_REQUIRES, "prerequirename1 = prerequireversion1"),
80
(DEB_REQUIRES, "requirename1 = requireversion1"),
81
(DEB_UPGRADES, "name1 < version1-release1"),
82
(DEB_CONFLICTS, "conflictsname1 = conflictsversion1")]
83
self.assertEqual(relations, skeleton.relations)
84
self.assertEqual(HASH1, skeleton.get_hash(), HASH1)
86
def test_build_skeleton_without_unicode(self):
88
If C{with_unicode} isn't passed to C{build_skeleton}, the name
89
and version of the skeleton are byte strings. The hash doesn't
92
pkg1 = self.get_package("name1")
93
skeleton = self.build_skeleton(pkg1)
94
self.assertTrue(isinstance(skeleton.name, str))
95
self.assertTrue(isinstance(skeleton.version, str))
96
self.assertEqual(HASH1, skeleton.get_hash())
98
def test_build_skeleton_with_unicode(self):
100
If C{with_unicode} is passed to C{build_skeleton}, the name
101
and version of the skeleton are unicode strings.
103
pkg1 = self.get_package("name1")
104
skeleton = self.build_skeleton(pkg1, with_unicode=True)
105
self.assertTrue(isinstance(skeleton.name, unicode))
106
self.assertTrue(isinstance(skeleton.version, unicode))
107
self.assertEqual(HASH1, skeleton.get_hash())
109
def test_build_skeleton_with_info(self):
111
If C{with_info} is passed to C{build_skeleton}, C{section},
112
C{summary}, C{description} and the size fields will be extracted
115
pkg1 = self.get_package("name1")
116
skeleton = self.build_skeleton(pkg1, with_info=True)
117
self.assertEqual("Group1", skeleton.section)
118
self.assertEqual("Summary1", skeleton.summary)
119
self.assertEqual("Description1", skeleton.description)
120
self.assertEqual(1038, skeleton.size)
121
self.assertEqual(28672, skeleton.installed_size)
123
def test_build_skeleton_with_unicode_and_extra_info(self):
125
If C{with_unicode} and C{with_info} are passed to
126
C{build_skeleton}, the name, version and the extra info of the
127
skeleton are unicode strings.
129
pkg1 = self.get_package("name1")
130
skeleton = self.build_skeleton(pkg1, with_unicode=True, with_info=True)
131
self.assertTrue(isinstance(skeleton.name, unicode))
132
self.assertTrue(isinstance(skeleton.version, unicode))
133
self.assertTrue(isinstance(skeleton.section, unicode))
134
self.assertTrue(isinstance(skeleton.summary, unicode))
135
self.assertTrue(isinstance(skeleton.description, unicode))
136
self.assertEqual(HASH1, skeleton.get_hash())
138
def test_build_skeleton_minimal(self):
140
A package that has only the required fields will still have some
143
minimal_package = self.get_package("minimal")
144
skeleton = self.build_skeleton(minimal_package)
145
self.assertEqual("minimal", skeleton.name)
146
self.assertEqual("1.0", skeleton.version)
147
self.assertEqual(None, skeleton.section)
148
self.assertEqual(None, skeleton.summary)
149
self.assertEqual(None, skeleton.description)
150
self.assertEqual(None, skeleton.size)
151
self.assertEqual(None, skeleton.installed_size)
153
(DEB_NAME_PROVIDES, "minimal = 1.0"),
154
(DEB_UPGRADES, "minimal < 1.0")]
155
self.assertEqual(relations, skeleton.relations)
156
self.assertEqual(HASH_MINIMAL, skeleton.get_hash())
158
def test_build_skeleton_minimal_with_info(self):
160
If some fields that C{with_info} wants aren't there, they will
161
be either an empty string or None, depending on which field.
163
package = self.get_package("minimal")
164
skeleton = self.build_skeleton(package, True)
165
self.assertEqual("", skeleton.section)
167
"A minimal package with no dependencies or other relations.",
169
self.assertEqual("", skeleton.description)
170
self.assertEqual(558, skeleton.size)
171
self.assertEqual(None, skeleton.installed_size)
173
def test_build_skeleton_simple_relations(self):
175
Relations that are specified in the package control file can be
176
simple, i.e. not specifying a version.
178
package = self.get_package("simple-relations")
179
skeleton = self.build_skeleton(package)
180
self.assertEqual("simple-relations", skeleton.name)
181
self.assertEqual("1.0", skeleton.version)
183
(DEB_PROVIDES, "provide1"),
184
(DEB_NAME_PROVIDES, "simple-relations = 1.0"),
185
(DEB_REQUIRES, "depend1"),
186
(DEB_REQUIRES, "predepend1"),
187
(DEB_UPGRADES, "simple-relations < 1.0"),
188
(DEB_CONFLICTS, "break1"),
189
(DEB_CONFLICTS, "conflict1")]
190
self.assertEqual(relations, skeleton.relations)
191
self.assertEqual(HASH_SIMPLE_RELATIONS, skeleton.get_hash())
193
def test_build_skeleton_version_relations(self):
195
Relations that are specified in the package control file can be
198
package = self.get_package("version-relations")
199
skeleton = self.build_skeleton(package)
200
self.assertEqual("version-relations", skeleton.name)
201
self.assertEqual("1.0", skeleton.version)
203
(DEB_PROVIDES, "provide1"),
204
(DEB_NAME_PROVIDES, "version-relations = 1.0"),
205
(DEB_REQUIRES, "depend1 = 2.0"),
206
(DEB_REQUIRES, "predepend1 <= 2.0"),
207
(DEB_UPGRADES, "version-relations < 1.0"),
208
(DEB_CONFLICTS, "break1 > 2.0"),
209
(DEB_CONFLICTS, "conflict1 < 2.0")]
210
self.assertEqual(relations, skeleton.relations)
211
self.assertEqual(HASH_VERSION_RELATIONS, skeleton.get_hash())
213
def test_build_skeleton_multiple_relations(self):
215
The relations in the package control can have multiple values.
216
In that case, one relation for each value is created in the
219
package = self.get_package("multiple-relations")
220
skeleton = self.build_skeleton(package)
221
self.assertEqual("multiple-relations", skeleton.name)
222
self.assertEqual("1.0", skeleton.version)
224
(DEB_PROVIDES, "provide1"),
225
(DEB_PROVIDES, "provide2"),
226
(DEB_NAME_PROVIDES, "multiple-relations = 1.0"),
227
(DEB_REQUIRES, "depend1 = 2.0"),
228
(DEB_REQUIRES, "depend2"),
229
(DEB_REQUIRES, "predepend1 <= 2.0"),
230
(DEB_REQUIRES, "predepend2"),
231
(DEB_OR_REQUIRES, "depend3 | depend4 > 2.0"),
232
(DEB_UPGRADES, "multiple-relations < 1.0"),
233
(DEB_CONFLICTS, "break1 > 2.0"),
234
(DEB_CONFLICTS, "break2"),
235
(DEB_CONFLICTS, "conflict1 < 2.0"),
236
(DEB_CONFLICTS, "conflict2")]
237
self.assertEqual(relations, skeleton.relations)
238
self.assertEqual(HASH_MULTIPLE_RELATIONS, skeleton.get_hash())
240
def test_build_skeleton_or_relations(self):
242
The Depend and Pre-Depend fields can have an or relation. That
243
is considered to be a single relation, with a special type.
245
package = self.get_package("or-relations")
246
skeleton = self.build_skeleton(package)
247
self.assertEqual("or-relations", skeleton.name)
248
self.assertEqual("1.0", skeleton.version)
250
(DEB_NAME_PROVIDES, "or-relations = 1.0"),
251
(DEB_OR_REQUIRES, "depend1 = 2.0 | depend2"),
252
(DEB_OR_REQUIRES, "predepend1 <= 2.0 | predepend2"),
253
(DEB_UPGRADES, "or-relations < 1.0")]
254
self.assertEqual(relations, skeleton.relations)
255
self.assertEqual(HASH_OR_RELATIONS, skeleton.get_hash())
258
class SmartSkeletonTest(LandscapeTest, SkeletonTestMixin):
259
"""C{PackageSkeleton} tests for smart packages."""
261
helpers = [SmartHelper, SkeletonTestHelper]
19
super(SkeletonTest, self).setUp()
264
super(SmartSkeletonTest, self).setUp()
20
265
install_landscape_interface()
21
266
self.ctrl = smart.init(interface="landscape", datadir=self.smart_dir)
22
smart.sysconf.set("channels", {"alias": {"type": "deb-dir",
23
"path": self.repository_dir}})
268
"channels", {"alias": {"type": "deb-dir",
269
"path": self.skeleton_repository_dir}})
24
270
self.ctrl.reloadChannels()
25
271
self.cache = self.ctrl.getCache()
27
273
def tearDown(self):
28
274
uninstall_landscape_interface()
29
super(SkeletonTest, self).tearDown()
31
def test_build_skeleton(self):
32
pkg1 = self.cache.getPackages("name1")[0]
33
skeleton = build_skeleton(pkg1)
34
self.assertEqual(skeleton.get_hash(), HASH1)
36
def test_build_skeleton_with_info(self):
37
pkg1 = self.cache.getPackages("name1")[0]
38
skeleton = build_skeleton(pkg1, True)
39
self.assertEqual(skeleton.section, "Group1")
40
self.assertEqual(skeleton.summary, "Summary1")
41
self.assertEqual(skeleton.description, "Description1")
42
self.assertEqual(skeleton.size, 1038)
43
self.assertEqual(skeleton.installed_size, 28672)
275
super(SmartSkeletonTest, self).tearDown()
277
def get_package(self, name):
278
"""Return the package with the specified name."""
279
[package] = self.cache.getPackages(name)
282
def build_skeleton(self, *args, **kwargs):
283
"""Build the skeleton to be tested."""
284
return build_skeleton(*args, **kwargs)
45
286
def test_refuse_to_build_non_debian_packages(self):
46
287
self.assertRaises(PackageTypeError, build_skeleton,
47
288
Package("name", "version"))
291
class SkeletonAptTest(LandscapeTest, SkeletonTestMixin):
292
"""C{PackageSkeleton} tests for apt packages."""
294
if not has_new_enough_apt:
295
skip = "Can't use AptFacade on hardy"
297
helpers = [AptFacadeHelper, SkeletonTestHelper]
300
super(SkeletonAptTest, self).setUp()
301
self.facade.add_channel_deb_dir(self.skeleton_repository_dir)
302
# Don't use reload_channels(), since that causes the test setup
303
# depending on build_skeleton_apt working correctly, which makes
304
# it harder to to TDD for these tests.
305
self.facade._cache.open(None)
306
self.facade._cache.update(None)
307
self.facade._cache.open(None)
309
def get_package(self, name):
310
"""Return the package with the specified name."""
311
# Don't use get_packages(), since that causes the test setup
312
# depending on build_skeleton_apt working correctly, which makes
313
# it harder to to TDD for these tests.
314
package = self.facade._cache[name]
315
return package.candidate
317
def build_skeleton(self, *args, **kwargs):
318
"""Build the skeleton to be tested."""
319
return build_skeleton_apt(*args, **kwargs)