summaryrefslogtreecommitdiff
path: root/test/pre-upload-check.py
blob: f9da8f941eaedc93c507354c92a1c8f044339a73 (plain)
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/usr/bin/python

import sys
import os
import glob
import os.path
import shutil
import time
from subprocess import call, PIPE

import unittest

stdout = os.open("/dev/null",0) #sys.stdout
stderr = os.open("/dev/null",0) # sys.stderr

apt_args = [] 
#apt_args = ["-o","Debug::pkgAcquire::Auth=true"]

class testAptAuthenticationReliability(unittest.TestCase):
    """
    test if the spec https://wiki.ubuntu.com/AptAuthenticationReliability 
    is properly implemented
    """
    #apt = "../bin/apt-get"
    apt = "apt-get"

    def setUp(self):
        if os.path.exists("/tmp/autFailure"):
            os.unlink("/tmp/authFailure");
        if os.path.exists("/tmp/autFailure2"):
            os.unlink("/tmp/authFailure2");
    def testRepositorySigFailure(self):
        """
        test if a repository that used to be authenticated and fails on
        apt-get update refuses to update and uses the old state
        """
        # copy valid signatures into lists (those are ok, even
        # if the name is "-broken-" ...
        for f in glob.glob("./authReliability/lists/*"):
            shutil.copy(f,"/var/lib/apt/lists")
            # ensure we do *not* get a I-M-S hit
            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (0,0))
        res = call([self.apt,
                    "update",
                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.failure", 
                    "-o",'APT::Update::Auth-Failure::=touch /tmp/authFailure',
                   ] + apt_args,
                   stdout=stdout, stderr=stderr)
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg"),
                     "The gpg file disappeared, this should not happen")
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages"),
                     "The Packages file disappeared, this should not happen")
        self.assert_(os.path.exists("/tmp/authFailure"),
                     "The APT::Update::Auth-Failure script did not run (1)")
        # the same with i-m-s hit this time
        for f in glob.glob("./authReliability/lists/*"):
            shutil.copy(f,"/var/lib/apt/lists")
            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (time.time(),time.time()))
        res = call([self.apt,
                    "update",
                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.failure",
                    "-o",'APT::Update::Auth-Failure::=touch /tmp/authFailure2',
                   ] + apt_args,
                   stdout=stdout, stderr=stderr)
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg"),
                     "The gpg file disappeared, this should not happen")
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages"),
                     "The Packages file disappeared, this should not happen")
        self.assert_(os.path.exists("/tmp/authFailure2"),
                     "The APT::Update::Auth-Failure script did not run (2)")
    def testRepositorySigGood(self):
        """
        test that a regular repository with good data stays good
        """
        res = call([self.apt,
                    "update",
                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
                   ] + apt_args,
                   stdout=stdout, stderr=stderr)
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
                     "The gpg file disappeared after a regular download, this should not happen")
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
                     "The Packages file disappeared, this should not happen")
        # test good is still good after non I-M-S hit and a previous files in lists/
        for f in glob.glob("./authReliability/lists/*"):
            shutil.copy(f,"/var/lib/apt/lists")
            # ensure we do *not* get a I-M-S hit
            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (0,0))
        res = call([self.apt,
                    "update",
                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
                   ] + apt_args,
                   stdout=stdout, stderr=stderr)
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
                     "The gpg file disappeared after a I-M-S hit, this should not happen")
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
                     "The Packages file disappeared, this should not happen")
        # test good is still good after I-M-S hit
        for f in glob.glob("./authReliability/lists/*"):
            shutil.copy(f,"/var/lib/apt/lists")
            # ensure we do get a I-M-S hit
            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (time.time(),time.time()))
        res = call([self.apt,
                    "update",
                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
                   ] + apt_args,
                   stdout=stdout, stderr=stderr)
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
                     "The gpg file disappeared, this should not happen")
        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
                     "The Packages file disappeared, this should not happen")


