~ubuntu-core-dev/update-manager/main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/python3
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-

import os

import apt
import shutil
import unittest
from UpdateManager.Core.UpdateList import UpdateList
from UpdateManager.Core.MyCache import MyCache

CURDIR = os.path.dirname(os.path.abspath(__file__))


class TestOriginMatcher(unittest.TestCase):
    def setUp(self):
        # mangle the arch
        real_arch = apt.apt_pkg.config.find("APT::Architecture")
        apt.apt_pkg.config.set("APT::Architecture", "amd64")
        self.addCleanup(
            lambda: apt.apt_pkg.config.set("APT::Architecture", real_arch)
        )

        self.aptroot = os.path.join(CURDIR, "aptroot-update-origin")
        self.dpkg_status = open("%s/var/lib/dpkg/status" % self.aptroot, "w")
        self.dpkg_status.flush()
        self.cache = MyCache(
            apt.progress.base.OpProgress(), rootdir=self.aptroot
        )
        self.cache._listsLock = 0
        self.cache.update()
        self.cache.open()

    def tearDown(self):
        # kill data dirs
        # FIXME: use tmpdir in the long run
        for d in ["var/lib/apt/lists/", "var/cache/apt"]:
            try:
                shutil.rmtree(os.path.join(self.aptroot, d))
            except IOError:
                pass
        # kill off status file
        try:
            os.remove(os.path.join(self.aptroot, "var/lib/dpkg/status"))
        except OSError:
            pass

    def testOriginMatcherSimple(self):
        test_pkgs = set()
        for pkg in self.cache:
            if pkg.candidate and pkg.candidate.origins:
                if [
                    line.archive
                    for line in pkg.candidate.origins
                    if line.archive == "xenial-security"
                ]:
                    test_pkgs.add(pkg.name)
        self.assertTrue(len(test_pkgs) > 0)
        ul = UpdateList(None, dist="xenial")
        for pkgname in test_pkgs:
            pkg = self.cache[pkgname]
            self.assertTrue(
                ul._is_security_update(pkg),
                "pkg '%s' is not in xenial-security" % pkg.name,
            )

    def testOriginMatcherWithVersionInUpdatesAndSecurity(self):
        # empty dpkg status
        self.cache.open(apt.progress.base.OpProgress())

        # find test packages set
        test_pkgs = set()
        for pkg in self.cache:
            # only test on native arch
            if ":" in pkg.name:
                continue
            # check if the candidate origin is -updates (but not also
            # -security, often packages are available in both)
            if pkg.candidate is not None:
                # ensure that the origin is not in -updates and -security
                is_in_updates = False
                is_in_security = False
                had_security = False
                for v in pkg.candidate.origins:
                    # test if the package is not in both updates and security
                    if v.archive == "xenial-updates":
                        is_in_updates = True
                    elif v.archive == "xenial-security":
                        is_in_security = True
                # ensure that the package actually has any version in -security
                for v in pkg.versions:
                    for (pkgfile, _unused) in v._cand.file_list:
                        o = apt.package.Origin(pkg, pkgfile)
                        if o.archive == "xenial-security":
                            had_security = True
                            break
                if (
                    is_in_updates
                    and not is_in_security
                    and had_security
                    and len(pkg._pkg.version_list) > 2
                ):
                    test_pkgs.add(pkg.name)
        self.assertTrue(
            len(test_pkgs) > 0,
            "no suitable test package found that has a version in "
            "both -security and -updates and where -updates is newer",
        )

        # now test if versions in -security are detected
        ul = UpdateList(None, dist="xenial")
        for pkgname in test_pkgs:
            pkg = self.cache[pkgname]
            self.assertTrue(
                ul._is_security_update(pkg),
                "package '%s' from xenial-updates contains also a "
                "(not yet installed) security update, but it is "
                "not labeled as such" % pkg.name,
            )

        # now check if it marks the version with -update if the -security
        # version is installed
        for pkgname in test_pkgs:
            pkg = self.cache[pkgname]
            # FIXME: make this more inteligent (picking the version from
            #        -security
            sec_ver = pkg._pkg.version_list[1]
            self.dpkg_status.write(
                "Package: %s\n"
                "Status: install ok installed\n"
                "Installed-Size: 1\n"
                "Version: %s\n"
                "Architecture: all\n"
                "Description: foo\n\n" % (pkg.name, sec_ver.ver_str)
            )
            self.dpkg_status.flush()
        self.cache.open()
        for pkgname in test_pkgs:
            pkg = self.cache[pkgname]
            self.assertIsNotNone(
                pkg._pkg.current_ver, "no package '%s' installed" % pkg.name
            )
            candidate_version = getattr(pkg.candidate, "version", None)
            self.assertFalse(
                ul._is_security_update(pkg),
                "package '%s' (%s) from xenial-updates is "
                "labelled as a security update even though we "
                "have marked this version as installed already"
                % (pkg.name, candidate_version),
            )


if __name__ == "__main__":
    unittest.main()