Example #1
0
class CallFromThreadTestCase(unittest.TestCase):
    """Task scheduling from threads tests."""

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "Nothing to test without thread support"

    def schedule(self, *args, **kwargs):
        """Override in subclasses."""
        reactor.callFromThread(*args, **kwargs)

    def testScheduling(self):
        c = Counter()
        for i in range(100):
            self.schedule(c.add)
        for i in range(100):
            reactor.iterate()
        self.assertEquals(c.index, 100)

    def testCorrectOrder(self):
        o = Order()
        self.schedule(o.a)
        self.schedule(o.b)
        self.schedule(o.c)
        reactor.iterate()
        reactor.iterate()
        reactor.iterate()
        self.assertEquals(o.stage, 3)

    def testNotRunAtOnce(self):
        c = Counter()
        self.schedule(c.add)
        # scheduled tasks should not be run at once:
        self.assertEquals(c.index, 0)
        reactor.iterate()
        self.assertEquals(c.index, 1)
Example #2
0
class WaitReentrancyTest(unittest.TestCase):

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = ("This test probably doesn't really need threads "
                "but hell if I can figure out how to rewrite it "
                "without them.  Skipping in the absence of "
                "thread-support.")

    def _returnedDeferredThenWait(self):
        def threadedOperation():
            time.sleep(0.1)
            return "Beginning"

        d = threads.deferToThread(threadedOperation)
        return d.addCallback(self._cbDoWait)

    def _cbDoWait(self, result):
        self.assertEquals(result, "Beginning")
        d = defer.succeed("End")
        self.assertEquals(util.wait(d), "End")

    def testReturnedDeferredThenWait(self):
        d = self._returnedDeferredThenWait()
        self.assertRaises(util.WaitIsNotReentrantError, util.wait, d)

    def _reentrantWait(self):
        def threadedOperation(n):
            time.sleep(n)
            return n

        d1 = threads.deferToThread(threadedOperation, 0.125)
        d2 = threads.deferToThread(threadedOperation, 0.250)
        d1.addCallback(lambda ignored: util.wait(d2))
        util.wait(d1)

    def testReentrantWait(self):
        self.assertRaises(util.WaitIsNotReentrantError, self._reentrantWait)

    def test_twoWaitImplementations(self):
        # If this test times out, then wait is being re-entered.
        tc = TestMktemp('test_name')
        tc._timedOut = False  # whitebox
        d = defer.Deferred()

        def _runsInsideWait(r):
            d = defer.Deferred()
            self.assertRaises(util.WaitIsNotReentrantError, util.wait, d)

        d.addCallback(utils.suppressWarnings(_runsInsideWait, *suppress))
        reactor.callLater(0, d.callback, 'yo')
        tc._wait(d)

    test_twoWaitImplementations.timeout = 4
Example #3
0
class TimeoutQueueTest(unittest.TestCase):
    """
    Test L{timeoutqueue.TimeoutQueue} class.
    """
    def tearDown(self):
        del self.q

    def put(self):
        time.sleep(1)
        self.q.put(1)

    def test_timeout(self):
        q = self.q = timeoutqueue.TimeoutQueue()

        try:
            q.wait(1)
        except timeoutqueue.TimedOut:
            pass
        else:
            self.fail("Didn't time out")

    test_timeout.suppress = [timeoutqueueSuppression]

    def test_get(self):
        q = self.q = timeoutqueue.TimeoutQueue()

        start = time.time()
        threading.Thread(target=self.put).start()
        q.wait(1.5)
        assert time.time() - start < 2

        result = q.get(0)
        if result != 1:
            self.fail("Didn't get item we put in")

    test_get.suppress = [timeoutqueueSuppression]

    def test_deprecation(self):
        """
        Test that L{timeoutqueue.TimeoutQueue} prints a warning message.
        """
        def createQueue():
            return timeoutqueue.TimeoutQueue()

        self.q = self.assertWarns(
            DeprecationWarning, "timeoutqueue is deprecated since Twisted 8.0",
            __file__, createQueue)

    if interfaces.IReactorThreads(reactor, None) is None:
        test_get.skip = "No thread support, no way to test putting during a blocked get"
    else:
        global threading
        import threading
Example #4
0
class ReconnectTestBase:
    """Test the asynchronous DB-API code with reconnect."""

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "ADB-API requires threads, no way to test without them"

    def wait(self, d, timeout=10.0):
        return unittest.wait(d, timeout=timeout)

    def setUp(self):
        if self.good_sql is None:
            raise unittest.SkipTest('no good sql for reconnect test')
        self.startDB()
        self.dbpool = self.makePool(cp_max=1,
                                    cp_reconnect=True,
                                    cp_good_sql=self.good_sql)
        self.dbpool.start()
        self.wait(self.dbpool.runOperation(simple_table_schema))

    def tearDown(self):
        self.wait(self.dbpool.runOperation('DROP TABLE simple'))
        self.dbpool.close()
        self.stopDB()

    def testPool(self):
        sql = "select count(1) from simple"
        row = self.wait(self.dbpool.runQuery(sql))
        self.failUnless(int(row[0][0]) == 0, "Table not empty")

        # reach in and close the connection manually
        self.dbpool.connections.values()[0].close()

        if not self.early_reconnect:
            try:
                self.wait(self.dbpool.runQuery(sql))
                self.fail('no exception')
            except ConnectionLost:
                pass
            except:
                self.fail('not connection lost')

        row = self.wait(self.dbpool.runQuery(sql))
        self.failUnless(int(row[0][0]) == 0, "Table not empty")

        sql = "select * from NOTABLE"  # bad sql
        try:
            self.wait(self.dbpool.runQuery(sql))
            self.fail('no exception')
        except ConnectionLost:
            self.fail('connection lost exception')
        except:
            pass
