test_middleware_system.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import unittest
  2. from cloudbridge.cloud.base.events import SimpleEventDispatcher
  3. from cloudbridge.cloud.base.middleware import BaseMiddleware
  4. from cloudbridge.cloud.base.middleware import SimpleMiddlewareManager
  5. from cloudbridge.cloud.base.middleware import implement
  6. from cloudbridge.cloud.base.middleware import intercept
  7. from cloudbridge.cloud.base.middleware import observe
  8. from cloudbridge.cloud.interfaces.middleware import Middleware
  9. class MiddlewareSystemTestCase(unittest.TestCase):
  10. def test_basic_middleware(self):
  11. class DummyMiddleWare(Middleware):
  12. def __init__(self):
  13. self.invocation_order = ""
  14. def install(self, event_manager):
  15. self.event_manager = event_manager
  16. self.invocation_order += "install_"
  17. def uninstall(self):
  18. self.invocation_order += "uninstall"
  19. dispatcher = SimpleEventDispatcher()
  20. manager = SimpleMiddlewareManager(dispatcher)
  21. middleware = DummyMiddleWare()
  22. manager.add(middleware)
  23. self.assertEqual(middleware.invocation_order, "install_",
  24. "install should be called when adding new middleware")
  25. manager.remove(middleware)
  26. self.assertEqual(middleware.invocation_order, "install_uninstall",
  27. "uninstall should be called when removing middleware")
  28. def test_base_middleware(self):
  29. EVENT_NAME = "some.event.occurred"
  30. class DummyMiddleWare(BaseMiddleware):
  31. def __init__(self):
  32. self.invocation_order = ""
  33. @intercept(event_pattern="some.event.*", priority=900)
  34. def my_callback_intcpt(self, event_args, *args, **kwargs):
  35. self.invocation_order += "intcpt_"
  36. assert 'first_pos_arg' in args
  37. assert kwargs.get('a_keyword_arg') == "something"
  38. next_handler = event_args.get('next_handler')
  39. return next_handler.invoke(event_args, *args, **kwargs)
  40. @implement(event_pattern="some.event.*", priority=950)
  41. def my_callback_impl(self, *args, **kwargs):
  42. self.invocation_order += "impl_"
  43. assert 'first_pos_arg' in args
  44. assert kwargs.get('a_keyword_arg') == "something"
  45. return "hello"
  46. @observe(event_pattern="some.event.*", priority=1000)
  47. def my_callback_obs(self, event_args, *args, **kwargs):
  48. self.invocation_order += "obs"
  49. assert 'first_pos_arg' in args
  50. assert event_args['result'] == "hello"
  51. assert kwargs.get('a_keyword_arg') == "something"
  52. dispatcher = SimpleEventDispatcher()
  53. manager = SimpleMiddlewareManager(dispatcher)
  54. middleware = DummyMiddleWare()
  55. manager.add(middleware)
  56. dispatcher.dispatch(self, EVENT_NAME, 'first_pos_arg',
  57. a_keyword_arg='something')
  58. self.assertEqual(middleware.invocation_order, "intcpt_impl_obs")
  59. self.assertListEqual(
  60. [middleware.my_callback_intcpt, middleware.my_callback_impl,
  61. middleware.my_callback_obs],
  62. [handler.callback for handler
  63. in dispatcher.get_handlers_for_event(EVENT_NAME)])
  64. manager.remove(middleware)
  65. self.assertListEqual([], dispatcher.get_handlers_for_event(EVENT_NAME))
  66. def test_multiple_middleware(self):
  67. EVENT_NAME = "some.really.interesting.event.occurred"
  68. class DummyMiddleWare1(BaseMiddleware):
  69. @observe(event_pattern="some.really.*", priority=1000)
  70. def my_obs1_3(self, *args, **kwargs):
  71. pass
  72. @implement(event_pattern="some.*", priority=970)
  73. def my_impl1_2(self, *args, **kwargs):
  74. return "hello"
  75. @intercept(event_pattern="some.*", priority=900)
  76. def my_intcpt1_1(self, event_args, *args, **kwargs):
  77. next_handler = event_args.get('next_handler')
  78. return next_handler.invoke(event_args, *args, **kwargs)
  79. class DummyMiddleWare2(BaseMiddleware):
  80. @observe(event_pattern="some.really.*", priority=1050)
  81. def my_obs2_3(self, *args, **kwargs):
  82. pass
  83. @intercept(event_pattern="*", priority=950)
  84. def my_intcpt2_2(self, event_args, *args, **kwargs):
  85. next_handler = event_args.get('next_handler')
  86. return next_handler.invoke(event_args, *args, **kwargs)
  87. @implement(event_pattern="some.really.*", priority=920)
  88. def my_impl2_1(self, *args, **kwargs):
  89. pass
  90. dispatcher = SimpleEventDispatcher()
  91. manager = SimpleMiddlewareManager(dispatcher)
  92. middleware1 = DummyMiddleWare1()
  93. middleware2 = DummyMiddleWare2()
  94. manager.add(middleware1)
  95. manager.add(middleware2)
  96. dispatcher.dispatch(self, EVENT_NAME)
  97. # Callbacks in both middleware classes should be registered
  98. self.assertListEqual(
  99. [middleware1.my_intcpt1_1, middleware2.my_impl2_1,
  100. middleware2.my_intcpt2_2, middleware1.my_impl1_2,
  101. middleware1.my_obs1_3, middleware2.my_obs2_3],
  102. [handler.callback for handler
  103. in dispatcher.get_handlers_for_event(EVENT_NAME)])
  104. manager.remove(middleware1)
  105. # Only middleware2 callbacks should be registered
  106. self.assertListEqual(
  107. [middleware2.my_impl2_1, middleware2.my_intcpt2_2,
  108. middleware2.my_obs2_3],
  109. [handler.callback for handler in
  110. dispatcher.get_handlers_for_event(EVENT_NAME)])
  111. # add middleware back to check that internal state is properly handled
  112. manager.add(middleware1)
  113. # should one again equal original list
  114. self.assertListEqual(
  115. [middleware1.my_intcpt1_1, middleware2.my_impl2_1,
  116. middleware2.my_intcpt2_2, middleware1.my_impl1_2,
  117. middleware1.my_obs1_3, middleware2.my_obs2_3],
  118. [handler.callback for handler
  119. in dispatcher.get_handlers_for_event(EVENT_NAME)])
  120. def test_automatic_middleware(self):
  121. EVENT_NAME = "another.interesting.event.occurred"
  122. class SomeDummyClass(object):
  123. @observe(event_pattern="another.really.*", priority=1000)
  124. def not_a_match(self, *args, **kwargs):
  125. pass
  126. @intercept(event_pattern="another.*", priority=900)
  127. def my_callback_intcpt2(self, *args, **kwargs):
  128. pass
  129. def not_an_event_handler(self, *args, **kwargs):
  130. pass
  131. @observe(event_pattern="another.interesting.*", priority=1000)
  132. def my_callback_obs1(self, *args, **kwargs):
  133. pass
  134. @implement(event_pattern="another.interesting.*", priority=1050)
  135. def my_callback_impl(self, *args, **kwargs):
  136. pass
  137. dispatcher = SimpleEventDispatcher()
  138. manager = SimpleMiddlewareManager(dispatcher)
  139. some_obj = SomeDummyClass()
  140. middleware = manager.add(some_obj)
  141. dispatcher.dispatch(self, EVENT_NAME)
  142. # Middleware should be discovered even if class containing interceptors
  143. # doesn't inherit from Middleware
  144. self.assertListEqual(
  145. [some_obj.my_callback_intcpt2, some_obj.my_callback_obs1,
  146. some_obj.my_callback_impl],
  147. [handler.callback for handler
  148. in dispatcher.get_handlers_for_event(EVENT_NAME)])
  149. manager.remove(middleware)
  150. # Callbacks should be correctly removed
  151. self.assertListEqual(
  152. [],
  153. [handler.callback for handler in
  154. dispatcher.get_handlers_for_event(EVENT_NAME)])