Browse Source

Fix for the database dumps hooks not respecting the "working_directory" option (#1127).

Reviewed-on: https://projects.torsion.org/borgmatic-collective/borgmatic/pulls/1129
Dan Helfman 1 week ago
parent
commit
a7356f2360

+ 7 - 1
borgmatic/hooks/data_source/mariadb.py

@@ -155,7 +155,11 @@ def database_names_to_dump(database, config, username, password, environment, dr
     if skip_names:
         logger.debug(f'Skipping database names: {", ".join(skip_names)}')
 
-    show_output = execute_command_and_capture_output(show_command, environment=environment)
+    show_output = execute_command_and_capture_output(
+        show_command,
+        environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
+    )
 
     return tuple(
         show_name
@@ -239,6 +243,7 @@ def execute_dump_command(
         dump_command,
         environment=environment,
         run_to_completion=False,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )
 
 
@@ -495,4 +500,5 @@ def restore_data_source_dump(
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )

+ 12 - 2
borgmatic/hooks/data_source/mongodb.py

@@ -90,11 +90,20 @@ def dump_data_sources(
 
         if dump_format == 'directory':
             dump.create_parent_directory_for_dump(dump_filename)
-            execute_command(command, shell=True)  # noqa: S604
+            execute_command(  # noqa: S604
+                command,
+                shell=True,
+                working_directory=borgmatic.config.paths.get_working_directory(config),
+            )
         else:
             dump.create_named_pipe_for_dump(dump_filename)
             processes.append(
-                execute_command(command, shell=True, run_to_completion=False),  # noqa: S604
+                execute_command(  # noqa: S604
+                    command,
+                    shell=True,
+                    run_to_completion=False,
+                    working_directory=borgmatic.config.paths.get_working_directory(config),
+                ),
             )
 
     if not dry_run:
@@ -273,6 +282,7 @@ def restore_data_source_dump(
         [extract_process] if extract_process else [],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout if extract_process else None,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )
 
 

+ 7 - 1
borgmatic/hooks/data_source/mysql.py

@@ -84,7 +84,11 @@ def database_names_to_dump(database, config, username, password, environment, dr
     if skip_names:
         logger.debug(f'Skipping database names: {", ".join(skip_names)}')
 
-    show_output = execute_command_and_capture_output(show_command, environment=environment)
+    show_output = execute_command_and_capture_output(
+        show_command,
+        environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
+    )
 
     return tuple(
         show_name
@@ -170,6 +174,7 @@ def execute_dump_command(
         dump_command,
         environment=environment,
         run_to_completion=False,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )
 
 
@@ -432,4 +437,5 @@ def restore_data_source_dump(
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )

+ 13 - 2
borgmatic/hooks/data_source/postgresql.py

@@ -103,7 +103,11 @@ def database_names_to_dump(database, config, environment, dry_run):
         + (tuple(database['list_options'].split(' ')) if 'list_options' in database else ())
     )
     logger.debug('Querying for "all" PostgreSQL databases to dump')
-    list_output = execute_command_and_capture_output(list_command, environment=environment)
+    list_output = execute_command_and_capture_output(
+        list_command,
+        environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
+    )
 
     return tuple(
         row[0]
@@ -245,6 +249,7 @@ def dump_data_sources(
                     command,
                     shell=True,
                     environment=environment,
+                    working_directory=borgmatic.config.paths.get_working_directory(config),
                 )
             else:
                 dump.create_named_pipe_for_dump(dump_filename)
@@ -254,6 +259,7 @@ def dump_data_sources(
                         shell=True,
                         environment=environment,
                         run_to_completion=False,
+                        working_directory=borgmatic.config.paths.get_working_directory(config),
                     ),
                 )
 
@@ -422,5 +428,10 @@ def restore_data_source_dump(
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout if extract_process else None,
         environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
+    )
+    execute_command(
+        analyze_command,
+        environment=environment,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )
-    execute_command(analyze_command, environment=environment)

+ 7 - 1
borgmatic/hooks/data_source/sqlite.py

@@ -101,7 +101,12 @@ def dump_data_sources(
 
         dump.create_named_pipe_for_dump(dump_filename)
         processes.append(
-            execute_command(command, shell=True, run_to_completion=False),  # noqa: S604
+            execute_command(  # noqa: S604
+                command,
+                shell=True,
+                run_to_completion=False,
+                working_directory=borgmatic.config.paths.get_working_directory(config),
+            ),
         )
 
     if not dry_run:
@@ -205,4 +210,5 @@ def restore_data_source_dump(
         [extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=borgmatic.config.paths.get_working_directory(config),
     )

+ 54 - 0
tests/unit/hooks/data_source/test_mariadb.py

@@ -186,6 +186,9 @@ def test_database_names_to_dump_queries_mariadb_for_database_names():
         'trustsome1',
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
+        '/path/to/working/dir'
+    )
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -196,6 +199,7 @@ def test_database_names_to_dump_queries_mariadb_for_database_names():
             'show schemas',
         ),
         environment=environment,
+        working_directory='/path/to/working/dir',
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -221,6 +225,7 @@ def test_database_names_to_dump_with_database_name_all_and_skip_names_filters_ou
         'trustsome1',
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -231,6 +236,7 @@ def test_database_names_to_dump_with_database_name_all_and_skip_names_filters_ou
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nbaz\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -252,6 +258,7 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul
     ).replace_with(lambda value, config: value)
     flexmock(module).should_receive('parse_extra_options').and_return((), None)
     flexmock(module).should_receive('make_defaults_file_options').never()
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -263,6 +270,7 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -288,6 +296,7 @@ def test_database_names_to_dump_runs_mariadb_with_tls():
         'trustsome1',
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -299,6 +308,7 @@ def test_database_names_to_dump_runs_mariadb_with_tls():
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -324,6 +334,7 @@ def test_database_names_to_dump_runs_mariadb_without_tls():
         'trustsome1',
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -335,6 +346,7 @@ def test_database_names_to_dump_runs_mariadb_without_tls():
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -699,6 +711,7 @@ def test_database_names_to_dump_runs_mariadb_with_list_options():
         'trustsome1',
         'mariadb.cnf',
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -710,6 +723,7 @@ def test_database_names_to_dump_runs_mariadb_with_list_options():
             'show schemas',
         ),
         environment=None,
+        working_directory=None,
     ).and_return('foo\nbar').once()
 
     assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == (
@@ -733,6 +747,7 @@ def test_database_names_to_dump_runs_non_default_mariadb_with_list_options():
         'trustsome1',
         'mariadb.cnf',
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         environment=None,
         full_command=(
@@ -744,6 +759,7 @@ def test_database_names_to_dump_runs_non_default_mariadb_with_list_options():
             '--execute',
             'show schemas',
         ),
+        working_directory=None,
     ).and_return('foo\nbar').once()
 
     assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == (
@@ -766,6 +782,7 @@ def test_execute_dump_command_runs_mariadb_dump():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -779,6 +796,7 @@ def test_execute_dump_command_runs_mariadb_dump():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -807,6 +825,7 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults
     flexmock(module).should_receive('parse_extra_options').and_return((), None)
     flexmock(module).should_receive('make_defaults_file_options').never()
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -821,6 +840,7 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -853,6 +873,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -865,6 +886,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -897,6 +919,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -916,6 +939,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -948,6 +972,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_tls():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -962,6 +987,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_tls():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -994,6 +1020,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_tls():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1008,6 +1035,7 @@ def test_execute_dump_command_runs_mariadb_dump_without_tls():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1040,6 +1068,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1053,6 +1082,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
         ),
         environment={},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1085,6 +1115,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_options():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1099,6 +1130,7 @@ def test_execute_dump_command_runs_mariadb_dump_with_options():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1131,6 +1163,7 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1145,6 +1178,7 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1241,12 +1275,14 @@ def test_restore_data_source_dump_runs_mariadb_to_restore():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1279,12 +1315,14 @@ def test_restore_data_source_dump_runs_mariadb_with_options():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1319,12 +1357,14 @@ def test_restore_data_source_dump_runs_non_default_mariadb_with_options():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('custom_mariadb', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1357,6 +1397,7 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mariadb',
@@ -1372,6 +1413,7 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1404,6 +1446,7 @@ def test_restore_data_source_dump_runs_mariadb_with_tls():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mariadb',
@@ -1414,6 +1457,7 @@ def test_restore_data_source_dump_runs_mariadb_with_tls():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1446,6 +1490,7 @@ def test_restore_data_source_dump_runs_mariadb_without_tls():
         None,
     ).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mariadb',
@@ -1456,6 +1501,7 @@ def test_restore_data_source_dump_runs_mariadb_without_tls():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1488,12 +1534,14 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password():
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--defaults-extra-file=/dev/fd/99', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1531,12 +1579,14 @@ def test_restore_data_source_with_environment_password_transport_skips_defaults_
     flexmock(module.os).should_receive('environ').and_return(
         {'USER': 'root', 'MYSQL_PWD': 'trustsome1'},
     )
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--batch', '--user', 'root'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1579,6 +1629,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mariadb',
@@ -1595,6 +1646,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1641,6 +1693,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mariadb',
@@ -1658,6 +1711,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(

+ 36 - 0
tests/unit/hooks/data_source/test_mongodb.py

@@ -31,12 +31,16 @@ def test_dump_data_sources_runs_mongodump_for_each_database():
         'databases/localhost/foo',
     ).and_return('databases/localhost/bar')
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
+        '/path/to/working/dir'
+    )
 
     for name, process in zip(('foo', 'bar'), processes):
         flexmock(module).should_receive('execute_command').with_args(
             ('mongodump', '--db', name, '--archive', '>', f'databases/localhost/{name}'),
             shell=True,
             run_to_completion=False,
+            working_directory='/path/to/working/dir',
         ).and_return(process).once()
 
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
@@ -100,6 +104,7 @@ def test_dump_data_sources_runs_mongodump_with_hostname_and_port():
         'databases/database.example.org/foo',
     )
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -116,6 +121,7 @@ def test_dump_data_sources_runs_mongodump_with_hostname_and_port():
         ),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -165,6 +171,7 @@ def test_dump_data_sources_runs_mongodump_with_username_and_password():
         '/dev/fd/99',
     )
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -183,6 +190,7 @@ def test_dump_data_sources_runs_mongodump_with_username_and_password():
         ),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -217,10 +225,12 @@ def test_dump_data_sources_runs_mongodump_with_directory_format():
     )
     flexmock(module.dump).should_receive('create_parent_directory_for_dump')
     flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         ('mongodump', '--out', 'databases/localhost/foo', '--db', 'foo'),
         shell=True,