Example #5
0
 def _bail(self):
     from twisted.internet import reactor
     d = defer.Deferred()
     reactor.addSystemEventTrigger('after', 'shutdown',
                                   lambda: d.callback(None))
     reactor.fireSystemEvent('shutdown')  # radix's suggestion
     treactor = interfaces.IReactorThreads(reactor, None)
     if treactor is not None:
         treactor.suggestThreadPoolSize(0)
     # As long as TestCase does crap stuff with the reactor we need to
     # manually shutdown the reactor here, and that requires util.wait
     # :(
     # so that the shutdown event completes
     unittest.TestCase('mktemp')._wait(d)
Example #6
0
class CallFromThreadStopsAndWakeUpTests(TestCase):
    @skipIf(
        not interfaces.IReactorThreads(reactor, None),
        "Nothing to wake up for without thread support",
    )
    def testWakeUp(self):
        # Make sure other threads can wake up the reactor
        d = Deferred()

        def wake():
            time.sleep(0.1)
            # callFromThread will call wakeUp for us
            reactor.callFromThread(d.callback, None)

        reactor.callInThread(wake)
        return d

    def _stopCallFromThreadCallback(self):
        self.stopped = True

    def _callFromThreadCallback(self, d):
        reactor.callFromThread(self._callFromThreadCallback2, d)
        reactor.callLater(0, self._stopCallFromThreadCallback)

    def _callFromThreadCallback2(self, d):
        try:
            self.assertTrue(self.stopped)
        except:
            # Send the error to the deferred
            d.errback()
        else:
            d.callback(None)

    def testCallFromThreadStops(self):
        """
        Ensure that callFromThread from inside a callFromThread
        callback doesn't sit in an infinite loop and lets other
        things happen too.
        """
        self.stopped = False
        d = defer.Deferred()
        reactor.callFromThread(self._callFromThreadCallback, d)
        return d
class TimeoutQueueTest(unittest.TestCase):
    def setUp(self):
        self.q = timeoutqueue.TimeoutQueue()

    def tearDown(self):
        del self.q

    def put(self):
        time.sleep(1)
        self.q.put(1)

    def testTimeout(self):
        q = self.q

        try:
            q.wait(1)
        except timeoutqueue.TimedOut:
            pass
        else:
            raise AssertionError, "didn't time out"

    def testGet(self):
        q = self.q
        start = time.time()
        threading.Thread(target=self.put).start()
        q.wait(1.5)
        assert time.time() - start < 2

        result = q.get(0)
        if result != 1:
            raise AssertionError, "didn't get item we put in"

    if interfaces.IReactorThreads(reactor, None) is None:
        testGet.skip = "No thread support, no way to test putting during a blocked get"
    else:
        global threading
        import threading
Example #8
0
class ReconnectTestBase:
    """Test the asynchronous DB-API code with reconnect."""

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "ADB-API requires threads, no way to test without them"

    def setUp(self):
        if self.good_sql is None:
            raise unittest.SkipTest('no good sql for reconnect test')
        self.startDB()
        self.dbpool = self.makePool(cp_max=1,
                                    cp_reconnect=True,
                                    cp_good_sql=self.good_sql)
        self.dbpool.start()
        return self.dbpool.runOperation(simple_table_schema)

    def tearDown(self):
        d = self.dbpool.runOperation('DROP TABLE simple')
        d.addCallback(lambda res: self.dbpool.close())
        d.addCallback(lambda res: self.stopDB())
        return d

    def testPool(self):
        d = defer.succeed(None)
        d.addCallback(self._testPool_1)
        d.addCallback(self._testPool_2)
        if not self.early_reconnect:
            d.addCallback(self._testPool_3)
        d.addCallback(self._testPool_4)
        d.addCallback(self._testPool_5)
        return d

    def _testPool_1(self, res):
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.failUnless(int(row[0][0]) == 0, "Table not empty")

        d.addCallback(_check)
        return d

    def _testPool_2(self, res):
        # reach in and close the connection manually
        self.dbpool.connections.values()[0].close()

    def _testPool_3(self, res):
        sql = "select count(1) from simple"
        d = defer.maybeDeferred(self.dbpool.runQuery, sql)
        d.addCallbacks(lambda res: self.fail('no exception'),
                       lambda f: f.trap(ConnectionLost))
        return d

    def _testPool_4(self, res):
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.failUnless(int(row[0][0]) == 0, "Table not empty")

        d.addCallback(_check)
        return d

    def _testPool_5(self, res):
        sql = "select * from NOTABLE"  # bad sql
        d = defer.maybeDeferred(self.dbpool.runQuery, sql)
        d.addCallbacks(lambda res: self.fail('no exception'),
                       lambda f: self.failIf(f.check(ConnectionLost)))
        return d
