Forráskód Böngészése

Get tests passing again (#1009).

Dan Helfman 3 hónapja
szülő
commit
1e5c256d54

+ 2 - 2
borgmatic/hooks/data_source/mariadb.py

@@ -41,7 +41,7 @@ def parse_extra_options(extra_options):
     split_extra_options = tuple(shlex.split(extra_options)) if extra_options else ()
 
     if not split_extra_options:
-        return (split_extra_options, None)
+        return ((), None)
 
     match = DEFAULTS_EXTRA_FILE_FLAG_PATTERN.match(split_extra_options[0])
 
@@ -434,7 +434,7 @@ def restore_data_source_dump(
     mariadb_restore_command = tuple(
         shlex.quote(part) for part in shlex.split(data_source.get('mariadb_command') or 'mariadb')
     )
-    extra_options, defaults_extra_filename = parse_extra_options(database.get('restore_options'))
+    extra_options, defaults_extra_filename = parse_extra_options(data_source.get('restore_options'))
     restore_command = (
         mariadb_restore_command
         + make_defaults_file_options(username, password, defaults_extra_filename)

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

@@ -305,7 +305,7 @@ def restore_data_source_dump(
         shlex.quote(part) for part in shlex.split(data_source.get('mysql_command') or 'mysql')
     )
     extra_options, defaults_extra_filename = (
-        borgmatic.hooks.data_source.mariadb.parse_extra_options(database.get('restore_options'))
+        borgmatic.hooks.data_source.mariadb.parse_extra_options(data_source.get('restore_options'))
     )
     restore_command = (
         mysql_restore_command

+ 146 - 71
tests/unit/hooks/data_source/test_mariadb.py

@@ -9,11 +9,11 @@ from borgmatic.hooks.data_source import mariadb as module
 def test_make_defaults_file_pipe_without_username_or_password_bails():
     flexmock(module.os).should_receive('pipe').never()
 
-    assert module.make_defaults_file_pipe(username=None, password=None) is None
+    assert module.make_defaults_file_options(username=None, password=None) is ()
 
 
-def test_make_defaults_file_pipe_with_username_and_password_writes_them_to_file_descriptor():
-    read_descriptor = flexmock()
+def test_make_defaults_file_option_with_username_and_password_writes_them_to_file_descriptor():
+    read_descriptor = 99
     write_descriptor = flexmock()
 
     flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor)
@@ -23,11 +23,11 @@ def test_make_defaults_file_pipe_with_username_and_password_writes_them_to_file_
     flexmock(module.os).should_receive('close')
     flexmock(module.os).should_receive('set_inheritable')
 
-    assert module.make_defaults_file_pipe(username='root', password='trustsome1') == read_descriptor
+    assert module.make_defaults_file_options(username='root', password='trustsome1') == ('--defaults-extra-file=/dev/fd/99',)
 
 
 def test_make_defaults_file_pipe_with_username_only_writes_it_to_file_descriptor():
-    read_descriptor = flexmock()
+    read_descriptor = 99
     write_descriptor = flexmock()
 
     flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor)
@@ -37,11 +37,11 @@ def test_make_defaults_file_pipe_with_username_only_writes_it_to_file_descriptor
     flexmock(module.os).should_receive('close')
     flexmock(module.os).should_receive('set_inheritable')
 
-    assert module.make_defaults_file_pipe(username='root', password=None) == read_descriptor
+    assert module.make_defaults_file_options(username='root', password=None) == ('--defaults-extra-file=/dev/fd/99',)
 
 
 def test_make_defaults_file_pipe_with_password_only_writes_it_to_file_descriptor():
-    read_descriptor = flexmock()
+    read_descriptor = 99
     write_descriptor = flexmock()
 
     flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor)
@@ -51,7 +51,21 @@ def test_make_defaults_file_pipe_with_password_only_writes_it_to_file_descriptor
     flexmock(module.os).should_receive('close')
     flexmock(module.os).should_receive('set_inheritable')
 
-    assert module.make_defaults_file_pipe(username=None, password='trustsome1') == read_descriptor
+    assert module.make_defaults_file_options(username=None, password='trustsome1') == ('--defaults-extra-file=/dev/fd/99',)
+
+
+def test_make_defaults_file_option_with_defaults_extra_filename_includes_it_in_file_descriptor():
+    read_descriptor = 99
+    write_descriptor = flexmock()
+
+    flexmock(module.os).should_receive('pipe').and_return(read_descriptor, write_descriptor)
+    flexmock(module.os).should_receive('write').with_args(
+        write_descriptor, b'!include extra.cnf\n[client]\nuser=root\npassword=trustsome1'
+    ).once()
+    flexmock(module.os).should_receive('close')
+    flexmock(module.os).should_receive('set_inheritable')
+
+    assert module.make_defaults_file_options(username='root', password='trustsome1', defaults_extra_filename='extra.cnf') == ('--defaults-extra-file=/dev/fd/99',)
 
 
 def test_database_names_to_dump_passes_through_name():
@@ -80,9 +94,12 @@ def test_database_names_to_dump_queries_mariadb_for_database_names():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args('root', 'trustsome1', None).and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
@@ -256,15 +273,18 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured
 
 
 def test_database_names_to_dump_runs_mariadb_with_list_options():
-    database = {'name': 'all', 'list_options': '--defaults-file=mariadb.cnf'}
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    database = {'name': 'all', 'list_options': '--defaults-extra-file=mariadb.cnf --skip-ssl'}
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--skip-ssl',), 'mariadb.cnf')
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args('root', 'trustsome1', 'mariadb.cnf').and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mariadb',
             '--defaults-extra-file=/dev/fd/99',
-            '--defaults-file=mariadb.cnf',
+            '--skip-ssl',
             '--skip-column-names',
             '--batch',
             '--execute',
@@ -282,18 +302,21 @@ def test_database_names_to_dump_runs_mariadb_with_list_options():
 def test_database_names_to_dump_runs_non_default_mariadb_with_list_options():
     database = {
         'name': 'all',
-        'list_options': '--defaults-file=mariadb.cnf',
+        'list_options': '--defaults-extra-file=mariadb.cnf --skip-ssl',
         'mariadb_command': 'custom_mariadb',
     }
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--skip-ssl',), 'mariadb.cnf')
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args('root', 'trustsome1', 'mariadb.cnf').and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         environment=None,
         full_command=(
             'custom_mariadb',  # Custom MariaDB command
             '--defaults-extra-file=/dev/fd/99',
-            '--defaults-file=mariadb.cnf',
+            '--skip-ssl',
             '--skip-column-names',
             '--batch',
             '--execute',
@@ -314,9 +337,12 @@ def test_execute_dump_command_runs_mariadb_dump():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -356,9 +382,12 @@ def test_execute_dump_command_runs_mariadb_dump_without_add_drop_database():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -397,9 +426,12 @@ def test_execute_dump_command_runs_mariadb_dump_with_hostname_and_port():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -445,9 +477,12 @@ def test_execute_dump_command_runs_mariadb_dump_with_username_and_password():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -487,9 +522,12 @@ def test_execute_dump_command_runs_mariadb_dump_with_options():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--stuff=such',), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -530,9 +568,12 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--stuff=such',), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').with_args(
@@ -573,9 +614,12 @@ def test_execute_dump_command_runs_non_default_mariadb_dump_with_options():
 def test_execute_dump_command_with_duplicate_dump_skips_mariadb_dump():
     flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
     flexmock(module.os.path).should_receive('exists').and_return(True)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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').never()
     flexmock(module).should_receive('execute_command').never()
 
@@ -601,9 +645,12 @@ def test_execute_dump_command_with_dry_run_skips_mariadb_dump():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command').never()
@@ -679,9 +726,12 @@ def test_restore_data_source_dump_runs_mariadb_to_restore():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(None, None).and_return(
-        None
-    )
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--batch'),
@@ -714,12 +764,15 @@ def test_restore_data_source_dump_runs_mariadb_with_options():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(None, None).and_return(
-        None
-    )
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--harder',), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
-        ('mariadb', '--batch', '--harder'),
+        ('mariadb', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
@@ -751,12 +804,15 @@ def test_restore_data_source_dump_runs_non_default_mariadb_with_options():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(None, None).and_return(
-        None
-    )
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return(('--harder',), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
-        ('custom_mariadb', '--batch', '--harder'),
+        ('custom_mariadb', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
@@ -786,9 +842,12 @@ def test_restore_data_source_dump_runs_mariadb_with_hostname_and_port():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(None, None).and_return(
-        None
-    )
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -830,9 +889,12 @@ def test_restore_data_source_dump_runs_mariadb_with_username_and_password():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'root', 'trustsome1'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        '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).should_receive('execute_command_with_processes').with_args(
         ('mariadb', '--defaults-extra-file=/dev/fd/99', '--batch'),
@@ -875,9 +937,14 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'cliusername', 'clipassword'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args('cliusername', 'clipassword', None).and_return(
+        ('--defaults-extra-file=/dev/fd/99',)
+    )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -932,9 +999,14 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(
-        'restoreuser', 'restorepass'
-    ).and_return(99)
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args('restoreuser', 'restorepass', None).and_return(
+        ('--defaults-extra-file=/dev/fd/99',)
+    )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -976,9 +1048,12 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
     flexmock(module.borgmatic.hooks.credential.parse).should_receive(
         'resolve_credential'
     ).replace_with(lambda value, config: value)
-    flexmock(module).should_receive('make_defaults_file_pipe').with_args(None, None).and_return(
-        None
-    )
+    flexmock(module).should_receive(
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').never()
 

+ 105 - 44
tests/unit/hooks/data_source/test_mysql.py

@@ -36,8 +36,11 @@ def test_database_names_to_dump_queries_mysql_for_database_names():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
@@ -208,15 +211,18 @@ def test_dump_data_sources_dumps_all_databases_separately_when_format_configured
 
 
 def test_database_names_to_dump_runs_mysql_with_list_options():
-    database = {'name': 'all', 'list_options': '--defaults-file=my.cnf'}
+    database = {'name': 'all', 'list_options': '--defaults-extra-file=my.cnf --skip-ssl'}
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'parse_extra_options'
+    ).and_return(('--skip-ssl',), 'my.cnf')
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'make_defaults_file_options'
+    ).with_args('root', 'trustsome1', 'my.cnf').and_return(('--defaults-extra-file=/dev/fd/99',))
     flexmock(module).should_receive('execute_command_and_capture_output').with_args(
         (
             'mysql',
             '--defaults-extra-file=/dev/fd/99',
-            '--defaults-file=my.cnf',
+            '--skip-ssl',
             '--skip-column-names',
             '--batch',
             '--execute',
@@ -234,18 +240,21 @@ def test_database_names_to_dump_runs_mysql_with_list_options():
 def test_database_names_to_dump_runs_non_default_mysql_with_list_options():
     database = {
         'name': 'all',
-        'list_options': '--defaults-file=my.cnf',
+        'list_options': '--defaults-extra-file=my.cnf --skip-ssl',
         'mysql_command': 'custom_mysql',
     }
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return(('--skip-ssl',), 'my.cnf')
+    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).should_receive('execute_command_and_capture_output').with_args(
         environment=None,
         full_command=(
             'custom_mysql',  # Custom MySQL command
             '--defaults-extra-file=/dev/fd/99',
-            '--defaults-file=my.cnf',
+            '--skip-ssl',
             '--skip-column-names',
             '--batch',
             '--execute',
@@ -267,8 +276,11 @@ def test_execute_dump_command_runs_mysqldump():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -309,8 +321,11 @@ def test_execute_dump_command_runs_mysqldump_without_add_drop_database():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -350,8 +365,11 @@ def test_execute_dump_command_runs_mysqldump_with_hostname_and_port():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -398,8 +416,11 @@ def test_execute_dump_command_runs_mysqldump_with_username_and_password():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -440,8 +461,11 @@ def test_execute_dump_command_runs_mysqldump_with_options():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return(('--stuff=such',), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -483,8 +507,11 @@ def test_execute_dump_command_runs_non_default_mysqldump():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').with_args(
@@ -524,8 +551,11 @@ def test_execute_dump_command_with_duplicate_dump_skips_mysqldump():
     flexmock(module.dump).should_receive('make_data_source_dump_filename').and_return('dump')
     flexmock(module.os.path).should_receive('exists').and_return(True)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump').never()
     flexmock(module).should_receive('execute_command').never()
 
@@ -552,8 +582,11 @@ def test_execute_dump_command_with_dry_run_skips_mysqldump():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.dump).should_receive('create_named_pipe_for_dump')
 
     flexmock(module).should_receive('execute_command').never()
@@ -630,8 +663,11 @@ def test_restore_data_source_dump_runs_mysql_to_restore():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args(None, None).and_return(None)
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--batch'),
@@ -665,11 +701,14 @@ def test_restore_data_source_dump_runs_mysql_with_options():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args(None, None).and_return(None)
+        'parse_extra_options'
+    ).and_return(('--harder',), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
-        ('mysql', '--batch', '--harder'),
+        ('mysql', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
@@ -700,11 +739,14 @@ def test_restore_data_source_dump_runs_non_default_mysql_with_options():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args(None, None).and_return(None)
+        'parse_extra_options'
+    ).and_return(('--harder',), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
-        ('custom_mysql', '--batch', '--harder'),
+        ('custom_mysql', '--harder', '--batch'),
         processes=[extract_process],
         output_log_level=logging.DEBUG,
         input_file=extract_process.stdout,
@@ -735,8 +777,11 @@ def test_restore_data_source_dump_runs_mysql_with_hostname_and_port():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args(None, None).and_return(None)
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -779,8 +824,11 @@ def test_restore_data_source_dump_runs_mysql_with_username_and_password():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('root', 'trustsome1').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    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.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         ('mysql', '--defaults-extra-file=/dev/fd/99', '--batch'),
@@ -824,8 +872,13 @@ def test_restore_data_source_dump_with_connection_params_uses_connection_params_
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('cliusername', 'clipassword').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args('cliusername', 'clipassword', None).and_return(
+        ('--defaults-extra-file=/dev/fd/99',)
+    )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -881,8 +934,13 @@ def test_restore_data_source_dump_without_connection_params_uses_restore_params_
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args('restoreuser', 'restorepass').and_return(99)
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args('restoreuser', 'restorepass', None).and_return(
+        ('--defaults-extra-file=/dev/fd/99',)
+    )
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').with_args(
         (
@@ -925,8 +983,11 @@ def test_restore_data_source_dump_with_dry_run_skips_restore():
         'resolve_credential'
     ).replace_with(lambda value, config: value)
     flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
-        'make_defaults_file_pipe'
-    ).with_args(None, None).and_return(None)
+        'parse_extra_options'
+    ).and_return((), None)
+    flexmock(module.borgmatic.hooks.data_source.mariadb).should_receive(
+        'make_defaults_file_options'
+    ).with_args(None, None, None).and_return(())
     flexmock(module.os).should_receive('environ').and_return({'USER': 'root'})
     flexmock(module).should_receive('execute_command_with_processes').never()