test_healthchecks.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. from flexmock import flexmock
  2. from borgmatic.hooks.monitoring import healthchecks as module
  3. def test_initialize_monitor_creates_log_handler_with_ping_body_limit():
  4. ping_body_limit = 100
  5. monitoring_log_level = 1
  6. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  7. 'Forgetful_buffering_handler',
  8. ).with_args(
  9. module.HANDLER_IDENTIFIER,
  10. ping_body_limit - len(module.borgmatic.hooks.monitoring.logs.PAYLOAD_TRUNCATION_INDICATOR),
  11. monitoring_log_level,
  12. ).once()
  13. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler')
  14. module.initialize_monitor(
  15. {'ping_body_limit': ping_body_limit},
  16. {},
  17. 'test.yaml',
  18. monitoring_log_level,
  19. dry_run=False,
  20. )
  21. def test_initialize_monitor_creates_log_handler_with_default_ping_body_limit():
  22. monitoring_log_level = 1
  23. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  24. 'Forgetful_buffering_handler',
  25. ).with_args(
  26. module.HANDLER_IDENTIFIER,
  27. module.DEFAULT_PING_BODY_LIMIT_BYTES
  28. - len(module.borgmatic.hooks.monitoring.logs.PAYLOAD_TRUNCATION_INDICATOR),
  29. monitoring_log_level,
  30. ).once()
  31. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler')
  32. module.initialize_monitor({}, {}, 'test.yaml', monitoring_log_level, dry_run=False)
  33. def test_initialize_monitor_creates_log_handler_with_zero_ping_body_limit():
  34. ping_body_limit = 0
  35. monitoring_log_level = 1
  36. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  37. 'Forgetful_buffering_handler',
  38. ).with_args(module.HANDLER_IDENTIFIER, ping_body_limit, monitoring_log_level).once()
  39. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler')
  40. module.initialize_monitor(
  41. {'ping_body_limit': ping_body_limit},
  42. {},
  43. 'test.yaml',
  44. monitoring_log_level,
  45. dry_run=False,
  46. )
  47. def test_initialize_monitor_creates_log_handler_when_send_logs_true():
  48. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  49. 'Forgetful_buffering_handler',
  50. ).once()
  51. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler')
  52. module.initialize_monitor(
  53. {'send_logs': True},
  54. {},
  55. 'test.yaml',
  56. monitoring_log_level=1,
  57. dry_run=False,
  58. )
  59. def test_initialize_monitor_bails_when_send_logs_false():
  60. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  61. 'Forgetful_buffering_handler',
  62. ).never()
  63. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('add_handler')
  64. module.initialize_monitor(
  65. {'send_logs': False},
  66. {},
  67. 'test.yaml',
  68. monitoring_log_level=1,
  69. dry_run=False,
  70. )
  71. def test_ping_monitor_hits_ping_url_for_start_state():
  72. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  73. 'Forgetful_buffering_handler',
  74. ).never()
  75. hook_config = {'ping_url': 'https://example.com'}
  76. flexmock(module.requests).should_receive('post').with_args(
  77. 'https://example.com/start',
  78. data=b'',
  79. verify=True,
  80. timeout=int,
  81. ).and_return(flexmock(ok=True))
  82. module.ping_monitor(
  83. hook_config,
  84. {},
  85. 'config.yaml',
  86. state=module.monitor.State.START,
  87. monitoring_log_level=1,
  88. dry_run=False,
  89. )
  90. def test_ping_monitor_hits_ping_url_for_finish_state():
  91. hook_config = {'ping_url': 'https://example.com'}
  92. payload = 'data'
  93. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  94. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  95. 'format_buffered_logs_for_payload',
  96. ).and_return(payload)
  97. flexmock(module.requests).should_receive('post').with_args(
  98. 'https://example.com',
  99. data=payload.encode('utf-8'),
  100. verify=True,
  101. timeout=int,
  102. ).and_return(flexmock(ok=True))
  103. module.ping_monitor(
  104. hook_config,
  105. {},
  106. 'config.yaml',
  107. state=module.monitor.State.FINISH,
  108. monitoring_log_level=1,
  109. dry_run=False,
  110. )
  111. def test_ping_monitor_hits_ping_url_for_fail_state():
  112. hook_config = {'ping_url': 'https://example.com'}
  113. payload = 'data'
  114. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  115. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  116. 'format_buffered_logs_for_payload',
  117. ).and_return(payload)
  118. flexmock(module.requests).should_receive('post').with_args(
  119. 'https://example.com/fail',
  120. data=payload.encode('utf'),
  121. verify=True,
  122. timeout=int,
  123. ).and_return(flexmock(ok=True))
  124. module.ping_monitor(
  125. hook_config,
  126. {},
  127. 'config.yaml',
  128. state=module.monitor.State.FAIL,
  129. monitoring_log_level=1,
  130. dry_run=False,
  131. )
  132. def test_ping_monitor_hits_ping_url_for_log_state():
  133. hook_config = {'ping_url': 'https://example.com'}
  134. payload = 'data'
  135. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  136. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  137. 'format_buffered_logs_for_payload',
  138. ).and_return(payload)
  139. flexmock(module.requests).should_receive('post').with_args(
  140. 'https://example.com/log',
  141. data=payload.encode('utf'),
  142. verify=True,
  143. timeout=int,
  144. ).and_return(flexmock(ok=True))
  145. module.ping_monitor(
  146. hook_config,
  147. {},
  148. 'config.yaml',
  149. state=module.monitor.State.LOG,
  150. monitoring_log_level=1,
  151. dry_run=False,
  152. )
  153. def test_ping_monitor_with_ping_uuid_hits_corresponding_url():
  154. hook_config = {'ping_url': 'abcd-efgh-ijkl-mnop'}
  155. payload = 'data'
  156. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  157. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  158. 'format_buffered_logs_for_payload',
  159. ).and_return(payload)
  160. flexmock(module.requests).should_receive('post').with_args(
  161. f"https://hc-ping.com/{hook_config['ping_url']}",
  162. data=payload.encode('utf-8'),
  163. verify=True,
  164. timeout=int,
  165. ).and_return(flexmock(ok=True))
  166. module.ping_monitor(
  167. hook_config,
  168. {},
  169. 'config.yaml',
  170. state=module.monitor.State.FINISH,
  171. monitoring_log_level=1,
  172. dry_run=False,
  173. )
  174. def test_ping_monitor_skips_ssl_verification_when_verify_tls_false():
  175. hook_config = {'ping_url': 'https://example.com', 'verify_tls': False}
  176. payload = 'data'
  177. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  178. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  179. 'format_buffered_logs_for_payload',
  180. ).and_return(payload)
  181. flexmock(module.requests).should_receive('post').with_args(
  182. 'https://example.com',
  183. data=payload.encode('utf-8'),
  184. verify=False,
  185. timeout=int,
  186. ).and_return(flexmock(ok=True))
  187. module.ping_monitor(
  188. hook_config,
  189. {},
  190. 'config.yaml',
  191. state=module.monitor.State.FINISH,
  192. monitoring_log_level=1,
  193. dry_run=False,
  194. )
  195. def test_ping_monitor_executes_ssl_verification_when_verify_tls_true():
  196. hook_config = {'ping_url': 'https://example.com', 'verify_tls': True}
  197. payload = 'data'
  198. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive('get_handler')
  199. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  200. 'format_buffered_logs_for_payload',
  201. ).and_return(payload)
  202. flexmock(module.requests).should_receive('post').with_args(
  203. 'https://example.com',
  204. data=payload.encode('utf-8'),
  205. verify=True,
  206. timeout=int,
  207. ).and_return(flexmock(ok=True))
  208. module.ping_monitor(
  209. hook_config,
  210. {},
  211. 'config.yaml',
  212. state=module.monitor.State.FINISH,
  213. monitoring_log_level=1,
  214. dry_run=False,
  215. )
  216. def test_ping_monitor_dry_run_does_not_hit_ping_url():
  217. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  218. 'Forgetful_buffering_handler',
  219. ).never()
  220. hook_config = {'ping_url': 'https://example.com'}
  221. flexmock(module.requests).should_receive('post').never()
  222. module.ping_monitor(
  223. hook_config,
  224. {},
  225. 'config.yaml',
  226. state=module.monitor.State.START,
  227. monitoring_log_level=1,
  228. dry_run=True,
  229. )
  230. def test_ping_monitor_does_not_hit_ping_url_when_states_not_matching():
  231. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  232. 'Forgetful_buffering_handler',
  233. ).never()
  234. hook_config = {'ping_url': 'https://example.com', 'states': ['finish']}
  235. flexmock(module.requests).should_receive('post').never()
  236. module.ping_monitor(
  237. hook_config,
  238. {},
  239. 'config.yaml',
  240. state=module.monitor.State.START,
  241. monitoring_log_level=1,
  242. dry_run=True,
  243. )
  244. def test_ping_monitor_hits_ping_url_when_states_matching():
  245. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  246. 'Forgetful_buffering_handler',
  247. ).never()
  248. hook_config = {'ping_url': 'https://example.com', 'states': ['start', 'finish']}
  249. flexmock(module.requests).should_receive('post').with_args(
  250. 'https://example.com/start',
  251. data=b'',
  252. verify=True,
  253. timeout=int,
  254. ).and_return(flexmock(ok=True))
  255. module.ping_monitor(
  256. hook_config,
  257. {},
  258. 'config.yaml',
  259. state=module.monitor.State.START,
  260. monitoring_log_level=1,
  261. dry_run=False,
  262. )
  263. def test_ping_monitor_adds_create_query_parameter_when_create_slug_true():
  264. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  265. 'Forgetful_buffering_handler',
  266. ).never()
  267. hook_config = {'ping_url': 'https://example.com', 'create_slug': True}
  268. flexmock(module.requests).should_receive('post').with_args(
  269. 'https://example.com/start?create=1',
  270. data=b'',
  271. verify=True,
  272. timeout=int,
  273. ).and_return(flexmock(ok=True))
  274. module.ping_monitor(
  275. hook_config,
  276. {},
  277. 'config.yaml',
  278. state=module.monitor.State.START,
  279. monitoring_log_level=1,
  280. dry_run=False,
  281. )
  282. def test_ping_monitor_does_not_add_create_query_parameter_when_create_slug_false():
  283. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  284. 'Forgetful_buffering_handler',
  285. ).never()
  286. hook_config = {'ping_url': 'https://example.com', 'create_slug': False}
  287. flexmock(module.requests).should_receive('post').with_args(
  288. 'https://example.com/start',
  289. data=b'',
  290. verify=True,
  291. timeout=int,
  292. ).and_return(flexmock(ok=True))
  293. module.ping_monitor(
  294. hook_config,
  295. {},
  296. 'config.yaml',
  297. state=module.monitor.State.START,
  298. monitoring_log_level=1,
  299. dry_run=False,
  300. )
  301. def test_ping_monitor_does_not_add_create_query_parameter_when_ping_url_is_uuid():
  302. hook_config = {'ping_url': 'b3611b24-df9c-4d36-9203-fa292820bf2a', 'create_slug': True}
  303. flexmock(module.requests).should_receive('post').with_args(
  304. f"https://hc-ping.com/{hook_config['ping_url']}",
  305. data=b'',
  306. verify=True,
  307. timeout=int,
  308. ).and_return(flexmock(ok=True))
  309. module.ping_monitor(
  310. hook_config,
  311. {},
  312. 'config.yaml',
  313. state=module.monitor.State.FINISH,
  314. monitoring_log_level=1,
  315. dry_run=False,
  316. )
  317. def test_ping_monitor_issues_warning_when_ping_url_is_uuid_and_create_slug_true():
  318. hook_config = {'ping_url': 'b3611b24-df9c-4d36-9203-fa292820bf2a', 'create_slug': True}
  319. flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True))
  320. flexmock(module.logger).should_receive('warning').once()
  321. module.ping_monitor(
  322. hook_config,
  323. {},
  324. 'config.yaml',
  325. state=module.monitor.State.FINISH,
  326. monitoring_log_level=1,
  327. dry_run=False,
  328. )
  329. def test_ping_monitor_with_connection_error_logs_warning():
  330. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  331. 'Forgetful_buffering_handler',
  332. ).never()
  333. hook_config = {'ping_url': 'https://example.com'}
  334. flexmock(module.requests).should_receive('post').with_args(
  335. 'https://example.com/start',
  336. data=b'',
  337. verify=True,
  338. timeout=int,
  339. ).and_raise(module.requests.exceptions.ConnectionError)
  340. flexmock(module.logger).should_receive('warning').once()
  341. module.ping_monitor(
  342. hook_config,
  343. {},
  344. 'config.yaml',
  345. state=module.monitor.State.START,
  346. monitoring_log_level=1,
  347. dry_run=False,
  348. )
  349. def test_ping_monitor_with_other_error_logs_warning():
  350. flexmock(module.borgmatic.hooks.monitoring.logs).should_receive(
  351. 'Forgetful_buffering_handler',
  352. ).never()
  353. hook_config = {'ping_url': 'https://example.com'}
  354. response = flexmock(ok=False)
  355. response.should_receive('raise_for_status').and_raise(
  356. module.requests.exceptions.RequestException,
  357. )
  358. flexmock(module.requests).should_receive('post').with_args(
  359. 'https://example.com/start',
  360. data=b'',
  361. verify=True,
  362. timeout=int,
  363. ).and_return(response)
  364. flexmock(module.logger).should_receive('warning').once()
  365. module.ping_monitor(
  366. hook_config,
  367. {},
  368. 'config.yaml',
  369. state=module.monitor.State.START,
  370. monitoring_log_level=1,
  371. dry_run=False,
  372. )