test_dispatch.py 11 KB

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