~ubuntu-branches/ubuntu/lucid/landscape-client/lucid-updates

« back to all changes in this revision

Viewing changes to landscape/package/tests/test_skeleton.py

  • Committer: Package Import Robot
  • Author(s): Andreas Hasenack
  • Date: 2012-04-10 14:28:48 UTC
  • mfrom: (1.1.27)
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: package-import@ubuntu.com-20120410142848-7xsy4g2xii7y7ntc
ImportĀ upstreamĀ versionĀ 12.04.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import smart
2
 
 
3
 
from smart.cache import Package
 
1
try:
 
2
    import smart
 
3
    from smart.cache import Package
 
4
except ImportError:
 
5
    # Smart is optional if AptFacade is being used.
 
6
    pass
4
7
 
5
8
from landscape.package.interface import (
6
9
    install_landscape_interface, uninstall_landscape_interface)
7
10
 
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,
 
15
    DEB_CONFLICTS)
9
16
 
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,
 
24
    HASH_OR_RELATIONS)
11
25
from landscape.tests.helpers import LandscapeTest
12
26
 
13
27
 
14
 
class SkeletonTest(LandscapeTest):
15
 
 
16
 
    helpers = [SmartHelper]
 
28
class SkeletonTestHelper(object):
 
29
    """A helper to set up a repository for the skeleton tests."""
 
30
 
 
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)
 
34
        create_deb(
 
35
            test_case.skeleton_repository_dir, PKGNAME_MINIMAL, PKGDEB_MINIMAL)
 
36
        create_deb(
 
37
            test_case.skeleton_repository_dir, PKGNAME_SIMPLE_RELATIONS,
 
38
            PKGDEB_SIMPLE_RELATIONS)
 
39
        create_deb(
 
40
            test_case.skeleton_repository_dir, PKGNAME_VERSION_RELATIONS,
 
41
            PKGDEB_VERSION_RELATIONS)
 
42
        create_deb(
 
43
            test_case.skeleton_repository_dir, PKGNAME_MULTIPLE_RELATIONS,
 
44
            PKGDEB_MULTIPLE_RELATIONS)
 
45
        create_deb(
 
46
            test_case.skeleton_repository_dir, PKGNAME_OR_RELATIONS,
 
47
            PKGDEB_OR_RELATIONS)
 
48
 
 
49
 
 
50
class SkeletonTestMixin(object):
 
51
    """Tests for building a skeleton from a package.
 
52
 
 
53
    This class should be mixed in to test different backends, like smart
 
54
    and apt.
 
55
 
 
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.
 
59
    """
 
60
 
 
61
    def test_build_skeleton(self):
 
62
        """
 
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}.
 
66
        """
 
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)
 
76
        relations = [
 
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)
 
85
 
 
86
    def test_build_skeleton_without_unicode(self):
 
87
        """
 
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
 
90
        change, though.
 
91
        """
 
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())
 
97
 
 
98
    def test_build_skeleton_with_unicode(self):
 
99
        """
 
100
        If C{with_unicode} is passed to C{build_skeleton}, the name
 
101
        and version of the skeleton are unicode strings.
 
102
        """
 
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())
 
108
 
 
109
    def test_build_skeleton_with_info(self):
 
110
        """
 
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
 
113
        from the package.
 
114
        """
 
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)
 
122
 
 
123
    def test_build_skeleton_with_unicode_and_extra_info(self):
 
124
        """
 
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.
 
128
        """
 
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())
 
137
 
 
138
    def test_build_skeleton_minimal(self):
 
139
        """
 
140
        A package that has only the required fields will still have some
 
141
        relations defined.
 
142
        """
 
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)
 
152
        relations = [
 
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())
 
157
 
 
158
    def test_build_skeleton_minimal_with_info(self):
 
159
        """
 
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.
 
162
        """
 
163
        package = self.get_package("minimal")
 
164
        skeleton = self.build_skeleton(package, True)
 
165
        self.assertEqual("", skeleton.section)
 
166
        self.assertEqual(
 
167
            "A minimal package with no dependencies or other relations.",
 
168
            skeleton.summary)
 
169
        self.assertEqual("", skeleton.description)
 
170
        self.assertEqual(558, skeleton.size)
 
171
        self.assertEqual(None, skeleton.installed_size)
 
172
 
 
173
    def test_build_skeleton_simple_relations(self):
 
174
        """
 
175
        Relations that are specified in the package control file can be
 
176
        simple, i.e. not specifying a version.
 
177
        """
 
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)
 
182
        relations = [
 
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())
 
192
 
 
193
    def test_build_skeleton_version_relations(self):
 
194
        """
 
195
        Relations that are specified in the package control file can be
 
196
        version dependent.
 
197
        """
 
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)
 
202
        relations = [
 
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())
 
212
 
 
213
    def test_build_skeleton_multiple_relations(self):
 
214
        """
 
215
        The relations in the package control can have multiple values.
 
216
        In that case, one relation for each value is created in the
 
217
        skeleton.
 
218
        """
 
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)
 
223
        relations = [
 
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())
 
239
 
 
240
    def test_build_skeleton_or_relations(self):
 
241
        """
 
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.
 
244
        """
 
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)
 
249
        relations = [
 
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())
 
256
 
 
257
 
 
258
class SmartSkeletonTest(LandscapeTest, SkeletonTestMixin):
 
259
    """C{PackageSkeleton} tests for smart packages."""
 
260
 
 
261
    helpers = [SmartHelper, SkeletonTestHelper]
17
262
 
18
263
    def setUp(self):
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}})
 
267
        smart.sysconf.set(
 
268
            "channels", {"alias": {"type": "deb-dir",
 
269
                                   "path": self.skeleton_repository_dir}})
24
270
        self.ctrl.reloadChannels()
25
271
        self.cache = self.ctrl.getCache()
26
272
 
27
273
    def tearDown(self):
28
274
        uninstall_landscape_interface()
29
 
        super(SkeletonTest, self).tearDown()
30
 
 
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)
35
 
 
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()
 
276
 
 
277
    def get_package(self, name):
 
278
        """Return the package with the specified name."""
 
279
        [package] = self.cache.getPackages(name)
 
280
        return package
 
281
 
 
282
    def build_skeleton(self, *args, **kwargs):
 
283
        """Build the skeleton to be tested."""
 
284
        return build_skeleton(*args, **kwargs)
44
285
 
45
286
    def test_refuse_to_build_non_debian_packages(self):
46
287
        self.assertRaises(PackageTypeError, build_skeleton,
47
288
                          Package("name", "version"))
 
289
 
 
290
 
 
291
class SkeletonAptTest(LandscapeTest, SkeletonTestMixin):
 
292
    """C{PackageSkeleton} tests for apt packages."""
 
293
 
 
294
    if not has_new_enough_apt:
 
295
        skip = "Can't use AptFacade on hardy"
 
296
 
 
297
    helpers = [AptFacadeHelper, SkeletonTestHelper]
 
298
 
 
299
    def setUp(self):
 
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)
 
308
 
 
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
 
316
 
 
317
    def build_skeleton(self, *args, **kwargs):
 
318
        """Build the skeleton to be tested."""
 
319
        return build_skeleton_apt(*args, **kwargs)