~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/poppy/tests/test_poppy.py

  • Committer: Julian Edwards
  • Date: 2011-02-23 15:16:38 UTC
  • mfrom: (12392.7.32 twisted-ftp-poppy)
  • mto: This revision was merged to the branch mainline in revision 12470.
  • Revision ID: julian.edwards@canonical.com-20110223151638-8cw0twgnyx2a8c0y
merge parent branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 
8
8
import os
9
9
import shutil
 
10
import stat
10
11
import StringIO
11
12
import tempfile
12
13
import time
34
35
from lp.registry.interfaces.ssh import (
35
36
    ISSHKeySet,
36
37
    )
 
38
from lp.poppy.hooks import Hooks
37
39
from lp.testing import TestCaseWithFactory
38
40
 
39
41
 
46
48
 
47
49
    def setUp(self):
48
50
        super(FTPServer, self).setUp()
49
 
        self.useFixture(PoppyTac(self.root_dir))
 
51
        self.poppytac = self.useFixture(PoppyTac(self.root_dir))
 
52
 
 
53
    def getAnonTransport(self):
 
54
        return get_transport(
 
55
            'ftp://anonymous:me@example.com@localhost:%s/' % (self.port,))
50
56
 
51
57
    def getTransport(self):
52
58
        return get_transport('ftp://ubuntu:@localhost:%s/' % (self.port,))
58
64
        """Wait for the FTP server to start up."""
59
65
        pass
60
66
 
61
 
    def waitForClose(self):
 
67
    def waitForClose(self, number=1):
62
68
        """Wait for an FTP connection to close.
63
69
 
64
 
        Poppy is configured to echo 'CLOSED' to stdout when a
65
 
        connection closes, so we wait for CLOSED to appear in its
 
70
        Poppy is configured to echo 'Post-processing finished' to stdout
 
71
        when a connection closes, so we wait for that to appear in its
66
72
        output as a way to tell that the server has finished with the
67
73
        connection.
68
74
        """
69
 
        time.sleep(5)
 
75
        self.poppytac.waitForPostProcessing(number)
70
76
 
71
77
 
72
78
class SFTPServer(Fixture):
106
112
    def setUp(self):
107
113
        super(SFTPServer, self).setUp()
108
114
        self.setUpUser('joe')
109
 
        self.useFixture(PoppyTac(self.root_dir))
 
115
        self.poppytac = self.useFixture(PoppyTac(self.root_dir))
110
116
 
111
117
    def disconnect(self, transport):
112
118
        transport._get_connection().close()
114
120
    def waitForStartUp(self):
115
121
        pass
116
122
 
117
 
    def waitForClose(self):
118
 
        # XXX: Steve Kowalik 2010-05-24 bug=586695 There has to be a
119
 
        # better way to wait for the SFTP server to process our upload
120
 
        # rather than sleeping for 10 seconds.
121
 
        time.sleep(10)
 
123
    def waitForClose(self, number=1):
 
124
        self.poppytac.waitForPostProcessing(number)
122
125
 
123
126
    def getTransport(self):
124
127
        return get_transport('sftp://joe@localhost:%s/' % (self.port,))
164
167
    def pidfile(self):
165
168
        return os.path.join(self.root, 'poppy-sftp.pid')
166
169
 
 
170
    def waitForPostProcessing(self, number=1):
 
171
        now = time.time()
 
172
        deadline = now + 20
 
173
        while now < deadline and not self._hasPostProcessed(number):
 
174
            time.sleep(0.1)
 
175
            now = time.time()
 
176
 
 
177
        if now >= deadline:
 
178
            raise Exception("Poppy post-processing did not complete")
 
179
 
 
180
    def _hasPostProcessed(self, number):
 
181
        if os.path.exists(self.logfile):
 
182
            with open(self.logfile, "r") as logfile:
 
183
                occurrences = logfile.read().count(Hooks.LOG_MAGIC)
 
184
                return occurrences >= number
 
185
        else:
 
186
            return False
 
187
 
167
188
 
168
189
class TestPoppy(TestCaseWithFactory):
169
190
    """Test if poppy.py daemon works properly."""
184
205
        upload_dir = contents[1]
185
206
        return os.path.join(self.root_dir, upload_dir, path)
186
207
 
187
 
    def test_change_directory(self):
 
208
    def test_change_directory_anonymous(self):
 
209
        # Check that FTP access with an anonymous user works.
 