+        working_directory=None,
     ).and_return(flexmock()).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -258,6 +268,7 @@ def test_dump_data_sources_runs_mongodump_with_options():
         'databases/localhost/foo',
     )
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -271,6 +282,7 @@ def test_dump_data_sources_runs_mongodump_with_options():
         ),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -305,11 +317,13 @@ def test_dump_data_sources_runs_mongodumpall_for_all_databases():
         'databases/localhost/all',
     )
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         ('mongodump', '--archive', '>', 'databases/localhost/all'),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -373,11 +387,13 @@ def test_restore_data_source_dump_runs_mongorestore():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ['mongorestore', '--archive', '--drop'],
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -407,6 +423,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'mongorestore',
@@ -420,6 +437,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_hostname_and_port():
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -458,6 +476,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_username_and_password()
     flexmock(module).should_receive('make_password_config_file').with_args('trustsome1').and_return(
         '/dev/fd/99',
     )
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'mongorestore',
@@ -473,6 +492,7 @@ def test_restore_data_source_dump_runs_mongorestore_with_username_and_password()
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -515,6 +535,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
     flexmock(module).should_receive('make_password_config_file').with_args(
         'clipassword',
     ).and_return('/dev/fd/99')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'mongorestore',
@@ -534,6 +555,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -576,6 +598,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
     flexmock(module).should_receive('make_password_config_file').with_args(
         'restorepass',
     ).and_return('/dev/fd/99')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'mongorestore',
