test_dispatch.py 12 KB

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