This file is indexed.

/usr/lib/python3/dist-packages/txfixtures/tachandler.py is in python3-txfixtures 0.2.6-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
# GNU General Public License version 3.

"""Test harness for TAC (Twisted Application Configuration) files."""

__metaclass__ = type

__all__ = [
    'TacException',
    'TacTestFixture',
    ]


import errno
import os
import socket
import subprocess
import sys
import time
import warnings

from fixtures import Fixture

from testtools.content import content_from_file
from txfixtures.osutils import (
    get_pid_from_file,
    kill_by_pidfile,
    two_stage_kill,
    until_no_eintr,
    )


class TacException(Exception):
    """Error raised by TacTestSetup."""


class TacTestFixture(Fixture):
    """Setup an TAC file as daemon for use by functional tests.

    You must override setUpRoot to set up a root directory for the daemon.

    You may override _hasDaemonStarted, typically by calling _isPortListening,
    to tell how long to wait before the daemon is available.
    """

    _proc = None

    def setUp(self, spew=False, umask=None,
              python_path=None, twistd_script=None):
        """Initialize a new TacTestFixture fixture.

        :param python_path: If set, run twistd under this Python interpreter.
        :param twistd_script: If set, run this twistd script rather than the
            system default.  Must be provided if python_path is given.
        """
        super(TacTestFixture, self).setUp()
        if get_pid_from_file(self.pidfile):
            # An attempt to run while there was an existing live helper
            # was made. Note that this races with helpers which use unique
            # roots, so when moving/eliminating this code check subclasses
            # for workarounds and remove those too.
            pid = get_pid_from_file(self.pidfile)
            warnings.warn("Attempt to start Tachandler %r with an existing "
                "instance (%d) running in %s." % (
                self.tacfile, pid, self.pidfile),
                UserWarning, stacklevel=2)
            two_stage_kill(pid)
            # If the pid file still exists, it may indicate that the process
            # respawned itself, or that two processes were started (race?) and
            # one is still running while the other has ended, or the process
            # was killed but it didn't remove the pid file (bug), or the
            # machine was hard-rebooted and the pid file was not cleaned up
            # (bug again). In other words, it's not safe to assume that a
            # stale pid file is safe to delete without human intervention.
            stale_pid = get_pid_from_file(self.pidfile)
            if stale_pid:
                raise TacException(
                    "Could not kill stale process %s from %s." % (
                        stale_pid, self.pidfile,))

        self.setUpRoot()
        if python_path is None:
            python_path = sys.executable
        if twistd_script is None:
            twistd_script = '/usr/bin/twistd'
        args = [python_path,
            '-Wignore::DeprecationWarning',
            twistd_script,
            '-o', '-y', self.tacfile, '--pidfile', self.pidfile,
            '--logfile', self.logfile]
        if spew:
            args.append('--spew')
        if umask is not None:
            args.extend(('--umask', umask))

        # 2010-04-26, Salgado, http://pad.lv/570246: Deprecation warnings
        # in Twisted are not our problem.  They also aren't easy to suppress,
        # and cause test failures due to spurious stderr output.  Just shut
        # the whole bloody mess up.

        # Run twistd, and raise an error if the return value is non-zero or
        # stdout/stderr are written to.
        self._proc = subprocess.Popen(
            args,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            )
        self.addCleanup(self.killTac)
        stdout = until_no_eintr(10, self._proc.stdout.read)
        if stdout:
            raise TacException('Error running %s: unclean stdout/err: %s'
                               % (args, stdout))
        rv = self._proc.wait()
        # twistd will normally fork off into the background with the
        # originally-spawned process exiting 0.
        if rv != 0:
            raise TacException('Error %d running %s' % (rv, args))

        self.addDetail(self.logfile, content_from_file(self.logfile))
        self._waitForDaemonStartup()

    def _hasDaemonStarted(self):
        """Has the daemon started?
        """
        return self._isPortListening('localhost', self.daemon_port)

    def _isPortListening(self, host, port):
        """True if a tcp port is accepting connections.

        This can be used by subclasses overriding _hasDaemonStarted, if they
        want to check the port is up rather than for the contents of the log
        file.
        """
        try:
            s = socket.socket()
            s.settimeout(2.0)
            s.connect((host, port))
            s.close()
            return True
        except socket.error as e:
            if e.errno == errno.ECONNREFUSED:
                return False
            else:
                raise

    def _waitForDaemonStartup(self):
        """ Wait for the daemon to fully start.

        Times out after 20 seconds.  If that happens, the log file content
        will be included in the exception message for debugging purpose.

        :raises TacException: Timeout.
        """
        # Watch the log file for readyservice.LOG_MAGIC to signal that startup
        # has completed.
        now = time.time()
        deadline = now + 20
        while now < deadline and not self._hasDaemonStarted():
            time.sleep(0.1)
            now = time.time()

        if now >= deadline:
            raise TacException('Unable to start %s.' % self.tacfile)

    def tearDown(self):
        # For compatibility - migrate to cleanUp.
        self.cleanUp()

    def killTac(self):
        """Kill the TAC file if it is running."""
        pidfile = self.pidfile
        kill_by_pidfile(pidfile)
        if self._proc:
            # Close the pipe
            self._proc.stdout.close()

    def sendSignal(self, sig):
        """Send the given signal to the tac process."""
        pid = get_pid_from_file(self.pidfile)
        if pid is None:
            return
        os.kill(pid, sig)

    def setUpRoot(self):
        """Override this.

        This should be able to cope with the root already existing, because it
        will be left behind after each test in case it's needed to diagnose a
        test failure (e.g. log files might contain helpful tracebacks).
        """
        raise NotImplementedError

    @property
    def root(self):
        raise NotImplementedError

    @property
    def tacfile(self):
        raise NotImplementedError

    @property
    def pidfile(self):
        raise NotImplementedError

    @property
    def logfile(self):
        raise NotImplementedError

    @property
    def daemon_port(self):
        raise NotImplementedError