@@ -595,6 +618,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -622,11 +646,13 @@ def test_restore_data_source_dump_runs_mongorestore_with_options():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ['mongorestore', '--archive', '--drop', '--harder'],
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -654,6 +680,7 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'mongorestore',
@@ -667,6 +694,7 @@ def test_restore_databases_dump_runs_mongorestore_with_schemas():
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -694,11 +722,13 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ['mongorestore', '--archive'],
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -751,11 +781,13 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ['mongorestore', '--dir', '/dump/path', '--drop'],
         processes=[],
         output_log_level=logging.DEBUG,
         input_file=None,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -785,6 +817,7 @@ def test_dump_data_sources_uses_custom_mongodump_command():
         'databases/localhost/foo',
     )
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -797,6 +830,7 @@ def test_dump_data_sources_uses_custom_mongodump_command():
         ),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -855,6 +889,7 @@ def test_restore_data_source_dump_uses_custom_mongorestore_command():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         [
             'custom_mongorestore',  # Should use custom command instead of default
@@ -865,6 +900,7 @@ def test_restore_data_source_dump_uses_custom_mongorestore_command():
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(

+ 52 - 0
tests/unit/hooks/data_source/test_mysql.py

@@ -68,6 +68,7 @@ def test_database_names_to_dump_queries_mysql_for_database_names():
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -78,6 +79,7 @@ def test_database_names_to_dump_queries_mysql_for_database_names():
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -107,6 +109,7 @@ def test_database_names_to_dump_with_database_name_all_and_skip_names_filters_ou
         'trustsome1',
         None,
     ).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -117,6 +120,7 @@ def test_database_names_to_dump_with_database_name_all_and_skip_names_filters_ou
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nbaz\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -142,6 +146,7 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).never()
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -153,6 +158,7 @@ def test_database_names_to_dump_with_environment_password_transport_skips_defaul
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -178,6 +184,7 @@ def test_database_names_to_dump_runs_mysql_with_tls():
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -189,6 +196,7 @@ def test_database_names_to_dump_runs_mysql_with_tls():
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -214,6 +222,7 @@ def test_database_names_to_dump_runs_mysql_without_tls():
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -225,6 +234,7 @@ def test_database_names_to_dump_runs_mysql_without_tls():
             'show schemas',
         ),
         environment=environment,
