Commit ec68f764 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub Committed by Sergei Golubchik

MDEV-9566 prepare mysqltest for mariabackup

- Do not throw output of exec command, if disable_result_log is set
save and dump it if exec fails. Need tha to meaningfully analyze
errors from mariabackup.

- rmdir now removes the entire tree. need that because xtrabackup tests
clean the whole directory.

- all filesystem modifying commands now require the argument to
  be under MYSQLTEST_VARDIR or MYSQL_TMP_DIR.
parent 7bf40959
......@@ -3373,6 +3373,12 @@ void do_exec(struct st_command *command)
#endif
#endif
if (disable_result_log)
{
/* Collect stderr output as well, for the case app. crashes or returns error.*/
dynstr_append(&ds_cmd, " 2>&1");
}
DBUG_PRINT("info", ("Executing '%s' as '%s'",
command->first_argument, ds_cmd.str));
......@@ -3408,16 +3414,7 @@ void do_exec(struct st_command *command)
len--;
}
#endif
if (disable_result_log)
{
if (len)
buf[len-1] = 0;
DBUG_PRINT("exec_result",("%s", buf));
}
else
{
replace_dynstr_append_mem(ds_result, buf, len);
}
replace_dynstr_append_mem(ds_result, buf, len);
}
error= pclose(res_file);
......@@ -3427,7 +3424,7 @@ void do_exec(struct st_command *command)
dynstr_free(&ds_sorted);
}
if (error > 0)
if (error)
{
uint status= WEXITSTATUS(error);
int i;
......@@ -3473,6 +3470,12 @@ void do_exec(struct st_command *command)
}
dynstr_free(&ds_cmd);
if (disable_result_log)
{
/* Disable output in case of successful exit.*/
dynstr_set(&ds_res,"");
}
DBUG_VOID_RETURN;
}
......@@ -3610,6 +3613,37 @@ void do_system(struct st_command *command)
}
/* returns TRUE if path is inside a sandbox */
bool is_sub_path(const char *path, size_t plen, const char *sandbox)
{
size_t len= strlen(sandbox);
if (!sandbox || !len || plen <= len || memcmp(path, sandbox, len - 1)
|| path[len] != '/')
return false;
return true;
}
/* returns TRUE if path cannot be modified */
bool bad_path(const char *path)
{
size_t plen= strlen(path);
const char *vardir= getenv("MYSQLTEST_VARDIR");
if (is_sub_path(path, plen, vardir))
return false;
const char *tmpdir= getenv("MYSQL_TMP_DIR");
if (is_sub_path(path, plen, tmpdir))
return false;
report_or_die("Path '%s' is not a subdirectory of MYSQLTEST_VARDIR '%s'"
"or MYSQL_TMP_DIR '%s'",
path, vardir, tmpdir);
return true;
}
/*
SYNOPSIS
set_wild_chars
......@@ -3668,6 +3702,9 @@ void do_remove_file(struct st_command *command)
rm_args, sizeof(rm_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("removing file: %s", ds_filename.str));
error= my_delete(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0;
handle_command_error(command, error, my_errno);
......@@ -3711,6 +3748,9 @@ void do_remove_files_wildcard(struct st_command *command)
' ');
fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME);
if (bad_path(ds_directory.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("listing directory: %s", dirname));
if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME))))
{
......@@ -3785,6 +3825,9 @@ void do_copy_file(struct st_command *command)
sizeof(copy_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_to_file.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str));
/* MY_HOLD_ORIGINAL_MODES prevents attempts to chown the file */
error= (my_copy(ds_from_file.str, ds_to_file.str,
......@@ -3822,6 +3865,9 @@ void do_move_file(struct st_command *command)
sizeof(move_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_to_file.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("Move %s to %s", ds_from_file.str, ds_to_file.str));
error= (my_rename(ds_from_file.str, ds_to_file.str,
MYF(disable_warnings ? 0 : MY_WME)) != 0);
......@@ -3860,6 +3906,9 @@ void do_chmod_file(struct st_command *command)
sizeof(chmod_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_file.str))
DBUG_VOID_RETURN;
/* Parse what mode to set */
if (ds_mode.length != 4 ||
str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS)
......@@ -3931,6 +3980,9 @@ void do_mkdir(struct st_command *command)
mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_dirname.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str));
error= my_mkdir(ds_dirname.str, 0777, MYF(MY_WME)) != 0;
handle_command_error(command, error, my_errno);
......@@ -3938,6 +3990,47 @@ void do_mkdir(struct st_command *command)
DBUG_VOID_RETURN;
}
/*
Remove directory recursively.
*/
static int rmtree(const char *dir)
{
char path[FN_REFLEN];
char sep[]={ FN_LIBCHAR, 0 };
int err=0;
MY_DIR *dir_info= my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT));
if (!dir_info)
return 1;
for (uint i= 0; i < dir_info->number_of_files; i++)
{
FILEINFO *file= dir_info->dir_entry + i;
/* Skip "." and ".." */
if (!strcmp(file->name, ".") || !strcmp(file->name, ".."))
continue;
strxnmov(path, sizeof(path), dir, sep, file->name, NULL);
if (!MY_S_ISDIR(file->mystat->st_mode))
err= my_delete(path, 0);
else
err= rmtree(path);
if(err)
break;
}
my_dirend(dir_info);
if (!err)
err= rmdir(dir);
return err;
}
/*
SYNOPSIS
do_rmdir
......@@ -3945,12 +4038,11 @@ void do_mkdir(struct st_command *command)
DESCRIPTION
rmdir <dir_name>
Remove the empty directory <dir_name>
Remove the directory tree
*/
void do_rmdir(struct st_command *command)
{
int error;
static DYNAMIC_STRING ds_dirname;
const struct command_arg rmdir_args[] = {
{ "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" }
......@@ -3961,9 +4053,13 @@ void do_rmdir(struct st_command *command)
rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_dirname.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str));
error= rmdir(ds_dirname.str) != 0;
handle_command_error(command, error, errno);
if (rmtree(ds_dirname.str))
handle_command_error(command, 1, errno);
dynstr_free(&ds_dirname);
DBUG_VOID_RETURN;
}
......@@ -4076,6 +4172,9 @@ static void do_list_files_write_file_command(struct st_command *command,
list_files_args,
sizeof(list_files_args)/sizeof(struct command_arg), ' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
init_dynamic_string(&ds_content, "", 1024, 1024);
error= get_list_files(&ds_content, &ds_dirname, &ds_wild);
handle_command_error(command, error, my_errno);
......@@ -4127,7 +4226,8 @@ void read_until_delimiter(DYNAMIC_STRING *ds,
while (1)
{
c= my_getc(cur_file->file);
if (c == '\r')
c= my_getc(cur_file->file);
if (c == '\n')
{
cur_file->lineno++;
......@@ -4178,6 +4278,9 @@ void do_write_file_command(struct st_command *command, my_bool append)
sizeof(write_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
if (!append && access(ds_filename.str, F_OK) == 0)
{
/* The file should not be overwritten */
......
......@@ -43,9 +43,8 @@ if ($write_to_file == 'GENERATE')
if (`SELECT LENGTH(@@secure_file_priv) > 0`)
{
--let $_wvtf_secure_file_priv= `SELECT @@secure_file_priv`
--let $_wvtf_suffix= `SELECT UUID()`
--let $_wvtf_tmp_file= $_wvtf_secure_file_priv/_wvtf_$_wvtf_suffix
--let $_wvtf_tmp_file= $MYSQLTEST_VARDIR/_wvtf_$_wvtf_suffix
--eval SELECT '$write_var' INTO DUMPFILE '$_wvtf_tmp_file'
--copy_file $_wvtf_tmp_file $write_to_file
......
#
# Ensure the plugin isn't loaded.
#
SELECT * FROM mysql.plugin WHERE dl like 'libdaemon%' ORDER BY name;
name dl
#
# Enable the plugin...
#
#
# Simulate loading a plugin libary with multiple entry points.
# This will test the DISABLE to ensure all rows are removed.
#
INSERT INTO mysql.plugin VALUES ('wicky', 'libdaemon_example.so');
INSERT INTO mysql.plugin VALUES ('wacky', 'libdaemon_example.so');
INSERT INTO mysql.plugin VALUES ('wonky', 'libdaemon_example.so');
#
# Ensure the plugin is now loaded.
#
SELECT * FROM mysql.plugin WHERE dl like 'libdaemon%' ORDER BY name;
name dl
daemon_example libdaemon_example.so
wacky libdaemon_example.so
wicky libdaemon_example.so
wonky libdaemon_example.so
#
# Ensure the plugin is loaded.
#
SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name;
name dl
daemon_example libdaemon_example.so
#
# Ensure the plugin is replaced.
#
SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name;
name dl
daemon_example liblibdaemon_example.so
#
# Disable the plugin...
#
#
# Ensure the plugin isn't loaded.
#
SELECT * FROM mysql.plugin WHERE dl like '%libdaemon%' ORDER BY name;
name dl
#
# Attempt to load non-existant plugin
#
ERROR: Cannot read plugin config file NOT_THERE_AT_ALL. File does not exist.
#
# Attempt to use non-existant plugin.ini file
#
ERROR: Cannot read plugin config file daemon_example. File does not exist.
#
# Attempt to omit the plugin
#
ERROR: No plugin specified.
#
# Attempt to omit DISABLE|ENABLE
#
ERROR: missing operation. Please specify either '<plugin> ENABLE' or '<plugin> DISABLE'.
#
# Attempt to use bad paths - datadir
#
ERROR: Cannot access datadir at '/data_not_there/'.
#
# Attempt to use bad paths - basedir
#
ERROR: Cannot access basedir at '/basedir_not_there/'.
#
# Attempt to use bad paths - plugin_dir
#
ERROR: Cannot read plugin config file daemon_example. File does not exist.
#
# Attempt to use bad paths - mysqld
#
ERROR: Cannot access mysqld path '/mysqld_not_there/'.
#
# Attempt to use bad paths - my_print_defaults
#
ERROR: Cannot access my-print-defaults path '/my_print_defaults_not_there/'.
#
# Missing library
#
ERROR: The plugin library is missing or in a different location.
#
# Bad format for config file
#
ERROR: Cannot read plugin config file daemon_example. Bad format in plugin configuration file.
#
# Missing base_dir option
#
ERROR: Missing --basedir option.
#
# Missing data_dir option
#
ERROR: Missing --datadir option.
#
# Missing plugin_dir option
#
ERROR: Missing --plugin_dir option.
#
# Show the help.
#
mysql_plugin Ver V.V.VV Distrib XX.XX.XX
Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
Enable or disable plugins.
Usage: mysql_plugin [options] <plugin> ENABLE|DISABLE
Options:
-?, --help Display this help and exit.
-b, --basedir=name The basedir for the server.
-d, --datadir=name The datadir for the server.
-p, --plugin-dir=name
The plugin dir for the server.
-i, --plugin-ini=name
Read plugin information from configuration file specified
instead of from <plugin-dir>/<plugin_name>.ini.
-n, --no-defaults Do not read values from configuration file.
-P, --print-defaults
Show default values from configuration file.
-m, --mysqld=name Path to mysqld executable. Example: /sbin/temp1/mysql/bin
-f, --my-print-defaults=name
Path to my_print_defaults executable. Example:
/source/temp11/extra
-v, --verbose More verbose output; you can use this multiple times to
get even more verbose output.
-V, --version Output version information and exit.
mysql_plugin Ver V.V.VV Distrib XX.XX.XX
This diff is collapsed.
......@@ -406,7 +406,7 @@ select 3 from t1 ;
--disable_abort_on_error ONCE
garbage;
--disable_abort_on_error ONCE
--remove_file DoesNotExist
--remove_file $MYSQLTEST_VARDIR/DoesNotExist
--disable_result_log
select 2;
......@@ -1940,8 +1940,6 @@ remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.result;
remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.reject;
--error 0,1
remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.log;
--error 0,1
remove_file $MYSQL_TEST_DIR/r/zero_length_file.reject;
--enable_warnings
#
......@@ -2194,7 +2192,7 @@ drop table t1;
--exec echo "remove_file ;" | $MYSQL_TEST 2>&1
--error 1
remove_file non_existing_file;
remove_file $MYSQLTEST_VARDIR/non_existing_file;
--enable_warnings
# ----------------------------------------------------------------------------
......@@ -2205,10 +2203,10 @@ remove_file non_existing_file;
--exec echo "remove_files_wildcard ;" | $MYSQL_TEST 2>&1
--error 1
remove_files_wildcard non_existing_dir;
remove_files_wildcard $MYSQLTEST_VARDIR/non_existing_dir;
--error 1
remove_files_wildcard non_existing_dir non_existing_file;
remove_files_wildcard $MYSQLTEST_VARDIR/non_existing_dir non_existing_file;
# ----------------------------------------------------------------------------
# test for write_file
......@@ -2217,7 +2215,7 @@ remove_files_wildcard non_existing_dir non_existing_file;
--exec echo "write_file ;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "write_file filename ;" | $MYSQL_TEST 2>&1
--exec echo "write_file $MYSQLTEST_VARDIR/filename ;" | $MYSQL_TEST 2>&1
# Comment out this test as it confuses cmd.exe with unmatched "
#--error 1
......@@ -2463,19 +2461,19 @@ remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp;
--exec echo "chmod ;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "chmod 0 from_file;" | $MYSQL_TEST 2>&1
--exec echo "chmod 0 $MYSQLTEST_VARDIR/from_file;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "chmod 08 from_file;" | $MYSQL_TEST 2>&1
--exec echo "chmod 08 $MYSQLTEST_VARDIR/from_file;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "chmod from_file;" | $MYSQL_TEST 2>&1
--exec echo "chmod $MYSQLTEST_VARDIR/from_file;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "chmod ABZD from_file;" | $MYSQL_TEST 2>&1
--exec echo "chmod ABZD $MYSQLTEST_VARDIR/from_file;" | $MYSQL_TEST 2>&1
--error 1
--exec echo "chmod 06789 from_file;" | $MYSQL_TEST 2>&1
--exec echo "chmod 06789 $MYSQLTEST_VARDIR/from_file;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------
......@@ -2876,8 +2874,6 @@ list_files_append_file $MYSQLTEST_VARDIR/tmp/testdir/file2.txt $MYSQLTEST_VARDIR
list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/file2.txt $MYSQLTEST_VARDIR/tmp/testdir file?.txt;
list_files_append_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt $MYSQLTEST_VARDIR/tmp/testdir file*.txt;
diff_files $MYSQLTEST_VARDIR/tmp/testdir/file2.txt $MYSQLTEST_VARDIR/tmp/testdir/file3.txt;
--error 1
rmdir $MYSQLTEST_VARDIR/tmp/testdir;
cat_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt;
......
......@@ -10,4 +10,4 @@ let $SECUREDIR= `select @@secure_file_priv`;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
DROP TABLE t1;
--remove_file $SECUREDIR/t1.dbf
--remove_file $MYSQL_TMP_DIR/t1.dbf
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment