~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/canonical/archivepublisher/ftests/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-03-17 20:41:13 UTC
  • mfrom: (3277.1.4 launchpad-foobar2)
  • Revision ID: pqm@pqm.ubuntu.com-20060317204113-9841a4470db3611b
[r=jamesh] Mainline soyuz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2004-2005 Canonical Ltd.  All rights reserved.
 
2
 
 
3
__metaclass__ = type
 
4
 
 
5
import os
 
6
import sys
 
7
import subprocess
 
8
import signal
 
9
import fcntl
 
10
import time
 
11
 
 
12
from canonical.config import config
 
13
 
 
14
class SoyuzUploadError(Exception):
 
15
    """Used in the soyuz-upload test."""
 
16
 
 
17
class PoppyTestSetup:
 
18
    """Provides a setup and teardown mechanism for a poppy subprocess instance.
 
19
 
 
20
    Use this like you would LibrarianTestSetup or similar.
 
21
    """
 
22
 
 
23
    def __init__(self, fsroot,
 
24
                 user='ubuntutest',
 
25
                 cmd='echo @distro@; ls @fsroot@',
 
26
                 port=3421):
 
27
        self.fsroot = fsroot
 
28
        self.user = user
 
29
        self.cmd = cmd
 
30
        self.port = str(port)
 
31
        self.running = False
 
32
 
 
33
    def startPoppy(self):
 
34
        """Start the poppy instance."""
 
35
        script = os.path.join(config.root, "daemons/poppy-upload.py")
 
36
        self.process = subprocess.Popen([sys.executable, script,
 
37
                                         "--allow-user", self.user,
 
38
                                         "--cmd", self.cmd,
 
39
                                         self.fsroot, self.port],
 
40
                                        stdout=subprocess.PIPE)
 
41
        self.running = True
 
42
 
 
43
    def setNonBlocking(self):
 
44
        """Ensure that Poppy's stdout is nonblocking."""
 
45
        flags = fcntl.fcntl(self.process.stdout.fileno(), fcntl.F_GETFL, 0)
 
46
        flags |= os.O_NONBLOCK
 
47
        fcntl.fcntl(self.process.stdout.fileno(), fcntl.F_SETFL, flags)
 
48
 
 
49
    def killPoppy(self):
 
50
        """Kill the poppy instance dead."""
 
51
        if not self.alive:
 
52
            return
 
53
        os.kill(self.process.pid, signal.SIGTERM)
 
54
        # Give poppy a chance to die
 
55
        time.sleep(2)
 
56
        # Look to see if it has died yet
 
57
        ret = self.process.poll()
 
58
        if ret is None:
 
59
            # Poppy had not died, so send it SIGKILL
 
60
            os.kill(self.process.pid, signal.SIGKILL)
 
61
        # Finally return the result.
 
62
        self.running = False
 
63
        return self.process.wait()
 
64
 
 
65
    @property
 
66
    def alive(self):
 
67
        """Whether or not the poppy instance is still alive."""
 
68
        if not self.running:
 
69
            return False
 
70
        return self.process.poll() is None
 
71
 
 
72
 
 
73
    def read(self):
 
74
        """Read some bytes from Poppy's stdout."""
 
75
        return self.process.stdout.read()
 
76
 
 
77
 
 
78
    def verify_output(self, expected):
 
79
        """Verify that poppy writes the expected output."""
 
80
        now = time.time()
 
81
        timeout = 60
 
82
        buffer = ""
 
83
        while time.time() - now < timeout:
 
84
            if not self.alive:
 
85
                raise SoyuzUploadError("Poppy died unexpectedly")
 
86
            data = self.read()
 
87
            if data:
 
88
                now = time.time() # Reset the timout
 
89
                buffer += data
 
90
                lines = buffer.splitlines()
 
91
                for line in lines:
 
92
                    if line == self.user:
 
93
                        continue
 
94
                    if line not in expected:
 
95
                        raise SoyuzUploadError("Unexpected line found in "
 
96
                                               "poppy output: %r" % line)
 
97
                    expected.remove(line)
 
98
                buffer = ""
 
99
            if not expected:
 
100
                break
 
101
            time.sleep(0.5)
 
102
        else:
 
103
            raise SoyuzUploadError("FTP server timed out. The following "
 
104
                                   "was expected but not yet received: %r"
 
105
                                   % expected)