+        working_directory=None,
     ).and_return('foo\nbar\nmysql\n').once()
 
     names = module.database_names_to_dump(
@@ -584,6 +594,7 @@ def test_database_names_to_dump_runs_mysql_with_list_options():
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', 'my.cnf').and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -595,6 +606,7 @@ def test_database_names_to_dump_runs_mysql_with_list_options():
             'show schemas',
         ),
         environment=None,
+        working_directory=None,
     ).and_return('foo\nbar').once()
 
     assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == (
@@ -615,6 +627,7 @@ def test_database_names_to_dump_runs_non_default_mysql_with_list_options():
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', 'my.cnf').and_return(('--defaults-extra-file=/dev/fd/99',))
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         environment=None,
         full_command=(
@@ -626,6 +639,7 @@ def test_database_names_to_dump_runs_non_default_mysql_with_list_options():
             '--execute',
             'show schemas',
         ),
+        working_directory=None,
     ).and_return('foo\nbar').once()
 
     assert module.database_names_to_dump(database, {}, 'root', 'trustsome1', None, '') == (
@@ -648,6 +662,7 @@ def test_execute_dump_command_runs_mysqldump():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -661,6 +676,7 @@ def test_execute_dump_command_runs_mysqldump():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -693,6 +709,7 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults
         'make_defaults_file_options',
     ).never()
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -707,6 +724,7 @@ def test_execute_dump_command_with_environment_password_transport_skips_defaults
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -739,6 +757,7 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -751,6 +770,7 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -783,6 +803,7 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -802,6 +823,7 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -834,6 +856,7 @@ def test_execute_dump_command_runs_mysqldump_with_tls():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -848,6 +871,7 @@ def test_execute_dump_command_runs_mysqldump_with_tls():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -880,6 +904,7 @@ def test_execute_dump_command_runs_mysqldump_without_tls():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -894,6 +919,7 @@ def test_execute_dump_command_runs_mysqldump_without_tls():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -926,6 +952,7 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -939,6 +966,7 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password():
         ),
         environment={},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -971,6 +999,7 @@ def test_execute_dump_command_runs_mysqldump_with_options():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -985,6 +1014,7 @@ def test_execute_dump_command_runs_mysqldump_with_options():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1017,6 +1047,7 @@ def test_execute_dump_command_runs_non_default_mysqldump():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1030,6 +1061,7 @@ def test_execute_dump_command_runs_non_default_mysqldump():
         ),
         environment=None,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
 
     assert (
@@ -1125,12 +1157,14 @@ def test_restore_data_source_dump_runs_mysql_to_restore():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1163,12 +1197,14 @@ def test_restore_data_source_dump_runs_mysql_with_options():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1201,12 +1237,14 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('custom_mysql', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1239,6 +1277,7 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mysql',
@@ -1254,6 +1293,7 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1286,6 +1326,7 @@ def test_restore_data_source_dump_runs_mysql_with_tls():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mysql',
@@ -1296,6 +1337,7 @@ def test_restore_data_source_dump_runs_mysql_with_tls():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1328,6 +1370,7 @@ def test_restore_data_source_dump_runs_mysql_without_tls():
         'make_defaults_file_options',
     ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mysql',
@@ -1338,6 +1381,7 @@ def test_restore_data_source_dump_runs_mysql_without_tls():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1370,12 +1414,14 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password():
         'make_defaults_file_options',
     ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--defaults-extra-file=/dev/fd/99', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1417,12 +1463,14 @@ def test_restore_data_source_with_environment_password_transport_skips_defaults_
     flexmock(module.os).should_receive('environ').and_return(
         {'USER': 'root', 'MYSQL_PWD': 'trustsome1'},
     )
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--batch', '--user', 'root'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root', 'MYSQL_PWD': 'trustsome1'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1467,6 +1515,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         ('--defaults-extra-file=/dev/fd/99',),
     )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mysql',
@@ -1483,6 +1532,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1531,6 +1581,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         ('--defaults-extra-file=/dev/fd/99',),
     )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'mysql',
