test_dispatch.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import sys
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic.hooks import dispatch as module
  5. def hook_function(hook_config, config, thing, value):
  6. '''
  7. This test function gets mocked out below.
  8. '''
  9. pass
  10. def test_call_hook_invokes_module_function_with_arguments_and_returns_value():
  11. config = {'super_hook': flexmock(), 'other_hook': flexmock()}
  12. expected_return_value = flexmock()
  13. test_module = sys.modules[__name__]
  14. flexmock(module).should_receive('get_submodule_names').with_args(
  15. module.borgmatic.hooks.data_source
  16. ).and_return(['other_hook'])
  17. flexmock(module).should_receive('get_submodule_names').with_args(
  18. module.borgmatic.hooks.monitoring
  19. ).and_return(['super_hook', 'third_hook'])
  20. flexmock(module.importlib).should_receive('import_module').with_args(
  21. 'borgmatic.hooks.monitoring.super_hook'
  22. ).and_return(test_module)
  23. flexmock(test_module).should_receive('hook_function').with_args(
  24. config['super_hook'], config, 55, value=66
  25. ).and_return(expected_return_value).once()
  26. return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66)
  27. assert return_value == expected_return_value
  28. def test_call_hook_probes_config_with_databases_suffix():
  29. config = {'super_hook_databases': flexmock(), 'other_hook': flexmock()}
  30. expected_return_value = flexmock()
  31. test_module = sys.modules[__name__]
  32. flexmock(module).should_receive('get_submodule_names').with_args(
  33. module.borgmatic.hooks.data_source
  34. ).and_return(['other_hook'])
  35. flexmock(module).should_receive('get_submodule_names').with_args(
  36. module.borgmatic.hooks.monitoring
  37. ).and_return(['super_hook', 'third_hook'])
  38. flexmock(module.importlib).should_receive('import_module').with_args(
  39. 'borgmatic.hooks.monitoring.super_hook'
  40. ).and_return(test_module)
  41. flexmock(test_module).should_receive('hook_function').with_args(
  42. config['super_hook_databases'], config, 55, value=66
  43. ).and_return(expected_return_value).once()
  44. return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66)
  45. assert return_value == expected_return_value
  46. def test_call_hook_strips_databases_suffix_from_hook_name():
  47. config = {'super_hook_databases': flexmock(), 'other_hook_databases': flexmock()}
  48. expected_return_value = flexmock()
  49. test_module = sys.modules[__name__]
  50. flexmock(module).should_receive('get_submodule_names').with_args(
  51. module.borgmatic.hooks.data_source
  52. ).and_return(['other_hook'])
  53. flexmock(module).should_receive('get_submodule_names').with_args(
  54. module.borgmatic.hooks.monitoring
  55. ).and_return(['super_hook', 'third_hook'])
  56. flexmock(module.importlib).should_receive('import_module').with_args(
  57. 'borgmatic.hooks.monitoring.super_hook'
  58. ).and_return(test_module)
  59. flexmock(test_module).should_receive('hook_function').with_args(
  60. config['super_hook_databases'], config, 55, value=66
  61. ).and_return(expected_return_value).once()
  62. return_value = module.call_hook('hook_function', config, 'super_hook_databases', 55, value=66)
  63. assert return_value == expected_return_value
  64. def test_call_hook_without_hook_config_invokes_module_function_with_arguments_and_returns_value():
  65. config = {'other_hook': flexmock()}
  66. expected_return_value = flexmock()
  67. test_module = sys.modules[__name__]
  68. flexmock(module).should_receive('get_submodule_names').with_args(
  69. module.borgmatic.hooks.data_source
  70. ).and_return(['other_hook'])
  71. flexmock(module).should_receive('get_submodule_names').with_args(
  72. module.borgmatic.hooks.monitoring
  73. ).and_return(['super_hook', 'third_hook'])
  74. flexmock(module.importlib).should_receive('import_module').with_args(
  75. 'borgmatic.hooks.monitoring.super_hook'
  76. ).and_return(test_module)
  77. flexmock(test_module).should_receive('hook_function').with_args(
  78. None, config, 55, value=66
  79. ).and_return(expected_return_value).once()
  80. return_value = module.call_hook('hook_function', config, 'super_hook', 55, value=66)
  81. assert return_value == expected_return_value
  82. def test_call_hook_without_corresponding_module_raises():
  83. config = {'super_hook': flexmock(), 'other_hook': flexmock()}
  84. test_module = sys.modules[__name__]
  85. flexmock(module).should_receive('get_submodule_names').with_args(
  86. module.borgmatic.hooks.data_source
  87. ).and_return(['other_hook'])
  88. flexmock(module).should_receive('get_submodule_names').with_args(
  89. module.borgmatic.hooks.monitoring
  90. ).and_return(['some_hook'])
  91. flexmock(module.importlib).should_receive('import_module').with_args(
  92. 'borgmatic.hooks.monitoring.super_hook'
  93. ).and_return(test_module)
  94. flexmock(test_module).should_receive('hook_function').never()
  95. with pytest.raises(ValueError):
  96. module.call_hook('hook_function', config, 'super_hook', 55, value=66)
  97. def test_call_hook_skips_non_hook_modules():
  98. config = {'not_a_hook': flexmock(), 'other_hook': flexmock()}
  99. flexmock(module).should_receive('get_submodule_names').with_args(
  100. module.borgmatic.hooks.data_source
  101. ).and_return(['other_hook'])
  102. flexmock(module).should_receive('get_submodule_names').with_args(
  103. module.borgmatic.hooks.monitoring
  104. ).and_return(['not_a_hook', 'third_hook'])
  105. not_a_hook_module = flexmock(IS_A_HOOK=False)
  106. flexmock(module.importlib).should_receive('import_module').with_args(
  107. 'borgmatic.hooks.monitoring.not_a_hook'
  108. ).and_return(not_a_hook_module)
  109. return_value = module.call_hook('hook_function', config, 'not_a_hook', 55, value=66)
  110. assert return_value is None
  111. def test_call_hooks_calls_each_hook_and_collects_return_values():
  112. config = {'super_hook': flexmock(), 'other_hook': flexmock()}
  113. expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()}
  114. flexmock(module.importlib).should_receive('import_module').with_args(
  115. 'borgmatic.hooks.monitoring'
  116. ).and_return(module.borgmatic.hooks.monitoring)
  117. flexmock(module).should_receive('get_submodule_names').with_args(
  118. module.borgmatic.hooks.monitoring
  119. ).and_return(['super_hook', 'other_hook'])
  120. flexmock(module).should_receive('call_hook').and_return(
  121. expected_return_values['super_hook']
  122. ).and_return(expected_return_values['other_hook'])
  123. return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55)
  124. assert return_values == expected_return_values
  125. def test_call_hooks_calls_skips_return_values_for_unconfigured_hooks():
  126. config = {'super_hook': flexmock()}
  127. expected_return_values = {'super_hook': flexmock()}
  128. flexmock(module.importlib).should_receive('import_module').with_args(
  129. 'borgmatic.hooks.monitoring'
  130. ).and_return(module.borgmatic.hooks.monitoring)
  131. flexmock(module).should_receive('get_submodule_names').with_args(
  132. module.borgmatic.hooks.monitoring
  133. ).and_return(['super_hook', 'other_hook'])
  134. flexmock(module).should_receive('call_hook').and_return(expected_return_values['super_hook'])
  135. return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55)
  136. assert return_values == expected_return_values
  137. def test_call_hooks_calls_treats_null_hook_as_optionless():
  138. config = {'super_hook': flexmock(), 'other_hook': None}
  139. expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()}
  140. flexmock(module.importlib).should_receive('import_module').with_args(
  141. 'borgmatic.hooks.monitoring'
  142. ).and_return(module.borgmatic.hooks.monitoring)
  143. flexmock(module).should_receive('get_submodule_names').with_args(
  144. module.borgmatic.hooks.monitoring
  145. ).and_return(['super_hook', 'other_hook'])
  146. flexmock(module).should_receive('call_hook').and_return(
  147. expected_return_values['super_hook']
  148. ).and_return(expected_return_values['other_hook'])
  149. return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55)
  150. assert return_values == expected_return_values
  151. def test_call_hooks_calls_looks_up_databases_suffix_in_config():
  152. config = {'super_hook_databases': flexmock(), 'other_hook': flexmock()}
  153. expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()}
  154. flexmock(module.importlib).should_receive('import_module').with_args(
  155. 'borgmatic.hooks.monitoring'
  156. ).and_return(module.borgmatic.hooks.monitoring)
  157. flexmock(module).should_receive('get_submodule_names').with_args(
  158. module.borgmatic.hooks.monitoring
  159. ).and_return(['super_hook', 'other_hook'])
  160. flexmock(module).should_receive('call_hook').and_return(
  161. expected_return_values['super_hook']
  162. ).and_return(expected_return_values['other_hook'])
  163. return_values = module.call_hooks('do_stuff', config, module.Hook_type.MONITORING, 55)
  164. assert return_values == expected_return_values
  165. def test_call_hooks_even_if_unconfigured_calls_each_hook_and_collects_return_values():
  166. config = {'super_hook': flexmock(), 'other_hook': flexmock()}
  167. expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()}
  168. flexmock(module.importlib).should_receive('import_module').with_args(
  169. 'borgmatic.hooks.monitoring'
  170. ).and_return(module.borgmatic.hooks.monitoring)
  171. flexmock(module).should_receive('get_submodule_names').with_args(
  172. module.borgmatic.hooks.monitoring
  173. ).and_return(['super_hook', 'other_hook'])
  174. flexmock(module).should_receive('call_hook').and_return(
  175. expected_return_values['super_hook']
  176. ).and_return(expected_return_values['other_hook'])
  177. return_values = module.call_hooks_even_if_unconfigured(
  178. 'do_stuff', config, module.Hook_type.MONITORING, 55
  179. )
  180. assert return_values == expected_return_values
  181. def test_call_hooks_even_if_unconfigured_calls_each_hook_configured_or_not_and_collects_return_values():
  182. config = {'other_hook': flexmock()}
  183. expected_return_values = {'super_hook': flexmock(), 'other_hook': flexmock()}
  184. flexmock(module.importlib).should_receive('import_module').with_args(
  185. 'borgmatic.hooks.monitoring'
  186. ).and_return(module.borgmatic.hooks.monitoring)
  187. flexmock(module).should_receive('get_submodule_names').with_args(
  188. module.borgmatic.hooks.monitoring
  189. ).and_return(['super_hook', 'other_hook'])
  190. flexmock(module).should_receive('call_hook').and_return(
  191. expected_return_values['super_hook']
  192. ).and_return(expected_return_values['other_hook'])
  193. return_values = module.call_hooks_even_if_unconfigured(
  194. 'do_stuff', config, module.Hook_type.MONITORING, 55
  195. )
  196. assert return_values == expected_return_values