Пример #1
0
 def setUp(self):
     super(ReactorIntegrationTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.reactor = EPollReactor()
     self.fixture = Reactor(self.reactor)
     self.patcher = ReactorPatcher(self.fixture.reactor)
     self.addCleanup(self._cleanup)
Пример #2
0
 def setUp(self):
     super(ServiceIntegrationTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.script = self.useFixture(FakeExecutable())
     reactor = self.useFixture(Reactor())
     command = self.script.path.encode("utf-8")
     self.fixture = Service(reactor, command)
Пример #3
0
    def setUp(self):
        super(PhantomJSIntegrationTest, self).setUp()
        self.logger = self.useFixture(FakeLogger())
        reactor = self.useFixture(Reactor())

        # Setup a local web server to test the WebDriver
        server = Service(reactor, "twist", args=["web"], timeout=5)
        server.expectOutput("Starting reactor...")
        server.expectPort(8080)
        self.useFixture(server)

        self.fixture = PhantomJS(reactor, timeout=10)
Пример #4
0
 def setUp(self):
     super(MongoDBTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.reactor = ThreadedMemoryReactorClock()
     self.fixture = MongoDB(Reactor(self.reactor))
Пример #5
0
 def setUp(self):
     super(ReactorTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.reactor = ThreadedMemoryReactorClock()
     self.fixture = Reactor(self.reactor, timeout=0)
     self.threads = self.useFixture(FakeThreads())
Пример #6
0
class ReactorTest(TestCase):
    def setUp(self):
        super(ReactorTest, self).setUp()
        self.logger = self.useFixture(FakeLogger())
        self.reactor = ThreadedMemoryReactorClock()
        self.fixture = Reactor(self.reactor, timeout=0)
        self.threads = self.useFixture(FakeThreads())

    def test_install_sigchld_waker(self):
        """
        At setup time, a reactor waker for the SIGCHLD signal is installed.
        """
        self.fixture.setUp()
        [reader] = list(self.reactor.readers)
        self.assertIsInstance(reader, _SIGCHLDWaker)
        self.assertTrue(reader.installed)

    def test_call(self):
        """The call() method is a convenience around blockingFromThread."""
        output = self.fixture.call(0, lambda: succeed("hello"))
        self.assertEqual("hello", output)

    def test_reset_thread_and_reactor_died(self):
        """
        The reset() method creates a new thread if the initial one has died.
        """
        self.fixture.setUp()
        self.fixture.reset()
        self.assertIn("Twisted reactor thread died, trying to recover",
                      self.logger.output)

    def test_reset_thread_died_but_reactor_is_running(self):
        """
        If the reactor crashes badly and is left in a bad state (e.g. running),
        the fixtures tries a best-effort clean up.
        """
        self.fixture.setUp()
        self.reactor.running = True
        self.fixture.reset()
        self.assertTrue(self.reactor.hasCrashed)
        self.assertIn("Twisted reactor thread died, trying to recover",
                      self.logger.output)
        self.assertIn("Twisted reactor has broken state, trying to reset",
                      self.logger.output)

    def test_reset_hung_thread(self):
        """
        The reset() method bails out if the thread is alive but the reactor
        doesn't appear to be running.
        """
        self.fixture.setUp()
        self.fixture.thread.alive = True
        self.reactor.running = False
        error = self.assertRaises(RuntimeError, self.fixture.reset)
        self.assertEqual("Hung reactor thread detected", str(error))

    def test_cleanup_stops_thread_and_reactor(self):
        """After cleanUp is run, the reactor is stopped."""
        self.fixture.setUp()
        self.fixture.cleanUp()
        self.assertFalse(self.fixture.thread.isAlive())
        self.assertFalse(self.fixture.reactor.running)

    def test_cleanup_thread_not_alive(self):
        """
        If the thread is not alive, the cleanup phase is essentially a no-op.
        """
        self.fixture.setUp()
        self.reactor.stop()
        self.fixture.thread.alive = False
        self.fixture.cleanUp()

        # There's only the entry about starting the thread, since upon cleanup
        # nothing was running.
        self.assertIn("Starting Twisted reactor in a separate thread",
                      self.logger.output)

    def test_cleanup_hung_thread(self):
        """
        If cleanUp() detects a hung thread with no reactor running, an error
        is raised.
        """
        self.fixture.setUp()
        self.fixture.thread.alive = True
        self.reactor.running = False
        error = self.assertRaises(RuntimeError, self.fixture.cleanUp)
        self.assertEqual("Hung reactor thread detected", str(error))

    def test_cleanup_hung_reactor(self):
        """
        If cleanUp() can't stop the reactor, an error is raised.
        """
        self.fixture.setUp()
        self.reactor.isAsync = True
        self.fixture.thread.alive = True

        error = self.assertRaises(RuntimeError, self.fixture.cleanUp)
        self.assertEqual("Could not stop the reactor", str(error))

    def test_cleanup_thread_does_not_die(self):
        """
        If cleanUp() can't stop the thread, an error is raised.
        """
        self.fixture.setUp()

        self.fixture.thread.hang = True
        self.fixture.thread.alive = True

        error = self.assertRaises(RuntimeError, self.fixture.cleanUp)
        self.assertEqual("Could not stop the reactor thread", str(error))
Пример #7
0
class ReactorIntegrationTest(TestCase):
    def setUp(self):
        super(ReactorIntegrationTest, self).setUp()
        self.logger = self.useFixture(FakeLogger())
        self.reactor = EPollReactor()
        self.fixture = Reactor(self.reactor)
        self.patcher = ReactorPatcher(self.fixture.reactor)
        self.addCleanup(self._cleanup)

    def _cleanup(self):
        # Make sure that the thread has terminated and that the
        # reactor is back to a clean state.
        self.patcher.restore()
        if self.fixture.thread:
            logging.info("Waiting for thread to terminate")
            self.fixture.thread.join(timeout=TIMEOUT)
            assert not self.fixture.thread.isAlive(), "Thread did not stop"

    def test_reactor_running(self):
        """After setUp is run, the reactor is spinning."""
        self.useFixture(self.fixture)
        self.assertTrue(self.reactor.running)

    @skipIf(not AsyncioSelectorReactor, "asyncio reactor not available")
    def test_asyncio_reactor(self):
        """It's possible to start a custom reactor, like the asyncio one."""
        eventloop = asyncio.new_event_loop()
        self.fixture.reactor = AsyncioSelectorReactor(eventloop=eventloop)
        self.useFixture(self.fixture)
        self.assertTrue(self.fixture.reactor.running)

        # The asyncio loop is actually running
        ready = Queue()
        eventloop.call_soon_threadsafe(ready.put, None)
        self.assertIsNone(ready.get(timeout=TIMEOUT))

    def test_separate_thread(self):
        """The reactor runs in a separate thread."""
        self.useFixture(self.fixture)
        # Figure the number of active threads, excluding the twisted thread
        # pool.
        threads = []
        for thread in threading.enumerate():
            if thread.name.startswith("PoolThread-twisted.internet.reactor"):
                continue
            threads.append(thread)
        self.assertEqual(2, len(threads))

    def test_call(self):
        """The call() method is a convenience around blockingFromThread."""
        self.useFixture(self.fixture)
        output = self.fixture.call(TIMEOUT,
                                   getProcessOutput,
                                   b("uptime"),
                                   reactor=self.reactor)
        self.assertIn(b("load average"), output)

    def test_reset_thread_and_reactor_died(self):
        """
        The reset() method creates a new thread if the initial one has died.
        """
        self.useFixture(self.fixture)
        self.fixture.call(TIMEOUT, self.reactor.crash)
        self.fixture.thread.join(timeout=TIMEOUT)
        self.assertFalse(self.fixture.thread.isAlive())

        self.fixture.reset()
        self.assertTrue(self.reactor.running)
        self.assertIn("Twisted reactor thread died, trying to recover",
                      self.logger.output)

    def test_reset_thread_died_but_reactor_is_running(self):
        """
        If the reactor crashes badly and is left in a bad state (e.g. running),
        the fixtures tries a best-effort clean up.
        """
        self.fixture.timeout = 100
        self.patcher.patch()
        self.patcher.scheduleCrash(abruptly=True)
        self.useFixture(self.fixture)
        self.patcher.crashingDo.put(None)

        # At this point the thread should be dead and the reactor broken
        self.fixture.thread.join(TIMEOUT)
        self.assertFalse(self.fixture.thread.isAlive())
        self.assertTrue(self.reactor.running)

        self.fixture.reset()

        self.assertIn("Twisted reactor thread died, trying to recover",
                      self.logger.output)
        self.assertIn("Twisted reactor has broken state, trying to reset",
                      self.logger.output)

        # Things should be back to normality
        self.assertTrue(self.fixture.thread.isAlive(), "Thread did not resume")
        self.assertTrue(self.reactor.running, "Reactor did not recover")

    def test_reset_thread_alive_but_reactor_is_not_running(self):
        """
        The reset() method bails out if the thread is alive but the reactor
        doesn't appear to be running.
        """
        self.patcher.patch()
        self.patcher.scheduleHang()
        self.patcher.scheduleCrash()
        self.fixture.setUp()
        self.patcher.crashingDo.put(None)
        self.patcher.crashingNotify.get(timeout=TIMEOUT)

        # At this point the thread should be alive and the reactor broken
        self.assertTrue(self.fixture.thread.isAlive())
        self.assertFalse(self.reactor.running)

        error = self.assertRaises(RuntimeError, self.fixture.reset)
        self.assertEqual("Hung reactor thread detected", str(error))

    def test_cleanup_stops_thread_and_reactor(self):
        """After cleanUp is run, the reactor is stopped."""
        self.fixture.setUp()
        self.fixture.cleanUp()
        self.assertFalse(self.fixture.thread.isAlive())
        self.assertFalse(self.reactor.running)

    def test_cleanup_thread_not_alive(self):
        """
        If the thread is not alive, the cleanup phase is essentially a no-op.
        """
        self.fixture.setUp()
        self.fixture.call(TIMEOUT, self.reactor.crash)
        self.fixture.thread.join(TIMEOUT)
        self.fixture.cleanUp()

        # There's only the entry about starting the thread, since upon cleanup
        # nothing was running.
        self.assertNotIn("Stopping Twisted reactor and wait for its thread",
                         self.logger.output)
        self.assertNotIn("Twisted reactor has broken state, trying to reset",
                         self.logger.output)

    def test_cleanup_hung_thread(self):
        """
        If cleanUp() detects a hung thread with no reactor running, an error
        is raised.
        """
        self.patcher.patch()
        self.patcher.scheduleHang()
        self.patcher.scheduleCrash()
        self.fixture.setUp()
        self.patcher.crashingDo.put(None)
        self.patcher.crashingNotify.get(timeout=TIMEOUT)

        # At this point the thread should be alive and the reactor stopped
        self.assertTrue(self.fixture.thread.isAlive())
        self.assertFalse(self.reactor.running)

        error = self.assertRaises(RuntimeError, self.fixture.cleanUp)
        self.assertEqual("Hung reactor thread detected", str(error))

    def test_cleanup_hung_reactor(self):
        """
        If cleanUp() can't stop the reactor, an error is raised.
        """
        self.patcher.patch()
        self.patcher.scheduleHang()
        self.patcher.scheduleCallFromThreadTimeout(self.reactor.crash)
        self.fixture.setUp()

        # At this point the thread should be alive and the reactor running
        self.assertTrue(self.fixture.thread.isAlive())
        self.assertTrue(self.reactor.running)

        error = self.assertRaises(RuntimeError, self.fixture.cleanUp)
        self.assertEqual("Could not stop the reactor", str(error))
Пример #8
0
 def setUp(self):
     super(MongoDBIntegrationTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     reactor = self.useFixture(Reactor())
     self.mongodb = MongoDB(reactor)
Пример #9
0
 def setUp(self):
     super(ServiceTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.reactor = ThreadedMemoryReactorClock()
     self.fixture = Service(Reactor(self.reactor), "foo")
Пример #10
0
 def setUp(self):
     super(InterruptableCallFromThreadTest, self).setUp()
     self.useFixture(Reactor(reactor))
Пример #11
0
 def setUp(self):
     super(PhantomJSTest, self).setUp()
     self.logger = self.useFixture(FakeLogger())
     self.reactor = ThreadedMemoryReactorClock()
     self.fixture = PhantomJS(Reactor(self.reactor))