@@ -1548,6 +1599,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'USER': 'root'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(

+ 63 - 0
tests/unit/hooks/data_source/test_postgresql.py

@@ -117,6 +117,9 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostnam
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
+        '/path/to/working/dir'
+    )
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'psql',
@@ -131,6 +134,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_hostnam
             '1234',
         ),
         environment=object,
+        working_directory='/path/to/working/dir',
     ).and_return('foo,test,\nbar,test,"stuff and such"')
 
     assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == (
@@ -144,6 +148,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'psql',
@@ -156,6 +161,7 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_usernam
             'postgres',
         ),
         environment=object,
+        working_directory=None,
     ).and_return('foo,test,\nbar,test,"stuff and such"')
 
     assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == (
@@ -169,9 +175,11 @@ def test_database_names_to_dump_with_all_and_format_lists_databases_with_options
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         ('psql', '--list', '--no-password', '--no-psqlrc', '--csv', '--tuples-only', '--harder'),
         environment=object,
+        working_directory=None,
     ).and_return('foo,test,\nbar,test,"stuff and such"')
 
     assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == (
@@ -201,6 +209,7 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential',
     ).replace_with(lambda value, config: value)
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'docker',
@@ -216,6 +225,7 @@ def test_database_names_to_dump_with_all_and_psql_command_uses_custom_command():
             '--tuples-only',
         ),
         environment=object,
+        working_directory=None,
     ).and_return('foo,text').once()
 
     assert module.database_names_to_dump(database, {}, flexmock(), dry_run=False) == ('foo',)
