예제 #1
0
    def test_metaDescriptorInheritance(self):
        """
        If a L{TwistdSlaveProcess} specifies a meta-file-descriptor to be
        inherited, it should be inherited by the subprocess, and a
        configuration argument should be passed that indicates to the
        subprocess.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)
        # Most arguments here will be ignored, so these are bogus values.
        slave = TwistdSlaveProcess(
            twistd="bleh",
            tapname="caldav",
            configFile="/does/not/exist",
            id=10,
            interfaces="127.0.0.1",
            metaSocket=FakeDispatcher().addSocket(),
        )

        dspm.addProcessObject(slave, {})
        dspm.startService()
        oneProcessTransport = imps.waitForOneProcess()
        self.assertIn("MetaFD=4", oneProcessTransport.args)
        self.assertEquals(
            oneProcessTransport.args[oneProcessTransport.args.index("MetaFD=4") - 1],
            "-o",
            "MetaFD argument was not passed as an option",
        )
        self.assertEquals(oneProcessTransport.childFDs, {0: "w", 1: "r", 2: "r", 4: 4})
예제 #2
0
    def test_acceptDescriptorInheritance(self):
        """
        If a L{TwistdSlaveProcess} specifies some file descriptors to be
        inherited, they should be inherited by the subprocess.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)

        # Most arguments here will be ignored, so these are bogus values.
        slave = TwistdSlaveProcess(
            twistd="bleh",
            tapname="caldav",
            configFile="/does/not/exist",
            id=10,
            interfaces="127.0.0.1",
            inheritFDs=[3, 7],
            inheritSSLFDs=[19, 25],
        )

        dspm.addProcessObject(slave, {})
        dspm.startService()
        # We can easily stub out spawnProcess, because caldav calls it, but a
        # bunch of callLater calls are buried in procmon itself, so we need to
        # use the real clock.
        oneProcessTransport = imps.waitForOneProcess()
        self.assertEquals(oneProcessTransport.childFDs, {0: "w", 1: "r", 2: "r", 3: 3, 7: 7, 19: 19, 25: 25})
예제 #3
0
    def test_lineAfterLongLine(self):
        """
        A "long" line of output from a monitored process (longer than
        L{LineReceiver.MAX_LENGTH}) should be logged in chunks rather than all
        at once, to avoid resource exhaustion.
        """
        dspm = DelayedStartupProcessMonitor()
        dspm.addProcessObject(
            ScriptProcessObject(
                'longlines.py',
                str(DelayedStartupLineLogger.MAX_LENGTH)
            ),
            os.environ
        )
        dspm.startService()
        self.addCleanup(dspm.stopService)

        logged = []

        def tempObserver(event):
            # Probably won't be a problem, but let's not have any intermittent
            # test issues that stem from multi-threaded log messages randomly
            # going off...
            if not isInIOThread():
                callFromThread(tempObserver, event)
                return
            if event.get('isError'):
                d.errback()
            m = event.get('message')[0]
            if m.startswith('[Dummy] '):
                logged.append(event)
                if m == '[Dummy] z':
                    d.callback("done")

        logging.addObserver(tempObserver)
        self.addCleanup(logging.removeObserver, tempObserver)
        d = Deferred()

        def assertions(result):
            self.assertEquals(["[Dummy] x",
                               "[Dummy] y",
                               "[Dummy] y",  # final segment
                               "[Dummy] z"],
                              [''.join(evt['message'])[:len('[Dummy]') + 2]
                               for evt in logged])
            self.assertEquals([" (truncated, continued)",
                               " (truncated, continued)",
                               "[Dummy] y",
                               "[Dummy] z"],
                              [''.join(evt['message'])[-len(" (truncated, continued)"):]
                               for evt in logged])
        d.addCallback(assertions)
        return d
예제 #4
0
 def test_changedArgumentEachSpawn(self):
     """
     If the result of C{getCommandLine} changes on subsequent calls,
     subsequent calls should result in different arguments being passed to
     C{spawnProcess} each time.
     """
     imps = InMemoryProcessSpawner()
     dspm = DelayedStartupProcessMonitor(imps)
     slave = DummyProcessObject("scriptname", "first")
     dspm.addProcessObject(slave, {})
     dspm.startService()
     oneProcessTransport = imps.waitForOneProcess()
     self.assertEquals(oneProcessTransport.args, ["scriptname", "first"])
     slave.args = ["second"]
     oneProcessTransport.processProtocol.processEnded(None)
     twoProcessTransport = imps.waitForOneProcess()
     self.assertEquals(twoProcessTransport.args, ["scriptname", "second"])