210
        transport = self.server.getAnonTransport()
 
211
        self.test_change_directory(transport)
 
212
 
 
213
    def test_change_directory(self, transport=None):
188
214
        """Check automatic creation of directories 'cwd'ed in.
189
215
 
190
216
        Also ensure they are created with proper permission (g+rwxs)
191
217
        """
192
218
        self.server.waitForStartUp()
193
219
 
194
 
        transport = self.server.getTransport()
 
220
        if transport is None:
 
221
            transport = self.server.getTransport()
195
222
        transport.stat('foo/bar') # .stat will implicity chdir for us
196
223
 
197
224
        self.server.disconnect(transport)
249
276
        wanted_path = self._uploadPath('foo/bar/baz')
250
277
        fs_content = open(os.path.join(wanted_path)).read()
251
278
        self.assertEqual(fs_content, "fake contents")
252
 
        # This is a magic and very opaque number.  It corresponds to
253
 
        # the following stat.S_* masks:
254
 
        # S_IROTH, S_ISGID, S_IRGRP, S_IWGRP, S_IWUSR, S_IWUSR
255
 
        # which in readable terms is: -rw-rwSr--
256
 
        self.assertEqual(os.stat(wanted_path).st_mode, 0102664)
 
279
        # Expected mode is -rw-rwSr--.
 
280
        self.assertEqual(
 
281
            os.stat(wanted_path).st_mode,
 
282
            stat.S_IROTH | stat.S_ISGID | stat.S_IRGRP | stat.S_IWGRP
 
283
            | stat.S_IWUSR | stat.S_IRUSR | stat.S_IFREG)
257
284
 
258
285
    def test_full_source_upload(self):
259
286
        """Check that the connection will deal with multiple files being
288
315
                "~ppa-user/ppa/ubuntu/%s" % upload)
289
316
            fs_content = open(os.path.join(wanted_path)).read()
290
317
            self.assertEqual(fs_content, upload)
291
 
            # This is a magic and very opaque number.  It corresponds to
292
 
            # the following stat.S_* masks:
293
 
            # S_IROTH, S_ISGID, S_IRGRP, S_IWGRP, S_IWUSR, S_IWUSR
294
 
            # which in readable terms is: -rw-rwSr--
295
 
            self.assertEqual(os.stat(wanted_path).st_mode, 0102664)
 
318
            # Expected mode is -rw-rwSr--.
 
319
            self.assertEqual(
 
320
                os.stat(wanted_path).st_mode,
 
321
                stat.S_IROTH | stat.S_ISGID | stat.S_IRGRP | stat.S_IWGRP
 
322
                | stat.S_IWUSR | stat.S_IRUSR | stat.S_IFREG)
296
323
 
297
324
    def test_upload_isolation(self):
298
325
        """Check if poppy isolates the uploads properly.
307
334
        fake_file = StringIO.StringIO("ONE")
308
335
        conn_one.put_file('test', fake_file, mode=None)
309
336
        self.server.disconnect(conn_one)
310
 
        self.server.waitForClose()
311
337
 
312
338
        conn_two = self.server.getTransport()
313
339
        fake_file = StringIO.StringIO("TWO")
314
340
        conn_two.put_file('test', fake_file, mode=None)
315
341
        self.server.disconnect(conn_two)
316
 
        self.server.waitForClose()
317
342
 
318
343
        # Perform a pair of sessions with simultaneous connections.
319
344
        conn_three = self.server.getTransport()
326
351
        conn_four.put_file('test', fake_file, mode=None)
327
352
 
328
353
        self.server.disconnect(conn_three)
329
 
        self.server.waitForClose()
330
354
 
331
355
        self.server.disconnect(conn_four)
332
 
        self.server.waitForClose()
 
356
 
 
357
        # Wait for the 4 uploads to finish.
 
358
        self.server.waitForClose(4)
333
359
 
334
360
        # Build a list of directories representing the 4 sessions.
335
361
        upload_dirs = [leaf for leaf in sorted(os.listdir(self.root_dir))
360
386
    # SFTP doesn't have the concept of the server changing directories, since
361
387
    # clients will only send absolute paths, so drop that test.
362
388
    return exclude_tests_by_condition(
363
 
        suite, condition_id_re(r'test_change_directory\(sftp\)$'))
 
389
        suite, condition_id_re(r'test_change_directory.*\(sftp\)$'))