@@ -255,6 +265,7 @@ def test_dump_data_sources_runs_pg_dump_for_each_database():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     for name, process in zip(('foo', 'bar'), processes):
         flexmock(module).should_receive('execute_command').with_args(
@@ -272,6 +283,7 @@ def test_dump_data_sources_runs_pg_dump_for_each_database():
             shell=True,
             environment={'PGSSLMODE': 'disable'},
             run_to_completion=False,
+            working_directory=None,
         ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -428,6 +440,7 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -448,6 +461,7 @@ def test_dump_data_sources_runs_pg_dump_with_hostname_and_port():
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -492,6 +506,7 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -510,6 +525,7 @@ def test_dump_data_sources_runs_pg_dump_with_username_and_password():
         shell=True,
         environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -552,6 +568,7 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -570,6 +587,7 @@ def test_dump_data_sources_with_username_injection_attack_gets_escaped():
         shell=True,
         environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -610,6 +628,7 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format():
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_parent_directory_for_dump')
     flexmock(module.dump).should_receive('create_named_pipe_for_dump').never()
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -625,6 +644,7 @@ def test_dump_data_sources_runs_pg_dump_with_directory_format():
         ),
         shell=True,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).and_return(flexmock()).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -668,6 +688,7 @@ def test_dump_data_sources_runs_pg_dump_with_string_compression():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -686,6 +707,7 @@ def test_dump_data_sources_runs_pg_dump_with_string_compression():
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(processes[0]).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -729,6 +751,7 @@ def test_dump_data_sources_runs_pg_dump_with_integer_compression():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -747,6 +770,7 @@ def test_dump_data_sources_runs_pg_dump_with_integer_compression():
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(processes[0]).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -790,6 +814,7 @@ def test_dump_data_sources_runs_pg_dump_with_options():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -807,6 +832,7 @@ def test_dump_data_sources_runs_pg_dump_with_options():
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -847,12 +873,14 @@ def test_dump_data_sources_runs_pg_dumpall_for_all_databases():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         ('pg_dumpall', '--no-password', '--clean', '--if-exists', '>', 'databases/localhost/all'),
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -893,6 +921,7 @@ def test_dump_data_sources_runs_non_default_pg_dump():
         'resolve_credential',
     ).replace_with(lambda value, config: value)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
 
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -911,6 +940,7 @@ def test_dump_data_sources_runs_non_default_pg_dump():
         shell=True,
         environment={'PGSSLMODE': 'disable'},
         run_to_completion=False,