예제 #5
0
    def test_startServiceDelay(self):
        """
        Starting a L{DelayedStartupProcessMonitor} should result in the process
        objects that have been added to it being started once per
        delayInterval.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)
        dspm.delayInterval = 3.0
        sampleCounter = range(0, 5)
        for counter in sampleCounter:
            slave = TwistdSlaveProcess(twistd="bleh",
                                       tapname="caldav",
                                       configFile="/does/not/exist",
                                       id=counter * 10,
                                       interfaces='127.0.0.1',
                                       metaSocket=FakeDispatcher().addSocket())
            dspm.addProcessObject(slave, {"SAMPLE_ENV_COUNTER": str(counter)})
        dspm.startService()

        # Advance the clock a bunch of times, allowing us to time things with a
        # comprehensible resolution.
        imps.pump([0] + [dspm.delayInterval / 2.0] * len(sampleCounter) * 3)
        expectedValues = [dspm.delayInterval * n for n in sampleCounter]
        self.assertEquals([x.startedAt for x in imps.processTransports],
                          expectedValues)
예제 #6
0
    def test_startServiceDelay(self):
        """
        Starting a L{DelayedStartupProcessMonitor} should result in the process
        objects that have been added to it being started once per
        delayInterval.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)
        dspm.delayInterval = 3.0
        sampleCounter = range(0, 5)
        for counter in sampleCounter:
            slave = TwistdSlaveProcess(
                twistd="bleh",
                tapname="caldav",
                configFile="/does/not/exist",
                id=counter * 10,
                interfaces="127.0.0.1",
                metaSocket=FakeDispatcher().addSocket(),
            )
            dspm.addProcessObject(slave, {"SAMPLE_ENV_COUNTER": str(counter)})
        dspm.startService()

        # Advance the clock a bunch of times, allowing us to time things with a
        # comprehensible resolution.
        imps.pump([0] + [dspm.delayInterval / 2.0] * len(sampleCounter) * 3)
        expectedValues = [dspm.delayInterval * n for n in sampleCounter]
        self.assertEquals([x.startedAt for x in imps.processTransports], expectedValues)