Example #9
0
class ADBAPITestBase:
    """Test the asynchronous DB-API code."""

    openfun_called = {}

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "ADB-API requires threads, no way to test without them"

    def setUp(self):
        self.startDB()
        self.dbpool = self.makePool(cp_openfun=self.openfun)
        self.dbpool.start()

    def tearDown(self):
        d = self.dbpool.runOperation('DROP TABLE simple')
        d.addCallback(lambda res: self.dbpool.close())
        d.addCallback(lambda res: self.stopDB())
        return d

    def openfun(self, conn):
        self.openfun_called[conn] = True

    def checkOpenfunCalled(self, conn=None):
        if not conn:
            self.failUnless(self.openfun_called)
        else:
            self.failUnless(self.openfun_called.has_key(conn))

    def testPool(self):
        d = self.dbpool.runOperation(simple_table_schema)
        if self.test_failures:
            d.addCallback(self._testPool_1_1)
            d.addCallback(self._testPool_1_2)
            d.addCallback(self._testPool_1_3)
            d.addCallback(self._testPool_1_4)
            d.addCallback(lambda res: log.flushErrors())
        d.addCallback(self._testPool_2)
        d.addCallback(self._testPool_3)
        d.addCallback(self._testPool_4)
        d.addCallback(self._testPool_5)
        d.addCallback(self._testPool_6)
        d.addCallback(self._testPool_7)
        d.addCallback(self._testPool_8)
        d.addCallback(self._testPool_9)
        return d

    def _testPool_1_1(self, res):
        d = defer.maybeDeferred(self.dbpool.runQuery, "select * from NOTABLE")
        d.addCallbacks(lambda res: self.fail('no exception'), lambda f: None)
        return d

    def _testPool_1_2(self, res):
        d = defer.maybeDeferred(self.dbpool.runOperation,
                                "deletexxx from NOTABLE")
        d.addCallbacks(lambda res: self.fail('no exception'), lambda f: None)
        return d

    def _testPool_1_3(self, res):
        d = defer.maybeDeferred(self.dbpool.runInteraction,
                                self.bad_interaction)
        d.addCallbacks(lambda res: self.fail('no exception'), lambda f: None)
        return d

    def _testPool_1_4(self, res):
        d = defer.maybeDeferred(self.dbpool.runWithConnection,
                                self.bad_withConnection)
        d.addCallbacks(lambda res: self.fail('no exception'), lambda f: None)
        return d

    def _testPool_2(self, res):
        # verify simple table is empty
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.failUnless(int(row[0][0]) == 0, "Interaction not rolled back")
            self.checkOpenfunCalled()

        d.addCallback(_check)
        return d

    def _testPool_3(self, res):
        sql = "select count(1) from simple"
        inserts = []
        # add some rows to simple table (runOperation)
        for i in range(self.num_iterations):
            sql = "insert into simple(x) values(%d)" % i
            inserts.append(self.dbpool.runOperation(sql))
        d = defer.gatherResults(inserts)

        def _select(res):
            # make sure they were added (runQuery)
            sql = "select x from simple order by x"
            d = self.dbpool.runQuery(sql)
            return d

        d.addCallback(_select)

        def _check(rows):
            self.failUnless(
                len(rows) == self.num_iterations, "Wrong number of rows")
            for i in range(self.num_iterations):
                self.failUnless(len(rows[i]) == 1, "Wrong size row")
                self.failUnless(rows[i][0] == i, "Values not returned.")

        d.addCallback(_check)

        return d

    def _testPool_4(self, res):
        # runInteraction
        d = self.dbpool.runInteraction(self.interaction)
        d.addCallback(lambda res: self.assertEquals(res, "done"))
        return d

    def _testPool_5(self, res):
        # withConnection
        d = self.dbpool.runWithConnection(self.withConnection)
        d.addCallback(lambda res: self.assertEquals(res, "done"))
        return d

    def _testPool_6(self, res):
        # Test a withConnection cannot be closed
        d = self.dbpool.runWithConnection(self.close_withConnection)
        return d

    def _testPool_7(self, res):
        # give the pool a workout
        ds = []
        for i in range(self.num_iterations):
            sql = "select x from simple where x = %d" % i
            ds.append(self.dbpool.runQuery(sql))
        dlist = defer.DeferredList(ds, fireOnOneErrback=True)

        def _check(result):
            for i in range(self.num_iterations):
                self.failUnless(result[i][1][0][0] == i, "Value not returned")

        dlist.addCallback(_check)
        return dlist

    def _testPool_8(self, res):
        # now delete everything
        ds = []
        for i in range(self.num_iterations):
            sql = "delete from simple where x = %d" % i
            ds.append(self.dbpool.runOperation(sql))
        dlist = defer.DeferredList(ds, fireOnOneErrback=True)
        return dlist

    def _testPool_9(self, res):
        # verify simple table is empty
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.failUnless(
                int(row[0][0]) == 0,
                "Didn't successfully delete table contents")
            self.checkConnect()

        d.addCallback(_check)
        return d

    def checkConnect(self):
        """Check the connect/disconnect synchronous calls."""
        conn = self.dbpool.connect()
        self.checkOpenfunCalled(conn)
        curs = conn.cursor()
        curs.execute("insert into simple(x) values(1)")
        curs.execute("select x from simple")
        res = curs.fetchall()
        self.failUnlessEqual(len(res), 1)
        self.failUnlessEqual(len(res[0]), 1)
        self.failUnlessEqual(res[0][0], 1)
        curs.execute("delete from simple")
        curs.execute("select x from simple")
        self.failUnlessEqual(len(curs.fetchall()), 0)
        curs.close()
        self.dbpool.disconnect(conn)

    def interaction(self, transaction):
        transaction.execute("select x from simple order by x")
        for i in range(self.num_iterations):
            row = transaction.fetchone()
            self.failUnless(len(row) == 1, "Wrong size row")
            self.failUnless(row[0] == i, "Value not returned.")
        # should test this, but gadfly throws an exception instead
        #self.failUnless(transaction.fetchone() is None, "Too many rows")
        return "done"

    def bad_interaction(self, transaction):
        if self.can_rollback:
            transaction.execute("insert into simple(x) values(0)")

        transaction.execute("select * from NOTABLE")

    def withConnection(self, conn):
        curs = conn.cursor()
        try:
            curs.execute("select x from simple order by x")
            for i in range(self.num_iterations):
                row = curs.fetchone()
                self.failUnless(len(row) == 1, "Wrong size row")
                self.failUnless(row[0] == i, "Value not returned.")
            # should test this, but gadfly throws an exception instead
            #self.failUnless(transaction.fetchone() is None, "Too many rows")
        finally:
            curs.close()
        return "done"

    def close_withConnection(self, conn):
        conn.close()

    def bad_withConnection(self, conn):
        curs = conn.cursor()
        try:
            curs.execute("select * from NOTABLE")
        finally:
            curs.close()
