test_logcontext.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import twisted.python.failure
  2. from twisted.internet import defer
  3. from twisted.internet import reactor
  4. from .. import unittest
  5. from synapse.util.async import sleep
  6. from synapse.util import logcontext
  7. from synapse.util.logcontext import LoggingContext
  8. class LoggingContextTestCase(unittest.TestCase):
  9. def _check_test_key(self, value):
  10. self.assertEquals(
  11. LoggingContext.current_context().request, value
  12. )
  13. def test_with_context(self):
  14. with LoggingContext() as context_one:
  15. context_one.request = "test"
  16. self._check_test_key("test")
  17. @defer.inlineCallbacks
  18. def test_sleep(self):
  19. @defer.inlineCallbacks
  20. def competing_callback():
  21. with LoggingContext() as competing_context:
  22. competing_context.request = "competing"
  23. yield sleep(0)
  24. self._check_test_key("competing")
  25. reactor.callLater(0, competing_callback)
  26. with LoggingContext() as context_one:
  27. context_one.request = "one"
  28. yield sleep(0)
  29. self._check_test_key("one")
  30. def _test_preserve_fn(self, function):
  31. sentinel_context = LoggingContext.current_context()
  32. callback_completed = [False]
  33. @defer.inlineCallbacks
  34. def cb():
  35. context_one.request = "one"
  36. yield function()
  37. self._check_test_key("one")
  38. callback_completed[0] = True
  39. with LoggingContext() as context_one:
  40. context_one.request = "one"
  41. # fire off function, but don't wait on it.
  42. logcontext.preserve_fn(cb)()
  43. self._check_test_key("one")
  44. # now wait for the function under test to have run, and check that
  45. # the logcontext is left in a sane state.
  46. d2 = defer.Deferred()
  47. def check_logcontext():
  48. if not callback_completed[0]:
  49. reactor.callLater(0.01, check_logcontext)
  50. return
  51. # make sure that the context was reset before it got thrown back
  52. # into the reactor
  53. try:
  54. self.assertIs(LoggingContext.current_context(),
  55. sentinel_context)
  56. d2.callback(None)
  57. except BaseException:
  58. d2.errback(twisted.python.failure.Failure())
  59. reactor.callLater(0.01, check_logcontext)
  60. # test is done once d2 finishes
  61. return d2
  62. def test_preserve_fn_with_blocking_fn(self):
  63. @defer.inlineCallbacks
  64. def blocking_function():
  65. yield sleep(0)
  66. return self._test_preserve_fn(blocking_function)
  67. def test_preserve_fn_with_non_blocking_fn(self):
  68. @defer.inlineCallbacks
  69. def nonblocking_function():
  70. with logcontext.PreserveLoggingContext():
  71. yield defer.succeed(None)
  72. return self._test_preserve_fn(nonblocking_function)
  73. @defer.inlineCallbacks
  74. def test_make_deferred_yieldable(self):
  75. # a function which retuns an incomplete deferred, but doesn't follow
  76. # the synapse rules.
  77. def blocking_function():
  78. d = defer.Deferred()
  79. reactor.callLater(0, d.callback, None)
  80. return d
  81. sentinel_context = LoggingContext.current_context()
  82. with LoggingContext() as context_one:
  83. context_one.request = "one"
  84. d1 = logcontext.make_deferred_yieldable(blocking_function())
  85. # make sure that the context was reset by make_deferred_yieldable
  86. self.assertIs(LoggingContext.current_context(), sentinel_context)
  87. yield d1
  88. # now it should be restored
  89. self._check_test_key("one")
  90. @defer.inlineCallbacks
  91. def test_make_deferred_yieldable_on_non_deferred(self):
  92. """Check that make_deferred_yieldable does the right thing when its
  93. argument isn't actually a deferred"""
  94. with LoggingContext() as context_one:
  95. context_one.request = "one"
  96. d1 = logcontext.make_deferred_yieldable("bum")
  97. self._check_test_key("one")
  98. r = yield d1
  99. self.assertEqual(r, "bum")
  100. self._check_test_key("one")