class testAuthentication(unittest.TestCase):
    """
    test if the authentication is working, the repository
    of the test-data can be found here:
    bzr get http://people.ubuntu.com/~mvo/bzr/apt/apt-auth-test-suit/
    """
    
    # some class wide data
    apt = "apt-get"
    pkg = "libglib2.0-data"
    pkgver = "2.13.6-1ubuntu1"
    pkgpath = "/var/cache/apt/archives/libglib2.0-data_2.13.6-1ubuntu1_all.deb"

    def setUp(self):
        for f in glob.glob("testkeys/*,key"):
            call(["apt-key", "add", f], stdout=stdout, stderr=stderr)

    def _cleanup(self):
        " make sure we get new lists and no i-m-s "
        call(["rm","-f", "/var/lib/apt/lists/*"])
        if os.path.exists(self.pkgpath):
            os.unlink(self.pkgpath)

    def _expectedRes(self, resultstr):
        if resultstr == 'ok':
            return 0
        elif resultstr == 'broken':
            return 100
        

    def testPackages(self):
        for f in glob.glob("testsources.list/sources.list*package*"):
            self._cleanup()
            (prefix, testtype, result) = f.split("-")
            expected_res = self._expectedRes(result)
            # update first
            call([self.apt,"update",
                  "-o","Dir::Etc::sourcelist=./%s" % f]+apt_args,
                 stdout=stdout, stderr=stderr)
            # then get the pkg
            cmd = ["install", "-y", "-d", "--reinstall",
                   "%s=%s" % (self.pkg, self.pkgver),
                   "-o","Dir::state::Status=./fake-status"]
            res = call([self.apt, "-o","Dir::Etc::sourcelist=./%s" % f]+cmd+apt_args,
                       stdout=stdout, stderr=stderr)
            self.assert_(res == expected_res,
                         "test '%s' failed (got %s expected %s" % (f,res,expected_res))
            

    def testGPG(self):
        for f in glob.glob("testsources.list/sources.list*gpg*"):
            self._cleanup()
            (prefix, testtype, result) = f.split("-")
            expected_res = self._expectedRes(result)
            # update first
            call([self.apt,"update",
                  "-o","Dir::Etc::sourcelist=./%s" % f]+apt_args,
                 stdout=stdout, stderr=stderr)
            cmd = ["install", "-y", "-d", "--reinstall",
                   "%s=%s" % (self.pkg, self.pkgver),
                   "-o","Dir::state::Status=./fake-status"]
            res = call([self.apt, "-o","Dir::Etc::sourcelist=./%s" % f]+
                       cmd+apt_args,
                       stdout=stdout, stderr=stderr)
            self.assert_(res == expected_res,
                         "test '%s' failed (got %s expected %s" % (f,res,expected_res))

    def testRelease(self):
        for f in glob.glob("testsources.list/sources.list*release*"):
            self._cleanup()
            (prefix, testtype, result) = f.split("-")
            expected_res = self._expectedRes(result)
            cmd = ["update"]
            res = call([self.apt,"-o","Dir::Etc::sourcelist=./%s" % f]+cmd+apt_args,
                       stdout=stdout, stderr=stderr)
            self.assert_(res == expected_res,
                         "test '%s' failed (got %s expected %s" % (f,res,expected_res))
            if expected_res == 0:
                self.assert_(len(glob.glob("/var/lib/apt/lists/partial/*")) == 0,
                             "partial/ dir has leftover files: %s" % glob.glob("/var/lib/apt/lists/partial/*"))

    def testValid(self):
        for f in glob.glob("testsources.list/sources.list*validuntil*"):
            self._cleanup()
            (prefix, testtype, result) = f.split("-")
            expected_res = self._expectedRes(result)
            cmd = ["update"]
            res = call([self.apt,"-o","Dir::Etc::sourcelist=./%s" % f]+cmd+apt_args,
                       stdout=stdout, stderr=stderr)
            self.assert_(res == expected_res,
                         "test '%s' failed (got %s expected %s" % (f,res,expected_res))
            if expected_res == 0:
                self.assert_(len(glob.glob("/var/lib/apt/lists/partial/*")) == 0,
                             "partial/ dir has leftover files: %s" % glob.glob("/var/lib/apt/lists/partial/*"))


class testLocalRepositories(unittest.TestCase):
    " test local repository regressions "

    repo_dir = "local-repo"
    apt = "apt-get"
    pkg = "gdebi-test4"

    def setUp(self):
        self.repo = os.path.abspath(os.path.join(os.getcwd(), self.repo_dir))
        self.sources = os.path.join(self.repo, "sources.list")
        s = open(self.sources,"w")
        s.write("deb file://%s/ /\n" % self.repo)
        s.close()

    def testLocalRepoAuth(self):
        # two times to get at least one i-m-s hit
        for i in range(2):
            self.assert_(os.path.exists(self.sources))
            cmd = [self.apt,"update","-o", "Dir::Etc::sourcelist=%s" % self.sources]+apt_args
            res = call(cmd, stdout=stdout, stderr=stderr)
            self.assertEqual(res, 0, "local repo test failed")
            self.assert_(os.path.exists(os.path.join(self.repo,"Packages.gz")),
                         "Packages.gz vanished from local repo")

    def testInstallFromLocalRepo(self):
        apt = [self.apt,"-o", "Dir::Etc::sourcelist=%s"% self.sources]+apt_args
        cmd = apt+["update"]
        res = call(cmd, stdout=stdout, stderr=stderr)
        self.assertEqual(res, 0)
        res = call(apt+["-y","install","--reinstall",self.pkg],
                   stdout=stdout, stderr=stderr)
        self.assert_(res == 0,
                     "installing %s failed (got %s)" % (self.pkg, res))
        res = call(apt+["-y","remove",self.pkg],
                   stdout=stdout, stderr=stderr)
        self.assert_(res == 0,
                     "removing %s failed (got %s)" % (self.pkg, res))

    def testPythonAptInLocalRepo(self):
        import apt, apt_pkg
        apt_pkg.Config.Set("Dir::Etc::sourcelist",self.sources)
        cache = apt.Cache()
        cache.update()
        pkg = cache["apt"]
        self.assert_(pkg.name == 'apt')
        


if __name__ == "__main__":
    print "Runing simple testsuit on current apt-get and libapt"
    if len(sys.argv) > 1 and sys.argv[1] == "-v":
        stdout = sys.stdout
        stderr = sys.stderr
    
    # run only one for now
    #unittest.main(defaultTest="testAptAuthenticationReliability")
    unittest.main()