Example #10
0
                self.fail(
                    (
                        "The child process failed to produce "
                        "the desired results:\n"
                        "   Reason for termination was: {!r}\n"
                        "   Output stream was: {!r}\n"
                        "   Error stream was: {!r}\n"
                    ).format(reason.getErrorMessage(), output, b"".join(error))
                )

        helperDeferred.addCallback(cbFinished)
        return helperDeferred


@skipIf(
    not interfaces.IReactorThreads(reactor, None),
    "Nothing to test without thread support",
)
class CallFromThreadTests(TestCase):
    """
    Task scheduling from threads tests.
    """

    def setUp(self):
        self.counter = 0
        self.deferred = Deferred()

    def schedule(self, *args, **kwargs):
        """
        Override in subclasses.
        """
Example #11
0
class ReconnectTestBase:
    """
    Test the asynchronous DB-API code with reconnect.
    """

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "ADB-API requires threads, no way to test without them"

    def extraSetUp(self):
        """
        Skip the test if C{good_sql} is unavailable.  Otherwise, set up the
        database, create a connection pool pointed at it, and set up a simple
        schema in it.
        """
        if self.good_sql is None:
            raise unittest.SkipTest("no good sql for reconnect test")
        self.startDB()
        self.dbpool = self.makePool(cp_max=1,
                                    cp_reconnect=True,
                                    cp_good_sql=self.good_sql)
        self.dbpool.start()
        return self.dbpool.runOperation(simple_table_schema)

    def tearDown(self):
        d = self.dbpool.runOperation("DROP TABLE simple")
        d.addCallback(lambda res: self.dbpool.close())
        d.addCallback(lambda res: self.stopDB())
        return d

    def test_pool(self):
        d = defer.succeed(None)
        d.addCallback(self._testPool_1)
        d.addCallback(self._testPool_2)
        if not self.early_reconnect:
            d.addCallback(self._testPool_3)
        d.addCallback(self._testPool_4)
        d.addCallback(self._testPool_5)
        return d

    def _testPool_1(self, res):
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.assertTrue(int(row[0][0]) == 0, "Table not empty")

        d.addCallback(_check)
        return d

    def _testPool_2(self, res):
        # reach in and close the connection manually
        list(self.dbpool.connections.values())[0].close()

    def _testPool_3(self, res):
        sql = "select count(1) from simple"
        d = defer.maybeDeferred(self.dbpool.runQuery, sql)
        d.addCallbacks(lambda res: self.fail("no exception"), lambda f: None)
        return d

    def _testPool_4(self, res):
        sql = "select count(1) from simple"
        d = self.dbpool.runQuery(sql)

        def _check(row):
            self.assertTrue(int(row[0][0]) == 0, "Table not empty")

        d.addCallback(_check)
        return d

    def _testPool_5(self, res):
        self.flushLoggedErrors()
        sql = "select * from NOTABLE"  # bad sql
        d = defer.maybeDeferred(self.dbpool.runQuery, sql)
        d.addCallbacks(
            lambda res: self.fail("no exception"),
            lambda f: self.assertFalse(f.check(ConnectionLost)),
        )
        return d
