Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_threadable.py 3.3KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Tests for L{twisted.python.threadable}.
  5. """
  6. import pickle
  7. import sys
  8. from unittest import skipIf
  9. try:
  10. import threading
  11. except ImportError:
  12. threadingSkip = True
  13. else:
  14. threadingSkip = False
  15. from twisted.python import threadable
  16. from twisted.trial.unittest import FailTest, SynchronousTestCase
  17. class TestObject:
  18. synchronized = ["aMethod"]
  19. x = -1
  20. y = 1
  21. def aMethod(self):
  22. for i in range(10):
  23. self.x, self.y = self.y, self.x
  24. self.z = self.x + self.y
  25. assert self.z == 0, "z == %d, not 0 as expected" % (self.z,)
  26. threadable.synchronize(TestObject)
  27. class SynchronizationTests(SynchronousTestCase):
  28. def setUp(self):
  29. """
  30. Reduce the CPython check interval so that thread switches happen much
  31. more often, hopefully exercising more possible race conditions. Also,
  32. delay actual test startup until the reactor has been started.
  33. """
  34. self.addCleanup(sys.setswitchinterval, sys.getswitchinterval())
  35. sys.setswitchinterval(0.0000001)
  36. def test_synchronizedName(self):
  37. """
  38. The name of a synchronized method is inaffected by the synchronization
  39. decorator.
  40. """
  41. self.assertEqual("aMethod", TestObject.aMethod.__name__)
  42. @skipIf(threadingSkip, "Platform does not support threads")
  43. def test_isInIOThread(self):
  44. """
  45. L{threadable.isInIOThread} returns C{True} if and only if it is called
  46. in the same thread as L{threadable.registerAsIOThread}.
  47. """
  48. threadable.registerAsIOThread()
  49. foreignResult = []
  50. t = threading.Thread(
  51. target=lambda: foreignResult.append(threadable.isInIOThread())
  52. )
  53. t.start()
  54. t.join()
  55. self.assertFalse(foreignResult[0], "Non-IO thread reported as IO thread")
  56. self.assertTrue(
  57. threadable.isInIOThread(), "IO thread reported as not IO thread"
  58. )
  59. @skipIf(threadingSkip, "Platform does not support threads")
  60. def testThreadedSynchronization(self):
  61. o = TestObject()
  62. errors = []
  63. def callMethodLots():
  64. try:
  65. for i in range(1000):
  66. o.aMethod()
  67. except AssertionError as e:
  68. errors.append(str(e))
  69. threads = []
  70. for x in range(5):
  71. t = threading.Thread(target=callMethodLots)
  72. threads.append(t)
  73. t.start()
  74. for t in threads:
  75. t.join()
  76. if errors:
  77. raise FailTest(errors)
  78. def testUnthreadedSynchronization(self):
  79. o = TestObject()
  80. for i in range(1000):
  81. o.aMethod()
  82. class SerializationTests(SynchronousTestCase):
  83. @skipIf(threadingSkip, "Platform does not support threads")
  84. def testPickling(self):
  85. lock = threadable.XLock()
  86. lockType = type(lock)
  87. lockPickle = pickle.dumps(lock)
  88. newLock = pickle.loads(lockPickle)
  89. self.assertIsInstance(newLock, lockType)
  90. def testUnpickling(self):
  91. lockPickle = b"ctwisted.python.threadable\nunpickle_lock\np0\n(tp1\nRp2\n."
  92. lock = pickle.loads(lockPickle)
  93. newPickle = pickle.dumps(lock, 2)
  94. pickle.loads(newPickle)