+        working_directory=None,
     ).and_return(process).once()
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -947,6 +977,7 @@ def test_restore_data_source_dump_runs_pg_restore():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -961,6 +992,7 @@ def test_restore_data_source_dump_runs_pg_restore():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -974,6 +1006,7 @@ def test_restore_data_source_dump_runs_pg_restore():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1004,6 +1037,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1022,6 +1056,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1039,6 +1074,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_hostname_and_port():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1071,6 +1107,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password():
     )
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1087,6 +1124,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1102,6 +1140,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_username_and_password():
             'ANALYZE',
         ),
         environment={'PGPASSWORD': 'trustsome1', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1145,6 +1184,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
     )
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1165,6 +1205,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1184,6 +1225,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
             'ANALYZE',
         ),
         environment={'PGPASSWORD': 'clipassword', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1227,6 +1269,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
     )
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1247,6 +1290,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1266,6 +1310,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
             'ANALYZE',
         ),
         environment={'PGPASSWORD': 'restorepassword', 'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1301,6 +1346,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1316,6 +1362,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1330,6 +1377,7 @@ def test_restore_data_source_dump_runs_pg_restore_with_options():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1358,6 +1406,7 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'psql',
@@ -1368,10 +1417,12 @@ def test_restore_data_source_dump_runs_psql_for_all_database_dump():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         ('psql', '--no-password', '--no-psqlrc', '--quiet', '--command', 'ANALYZE'),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1400,12 +1451,14 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('psql', '--no-password', '--no-psqlrc', '--dbname', 'foo'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1419,6 +1472,7 @@ def test_restore_data_source_dump_runs_psql_for_plain_database_dump():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1454,6 +1508,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'docker',
@@ -1473,6 +1528,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql():
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1491,6 +1547,7 @@ def test_restore_data_source_dump_runs_non_default_pg_restore_and_psql():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1545,6 +1602,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1560,6 +1618,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
         output_log_level=logging.DEBUG,
         input_file=None,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1573,6 +1632,7 @@ def test_restore_data_source_dump_without_extract_process_restores_from_disk():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(
@@ -1600,6 +1660,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas():
     flexmock(module).should_receive('make_environment').and_return({'PGSSLMODE': 'disable'})
     flexmock(module).should_receive('make_dump_path')
     flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('/dump/path')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'pg_restore',
@@ -1619,6 +1680,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas():
         output_log_level=logging.DEBUG,
         input_file=None,
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
     flexmock(module).should_receive('execute_command').with_args(
         (
@@ -1632,6 +1694,7 @@ def test_restore_data_source_dump_with_schemas_restores_schemas():
             'ANALYZE',
         ),
         environment={'PGSSLMODE': 'disable'},
+        working_directory=None,
     ).once()
 
     module.restore_data_source_dump(

+ 17 - 0
tests/unit/hooks/data_source/test_sqlite.py

@@ -111,6 +111,9 @@ def test_dump_data_sources_with_path_injection_attack_gets_escaped():
     )
     flexmock(module.os.path).should_receive('exists').and_return(False)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(
+        '/path/to/working/dir'
+    )
     flexmock(module).should_receive('execute_command').with_args(
         (
             'sqlite3',
@@ -122,6 +125,7 @@ def test_dump_data_sources_with_path_injection_attack_gets_escaped():
         ),
         shell=True,
         run_to_completion=False,
+        working_directory='/path/to/working/dir',
     ).and_return(processes[0])
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -167,6 +171,7 @@ def test_dump_data_sources_runs_non_default_sqlite_with_path_injection_attack_ge
     )
     flexmock(module.os.path).should_receive('exists').and_return(False)
     flexmock(module.dump).should_receive('create_named_pipe_for_dump')
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command').with_args(
         (
             'custom_sqlite',  # custom sqlite command
@@ -179,6 +184,7 @@ def test_dump_data_sources_runs_non_default_sqlite_with_path_injection_attack_ge
         ),
         shell=True,
         run_to_completion=False,
+        working_directory=None,
     ).and_return(processes[0])
     flexmock(module.dump).should_receive('write_data_source_dumps_metadata').with_args(
         '/run/borgmatic',
@@ -324,6 +330,7 @@ def test_restore_data_source_dump_restores_database():
     hook_config = [{'path': '/path/to/database', 'name': 'database'}, {'name': 'other'}]
     extract_process = flexmock(stdout=flexmock())
 
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'sqlite3',
@@ -333,6 +340,7 @@ def test_restore_data_source_dump_restores_database():
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()
@@ -359,6 +367,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_restores_database():
     ]
     extract_process = flexmock(stdout=flexmock())
 
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'custom_sqlite',
@@ -369,6 +378,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_restores_database():
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()
@@ -394,6 +404,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
     ]
     extract_process = flexmock(stdout=flexmock())
 
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'sqlite3',
@@ -403,6 +414,7 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()
@@ -428,6 +440,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_with_connection_params
     ]
     extract_process = flexmock(stdout=flexmock())
 
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'custom_sqlite',
@@ -437,6 +450,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_with_connection_params
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()
@@ -474,6 +488,7 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()
@@ -500,6 +515,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_without_connection_par
     ]
     extract_process = flexmock(stdout=flexmock())
 
+    flexmock(module.borgmatic.config.paths).should_receive('get_working_directory').and_return(None)
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
             'custom_sqlite',
@@ -509,6 +525,7 @@ def test_restore_data_source_dump_runs_non_default_sqlite_without_connection_par
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
+        working_directory=None,
     ).once()
 
     flexmock(module.os).should_receive('remove').once()