Example #12
0
class InterfaceTestCase(unittest.TestCase):

    _called = 0

    def _callback(self, deferred, x, **d):
        """Callback for testCallLater"""
        self.assertEquals(x, 1)
        self.assertEquals(d, {'a': 1})
        self._called = 1
        self._calledTime = time.time()
        deferred.callback(None)

    def testCallLater(self):
        # add and remove a callback
        def bad():
            raise RuntimeError, "this shouldn't have been called"

        i = reactor.callLater(0.1, bad)
        i.cancel()

        self.assertRaises(error.AlreadyCancelled, i.cancel)

        d = defer.Deferred()
        i = reactor.callLater(0.5, self._callback, d, 1, a=1)
        start = time.time()

        def check(ignored):
            self.assertApproximates(self._calledTime, start + 0.5, 0.2)
            self.assertRaises(error.AlreadyCalled, i.cancel)
            del self._called
            del self._calledTime

        d.addCallback(check)
        return d

    def testCallLaterDelayAndReset(self):
        clock = Clock()
        clock.install()
        try:
            callbackTimes = [None, None]

            def resetCallback():
                callbackTimes[0] = clock()

            def delayCallback():
                callbackTimes[1] = clock()

            ireset = reactor.callLater(2, resetCallback)
            idelay = reactor.callLater(3, delayCallback)

            clock.pump(reactor, [0, 1])

            ireset.reset(2)  # (now)1 + 2 = 3
            idelay.delay(3)  # (orig)3 + 3 = 6

            clock.pump(reactor, [0, 1])

            self.assertIdentical(callbackTimes[0], None)
            self.assertIdentical(callbackTimes[0], None)

            clock.pump(reactor, [0, 1])

            self.assertEquals(callbackTimes[0], 3)
            self.assertEquals(callbackTimes[1], None)

            clock.pump(reactor, [0, 3])
            self.assertEquals(callbackTimes[1], 6)
        finally:
            clock.uninstall()

    def testCallLaterTime(self):
        d = reactor.callLater(10, lambda: None)
        try:
            self.failUnless(d.getTime() - (time.time() + 10) < 1)
        finally:
            d.cancel()

    def testCallInNextIteration(self):
        calls = []

        def f1():
            calls.append('f1')
            reactor.callLater(0.0, f2)

        def f2():
            calls.append('f2')
            reactor.callLater(0.0, f3)

        def f3():
            calls.append('f3')

        reactor.callLater(0, f1)
        self.assertEquals(calls, [])
        reactor.iterate()
        self.assertEquals(calls, ['f1'])
        reactor.iterate()
        self.assertEquals(calls, ['f1', 'f2'])
        reactor.iterate()
        self.assertEquals(calls, ['f1', 'f2', 'f3'])

    def testCallLaterOrder(self):
        l = []
        l2 = []

        def f(x):
            l.append(x)

        def f2(x):
            l2.append(x)

        def done():
            self.assertEquals(l, range(20))

        def done2():
            self.assertEquals(l2, range(10))

        for n in range(10):
            reactor.callLater(0, f, n)
        for n in range(10):
            reactor.callLater(0, f, n + 10)
            reactor.callLater(0.1, f2, n)

        reactor.callLater(0, done)
        reactor.callLater(0.1, done2)
        d = Deferred()
        reactor.callLater(0.2, d.callback, None)
        return d

    testCallLaterOrder.todo = "See bug 1396"
    testCallLaterOrder.skip = "Trial bug, todo doesn't work! See bug 1397"

    def testCallLaterOrder2(self):
        # This time destroy the clock resolution so that it fails reliably
        # even on systems that don't have a crappy clock resolution.

        def seconds():
            return int(time.time())

        from twisted.internet import base
        from twisted.python import runtime
        base_original = base.seconds
        runtime_original = runtime.seconds
        base.seconds = seconds
        runtime.seconds = seconds

        def cleanup(x):
            runtime.seconds = runtime_original
            base.seconds = base_original
            return x

        return maybeDeferred(self.testCallLaterOrder).addBoth(cleanup)

    testCallLaterOrder2.todo = "See bug 1396"
    testCallLaterOrder2.skip = "Trial bug, todo doesn't work! See bug 1397"

    def testDelayedCallStringification(self):
        # Mostly just make sure str() isn't going to raise anything for
        # DelayedCalls within reason.
        dc = reactor.callLater(0, lambda x, y: None, 'x', y=10)
        str(dc)
        dc.reset(5)
        str(dc)
        dc.cancel()
        str(dc)

        dc = reactor.callLater(0,
                               lambda: None,
                               x=[({
                                   'hello': u'world'
                               }, 10j), reactor],
                               *range(10))
        str(dc)
        dc.cancel()
        str(dc)

        def calledBack(ignored):
            str(dc)

        d = Deferred().addCallback(calledBack)
        dc = reactor.callLater(0, d.callback, None)
        str(dc)
        return d

    def testDelayedCallSecondsOverride(self):
        """
        Test that the C{seconds} argument to DelayedCall gets used instead of
        the default timing function, if it is not None.
        """
        def seconds():
            return 10

        dc = base.DelayedCall(5, lambda: None, (), {}, lambda dc: None,
                              lambda dc: None, seconds)
        self.assertEquals(dc.getTime(), 5)
        dc.reset(3)
        self.assertEquals(dc.getTime(), 13)

    def testWakeUp(self):
        # Make sure other threads can wake up the reactor
        d = Deferred()

        def wake():
            time.sleep(0.1)
            # callFromThread will call wakeUp for us
            reactor.callFromThread(d.callback, None)

        reactor.callInThread(wake)
        return d

    if interfaces.IReactorThreads(reactor, None) is None:
        testWakeUp.skip = "Nothing to wake up for without thread support"