예제 #7
0
    def test_metaDescriptorInheritance(self):
        """
        If a L{TwistdSlaveProcess} specifies a meta-file-descriptor to be
        inherited, it should be inherited by the subprocess, and a
        configuration argument should be passed that indicates to the
        subprocess.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)
        # Most arguments here will be ignored, so these are bogus values.
        slave = TwistdSlaveProcess(twistd="bleh",
                                   tapname="caldav",
                                   configFile="/does/not/exist",
                                   id=10,
                                   interfaces='127.0.0.1',
                                   metaSocket=FakeDispatcher().addSocket())

        dspm.addProcessObject(slave, {})
        dspm.startService()
        oneProcessTransport = imps.waitForOneProcess()
        self.assertIn("MetaFD=4", oneProcessTransport.args)
        self.assertEquals(
            oneProcessTransport.args[oneProcessTransport.args.index("MetaFD=4")
                                     - 1], '-o',
            "MetaFD argument was not passed as an option")
        self.assertEquals(oneProcessTransport.childFDs, {
            0: 'w',
            1: 'r',
            2: 'r',
            4: 4
        })
예제 #8
0
    def test_acceptDescriptorInheritance(self):
        """
        If a L{TwistdSlaveProcess} specifies some file descriptors to be
        inherited, they should be inherited by the subprocess.
        """
        imps = InMemoryProcessSpawner()
        dspm = DelayedStartupProcessMonitor(imps)

        # Most arguments here will be ignored, so these are bogus values.
        slave = TwistdSlaveProcess(
            twistd="bleh",
            tapname="caldav",
            configFile="/does/not/exist",
            id=10,
            interfaces='127.0.0.1',
            inheritFDs=[3, 7],
            inheritSSLFDs=[19, 25],
        )

        dspm.addProcessObject(slave, {})
        dspm.startService()
        # We can easily stub out spawnProcess, because caldav calls it, but a
        # bunch of callLater calls are buried in procmon itself, so we need to
        # use the real clock.
        oneProcessTransport = imps.waitForOneProcess()
        self.assertEquals(oneProcessTransport.childFDs, {
            0: 'w',
            1: 'r',
            2: 'r',
            3: 3,
            7: 7,
            19: 19,
            25: 25
        })
예제 #9
0
    def test_lineAfterLongLine(self):
        """
        A "long" line of output from a monitored process (longer than
        L{LineReceiver.MAX_LENGTH}) should be logged in chunks rather than all
        at once, to avoid resource exhaustion.
        """
        dspm = DelayedStartupProcessMonitor()
        dspm.addProcessObject(
            ScriptProcessObject('longlines.py',
                                str(DelayedStartupLineLogger.MAX_LENGTH)),
            os.environ)
        dspm.startService()
        self.addCleanup(dspm.stopService)

        logged = []

        def tempObserver(event):
            # Probably won't be a problem, but let's not have any intermittent
            # test issues that stem from multi-threaded log messages randomly
            # going off...
            if not isInIOThread():
                callFromThread(tempObserver, event)
                return
            if event.get('isError'):
                d.errback()
            m = event.get('message')[0]
            if m.startswith('[Dummy] '):
                logged.append(event)
                if m == '[Dummy] z':
                    d.callback("done")

        logging.addObserver(tempObserver)
        self.addCleanup(logging.removeObserver, tempObserver)
        d = Deferred()

        def assertions(result):
            self.assertEquals(
                [
                    "[Dummy] x",
                    "[Dummy] y",
                    "[Dummy] y",  # final segment
                    "[Dummy] z"
                ],
                [
                    ''.join(evt['message'])[:len('[Dummy]') + 2]
                    for evt in logged
                ])
            self.assertEquals([
                " (truncated, continued)", " (truncated, continued)",
                "[Dummy] y", "[Dummy] z"
            ], [
                ''.join(evt['message'])[-len(" (truncated, continued)"):]
                for evt in logged
            ])

        d.addCallback(assertions)
        return d
예제 #10
0
 def test_changedArgumentEachSpawn(self):
     """
     If the result of C{getCommandLine} changes on subsequent calls,
     subsequent calls should result in different arguments being passed to
     C{spawnProcess} each time.
     """
     imps = InMemoryProcessSpawner()
     dspm = DelayedStartupProcessMonitor(imps)
     slave = DummyProcessObject('scriptname', 'first')
     dspm.addProcessObject(slave, {})
     dspm.startService()
     oneProcessTransport = imps.waitForOneProcess()
     self.assertEquals(oneProcessTransport.args, ['scriptname', 'first'])
     slave.args = ['second']
     oneProcessTransport.processProtocol.processEnded(None)
     twoProcessTransport = imps.waitForOneProcess()
     self.assertEquals(twoProcessTransport.args, ['scriptname', 'second'])
예제 #11
0
    def test_metaDescriptorInheritance(self):
        """
        If a L{TwistdSlaveProcess} specifies a meta-file-descriptor to be
        inherited, it should be inherited by the subprocess, and a
        configuration argument should be passed that indicates to the
        subprocess.
        """
        dspm         = DelayedStartupProcessMonitor()
        dspm.reactor = InMemoryProcessSpawner()
        class FakeFD:
            def __init__(self, n):
                self.fd = n
            def fileno(self):
                return self.fd

        class FakeDispatcher:
            n = 3
            def addSocket(self):
                self.n += 1
                return FakeFD(self.n)

        # Most arguments here will be ignored, so these are bogus values.
        slave = TwistdSlaveProcess(
            twistd     = "bleh",
            tapname    = "caldav",
            configFile = "/does/not/exist",
            id         = 10,
            interfaces = '127.0.0.1',
            metaSocket = FakeDispatcher().addSocket()
        )

        dspm.addProcessObject(slave, {})
        dspm.startService()
        self.addCleanup(dspm.consistency.cancel)
        oneProcessTransport = yield dspm.reactor.waitForOneProcess()
        self.assertIn("MetaFD=4", oneProcessTransport.args)
        self.assertEquals(
            oneProcessTransport.args[oneProcessTransport.args.index("MetaFD=4")-1],
            '-o',
            "MetaFD argument was not passed as an option"
        )
        self.assertEquals(oneProcessTransport.childFDs,
                          {0: 'w', 1: 'r', 2: 'r',
                           4: 4})