test_mysql.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. import logging
  2. import pytest
  3. from flexmock import flexmock
  4. from borgmatic.hooks.data_source import mysql as module
  5. def test_database_names_to_dump_passes_through_name():
  6. extra_environment = flexmock()
  7. names = module.database_names_to_dump({'name': 'foo'}, extra_environment, dry_run=False)
  8. assert names == ('foo',)
  9. def test_database_names_to_dump_bails_for_dry_run():
  10. extra_environment = flexmock()
  11. flexmock(module).should_receive('execute_command_and_capture_output').never()
  12. names = module.database_names_to_dump({'name': 'all'}, extra_environment, dry_run=True)
  13. assert names == ()
  14. def test_database_names_to_dump_queries_mysql_for_database_names():
  15. extra_environment = flexmock()
  16. flexmock(module).should_receive('execute_command_and_capture_output').with_args(
  17. ('mysql', '--skip-column-names', '--batch', '--execute', 'show schemas'),
  18. extra_environment=extra_environment,
  19. ).and_return('foo\nbar\nmysql\n').once()
  20. names = module.database_names_to_dump({'name': 'all'}, extra_environment, dry_run=False)
  21. assert names == ('foo', 'bar')
  22. def test_use_streaming_true_for_any_databases():
  23. assert module.use_streaming(
  24. databases=[flexmock(), flexmock()],
  25. config=flexmock(),
  26. )
  27. def test_use_streaming_false_for_no_databases():
  28. assert not module.use_streaming(databases=[], config=flexmock())
  29. def test_dump_data_sources_dumps_each_database():
  30. databases = [{'name': 'foo'}, {'name': 'bar'}]
  31. processes = [flexmock(), flexmock()]
  32. flexmock(module).should_receive('make_dump_path').and_return('')
  33. flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
  34. ('bar',)
  35. )
  36. for name, process in zip(('foo', 'bar'), processes):
  37. flexmock(module).should_receive('execute_dump_command').with_args(
  38. database={'name': name},
  39. dump_path=object,
  40. database_names=(name,),
  41. extra_environment=object,
  42. dry_run=object,
  43. dry_run_label=object,
  44. ).and_return(process).once()
  45. assert (
  46. module.dump_data_sources(
  47. databases,
  48. {},
  49. 'test.yaml',
  50. config_paths=('test.yaml',),
  51. borgmatic_runtime_directory='/run/borgmatic',
  52. patterns=[],
  53. dry_run=False,
  54. )
  55. == processes
  56. )
  57. def test_dump_data_sources_dumps_with_password():
  58. database = {'name': 'foo', 'username': 'root', 'password': 'trustsome1'}
  59. process = flexmock()
  60. flexmock(module).should_receive('make_dump_path').and_return('')
  61. flexmock(module).should_receive('database_names_to_dump').and_return(('foo',)).and_return(
  62. ('bar',)
  63. )
  64. flexmock(module).should_receive('execute_dump_command').with_args(
  65. database=database,
  66. dump_path=object,
  67. database_names=('foo',),
  68. extra_environment={'MYSQL_PWD': 'trustsome1'},
  69. dry_run=object,
  70. dry_run_label=object,
  71. ).and_return(process).once()
  72. assert module.dump_data_sources(
  73. [database],
  74. {},
  75. 'test.yaml',
  76. config_paths=('test.yaml',),
  77. borgmatic_runtime_directory='/run/borgmatic',
  78. patterns=[],
  79. dry_run=False,
  80. ) == [process]
  81. def test_dump_data_sources_dumps_all_databases_at_once():
  82. databases = [{'name': 'all'}]
  83. process = flexmock()
  84. flexmock(module).should_receive('make_dump_path').and_return('')
  85. flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar'))
  86. flexmock(module).should_receive('execute_dump_command').with_args(
  87. database={'name': 'all'},
  88. dump_path=object,
  89. database_names=('foo', 'bar'),
  90. extra_environment=object,
  91. dry_run=object,
  92. dry_run_label=object,
  93. ).and_return(process).once()
  94. assert module.dump_data_sources(
  95. databases,
  96. {},
  97. 'test.yaml',
  98. config_paths=('test.yaml',),
  99. borgmatic_runtime_directory='/run/borgmatic',
  100. patterns=[],
  101. dry_run=False,
  102. ) == [process]
  103. def test_dump_data_sources_dumps_all_databases_separately_when_format_configured():
  104. databases = [{'name': 'all', 'format': 'sql'}]
  105. processes = [flexmock(), flexmock()]
  106. flexmock(module).should_receive('make_dump_path').and_return('')
  107. flexmock(module).should_receive('database_names_to_dump').and_return(('foo', 'bar'))
  108. for name, process in zip(('foo', 'bar'), processes):
  109. flexmock(module).should_receive('execute_dump_command').with_args(
  110. database={'name': name, 'format': 'sql'},
  111. dump_path=object,
  112. database_names=(name,),
  113. extra_environment=object,
  114. dry_run=object,
  115. dry_run_label=object,
  116. ).and_return(process).once()
  117. assert (
  118. module.dump_data_sources(
  119. databases,
  120. {},
  121. 'test.yaml',
  122. config_paths=('test.yaml',),
  123. borgmatic_runtime_directory='/run/borgmatic',
  124. patterns=[],
  125. dry_run=False,
  126. )
  127. == processes
  128. )
  129. def test_database_names_to_dump_runs_mysql_with_list_options():
  130. database = {'name': 'all', 'list_options': '--defaults-extra-file=my.cnf'}
  131. flexmock(module).should_receive('execute_command_and_capture_output').with_args(
  132. (
  133. 'mysql',
  134. '--defaults-extra-file=my.cnf',
  135. '--skip-column-names',
  136. '--batch',
  137. '--execute',
  138. 'show schemas',
  139. ),
  140. extra_environment=None,
  141. ).and_return(('foo\nbar')).once()
  142. assert module.database_names_to_dump(database, None, 'test.yaml', '') == ('foo', 'bar')
  143. def test_database_names_to_dump_runs_non_default_mysql_with_list_options():
  144. database = {
  145. 'name': 'all',
  146. 'list_options': '--defaults-extra-file=my.cnf',
  147. 'mysql_command': 'custom_mysql',
  148. }
  149. flexmock(module).should_receive('execute_command_and_capture_output').with_args(
  150. extra_environment=None,
  151. full_command=(
  152. 'custom_mysql', # Custom MySQL command
  153. '--defaults-extra-file=my.cnf',
  154. '--skip-column-names',
  155. '--batch',
  156. '--execute',
  157. 'show schemas',
  158. ),
  159. ).and_return(('foo\nbar')).once()
  160. assert module.database_names_to_dump(database, None, 'test.yaml', '') == ('foo', 'bar')
  161. def test_execute_dump_command_runs_mysqldump():
  162. process = flexmock()
  163. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  164. flexmock(module.os.path).should_receive('exists').and_return(False)
  165. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  166. flexmock(module).should_receive('execute_command').with_args(
  167. (
  168. 'mysqldump',
  169. '--add-drop-database',
  170. '--databases',
  171. 'foo',
  172. '--result-file',
  173. 'dump',
  174. ),
  175. extra_environment=None,
  176. run_to_completion=False,
  177. ).and_return(process).once()
  178. assert (
  179. module.execute_dump_command(
  180. database={'name': 'foo'},
  181. dump_path=flexmock(),
  182. database_names=('foo',),
  183. extra_environment=None,
  184. dry_run=False,
  185. dry_run_label='',
  186. )
  187. == process
  188. )
  189. def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
  190. process = flexmock()
  191. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  192. flexmock(module.os.path).should_receive('exists').and_return(False)
  193. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  194. flexmock(module).should_receive('execute_command').with_args(
  195. (
  196. 'mysqldump',
  197. '--databases',
  198. 'foo',
  199. '--result-file',
  200. 'dump',
  201. ),
  202. extra_environment=None,
  203. run_to_completion=False,
  204. ).and_return(process).once()
  205. assert (
  206. module.execute_dump_command(
  207. database={'name': 'foo', 'add_drop_database': False},
  208. dump_path=flexmock(),
  209. database_names=('foo',),
  210. extra_environment=None,
  211. dry_run=False,
  212. dry_run_label='',
  213. )
  214. == process
  215. )
  216. def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
  217. process = flexmock()
  218. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  219. flexmock(module.os.path).should_receive('exists').and_return(False)
  220. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  221. flexmock(module).should_receive('execute_command').with_args(
  222. (
  223. 'mysqldump',
  224. '--add-drop-database',
  225. '--host',
  226. 'database.example.org',
  227. '--port',
  228. '5433',
  229. '--protocol',
  230. 'tcp',
  231. '--databases',
  232. 'foo',
  233. '--result-file',
  234. 'dump',
  235. ),
  236. extra_environment=None,
  237. run_to_completion=False,
  238. ).and_return(process).once()
  239. assert (
  240. module.execute_dump_command(
  241. database={'name': 'foo', 'hostname': 'database.example.org', 'port': 5433},
  242. dump_path=flexmock(),
  243. database_names=('foo',),
  244. extra_environment=None,
  245. dry_run=False,
  246. dry_run_label='',
  247. )
  248. == process
  249. )
  250. def test_execute_dump_command_runs_mysqldump_with_username_and_password():
  251. process = flexmock()
  252. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  253. flexmock(module.os.path).should_receive('exists').and_return(False)
  254. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  255. flexmock(module).should_receive('execute_command').with_args(
  256. (
  257. 'mysqldump',
  258. '--add-drop-database',
  259. '--user',
  260. 'root',
  261. '--databases',
  262. 'foo',
  263. '--result-file',
  264. 'dump',
  265. ),
  266. extra_environment={'MYSQL_PWD': 'trustsome1'},
  267. run_to_completion=False,
  268. ).and_return(process).once()
  269. assert (
  270. module.execute_dump_command(
  271. database={'name': 'foo', 'username': 'root', 'password': 'trustsome1'},
  272. dump_path=flexmock(),
  273. database_names=('foo',),
  274. extra_environment={'MYSQL_PWD': 'trustsome1'},
  275. dry_run=False,
  276. dry_run_label='',
  277. )
  278. == process
  279. )
  280. def test_execute_dump_command_runs_mysqldump_with_options():
  281. process = flexmock()
  282. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  283. flexmock(module.os.path).should_receive('exists').and_return(False)
  284. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  285. flexmock(module).should_receive('execute_command').with_args(
  286. (
  287. 'mysqldump',
  288. '--stuff=such',
  289. '--add-drop-database',
  290. '--databases',
  291. 'foo',
  292. '--result-file',
  293. 'dump',
  294. ),
  295. extra_environment=None,
  296. run_to_completion=False,
  297. ).and_return(process).once()
  298. assert (
  299. module.execute_dump_command(
  300. database={'name': 'foo', 'options': '--stuff=such'},
  301. dump_path=flexmock(),
  302. database_names=('foo',),
  303. extra_environment=None,
  304. dry_run=False,
  305. dry_run_label='',
  306. )
  307. == process
  308. )
  309. def test_execute_dump_command_runs_non_default_mysqldump():
  310. process = flexmock()
  311. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  312. flexmock(module.os.path).should_receive('exists').and_return(False)
  313. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  314. flexmock(module).should_receive('execute_command').with_args(
  315. (
  316. 'custom_mysqldump', # Custom MySQL dump command
  317. '--add-drop-database',
  318. '--databases',
  319. 'foo',
  320. '--result-file',
  321. 'dump',
  322. ),
  323. extra_environment=None,
  324. run_to_completion=False,
  325. ).and_return(process).once()
  326. assert (
  327. module.execute_dump_command(
  328. database={
  329. 'name': 'foo',
  330. 'mysql_dump_command': 'custom_mysqldump',
  331. }, # Custom MySQL dump command specified
  332. dump_path=flexmock(),
  333. database_names=('foo',),
  334. extra_environment=None,
  335. dry_run=False,
  336. dry_run_label='',
  337. )
  338. == process
  339. )
  340. def test_execute_dump_command_with_duplicate_dump_skips_mysqldump():
  341. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  342. flexmock(module.os.path).should_receive('exists').and_return(True)
  343. flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
  344. flexmock(module).should_receive('execute_command').never()
  345. assert (
  346. module.execute_dump_command(
  347. database={'name': 'foo'},
  348. dump_path=flexmock(),
  349. database_names=('foo',),
  350. extra_environment=None,
  351. dry_run=True,
  352. dry_run_label='SO DRY',
  353. )
  354. is None
  355. )
  356. def test_execute_dump_command_with_dry_run_skips_mysqldump():
  357. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
  358. flexmock(module.os.path).should_receive('exists').and_return(False)
  359. flexmock(module.dump).should_receive('create_named_pipe_for_dump')
  360. flexmock(module).should_receive('execute_command').never()
  361. assert (
  362. module.execute_dump_command(
  363. database={'name': 'foo'},
  364. dump_path=flexmock(),
  365. database_names=('foo',),
  366. extra_environment=None,
  367. dry_run=True,
  368. dry_run_label='SO DRY',
  369. )
  370. is None
  371. )
  372. def test_dump_data_sources_errors_for_missing_all_databases():
  373. databases = [{'name': 'all'}]
  374. flexmock(module).should_receive('make_dump_path').and_return('')
  375. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  376. 'databases/localhost/all'
  377. )
  378. flexmock(module).should_receive('database_names_to_dump').and_return(())
  379. with pytest.raises(ValueError):
  380. assert module.dump_data_sources(
  381. databases,
  382. {},
  383. 'test.yaml',
  384. config_paths=('test.yaml',),
  385. borgmatic_runtime_directory='/run/borgmatic',
  386. patterns=[],
  387. dry_run=False,
  388. )
  389. def test_dump_data_sources_does_not_error_for_missing_all_databases_with_dry_run():
  390. databases = [{'name': 'all'}]
  391. flexmock(module).should_receive('make_dump_path').and_return('')
  392. flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return(
  393. 'databases/localhost/all'
  394. )
  395. flexmock(module).should_receive('database_names_to_dump').and_return(())
  396. assert (
  397. module.dump_data_sources(
  398. databases,
  399. {},
  400. 'test.yaml',
  401. config_paths=('test.yaml',),
  402. borgmatic_runtime_directory='/run/borgmatic',
  403. patterns=[],
  404. dry_run=True,
  405. )
  406. == []
  407. )
  408. def test_restore_data_source_dump_runs_mysql_to_restore():
  409. hook_config = [{'name': 'foo'}, {'name': 'bar'}]
  410. extract_process = flexmock(stdout=flexmock())
  411. flexmock(module).should_receive('execute_command_with_processes').with_args(
  412. ('mysql', '--batch'),
  413. processes=[extract_process],
  414. output_log_level=logging.DEBUG,
  415. input_file=extract_process.stdout,
  416. extra_environment=None,
  417. ).once()
  418. module.restore_data_source_dump(
  419. hook_config,
  420. {},
  421. 'test.yaml',
  422. data_source={'name': 'foo'},
  423. dry_run=False,
  424. extract_process=extract_process,
  425. connection_params={
  426. 'hostname': None,
  427. 'port': None,
  428. 'username': None,
  429. 'password': None,
  430. },
  431. borgmatic_runtime_directory='/run/borgmatic',
  432. )
  433. def test_restore_data_source_dump_runs_mysql_with_options():
  434. hook_config = [{'name': 'foo', 'restore_options': '--harder'}]
  435. extract_process = flexmock(stdout=flexmock())
  436. flexmock(module).should_receive('execute_command_with_processes').with_args(
  437. ('mysql', '--batch', '--harder'),
  438. processes=[extract_process],
  439. output_log_level=logging.DEBUG,
  440. input_file=extract_process.stdout,
  441. extra_environment=None,
  442. ).once()
  443. module.restore_data_source_dump(
  444. hook_config,
  445. {},
  446. 'test.yaml',
  447. data_source=hook_config[0],
  448. dry_run=False,
  449. extract_process=extract_process,
  450. connection_params={
  451. 'hostname': None,
  452. 'port': None,
  453. 'username': None,
  454. 'password': None,
  455. },
  456. borgmatic_runtime_directory='/run/borgmatic',
  457. )
  458. def test_restore_data_source_dump_runs_non_default_mysql_with_options():
  459. hook_config = [{'name': 'foo', 'mysql_command': 'custom_mysql', 'restore_options': '--harder'}]
  460. extract_process = flexmock(stdout=flexmock())
  461. flexmock(module).should_receive('execute_command_with_processes').with_args(
  462. ('custom_mysql', '--batch', '--harder'),
  463. processes=[extract_process],
  464. output_log_level=logging.DEBUG,
  465. input_file=extract_process.stdout,
  466. extra_environment=None,
  467. ).once()
  468. module.restore_data_source_dump(
  469. hook_config,
  470. {},
  471. 'test.yaml',
  472. data_source=hook_config[0],
  473. dry_run=False,
  474. extract_process=extract_process,
  475. connection_params={
  476. 'hostname': None,
  477. 'port': None,
  478. 'username': None,
  479. 'password': None,
  480. },
  481. borgmatic_runtime_directory='/run/borgmatic',
  482. )
  483. def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
  484. hook_config = [{'name': 'foo', 'hostname': 'database.example.org', 'port': 5433}]
  485. extract_process = flexmock(stdout=flexmock())
  486. flexmock(module).should_receive('execute_command_with_processes').with_args(
  487. (
  488. 'mysql',
  489. '--batch',
  490. '--host',
  491. 'database.example.org',
  492. '--port',
  493. '5433',
  494. '--protocol',
  495. 'tcp',
  496. ),
  497. processes=[extract_process],
  498. output_log_level=logging.DEBUG,
  499. input_file=extract_process.stdout,
  500. extra_environment=None,
  501. ).once()
  502. module.restore_data_source_dump(
  503. hook_config,
  504. {},
  505. 'test.yaml',
  506. data_source=hook_config[0],
  507. dry_run=False,
  508. extract_process=extract_process,
  509. connection_params={
  510. 'hostname': None,
  511. 'port': None,
  512. 'username': None,
  513. 'password': None,
  514. },
  515. borgmatic_runtime_directory='/run/borgmatic',
  516. )
  517. def test_restore_data_source_dump_runs_mysql_with_username_and_password():
  518. hook_config = [{'name': 'foo', 'username': 'root', 'password': 'trustsome1'}]
  519. extract_process = flexmock(stdout=flexmock())
  520. flexmock(module).should_receive('execute_command_with_processes').with_args(
  521. ('mysql', '--batch', '--user', 'root'),
  522. processes=[extract_process],
  523. output_log_level=logging.DEBUG,
  524. input_file=extract_process.stdout,
  525. extra_environment={'MYSQL_PWD': 'trustsome1'},
  526. ).once()
  527. module.restore_data_source_dump(
  528. hook_config,
  529. {},
  530. 'test.yaml',
  531. data_source=hook_config[0],
  532. dry_run=False,
  533. extract_process=extract_process,
  534. connection_params={
  535. 'hostname': None,
  536. 'port': None,
  537. 'username': None,
  538. 'password': None,
  539. },
  540. borgmatic_runtime_directory='/run/borgmatic',
  541. )
  542. def test_restore_data_source_dump_with_connection_params_uses_connection_params_for_restore():
  543. hook_config = [
  544. {
  545. 'name': 'foo',
  546. 'username': 'root',
  547. 'password': 'trustsome1',
  548. 'restore_hostname': 'restorehost',
  549. 'restore_port': 'restoreport',
  550. 'restore_username': 'restoreusername',
  551. 'restore_password': 'restorepassword',
  552. }
  553. ]
  554. extract_process = flexmock(stdout=flexmock())
  555. flexmock(module).should_receive('execute_command_with_processes').with_args(
  556. (
  557. 'mysql',
  558. '--batch',
  559. '--host',
  560. 'clihost',
  561. '--port',
  562. 'cliport',
  563. '--protocol',
  564. 'tcp',
  565. '--user',
  566. 'cliusername',
  567. ),
  568. processes=[extract_process],
  569. output_log_level=logging.DEBUG,
  570. input_file=extract_process.stdout,
  571. extra_environment={'MYSQL_PWD': 'clipassword'},
  572. ).once()
  573. module.restore_data_source_dump(
  574. hook_config,
  575. {},
  576. 'test.yaml',
  577. data_source={'name': 'foo'},
  578. dry_run=False,
  579. extract_process=extract_process,
  580. connection_params={
  581. 'hostname': 'clihost',
  582. 'port': 'cliport',
  583. 'username': 'cliusername',
  584. 'password': 'clipassword',
  585. },
  586. borgmatic_runtime_directory='/run/borgmatic',
  587. )
  588. def test_restore_data_source_dump_without_connection_params_uses_restore_params_in_config_for_restore():
  589. hook_config = [
  590. {
  591. 'name': 'foo',
  592. 'username': 'root',
  593. 'password': 'trustsome1',
  594. 'hostname': 'dbhost',
  595. 'port': 'dbport',
  596. 'restore_username': 'restoreuser',
  597. 'restore_password': 'restorepass',
  598. 'restore_hostname': 'restorehost',
  599. 'restore_port': 'restoreport',
  600. }
  601. ]
  602. extract_process = flexmock(stdout=flexmock())
  603. flexmock(module).should_receive('execute_command_with_processes').with_args(
  604. (
  605. 'mysql',
  606. '--batch',
  607. '--host',
  608. 'restorehost',
  609. '--port',
  610. 'restoreport',
  611. '--protocol',
  612. 'tcp',
  613. '--user',
  614. 'restoreuser',
  615. ),
  616. processes=[extract_process],
  617. output_log_level=logging.DEBUG,
  618. input_file=extract_process.stdout,
  619. extra_environment={'MYSQL_PWD': 'restorepass'},
  620. ).once()
  621. module.restore_data_source_dump(
  622. hook_config,
  623. {},
  624. 'test.yaml',
  625. data_source=hook_config[0],
  626. dry_run=False,
  627. extract_process=extract_process,
  628. connection_params={
  629. 'hostname': None,
  630. 'port': None,
  631. 'username': None,
  632. 'password': None,
  633. },
  634. borgmatic_runtime_directory='/run/borgmatic',
  635. )
  636. def test_restore_data_source_dump_with_dry_run_skips_restore():
  637. hook_config = [{'name': 'foo'}]
  638. flexmock(module).should_receive('execute_command_with_processes').never()
  639. module.restore_data_source_dump(
  640. hook_config,
  641. {},
  642. 'test.yaml',
  643. data_source={'name': 'foo'},
  644. dry_run=True,
  645. extract_process=flexmock(),
  646. connection_params={
  647. 'hostname': None,
  648. 'port': None,
  649. 'username': None,
  650. 'password': None,
  651. },
  652. borgmatic_runtime_directory='/run/borgmatic',
  653. )