Example #13
0
class ThreadedFlowTest(unittest.TestCase):
    if interfaces.IReactorThreads(reactor, None) is None:
        skip = ("No thread support in reactor, "
                "cannot test threaded flow constructs.")


    def testThreaded(self):
        expect = [5,4,3,2,1]
        d = flow.Deferred(Threaded(CountIterator(5)))
        d.addCallback(self.assertEquals, expect)
        return d

    def testThreadedError(self):
        # is this the expected behaviour?
        def iterator():
            yield 1
            raise ValueError
        d = flow.Deferred(Threaded(iterator()))
        return self.assertFailure(d, ValueError)

    def testThreadedSleep(self):
        expect = [5,4,3,2,1]
        d = flow.Deferred(Threaded(CountIterator(5)))
        sleep(.5)
        d.addCallback(self.assertEquals, expect)
        return d

    def testQueryIterator(self):
        try:
            from pyPgSQL import PgSQL
            dbpool = PgSQL
            c = dbpool.connect()
            r = c.cursor()
            r.execute("SELECT 'x'")
            r.fetchone()
        except:
            # PostgreSQL is not installed or bad permissions
            return
        expect = [['one'],['two'],['three']]
        sql = """
          (SELECT 'one')
        UNION ALL
          (SELECT 'two')
        UNION ALL
          (SELECT 'three')
        """
        d = flow.Deferred(Threaded(QueryIterator(dbpool, sql)))
        d.addCallback(self.assertEquals, expect)
        return d

    def testThreadedImmediate(self):
        """
            The goal of this test is to test the callback mechanism with
            regard to threads, namely to assure that results can be
            accumulated before they are needed; and that left-over results
            are immediately made available on the next round (even though
            the producing thread has shut down).  This is a very tough thing
            to test due to the timing issues.  So it may fail on some
            platforms, I'm not sure.
        """
        expect = [5,4,3,2,1]
        result = []
        f = Threaded(CountIterator(5))
        d = defer.Deferred()
        def process():
            coop = f._yield()
            if f.results:
                result.extend(f.results)
                del f.results[:len(result)]
                reactor.callLater(0, process)
                return
            if coop:
                sleep(.3)
                reactor.callLater(0, coop.callLater, process)
                return
            if f.stop:
                reactor.callLater(0, d.callback, result)
        reactor.callLater(0, process)
        d.addCallback(self.assertEquals, expect)
        return d
Example #14
0
class ReflectorTestBase:
    """
    Base class for testing reflectors.

    @ivar reflector: The reflector created during setup.
    """

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "No thread support, no reflector tests"

    count = 100 # a parameter used for running iterative tests

    def randomizeRow(self, row):
        return randomizeRow(row, self.nulls_ok, self.trailing_spaces_ok)

    def extraSetUp(self):
        """
        Create and store a reference to a SQL reflector for use by the tests.
        """
        d = self.createReflector()
        d.addCallback(self._cbSetUp)
        return d

    def _cbSetUp(self, reflector):
        self.reflector = reflector

    def tearDown(self):
        return self.destroyReflector()

    def destroyReflector(self):
        pass

    def test_reflector(self):
        """
        Full featured tests of reflector.
        """
        # create one row to work with
        row = TestRow()
        row.assignKeyAttr("key_string", "first")
        values = self.randomizeRow(row)

        # save it
        d = self.reflector.insertRow(row)

        def _loadBack(_):
            # now load it back in
            whereClause = [("key_string", EQUAL, "first")]
            d = self.reflector.loadObjectsFrom(tableName,
                                               whereClause=whereClause)
            return d.addCallback(self.gotData)

        def _getParent(_):
            # make sure it came back as what we saved
            self.failUnless(len(self.data) == 1, "no row")
            parent = self.data[0]
            self.failUnless(rowMatches(parent, values), "no match")
            return parent

        d.addCallback(_loadBack)
        d.addCallback(_getParent)
        d.addCallback(self._cbTestReflector)
        return d
    test_reflector.suppress = [rowObjectSuppression, reflectorSuppression]

    def _cbTestReflector(self, parent):
        # create some child rows
        test_values = {}
        inserts = []
        child_values = {}
        for i in range(0, self.num_iterations):
            row = ChildRow()
            row.assignKeyAttr("childId", i)
            values = self.randomizeRow(row)
            values['test_key'] = row.test_key = "first"
            child_values[i] = values
            inserts.append(self.reflector.insertRow(row))
            row = None
        #del inserts
        d = defer.gatherResults(inserts)
        values = [None]

        def _loadObjects(_):
            d = self.reflector.loadObjectsFrom(childTableName, parentRow=parent)
            return d.addCallback(self.gotData)

        def _checkLoadObjects(_):
            self.failUnless(len(self.data) == self.num_iterations,
                            "no rows on query")
            self.failUnless(len(parent.childRows) == self.num_iterations,
                            "did not load child rows: %d" % len(parent.childRows))
            for child in parent.childRows:
                self.failUnless(rowMatches(child, child_values[child.childId]),
                                "child %d does not match" % child.childId)

        def _checkLoadObjects2(_):
            self.failUnless(len(self.data) == self.num_iterations,
                            "no rows on query")
            self.failUnless(len(parent.childRows) == self.num_iterations,
                            "child rows added twice!: %d" % len(parent.childRows))

        def _changeParent(_):
            # now change the parent
            values[0] = self.randomizeRow(parent)
            return self.reflector.updateRow(parent)

        def _loadBack(_):
            # now load it back in
            whereClause = [("key_string", EQUAL, "first")]
            d = self.reflector.loadObjectsFrom(tableName, whereClause=whereClause)
            return d.addCallback(self.gotData)

        def _checkLoadBack(_):
            # make sure it came back as what we saved
            self.failUnless(len(self.data) == 1, "no row")
            parent = self.data[0]
            self.failUnless(rowMatches(parent, values[0]), "no match")
            # save parent
            test_values[parent.key_string] = values[0]
            parent = None

        def _saveMoreTestRows(_):
            # save some more test rows
            ds = []
            for i in range(0, self.num_iterations):
                row = TestRow()
                row.assignKeyAttr("key_string", "bulk%d"%i)
                test_values[row.key_string] = self.randomizeRow(row)
                ds.append(self.reflector.insertRow(row))
            return defer.gatherResults(ds)

        def _loadRowsBack(_):
            # now load them all back in
            d = self.reflector.loadObjectsFrom("testTable")
            return d.addCallback(self.gotData)

        def _checkRowsBack(_):
            # make sure they are the same
            self.failUnless(len(self.data) == self.num_iterations + 1,
                            "query did not get rows")
            for row in self.data:
                self.failUnless(rowMatches(row, test_values[row.key_string]),
                                "child %s does not match" % row.key_string)

        def _changeRows(_):
            # now change them all
            ds = []
            for row in self.data:
                test_values[row.key_string] = self.randomizeRow(row)
                ds.append(self.reflector.updateRow(row))
            d = defer.gatherResults(ds)
            return d.addCallback(_cbChangeRows)

        def _cbChangeRows(_):
            self.data = None

        def _deleteRows(_):
            # now delete them
            ds = []
            for row in self.data:
                ds.append(self.reflector.deleteRow(row))
            d = defer.gatherResults(ds)
            return d.addCallback(_cbChangeRows)

        def _checkRowsDeleted(_):
            self.failUnless(len(self.data) == 0, "rows were not deleted")

        d.addCallback(_loadObjects)
        d.addCallback(_checkLoadObjects)
        d.addCallback(_loadObjects)
        d.addCallback(_checkLoadObjects2)
        d.addCallback(_changeParent)
        d.addCallback(_loadBack)
        d.addCallback(_checkLoadBack)
        d.addCallback(_saveMoreTestRows)
        d.addCallback(_loadRowsBack)
        d.addCallback(_checkRowsBack)
        d.addCallback(_changeRows)
        d.addCallback(_loadRowsBack)
        d.addCallback(_checkRowsBack)
        d.addCallback(_deleteRows)
        d.addCallback(_loadRowsBack)
        d.addCallback(_checkRowsDeleted)
        return d


    def test_saveAndDelete(self):
        """
        Create a row and then try to delete it.
        """
        # create one row to work with
        row = TestRow()
        row.assignKeyAttr("key_string", "first")
        values = self.randomizeRow(row)
        # save it
        d = self.reflector.insertRow(row)
        def _deleteRow(_):
            # delete it
            return self.reflector.deleteRow(row)
        d.addCallback(_deleteRow)
        return d
    test_saveAndDelete.suppress = [rowObjectSuppression, reflectorSuppression]


    def gotData(self, data):
        self.data = data
