123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- # Copyright (c) Twisted Matrix Laboratories.
- # See LICENSE for details.
-
- """
- Tests for L{twisted.python.threadable}.
- """
-
-
- import pickle
- import sys
- from unittest import skipIf
-
- try:
- import threading
- except ImportError:
- threadingSkip = True
- else:
- threadingSkip = False
-
- from twisted.python import threadable
- from twisted.trial.unittest import FailTest, SynchronousTestCase
-
-
- class TestObject:
- synchronized = ["aMethod"]
-
- x = -1
- y = 1
-
- def aMethod(self):
- for i in range(10):
- self.x, self.y = self.y, self.x
- self.z = self.x + self.y
- assert self.z == 0, "z == %d, not 0 as expected" % (self.z,)
-
-
- threadable.synchronize(TestObject)
-
-
- class SynchronizationTests(SynchronousTestCase):
- def setUp(self):
- """
- Reduce the CPython check interval so that thread switches happen much
- more often, hopefully exercising more possible race conditions. Also,
- delay actual test startup until the reactor has been started.
- """
- self.addCleanup(sys.setswitchinterval, sys.getswitchinterval())
- sys.setswitchinterval(0.0000001)
-
- def test_synchronizedName(self):
- """
- The name of a synchronized method is inaffected by the synchronization
- decorator.
- """
- self.assertEqual("aMethod", TestObject.aMethod.__name__)
-
- @skipIf(threadingSkip, "Platform does not support threads")
- def test_isInIOThread(self):
- """
- L{threadable.isInIOThread} returns C{True} if and only if it is called
- in the same thread as L{threadable.registerAsIOThread}.
- """
- threadable.registerAsIOThread()
- foreignResult = []
- t = threading.Thread(
- target=lambda: foreignResult.append(threadable.isInIOThread())
- )
- t.start()
- t.join()
- self.assertFalse(foreignResult[0], "Non-IO thread reported as IO thread")
- self.assertTrue(
- threadable.isInIOThread(), "IO thread reported as not IO thread"
- )
-
- @skipIf(threadingSkip, "Platform does not support threads")
- def testThreadedSynchronization(self):
- o = TestObject()
-
- errors = []
-
- def callMethodLots():
- try:
- for i in range(1000):
- o.aMethod()
- except AssertionError as e:
- errors.append(str(e))
-
- threads = []
- for x in range(5):
- t = threading.Thread(target=callMethodLots)
- threads.append(t)
- t.start()
-
- for t in threads:
- t.join()
-
- if errors:
- raise FailTest(errors)
-
- def testUnthreadedSynchronization(self):
- o = TestObject()
- for i in range(1000):
- o.aMethod()
-
-
- class SerializationTests(SynchronousTestCase):
- @skipIf(threadingSkip, "Platform does not support threads")
- def testPickling(self):
- lock = threadable.XLock()
- lockType = type(lock)
- lockPickle = pickle.dumps(lock)
- newLock = pickle.loads(lockPickle)
- self.assertIsInstance(newLock, lockType)
-
- def testUnpickling(self):
- lockPickle = b"ctwisted.python.threadable\nunpickle_lock\np0\n(tp1\nRp2\n."
- lock = pickle.loads(lockPickle)
- newPickle = pickle.dumps(lock, 2)
- pickle.loads(newPickle)
|