Example #15
0
from __future__ import generators

import time
from OPSI.web2.test.test_server import BaseCase
from OPSI.web2 import resource
from twisted.internet import reactor, interfaces
from twisted.python import log

if interfaces.IReactorThreads(reactor, None) is not None:
    from OPSI.web2.wsgi import WSGIResource as WSGI
else:
    WSGI = None


class TestError(Exception):
    pass


class TestContainer(BaseCase):
    wait_timeout = 10.0

    def flushErrors(self, result, error):
        log.flushErrors(error)
        return result

    def test_getContainedResource(self):
        """Test that non-blocking WSGI applications render properly."""
        def application(environ, start_response):
            status = '200 OK'
            response_headers = [('Content-type', 'text/html')]
            writer = start_response(status, response_headers)
Example #16
0
class CallFromThreadTests(unittest.TestCase):
    """
    Task scheduling from threads tests.
    """
    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "Nothing to test without thread support"

    def setUp(self):
        self.counter = 0
        self.deferred = Deferred()


    def schedule(self, *args, **kwargs):
        """
        Override in subclasses.
        """
        reactor.callFromThread(*args, **kwargs)


    def test_lotsOfThreadsAreScheduledCorrectly(self):
        """
        L{IReactorThreads.callFromThread} can be used to schedule a large
        number of calls in the reactor thread.
        """
        def addAndMaybeFinish():
            self.counter += 1
            if self.counter == 100:
                self.deferred.callback(True)

        for i in range(100):
            self.schedule(addAndMaybeFinish)

        return self.deferred


    def test_threadsAreRunInScheduledOrder(self):
        """
        Callbacks should be invoked in the order they were scheduled.
        """
        order = []

        def check(_):
            self.assertEqual(order, [1, 2, 3])

        self.deferred.addCallback(check)
        self.schedule(order.append, 1)
        self.schedule(order.append, 2)
        self.schedule(order.append, 3)
        self.schedule(reactor.callFromThread, self.deferred.callback, None)

        return self.deferred


    def test_scheduledThreadsNotRunUntilReactorRuns(self):
        """
        Scheduled tasks should not be run until the reactor starts running.
        """
        def incAndFinish():
            self.counter = 1
            self.deferred.callback(True)
        self.schedule(incAndFinish)

        # Callback shouldn't have fired yet.
        self.assertEqual(self.counter, 0)

        return self.deferred
Example #17
0
class ReflectorTestBase:
    """Base class for testing reflectors."""

    if interfaces.IReactorThreads(reactor, None) is None:
        skip = "No thread support, no reflector tests"

    count = 100  # a parameter used for running iterative tests

    def wait(self, d, timeout=10.0):
        return unittest.wait(d, timeout=timeout)

    def randomizeRow(self, row):
        return randomizeRow(row, self.nulls_ok, self.trailing_spaces_ok)

    def setUp(self):
        self.reflector = self.createReflector()

    def tearDown(self):
        self.destroyReflector()

    def destroyReflector(self):
        pass

    def testReflector(self):
        # create one row to work with
        row = TestRow()
        row.assignKeyAttr("key_string", "first")
        values = self.randomizeRow(row)

        # save it
        self.wait(self.reflector.insertRow(row))

        # now load it back in
        whereClause = [("key_string", EQUAL, "first")]
        d = self.reflector.loadObjectsFrom(tableName, whereClause=whereClause)
        d.addCallback(self.gotData)
        self.wait(d)

        # make sure it came back as what we saved
        self.failUnless(len(self.data) == 1, "no row")
        parent = self.data[0]
        self.failUnless(rowMatches(parent, values), "no match")

        # create some child rows
        inserts = []
        child_values = {}
        for i in range(0, self.num_iterations):
            row = ChildRow()
            row.assignKeyAttr("childId", i)
            values = self.randomizeRow(row)
            values['test_key'] = row.test_key = "first"
            child_values[i] = values
            inserts.append(self.reflector.insertRow(row))
            row = None
        self.wait(defer.gatherResults(inserts), timeout=self.num_iterations)
        del inserts

        d = self.reflector.loadObjectsFrom(childTableName, parentRow=parent)
        d.addCallback(self.gotData)
        self.wait(d)

        self.failUnless(
            len(self.data) == self.num_iterations, "no rows on query")
        self.failUnless(
            len(parent.childRows) == self.num_iterations,
            "did not load child rows: %d" % len(parent.childRows))
        for child in parent.childRows:
            self.failUnless(rowMatches(child, child_values[child.childId]),
                            "child %d does not match" % child.childId)

        # loading these objects a second time should not re-add them
        # to the parentRow.
        d = self.reflector.loadObjectsFrom(childTableName, parentRow=parent)
        d.addCallback(self.gotData)
        self.wait(d)

        self.failUnless(
            len(self.data) == self.num_iterations, "no rows on query")
        self.failUnless(
            len(parent.childRows) == self.num_iterations,
            "child rows added twice!: %d" % len(parent.childRows))

        # now change the parent
        values = self.randomizeRow(parent)
        self.wait(self.reflector.updateRow(parent))
        parent = None

        # now load it back in
        whereClause = [("key_string", EQUAL, "first")]
        d = self.reflector.loadObjectsFrom(tableName, whereClause=whereClause)
        d.addCallback(self.gotData)
        self.wait(d)

        # make sure it came back as what we saved
        self.failUnless(len(self.data) == 1, "no row")
        parent = self.data[0]
        self.failUnless(rowMatches(parent, values), "no match")

        # save parent
        test_values = {}
        test_values[parent.key_string] = values
        parent = None

        # save some more test rows
        for i in range(0, self.num_iterations):
            row = TestRow()
            row.assignKeyAttr("key_string", "bulk%d" % i)
            test_values[row.key_string] = self.randomizeRow(row)
            self.wait(self.reflector.insertRow(row))
            row = None

        # now load them all back in
        d = self.reflector.loadObjectsFrom("testTable")
        d.addCallback(self.gotData)
        self.wait(d, 100.0)

        # make sure they are the same
        self.failUnless(
            len(self.data) == self.num_iterations + 1,
            "query did not get rows")
        for row in self.data:
            self.failUnless(rowMatches(row, test_values[row.key_string]),
                            "child %s does not match" % row.key_string)

        # now change them all
        for row in self.data:
            test_values[row.key_string] = self.randomizeRow(row)
            self.wait(self.reflector.updateRow(row))
        self.data = None

        # load'em back
        d = self.reflector.loadObjectsFrom("testTable")
        d.addCallback(self.gotData)
        self.wait(d)

        # make sure they are the same
        self.failUnless(
            len(self.data) == self.num_iterations + 1,
            "query did not get rows")
        for row in self.data:
            self.failUnless(rowMatches(row, test_values[row.key_string]),
                            "child %s does not match" % row.key_string)

        # now delete them
        for row in self.data:
            self.wait(self.reflector.deleteRow(row))
        self.data = None

        # load'em back
        d = self.reflector.loadObjectsFrom("testTable")
        d.addCallback(self.gotData)
        self.wait(d)

        self.failUnless(len(self.data) == 0, "rows were not deleted")

        # create one row to work with
        row = TestRow()
        row.assignKeyAttr("key_string", "first")
        values = self.randomizeRow(row)

        # save it
        self.wait(self.reflector.insertRow(row))

        # delete it
        self.wait(self.reflector.deleteRow(row))

    def gotData(self, data):
        self.data = data