diff options
21 files changed, 860 insertions, 294 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 9a977e2a521..9281d40bd60 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -67,6 +67,7 @@ #define MAX_COLUMNS 256 #define MAX_EMBEDDED_SERVER_ARGS 64 #define MAX_DELIMITER_LENGTH 16 +#define DEFAULT_MAX_CONN 128 /* Flags controlling send and reap */ #define QUERY_SEND_FLAG 1 @@ -79,8 +80,8 @@ static int setenv(const char *name, const char *value, int overwrite); enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, - OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES, - OPT_RESULT_FORMAT_VERSION + OPT_MAX_CONNECT_RETRIES, OPT_MAX_CONNECTIONS, OPT_MARK_PROGRESS, + OPT_LOG_DIR, OPT_TAIL_LINES, OPT_RESULT_FORMAT_VERSION, }; static int record= 0, opt_sleep= -1; @@ -92,6 +93,7 @@ const char *opt_include= 0, *opt_charsets_dir; static int opt_port= 0; static int opt_max_connect_retries; static int opt_result_format_version; +static int opt_max_connections= DEFAULT_MAX_CONN; static my_bool opt_compress= 0, silent= 0, verbose= 0; static my_bool debug_info_flag= 0, debug_check_flag= 0; static my_bool tty_password= 0; @@ -101,7 +103,7 @@ static my_bool sp_protocol= 0, sp_protocol_enabled= 0; static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; static my_bool parsing_disabled= 0; -static my_bool display_result_vertically= FALSE, +static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; static my_bool disable_warnings= 0; @@ -138,6 +140,7 @@ struct st_block int line; /* Start line of block */ my_bool ok; /* Should block be executed */ enum block_cmd cmd; /* Command owning the block */ + char delim[MAX_DELIMITER_LENGTH]; /* Delimiter before block */ }; static struct st_block block_stack[32]; @@ -233,6 +236,8 @@ struct st_connection char *name; size_t name_len; MYSQL_STMT* stmt; + /* Set after send to disallow other queries before reap */ + my_bool pending; #ifdef EMBEDDED_LIBRARY const char *cur_query; @@ -242,7 +247,8 @@ struct st_connection int query_done; #endif /*EMBEDDED_LIBRARY*/ }; -struct st_connection connections[128]; + +struct st_connection *connections= NULL; struct st_connection* cur_con= NULL, *next_con, *connections_end; /* @@ -276,6 +282,7 @@ enum enum_commands { Q_DISABLE_ABORT_ON_ERROR, Q_ENABLE_ABORT_ON_ERROR, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_SORTED_RESULT, + Q_LOWERCASE, Q_START_TIMER, Q_END_TIMER, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, @@ -288,7 +295,7 @@ enum enum_commands { Q_LIST_FILES, Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE, Q_SEND_SHUTDOWN, Q_SHUTDOWN_SERVER, Q_RESULT_FORMAT_VERSION, - Q_MOVE_FILE, Q_SEND_EVAL, + Q_MOVE_FILE, Q_REMOVE_FILES_WILDCARD, Q_SEND_EVAL, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ Q_COMMENT_WITH_COMMAND, @@ -348,6 +355,7 @@ const char *command_names[]= "query_vertical", "query_horizontal", "sorted_result", + "lowercase_result", "start_timer", "end_timer", "character_set", @@ -384,6 +392,7 @@ const char *command_names[]= "shutdown_server", "result_format", "move_file", + "remove_files_wildcard", "send_eval", 0 @@ -488,6 +497,8 @@ void free_replace(); void do_get_replace_regex(struct st_command *command); void free_replace_regex(); +/* Used by sleep */ +void check_eol_junk_line(const char *eol); void free_all_replace(){ free_replace(); @@ -1034,7 +1045,7 @@ void check_command_args(struct st_command *command, } /* Check for too many arguments passed */ ptr= command->last_argument; - while(ptr <= command->end) + while(ptr <= command->end && *ptr != '#') { if (*ptr && *ptr != ' ') die("Extra argument '%s' passed to '%.*s'", @@ -1092,6 +1103,7 @@ void close_connections() mysql_close(next_con->util_mysql); my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); } + my_free(connections, MYF(MY_WME)); DBUG_VOID_RETURN; } @@ -1118,7 +1130,7 @@ void close_files() if (cur_file->file && cur_file->file != stdin) { DBUG_PRINT("info", ("closing file: %s", cur_file->file_name)); - my_fclose(cur_file->file, MYF(0)); + fclose(cur_file->file); } my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); cur_file->file_name= 0; @@ -1132,7 +1144,8 @@ void free_used_memory() uint i; DBUG_ENTER("free_used_memory"); - close_connections(); + if (connections) + close_connections(); close_files(); my_hash_free(&var_hash); @@ -2493,7 +2506,7 @@ int open_file(const char *name) if (cur_file == file_stack_end) die("Source directives are nesting too deep"); cur_file++; - if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + if (!(cur_file->file = fopen(buff, "rb"))) { cur_file--; die("Could not open '%s' for reading, errno: %d", buff, errno); @@ -2705,6 +2718,10 @@ void do_exec(struct st_command *command) #endif #endif + /* exec command is interpreted externally and will not take newlines */ + while(replace(&ds_cmd, "\n", 1, " ", 1) == 0) + ; + DBUG_PRINT("info", ("Executing '%s' as '%s'", command->first_argument, ds_cmd.str)); @@ -2930,6 +2947,81 @@ void do_remove_file(struct st_command *command) /* SYNOPSIS + do_remove_files_wildcard + command called command + + DESCRIPTION + remove_files_wildcard <directory> [<file_name_pattern>] + Remove the files in <directory> optionally matching <file_name_pattern> +*/ + +void do_remove_files_wildcard(struct st_command *command) +{ + int error= 0; + uint i; + MY_DIR *dir_info; + FILEINFO *file; + char dir_separator[2]; + static DYNAMIC_STRING ds_directory; + static DYNAMIC_STRING ds_wild; + static DYNAMIC_STRING ds_file_to_remove; + char dirname[FN_REFLEN]; + + const struct command_arg rm_args[] = { + { "directory", ARG_STRING, TRUE, &ds_directory, + "Directory containing files to delete" }, + { "filename", ARG_STRING, FALSE, &ds_wild, "File pattern to delete" } + }; + DBUG_ENTER("do_remove_files_wildcard"); + + check_command_args(command, command->first_argument, + rm_args, sizeof(rm_args)/sizeof(struct command_arg), + ' '); + fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME); + + DBUG_PRINT("info", ("listing directory: %s", dirname)); + /* Note that my_dir sorts the list if not given any flags */ + if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT)))) + { + error= 1; + goto end; + } + init_dynamic_string(&ds_file_to_remove, dirname, 1024, 1024); + dir_separator[0]= FN_LIBCHAR; + dir_separator[1]= 0; + dynstr_append(&ds_file_to_remove, dir_separator); + for (i= 0; i < (uint) dir_info->number_off_files; i++) + { + file= dir_info->dir_entry + i; + /* Remove only regular files, i.e. no directories etc. */ + /* if (!MY_S_ISREG(file->mystat->st_mode)) */ + /* MY_S_ISREG does not work here on Windows, just skip directories */ + if (MY_S_ISDIR(file->mystat->st_mode)) + continue; + if (ds_wild.length && + wild_compare(file->name, ds_wild.str, 0)) + continue; + ds_file_to_remove.length= ds_directory.length + 1; + ds_file_to_remove.str[ds_directory.length + 1]= 0; + dynstr_append(&ds_file_to_remove, file->name); + DBUG_PRINT("info", ("removing file: %s", ds_file_to_remove.str)); + error= my_delete(ds_file_to_remove.str, MYF(0)) != 0; + if (error) + break; + } + my_dirend(dir_info); + +end: + handle_command_error(command, error); + dynstr_free(&ds_directory); + dynstr_free(&ds_wild); + dynstr_free(&ds_file_to_remove); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS do_copy_file command command handle @@ -3688,49 +3780,58 @@ void do_perl(struct st_command *command) sizeof(perl_args)/sizeof(struct command_arg), ' '); - /* If no delimiter was provided, use EOF */ - if (ds_delimiter.length == 0) - dynstr_set(&ds_delimiter, "EOF"); + ds_script= command->content; + /* If it hasn't been done already by a loop iteration, fill it in */ + if (! ds_script.str) + { + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); - init_dynamic_string(&ds_script, "", 1024, 1024); - read_until_delimiter(&ds_script, &ds_delimiter); + init_dynamic_string(&ds_script, "", 1024, 1024); + read_until_delimiter(&ds_script, &ds_delimiter); + command->content= ds_script; + } - DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); + /* This function could be called even if "false", so check before doing */ + if (cur_block->ok) + { + DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); - /* Create temporary file name */ - if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), - "tmp", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) - die("Failed to create temporary file for perl command"); - my_close(fd, MYF(0)); + /* Create temporary file name */ + if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), + "tmp", O_CREAT | O_SHARE | O_RDWR, + MYF(MY_WME))) < 0) + die("Failed to create temporary file for perl command"); + my_close(fd, MYF(0)); - str_to_file(temp_file_path, ds_script.str, ds_script.length); + str_to_file(temp_file_path, ds_script.str, ds_script.length); - /* Format the "perl <filename>" command */ - my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); + /* Format the "perl <filename>" command */ + my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path); - if (!(res_file= popen(buf, "r")) && command->abort_on_error) - die("popen(\"%s\", \"r\") failed", buf); + if (!(res_file= popen(buf, "r")) && command->abort_on_error) + die("popen(\"%s\", \"r\") failed", buf); - while (fgets(buf, sizeof(buf), res_file)) - { - if (disable_result_log) - { - buf[strlen(buf)-1]=0; - DBUG_PRINT("exec_result",("%s", buf)); - } - else + while (fgets(buf, sizeof(buf), res_file)) { - replace_dynstr_append(&ds_res, buf); + if (disable_result_log) + { + buf[strlen(buf)-1]=0; + DBUG_PRINT("exec_result",("%s", buf)); + } + else + { + replace_dynstr_append(&ds_res, buf); + } } - } - error= pclose(res_file); + error= pclose(res_file); - /* Remove the temporary file */ - my_delete(temp_file_path, MYF(0)); + /* Remove the temporary file */ + my_delete(temp_file_path, MYF(0)); - handle_command_error(command, WEXITSTATUS(error)); - dynstr_free(&ds_script); + handle_command_error(command, WEXITSTATUS(error)); + } dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -4138,10 +4239,19 @@ void do_let(struct st_command *command) int do_sleep(struct st_command *command, my_bool real_sleep) { int error= 0; - char *p= command->first_argument; - char *sleep_start, *sleep_end= command->end; + char *sleep_start, *sleep_end; double sleep_val; + char *p; + static DYNAMIC_STRING ds_sleep; + const struct command_arg sleep_args[] = { + { "sleep_delay", ARG_STRING, TRUE, &ds_sleep, "Number of seconds to sleep." } + }; + check_command_args(command, command->first_argument, sleep_args, + sizeof(sleep_args)/sizeof(struct command_arg), + ' '); + p= ds_sleep.str; + sleep_end= ds_sleep.str + ds_sleep.length; while (my_isspace(charset_info, *p)) p++; if (!*p) @@ -4150,11 +4260,13 @@ int do_sleep(struct st_command *command, my_bool real_sleep) /* Check that arg starts with a digit, not handled by my_strtod */ if (!my_isdigit(charset_info, *sleep_start)) die("Invalid argument to %.*s \"%s\"", command->first_word_len, - command->query,command->first_argument); + command->query, sleep_start); sleep_val= my_strtod(sleep_start, &sleep_end, &error); + check_eol_junk_line(sleep_end); if (error) die("Invalid argument to %.*s \"%s\"", command->first_word_len, command->query, command->first_argument); + dynstr_free(&ds_sleep); /* Fixed sleep time selected by --sleep option */ if (opt_sleep >= 0 && !real_sleep) @@ -4163,7 +4275,6 @@ int do_sleep(struct st_command *command, my_bool real_sleep) DBUG_PRINT("info", ("sleep_val: %f", sleep_val)); if (sleep_val) my_sleep((ulong) (sleep_val * 1000000L)); - command->last_argument= sleep_end; return 0; } @@ -4701,7 +4812,8 @@ void do_close_connection(struct st_command *command) if (con->util_mysql) mysql_close(con->util_mysql); con->util_mysql= 0; - + con->pending= FALSE; + my_free(con->name, MYF(0)); /* @@ -5035,7 +5147,7 @@ void do_connect(struct st_command *command) { if (!(con_slot= find_connection_by_name("-closed_connection-"))) die("Connection limit exhausted, you can have max %d connections", - (int) (sizeof(connections)/sizeof(struct st_connection))); + opt_max_connections); } #ifdef EMBEDDED_LIBRARY @@ -5154,6 +5266,12 @@ int do_done(struct st_command *command) } else { + if (*cur_block->delim) + { + /* Restore "old" delimiter after false if block */ + strcpy (delimiter, cur_block->delim); + delimiter_length= strlen(delimiter); + } /* Pop block from stack, goto next line */ cur_block--; parser.current_line++; @@ -5212,6 +5330,7 @@ void do_block(enum block_cmd cmd, struct st_command* command) cur_block++; cur_block->cmd= cmd; cur_block->ok= FALSE; + cur_block->delim[0]= '\0'; DBUG_VOID_RETURN; } @@ -5248,6 +5367,15 @@ void do_block(enum block_cmd cmd, struct st_command* command) if (not_expr) cur_block->ok = !cur_block->ok; + if (cur_block->ok) + { + cur_block->delim[0]= '\0'; + } else + { + /* Remember "old" delimiter if entering a false if block */ + strcpy (cur_block->delim, delimiter); + } + DBUG_PRINT("info", ("OK: %d", cur_block->ok)); var_free(&v); @@ -5350,7 +5478,7 @@ int read_line(char *buf, int size) found_eof: if (cur_file->file != stdin) { - my_fclose(cur_file->file, MYF(0)); + fclose(cur_file->file); cur_file->file= 0; } my_free((uchar*) cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); @@ -5790,6 +5918,10 @@ static struct my_option my_long_options[] = "Max number of connection attempts when connecting to server", (uchar**) &opt_max_connect_retries, (uchar**) &opt_max_connect_retries, 0, GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0}, + {"max-connections", OPT_MAX_CONNECTIONS, + "Max number of open connections to server", + (uchar**) &opt_max_connections, (uchar**) &opt_max_connections, 0, + GET_INT, REQUIRED_ARG, 128, 8, 5120, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection or 0 for default to, in " @@ -5960,7 +6092,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0); if (!(cur_file->file= - my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + fopen(buff, "rb"))) die("Could not open '%s' for reading, errno: %d", buff, errno); cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); cur_file->lineno= 1; @@ -6579,8 +6711,11 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, wait_query_thread_end(cn); #endif /*EMBEDDED_LIBRARY*/ if (!(flags & QUERY_REAP_FLAG)) + { + cn->pending= TRUE; DBUG_VOID_RETURN; - + } + do { /* @@ -6664,6 +6799,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, end: + cn->pending= FALSE; /* We save the return code (mysql_errno(mysql)) from the last call sent to the server into the mysqltest builtin variable $mysql_errno. This @@ -7140,6 +7276,9 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) init_dynamic_string(&ds_warnings, NULL, 0, 256); + if (cn->pending && (flags & QUERY_SEND_FLAG)) + die ("Cannot run query on connection between send and reap"); + /* Evaluate query if this is an eval command */ @@ -7662,12 +7801,6 @@ int main(int argc, char **argv) /* Init expected errors */ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); - /* Init connections */ - memset(connections, 0, sizeof(connections)); - connections_end= connections + - (sizeof(connections)/sizeof(struct st_connection)) - 1; - next_con= connections + 1; - #ifdef EMBEDDED_LIBRARY /* set appropriate stack for the 'query' threads */ (void) pthread_attr_init(&cn_thd_attrib); @@ -7694,7 +7827,14 @@ int main(int argc, char **argv) 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); - var_set_string("$MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); + var_set_string("MYSQL_SERVER_VERSION", MYSQL_SERVER_VERSION); + var_set_string("MYSQL_SYSTEM_TYPE", SYSTEM_TYPE); + var_set_string("MYSQL_MACHINE_TYPE", MACHINE_TYPE); + if (sizeof(void *) == 8) { + var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "64"); + } else { + var_set_string("MYSQL_SYSTEM_ARCHITECTURE", "32"); + } memset(&master_pos, 0, sizeof(master_pos)); @@ -7722,6 +7862,13 @@ int main(int argc, char **argv) verbose_msg("Tracing progress in '%s'.", progress_file.file_name()); } + /* Init connections, allocate 1 extra as buffer + 1 for default */ + connections= (struct st_connection*) + my_malloc((opt_max_connections+2) * sizeof(struct st_connection), + MYF(MY_WME | MY_ZEROFILL)); + connections_end= connections + opt_max_connections +1; + next_con= connections + 1; + var_set_int("$PS_PROTOCOL", ps_protocol); var_set_int("$SP_PROTOCOL", sp_protocol); var_set_int("$VIEW_PROTOCOL", view_protocol); @@ -7825,7 +7972,8 @@ int main(int argc, char **argv) command->type= Q_COMMENT; } - my_bool ok_to_do= cur_block->ok; + /* delimiter needs to be executed so we can continue to parse */ + my_bool ok_to_do= cur_block->ok || command->type == Q_DELIMITER; /* Some commands need to be "done" the first time if they may get re-iterated over in a true context. This can only happen if there's @@ -7883,6 +8031,7 @@ int main(int argc, char **argv) case Q_ECHO: do_echo(command); command_executed++; break; case Q_SYSTEM: do_system(command); break; case Q_REMOVE_FILE: do_remove_file(command); break; + case Q_REMOVE_FILES_WILDCARD: do_remove_files_wildcard(command); break; case Q_MKDIR: do_mkdir(command); break; case Q_RMDIR: do_rmdir(command); break; case Q_LIST_FILES: do_list_files(command); break; @@ -7920,6 +8069,13 @@ int main(int argc, char **argv) */ display_result_sorted= TRUE; break; + case Q_LOWERCASE: + /* + Turn on lowercasing of result, will be reset after next + command + */ + display_result_lower= TRUE; + break; case Q_LET: do_let(command); break; case Q_EVAL_RESULT: die("'eval_result' command is deprecated"); @@ -8164,8 +8320,9 @@ int main(int argc, char **argv) */ free_all_replace(); - /* Also reset "sorted_result" */ + /* Also reset "sorted_result" and "lowercase"*/ display_result_sorted= FALSE; + display_result_lower= FALSE; } last_command_executed= command_executed; @@ -9505,7 +9662,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) if (pa->length+length >= pa->max_length) { if (!(new_pos= (uchar*) my_realloc((uchar*) pa->str, - (uint) (pa->max_length+PS_MALLOC), + (uint) (pa->length+length+PS_MALLOC), MYF(MY_WME)))) DBUG_RETURN(1); if (new_pos != pa->str) @@ -9516,7 +9673,7 @@ int insert_pointer_name(reg1 POINTER_ARRAY *pa,char * name) char*); pa->str=new_pos; } - pa->max_length+=PS_MALLOC; + pa->max_length= pa->length+length+PS_MALLOC; } if (pa->typelib.count >= pa->max_count-1) { @@ -9569,6 +9726,18 @@ void replace_dynstr_append_mem(DYNAMIC_STRING *ds, fix_win_paths(val, len); #endif + if (display_result_lower) + { + /* Convert to lower case, and do this first */ + char lower[512]; + char *c= lower; + for (const char *v= val; *v; v++) + *c++= my_tolower(charset_info, *v); + *c= '\0'; + /* Copy from this buffer instead */ + val= lower; + } + if (glob_replace_regex) { /* Regex replace */ diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc index 4b2e64e3bb5..2de514f27bb 100644 --- a/mysql-test/include/handler.inc +++ b/mysql-test/include/handler.inc @@ -774,6 +774,7 @@ connection default; handler t1 read a next; handler t1 close; connection con1; +--reap # Since last in this connection was a send drop table t1; disconnect con1; --source include/wait_until_disconnected.inc diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql index e62dba8ae82..9378329353b 100644 --- a/mysql-test/include/mtr_warnings.sql +++ b/mysql-test/include/mtr_warnings.sql @@ -194,6 +194,27 @@ INSERT INTO global_suppressions VALUES ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"), ("Slave I/O: Get master TIME_ZONE failed with error:.*"), + /* Messages from valgrind */ + ("==[0-9]*== Memcheck,"), + ("==[0-9]*== Copyright"), + ("==[0-9]*== Using"), + ("==[0-9]*== For more details"), + /* This comes with innodb plugin tests */ + ("==[0-9]*== Warning: set address range perms: large range"), + + /* valgrind warnings: invalid file descriptor -1 in syscall + write()/read(). Bug #50414 */ + ("==[0-9]*== Warning: invalid file descriptor -1 in syscall write()"), + ("==[0-9]*== Warning: invalid file descriptor -1 in syscall read()"), + + /* + Transient network failures that cause warnings on reconnect. + BUG#47743 and BUG#47983. + */ + ("Slave I/O: Get master SERVER_ID failed with error:.*"), + ("Slave I/O: Get master clock failed with error:.*"), + ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"), + ("Slave I/O: Get master TIME_ZONE failed with error:.*"), /* BUG#42147 - Concurrent DML and LOCK TABLE ... READ for InnoDB table cause warnings in errlog diff --git a/mysql-test/lib/My/SafeProcess.pm b/mysql-test/lib/My/SafeProcess.pm index 0fac25b814b..b8f05778b6e 100644 --- a/mysql-test/lib/My/SafeProcess.pm +++ b/mysql-test/lib/My/SafeProcess.pm @@ -81,7 +81,6 @@ sub is_child { } -# Find the safe process binary or script my @safe_process_cmd; my $safe_kill; my $bindir; @@ -96,21 +95,26 @@ else $bindir = "."; } -if (IS_WIN32PERL or IS_CYGWIN){ - # Use my_safe_process.exe - my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], - "my_safe_process"); - push(@safe_process_cmd, $exe); - # Use my_safe_kill.exe - $safe_kill= my_find_bin($bindir, "lib/My/SafeProcess", "my_safe_kill"); -} -else -{ - # Use my_safe_process - my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], - "my_safe_process"); - push(@safe_process_cmd, $exe); +# Find the safe process binary or script +sub find_bin { + if (IS_WIN32PERL or IS_CYGWIN) + { + # Use my_safe_process.exe + my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], + "my_safe_process"); + push(@safe_process_cmd, $exe); + + # Use my_safe_kill.exe + $safe_kill= my_find_bin($bindir, "lib/My/SafeProcess", "my_safe_kill"); + } + else + { + # Use my_safe_process + my $exe= my_find_bin($bindir, ["lib/My/SafeProcess", "My/SafeProcess"], + "my_safe_process"); + push(@safe_process_cmd, $exe); + } } @@ -196,63 +200,6 @@ sub run { } # -# Start a process that returns after "duration" seconds -# or when it's parent process does not exist anymore -# -sub timer { - my $class= shift; - my $duration= shift or croak "duration required"; - my $parent_pid= $$; - - my $pid= My::SafeProcess::Base::_safe_fork(); - if ($pid){ - # Parent - my $proc= bless - ({ - SAFE_PID => $pid, - SAFE_NAME => "timer", - PARENT => $$, - }, $class); - - # Put the new process in list of running - $running{$pid}= $proc; - return $proc; - } - - # Child, install signal handlers and sleep for "duration" - $SIG{INT}= 'IGNORE'; - - $SIG{TERM}= sub { - #print STDERR "timer $$: woken up, exiting!\n"; - exit(0); - }; - - $0= "safe_timer($duration)"; - - if (IS_WIN32PERL){ - # Just a thread in same process - sleep($duration); - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); - } - - my $count_down= $duration; - while($count_down--){ - - # Check that parent is still alive - if (kill(0, $parent_pid) == 0){ - #print STDERR "timer $$: parent gone, exiting!\n"; - exit(0); - } - - sleep(1); - } - print STDERR "timer $$: expired after $duration seconds\n"; - exit(0); -} - - -# # Shutdown process nicely, and wait for shutdown_timeout seconds # If processes hasn't shutdown, kill them hard and wait for return # @@ -350,12 +297,12 @@ sub start_kill { $ret= system($safe_kill, $winpid) >> 8; if ($ret == 3){ - print "Couldn't open the winpid: $winpid ", + print "Couldn't open the winpid: $winpid ". "for pid: $pid, try one more time\n"; sleep(1); $winpid= _winpid($pid); $ret= system($safe_kill, $winpid) >> 8; - print "Couldn't open the winpid: $winpid ", + print "Couldn't open the winpid: $winpid ". "for pid: $pid, continue and see what happens...\n"; } } @@ -550,6 +497,40 @@ sub wait_any { # +# Wait for any process to exit, or a timeout +# +# Returns a reference to the SafeProcess that +# exited or a pseudo-process with $proc->{timeout} == 1 +# + +sub wait_any_timeout { + my $class= shift; + my $timeout= shift; + my $proc; + my $millis=10; + + do { + ::mtr_milli_sleep($millis); + # Slowly increse interval up to max. 1 second + $millis++ if $millis < 1000; + # Return a "fake" process for timeout + if (::has_expired($timeout)) { + $proc= bless + ({ + SAFE_PID => 0, + SAFE_NAME => "timer", + timeout => 1, + }, $class); + } else { + $proc= check_any(); + } + } while (! $proc); + + return $proc; +} + + +# # Wait for all processes to exit # sub wait_all { @@ -606,7 +587,7 @@ sub self2str { sub _verbose { return unless $_verbose; - print STDERR " ## ", @_, "\n"; + print STDERR " ## ". @_. "\n"; } diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc index 7b47fcbe2dd..8fffede0b62 100755 --- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc @@ -187,14 +187,20 @@ int main(int argc, const char** argv ) die("No real args -> nothing to do"); /* Copy the remaining args to child_arg */ for (int j= i+1; j < argc; j++) { - if (strchr (argv[j], ' ')) { - /* Protect with "" if this arg contains a space */ - to+= _snprintf(to, child_args + sizeof(child_args) - to, - "\"%s\" ", argv[j]); - } else { - to+= _snprintf(to, child_args + sizeof(child_args) - to, - "%s ", argv[j]); - } + arg= argv[j]; + if (strchr (arg, ' ') && + arg[0] != '\"' && + arg[strlen(arg)] != '\"') + { + /* Quote arg that contains spaces and are not quoted already */ + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "\"%s\" ", arg); + } + else + { + to+= _snprintf(to, child_args + sizeof(child_args) - to, + "%s ", arg); + } } break; } else { diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 8d02914c1e3..7b7dd70a696 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -40,7 +40,6 @@ our $default_storage_engine; our $opt_with_ndbcluster_only; our $defaults_file; our $defaults_extra_file; -our $reorder= 1; our $quick_collect; sub collect_option { @@ -99,7 +98,8 @@ sub init_pattern { # ############################################################################## -sub collect_test_cases ($$) { +sub collect_test_cases ($$$) { + my $opt_reorder= shift; # True if we're reordering tests my $suites= shift; # Semicolon separated list of test suites my $opt_cases= shift; my $cases= []; # Array of hash(one hash for each testcase) @@ -118,10 +118,16 @@ sub collect_test_cases ($$) { !(IS_WINDOWS && $::opt_embedded_server) && $lib_innodb_plugin); - foreach my $suite (split(",", $suites)) + # If not reordering, we also shouldn't group by suites, unless + # no test cases were named. + # This also effects some logic in the loop following this. + if ($opt_reorder or !@$opt_cases) { - push(@$cases, collect_one_suite($suite, $opt_cases)); - last if $some_test_found; + foreach my $suite (split(",", $suites)) + { + push(@$cases, collect_one_suite($suite, $opt_cases)); + last if $some_test_found; + } } if ( @$opt_cases ) @@ -135,6 +141,7 @@ sub collect_test_cases ($$) { my ($sname, $tname, $extension)= split_testname($test_name_spec); foreach my $test ( @$cases ) { + last unless $opt_reorder; # test->{name} is always in suite.name format if ( $test->{name} =~ /.*\.$tname/ ) { @@ -144,12 +151,13 @@ sub collect_test_cases ($$) { } if ( not $found ) { + $sname= "main" if !$opt_reorder and !$sname; mtr_error("Could not find '$tname' in '$suites' suite(s)") unless $sname; - # If suite was part of name, find it there - my ($this_case) = collect_one_suite($sname, [ $tname ]); - if ($this_case) + # If suite was part of name, find it there, may come with combinations + my @this_case = collect_one_suite($sname, [ $tname ]); + if (@this_case) { - push (@$cases, $this_case); + push (@$cases, @this_case); } else { @@ -159,7 +167,7 @@ sub collect_test_cases ($$) { } } - if ( $reorder && !$quick_collect) + if ( $opt_reorder && !$quick_collect) { # Reorder the test cases in an order that will make them faster to run my %sort_criteria; diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl index f6615301dd7..5820a4007b8 100644 --- a/mysql-test/lib/mtr_gprof.pl +++ b/mysql-test/lib/mtr_gprof.pl @@ -20,43 +20,20 @@ use strict; -# These are not to be prefixed with "mtr_" +sub gprof_collect ($@) { + my ($exe_mysqld, @gprof_dirs)= @_; -sub gprof_prepare (); -sub gprof_collect (); + print ("Collecting gprof reports.....\n"); -############################################################################## -# -# -# -############################################################################## - -sub gprof_prepare () { - - rmtree($::opt_gprof_dir); - mkdir($::opt_gprof_dir); -} - -# FIXME what about master1 and slave1?! -sub gprof_collect () { - - if ( -f "$::master->[0]->{'path_myddir'}/gmon.out" ) - { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_master_mysqld, - "$::master->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_master, "", "", ""); - print "Master execution profile has been saved in $::opt_gprof_master\n"; - } - if ( -f "$::slave->[0]->{'path_myddir'}/gmon.out" ) + foreach my $datadir (@gprof_dirs) { - # FIXME check result code?! - mtr_run("gprof", - [$::exe_slave_mysqld, - "$::slave->[0]->{'path_myddir'}/gmon.out"], - $::opt_gprof_slave, "", "", ""); - print "Slave execution profile has been saved in $::opt_gprof_slave\n"; + my $gprof_msg= "$datadir/gprof.msg"; + my $gprof_err= "$datadir/gprof.err"; + if ( -f "$datadir/gmon.out" ) + { + system("gprof $exe_mysqld $datadir/gmon.out 2>$gprof_err >$gprof_msg"); + print ("GPROF output in $gprof_msg, errors in $gprof_err\n"); + } } } diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 658eb270535..97eb693b52e 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -30,7 +30,9 @@ sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_exe_maybe_exists(@); - +sub mtr_milli_sleep($); +sub start_timer($); +sub has_expired($); ############################################################################## # @@ -167,11 +169,18 @@ sub mtr_exe_exists (@) { } -sub mtr_milli_sleep { +sub mtr_milli_sleep ($) { die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1; my ($millis)= @_; select(undef, undef, undef, ($millis/1000)); } +# Simple functions to start and check timers (have to be actively polled) +# Timer can be "killed" by setting it to 0 + +sub start_timer ($) { return time + $_[0]; } + +sub has_expired ($) { return $_[0] && time gt $_[0]; } + 1; diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 937e19111fb..1c4b940bbee 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -69,7 +69,7 @@ sub _mtr_report_test_name ($) { $tname.= " '$tinfo->{combination}'" if defined $tinfo->{combination}; - print _name(), _timestamp(); + print _name(). _timestamp(); printf "%-40s ", $tname; my $worker = $tinfo->{worker}; printf "w$worker " if $worker; @@ -222,8 +222,8 @@ sub mtr_report_test ($) { } -sub mtr_report_stats ($;$) { - my ($tests, $dont_error)= @_; +sub mtr_report_stats ($$;$) { + my ($prefix, $tests, $dont_error)= @_; # ---------------------------------------------------------------------- # Find out how we where doing @@ -328,6 +328,9 @@ sub mtr_report_stats ($;$) { } } + # Print summary line prefix + print "$prefix: "; + # Print a list of testcases that failed if ( $tot_failed != 0 ) { @@ -387,13 +390,13 @@ sub mtr_report_stats ($;$) { ############################################################################## sub mtr_print_line () { - print '-' x 60, "\n"; + print '-' x 60 . "\n"; } sub mtr_print_thick_line { my $char= shift || '='; - print $char x 78, "\n"; + print $char x 78 . "\n"; } @@ -451,7 +454,7 @@ sub _timestamp { # Always print message to screen sub mtr_print (@) { - print _name(), join(" ", @_), "\n"; + print _name(). join(" ", @_). "\n"; } @@ -459,22 +462,22 @@ sub mtr_print (@) { sub mtr_report (@) { if (defined $verbose) { - print _name(), join(" ", @_), "\n"; + print _name(). join(" ", @_). "\n"; } } # Print warning to screen sub mtr_warning (@) { - print STDERR _name(), _timestamp(), - "mysql-test-run: WARNING: ", join(" ", @_), "\n"; + print STDERR _name(). _timestamp(). + "mysql-test-run: WARNING: ". join(" ", @_). "\n"; } # Print error to screen and then exit sub mtr_error (@) { - print STDERR _name(), _timestamp(), - "mysql-test-run: *** ERROR: ", join(" ", @_), "\n"; + print STDERR _name(). _timestamp(). + "mysql-test-run: *** ERROR: ". join(" ", @_). "\n"; if (IS_WINDOWS) { POSIX::_exit(1); @@ -489,8 +492,8 @@ sub mtr_error (@) { sub mtr_debug (@) { if ( $verbose > 2 ) { - print STDERR _name(), - _timestamp(), "####: ", join(" ", @_), "\n"; + print STDERR _name(). + _timestamp(). "####: ". join(" ", @_). "\n"; } } @@ -498,8 +501,8 @@ sub mtr_debug (@) { sub mtr_verbose (@) { if ( $verbose ) { - print STDERR _name(), _timestamp(), - "> ",join(" ", @_),"\n"; + print STDERR _name(). _timestamp(). + "> ".join(" ", @_)."\n"; } } @@ -509,8 +512,8 @@ sub mtr_verbose_restart (@) { my $proc= $server->{proc}; if ( $verbose_restart ) { - print STDERR _name(),_timestamp(), - "> Restart $proc - ",join(" ", @args),"\n"; + print STDERR _name()._timestamp(). + "> Restart $proc - ".join(" ", @args)."\n"; } } diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl index cd5c7b0dbb7..702bc178ae5 100644 --- a/mysql-test/lib/mtr_stress.pl +++ b/mysql-test/lib/mtr_stress.pl @@ -150,7 +150,7 @@ sub run_stress_test () mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--cleanup"); mtr_add_arg($args, "--log-error-details"); - mtr_add_arg($args, "--abort-on-error"); + mtr_add_arg($args, "--abort-on-error=1"); if ( $::opt_stress_init_file ) { diff --git a/mysql-test/lib/v1/mtr_stress.pl b/mysql-test/lib/v1/mtr_stress.pl index 93b06b32c5f..40800c9729b 100644 --- a/mysql-test/lib/v1/mtr_stress.pl +++ b/mysql-test/lib/v1/mtr_stress.pl @@ -150,7 +150,7 @@ sub run_stress_test () mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--cleanup"); mtr_add_arg($args, "--log-error-details"); - mtr_add_arg($args, "--abort-on-error"); + mtr_add_arg($args, "--abort-on-error=1"); if ( $::opt_stress_init_file ) { diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl index b1e746dd80e..3ea815cb45a 100755 --- a/mysql-test/lib/v1/mysql-test-run.pl +++ b/mysql-test/lib/v1/mysql-test-run.pl @@ -905,6 +905,11 @@ sub command_line_setup () { mtr_report("Using default engine '$used_default_engine'") if defined $used_default_engine; + if ($glob_win32 and defined $opt_mem) { + mtr_report("--mem not supported on Windows, ignored"); + $opt_mem= undef; + } + # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 09703086e66..2fbbdf0b819 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -102,6 +102,7 @@ use IO::Select; require "lib/mtr_process.pl"; require "lib/mtr_io.pl"; require "lib/mtr_gcov.pl"; +require "lib/mtr_gprof.pl"; require "lib/mtr_misc.pl"; $SIG{INT}= sub { mtr_error("Got ^C signal"); }; @@ -187,6 +188,9 @@ our $opt_gcov_exe= "gcov"; our $opt_gcov_err= "mysql-test-gcov.msg"; our $opt_gcov_msg= "mysql-test-gcov.err"; +our $opt_gprof; +our %gprof_dirs; + our $glob_debugger= 0; our $opt_gdb; our $opt_client_gdb; @@ -205,7 +209,9 @@ our $opt_experimental; our $experimental_test_cases; my $baseport; +# $opt_build_thread may later be set from $opt_port_base my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto"; +my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto"; my $build_thread= 0; my $opt_record; @@ -215,6 +221,7 @@ my $opt_skip_core; our $opt_check_testcases= 1; my $opt_mark_progress; +my $opt_max_connections; my $opt_sleep; @@ -234,6 +241,7 @@ my $opt_wait_all; my $opt_repeat= 1; my $opt_retry= 3; my $opt_retry_failure= env_or_val(MTR_RETRY_FAILURE => 2); +my $opt_reorder= 1; my $opt_strace_client; @@ -246,6 +254,7 @@ my @default_valgrind_args= ("--show-reachable=yes"); my @valgrind_args; my $opt_valgrind_path; my $opt_callgrind; +my %mysqld_logs; my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions. our $opt_warnings= 1; @@ -285,6 +294,9 @@ sub main { command_line_setup(); + # --help will not reach here, so now it's safe to assume we have binaries + My::SafeProcess::find_bin(); + if ( $opt_gcov ) { gcov_prepare($basedir); } @@ -314,7 +326,7 @@ sub main { } mtr_report("Collecting tests..."); - my $tests= collect_test_cases($opt_suites, \@opt_cases); + my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases); if ( $opt_report_features ) { # Put "report features" as the first test to run @@ -431,7 +443,7 @@ sub main { $opt_gcov_msg, $opt_gcov_err); } - mtr_report_stats($completed); + mtr_report_stats("Completed", $completed); exit(0); } @@ -455,7 +467,7 @@ sub run_test_server ($$$) { my $result; my $exe_mysqld= find_mysqld($basedir) || ""; # Used as hint to CoreDump - my $suite_timeout_proc= My::SafeProcess->timer(suite_timeout()); + my $suite_timeout= start_timer(suite_timeout()); my $s= IO::Select->new(); $s->add($server); @@ -476,7 +488,6 @@ sub run_test_server ($$$) { mtr_verbose("Child closed socket"); $s->remove($sock); if (--$childs == 0){ - $suite_timeout_proc->kill(); return $completed; } next; @@ -545,15 +556,13 @@ sub run_test_server ($$$) { if ( !$opt_force ) { # Test has failed, force is off - $suite_timeout_proc->kill(); push(@$completed, $result); return $completed; } elsif ($opt_max_test_fail > 0 and $num_failed_test >= $opt_max_test_fail) { - $suite_timeout_proc->kill(); push(@$completed, $result); - mtr_report_stats($completed, 1); + mtr_report_stats("Too many failed", $completed, 1); mtr_report("Too many tests($num_failed_test) failed!", "Terminating..."); return undef; @@ -640,9 +649,9 @@ sub run_test_server ($$$) { next; } - # Prefer same configuration - if (defined $result and - $result->{template_path} eq $t->{template_path}) + # Prefer same configuration, or just use next if --noreorder + if (!$opt_reorder or (defined $result and + $result->{template_path} eq $t->{template_path})) { #mtr_report("Test uses same config => good match"); # Test uses same config => good match @@ -683,9 +692,9 @@ sub run_test_server ($$$) { # ---------------------------------------------------- # Check if test suite timer expired # ---------------------------------------------------- - if ( ! $suite_timeout_proc->wait_one(0) ) + if ( has_expired($suite_timeout) ) { - mtr_report_stats($completed, 1); + mtr_report_stats("Timeout", $completed, 1); mtr_report("Test suite timeout! Terminating..."); return undef; } @@ -761,6 +770,12 @@ sub run_worker ($) { elsif ($line eq 'BYE'){ mtr_report("Server said BYE"); stop_all_servers($opt_shutdown_timeout); + if ($opt_valgrind_mysqld) { + valgrind_exit_reports(); + } + if ( $opt_gprof ) { + gprof_collect (find_mysqld($basedir), keys %gprof_dirs); + } exit(0); } else { @@ -841,9 +856,11 @@ sub command_line_setup { 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, 'experimental=s' => \$opt_experimental, + 'skip-im' => \&ignore_option, # Specify ports 'build-thread|mtr-build-thread=i' => \$opt_build_thread, + 'port-base|mtr-port-base=i' => \$opt_port_base, # Test case authoring 'record' => \$opt_record, @@ -874,6 +891,7 @@ sub command_line_setup { # Coverage, profiling etc 'gcov' => \$opt_gcov, + 'gprof' => \$opt_gprof, 'valgrind|valgrind-all' => \$opt_valgrind, 'valgrind-mysqltest' => \$opt_valgrind_mysqltest, 'valgrind-mysqld' => \$opt_valgrind_mysqld, @@ -904,7 +922,7 @@ sub command_line_setup { 'report-features' => \$opt_report_features, 'comment=s' => \$opt_comment, 'fast' => \$opt_fast, - 'reorder!' => \&collect_option, + 'reorder!' => \$opt_reorder, 'enable-disabled' => \&collect_option, 'verbose+' => \$opt_verbose, 'verbose-restart' => \&report_option, @@ -924,6 +942,7 @@ sub command_line_setup { 'warnings!' => \$opt_warnings, 'timestamp' => \&report_option, 'timediff' => \&report_option, + 'max-connections=i' => \$opt_max_connections, 'help|h' => \$opt_usage, 'list-options' => \$opt_list_options, @@ -948,6 +967,11 @@ sub command_line_setup { # Find the absolute path to the test directory $glob_mysql_test_dir= cwd(); + if ($glob_mysql_test_dir =~ / /) + { + die("Working directory \"$glob_mysql_test_dir\" contains space\n". + "Bailing out, cannot function properly with space in path"); + } if (IS_CYGWIN) { # Use mixed path format i.e c:/path/to/ @@ -1104,6 +1128,21 @@ sub command_line_setup { } } + if (IS_WINDOWS and defined $opt_mem) { + mtr_report("--mem not supported on Windows, ignored"); + $opt_mem= undef; + } + + if ($opt_port_base ne "auto") + { + if (my $rem= $opt_port_base % 10) + { + mtr_warning ("Port base $opt_port_base rounded down to multiple of 10"); + $opt_port_base-= $rem; + } + $opt_build_thread= $opt_port_base / 10 - 1000; + } + # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- @@ -1276,7 +1315,7 @@ sub command_line_setup { # -------------------------------------------------------------------------- # Gcov flag # -------------------------------------------------------------------------- - if ( $opt_gcov and ! $source_dist ) + if ( ($opt_gcov or $opt_gprof) and ! $source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } @@ -1375,8 +1414,7 @@ sub command_line_setup { push(@valgrind_args, @default_valgrind_args) unless @valgrind_args; - # Make valgrind run in quiet mode so it only print errors - push(@valgrind_args, "--quiet" ); + # Don't add --quiet; you will loose the summary reports. mtr_report("Running valgrind with options \"", join(" ", @valgrind_args), "\""); @@ -1481,6 +1519,12 @@ sub collect_mysqld_features { mtr_add_arg($args, "--verbose"); mtr_add_arg($args, "--help"); + # Need --user=root if running as *nix root user + if (!IS_WINDOWS and $> == 0) + { + mtr_add_arg($args, "--user=root"); + } + my $exe_mysqld= find_mysqld($basedir); my $cmd= join(" ", $exe_mysqld, @$args); my $list= `$cmd`; @@ -1824,11 +1868,11 @@ sub environment_setup { { push(@ld_library_paths, "$basedir/libmysql/.libs/", "$basedir/libmysql_r/.libs/", - "$basedir/zlib.libs/"); + "$basedir/zlib/.libs/"); } else { - push(@ld_library_paths, "$basedir/lib"); + push(@ld_library_paths, "$basedir/lib", "$basedir/lib/mysql"); } } @@ -2601,6 +2645,7 @@ sub create_config_file_for_extern { # binlog reads from [client] and [mysqlbinlog] [mysqlbinlog] character-sets-dir= $path_charsetsdir +local-load= $opt_tmpdir # mysql_fix_privilege_tables.sh don't read from [client] [mysql_fix_privilege_tables] @@ -3030,11 +3075,11 @@ sub check_testcase($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3058,9 +3103,6 @@ sub check_testcase($$) if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return 0; } # Wait for next process to exit @@ -3101,10 +3143,9 @@ test case was executed:\n"; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check-testcase' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check-testcase' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3119,8 +3160,6 @@ test case was executed:\n"; # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } @@ -3192,11 +3231,11 @@ sub run_on_all($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3215,17 +3254,15 @@ sub run_on_all($$) if ( keys(%started) == 0){ # All completed - $timeout_proc->kill(); return 0; } # Wait for next process to exit next; } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for '$run' ". - "expired after ". check_timeout(). - " seconds"; + elsif ($proc->{timeout}) { + $tinfo->{comment}.= "Timeout for '$run' expired after " + .check_timeout()." seconds"; } else { # Unknown process returned, most likley a crash, abort everything @@ -3237,8 +3274,6 @@ sub run_on_all($$) # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return 1; } mtr_error("INTERNAL_ERROR: run_on_all"); @@ -3345,9 +3380,11 @@ sub run_testcase ($) { mtr_verbose("Running test:", $tinfo->{name}); - # Allow only alpanumerics pluss _ - + . in combination names + # Allow only alpanumerics pluss _ - + . in combination names, + # or anything beginning with -- (the latter comes from --combination) my $combination= $tinfo->{combination}; - if ($combination && $combination !~ /^\w[-\w\.\+]+$/) + if ($combination && $combination !~ /^\w[-\w\.\+]+$/ + && $combination !~ /^--/) { mtr_error("Combination '$combination' contains illegal characters"); } @@ -3468,7 +3505,7 @@ sub run_testcase ($) { } } - my $test_timeout_proc= My::SafeProcess->timer(testcase_timeout()); + my $test_timeout= start_timer(testcase_timeout()); do_before_run_mysqltest($tinfo); @@ -3476,9 +3513,6 @@ sub run_testcase ($) { # Failed to record state of server or server crashed report_failure_and_restart($tinfo); - # Stop the test case timer - $test_timeout_proc->kill(); - return 1; } @@ -3496,20 +3530,20 @@ sub run_testcase ($) { if ($proc) { mtr_verbose ("Found exited process $proc"); - # If that was the timeout, cancel waiting - if ( $proc eq $test_timeout_proc ) - { - $keep_waiting_proc = 0; - } } else { $proc = $keep_waiting_proc; + # Also check if timer has expired, if so cancel waiting + if ( has_expired($test_timeout) ) + { + $keep_waiting_proc = 0; + } } } - else + if (! $keep_waiting_proc) { - $proc= My::SafeProcess->wait_any(); + $proc= My::SafeProcess->wait_any_timeout($test_timeout); } # Will be restored if we need to keep waiting @@ -3526,9 +3560,6 @@ sub run_testcase ($) { # ---------------------------------------------------- if ($proc eq $test) { - # Stop the test case timer - $test_timeout_proc->kill(); - my $res= $test->exit_status(); if ($res == 0 and $opt_warnings and check_warnings($tinfo) ) @@ -3585,6 +3616,14 @@ sub run_testcase ($) { run_on_all($tinfo, "analyze-$analyze"); } + # Wait a bit and see if a server died, if so report that instead + mtr_milli_sleep(100); + my $srvproc= My::SafeProcess::check_any(); + if ($srvproc && grep($srvproc eq $_, started(all_servers()))) { + $proc= $srvproc; + goto SRVDIED; + } + # Test case failure reported by mysqltest report_failure_and_restart($tinfo); } @@ -3592,7 +3631,7 @@ sub run_testcase ($) { { # mysqltest failed, probably crashed $tinfo->{comment}= - "mysqltest failed with unexpected return code $res"; + "mysqltest failed with unexpected return code $res\n"; report_failure_and_restart($tinfo); } @@ -3610,6 +3649,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if it was an expected crash # ---------------------------------------------------- + SRVDIED: my $check_crash = check_expected_crash_and_restart($proc); if ($check_crash) { @@ -3622,7 +3662,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Stop the test case timer # ---------------------------------------------------- - $test_timeout_proc->kill(); + $test_timeout= 0; # ---------------------------------------------------- # Check if it was a server that died @@ -3661,7 +3701,7 @@ sub run_testcase ($) { # ---------------------------------------------------- # Check if testcase timer expired # ---------------------------------------------------- - if ( $proc eq $test_timeout_proc ) + if ( $proc->{timeout} ) { my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; $tinfo->{comment}= @@ -3783,16 +3823,24 @@ sub extract_warning_lines ($$) { ( qr/^Warning:|mysqld: Warning|\[Warning\]/, qr/^Error:|\[ERROR\]/, - qr/^==\d*==/, # valgrind errors + qr/^==\d+==\s+\S/, # valgrind errors qr/InnoDB: Warning|InnoDB: Error/, qr/^safe_mutex:|allocated at line/, qr/missing DBUG_RETURN/, qr/Attempting backtrace/, qr/Assertion .* failed/, ); + my $skip_valgrind= 0; foreach my $line ( @lines ) { + if ($opt_valgrind_mysqld) { + # Skip valgrind summary from tests where server has been restarted + # Should this contain memory leaks, the final report will find it + $skip_valgrind= 1 if $line =~ /^==\d+== ERROR SUMMARY:/; + $skip_valgrind= 0 unless $line =~ /^==\d+==/; + next if $skip_valgrind; + } foreach my $pat ( @patterns ) { if ( $line =~ /$pat/ ) @@ -3832,7 +3880,6 @@ sub start_check_warnings ($$) { mtr_add_arg($args, "--loose-skip-safemalloc"); mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test"); - mtr_add_arg($args, "--verbose"); if ( $opt_embedded_server ) { @@ -3895,11 +3942,11 @@ sub check_warnings ($) { # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout_proc= My::SafeProcess->timer(check_timeout()); + my $timeout= start_timer(check_timeout()); while (1){ my $result= 0; - my $proc= My::SafeProcess->wait_any(); + my $proc= My::SafeProcess->wait_any_timeout($timeout); mtr_report("Got $proc"); if ( delete $started{$proc->pid()} ) { @@ -3928,9 +3975,6 @@ sub check_warnings ($) { if ( keys(%started) == 0){ # All checks completed - - $timeout_proc->kill(); - return $result; } # Wait for next process to exit @@ -3947,10 +3991,9 @@ sub check_warnings ($) { $result= 2; } } - elsif ( $proc eq $timeout_proc ) { - $tinfo->{comment}.= "Timeout $timeout_proc for ". - "'check warnings' expired after ".check_timeout(). - " seconds"; + elsif ( $proc->{timeout} ) { + $tinfo->{comment}.= "Timeout for 'check warnings' expired after " + .check_timeout()." seconds"; $result= 4; } else { @@ -3964,8 +4007,6 @@ sub check_warnings ($) { # Kill any check processes still running map($_->kill(), values(%started)); - $timeout_proc->kill(); - return $result; } @@ -3983,7 +4024,7 @@ sub check_expected_crash_and_restart { foreach my $mysqld ( mysqlds() ) { - next unless ( $mysqld->{proc} eq $proc ); + next unless ( $mysqld->{proc} and $mysqld->{proc} eq $proc ); # Check if crash expected by looking at the .expect file # in var/tmp @@ -4181,6 +4222,20 @@ sub report_failure_and_restart ($) { # about what failed has been saved to file. Save the report # in tinfo $tinfo->{logfile}= mtr_fromfile($logfile); + # If no newlines in the test log: + # (it will contain the CURRENT_TEST written by mtr, so is not empty) + if ($tinfo->{logfile} !~ /\n/) + { + # Show how far it got before suddenly failing + $tinfo->{comment}.= "mysqltest failed but provided no output\n"; + my $log_file_name= $opt_vardir."/log/".$tinfo->{shortname}.".log"; + if (-e $log_file_name) { + $tinfo->{comment}.= + "The result from queries just before the failure was:". + "\n< snip >\n". + mtr_lastlinesfromfile($log_file_name, 20)."\n"; + } + } } else { @@ -4395,6 +4450,10 @@ sub mysqld_start ($$) { # see the exact location where valgrind complains $output= "$opt_vardir/log/".$mysqld->name().".trace"; } + # Remember this log file for valgrind error report search + $mysqld_logs{$output}= 1 if $opt_valgrind; + # Remember data dir for gmon.out files if using gprof + $gprof_dirs{$mysqld->value('datadir')}= 1 if $opt_gprof; if ( defined $exe ) { @@ -4944,6 +5003,10 @@ sub start_mysqltest ($) { mtr_add_arg($args, "--ssl"); } + if ( $opt_max_connections ) { + mtr_add_arg($args, "--max-connections=%d", $opt_max_connections); + } + if ( $opt_embedded_server ) { @@ -5172,7 +5235,7 @@ sub debugger_arguments { { # vc[express] /debugexe exe arg1 .. argn - # Add /debugexe and name of the exe before args + # Add name of the exe and /debugexe before args unshift(@$$args, "$$exe"); unshift(@$$args, "/debugexe"); @@ -5247,6 +5310,66 @@ sub valgrind_arguments { } } +# +# Search server logs for valgrind reports printed at mysqld termination +# + +sub valgrind_exit_reports() { + foreach my $log_file (keys %mysqld_logs) + { + my @culprits= (); + my $valgrind_rep= ""; + my $found_report= 0; + my $err_in_report= 0; + + my $LOGF = IO::File->new($log_file) + or mtr_error("Could not open file '$log_file' for reading: $!"); + + while ( my $line = <$LOGF> ) + { + if ($line =~ /^CURRENT_TEST: (.+)$/) + { + my $testname= $1; + # If we have a report, report it if needed and start new list of tests + if ($found_report) + { + if ($err_in_report) + { + mtr_print ("Valgrind report from $log_file after tests:\n", + @culprits); + mtr_print_line(); + print ("$valgrind_rep\n"); + $err_in_report= 0; + } + # Make ready to collect new report + @culprits= (); + $found_report= 0; + $valgrind_rep= ""; + } + push (@culprits, $testname); + next; + } + # This line marks the start of a valgrind report + $found_report= 1 if $line =~ /ERROR SUMMARY:/; + + if ($found_report) { + $line=~ s/^==\d+== //; + $valgrind_rep .= $line; + $err_in_report= 1 if $line =~ /ERROR SUMMARY: [1-9]/; + $err_in_report= 1 if $line =~ /definitely lost: [1-9]/; + $err_in_report= 1 if $line =~ /possibly lost: [1-9]/; + } + } + + $LOGF= undef; + + if ($err_in_report) { + mtr_print ("Valgrind report from $log_file after tests:\n", @culprits); + mtr_print_line(); + print ("$valgrind_rep\n"); + } + } +} # # Usage @@ -5326,6 +5449,11 @@ Options to control what test suites or cases to run Options that specify ports + mtr-port-base=# Base for port numbers, ports from this number to + port-base=# number+9 are reserved. Should be divisible by 10; + if not it will be rounded down. May be set with + environment variable MTR_PORT_BASE. If this value is + set and is not "auto", it overrides build-thread. mtr-build-thread=# Specify unique number to calculate port number(s) from. build-thread=# Can be set in environment variable MTR_BUILD_THREAD. Set MTR_BUILD_THREAD="auto" to automatically aquire @@ -5437,6 +5565,7 @@ Misc options timestamp Print timestamp before each test report line timediff With --timestamp, also print time passed since *previous* test started + max-connections=N Max number of open connection to server in mysqltest HERE exit(1); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 2e3a9489593..67c08b0ae97 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -147,9 +147,10 @@ hello hello ;;;;;;;; # MySQL: -- The -mysqltest: At line 1: End of line junk detected: "6" -mysqltest: At line 1: End of line junk detected: "6" -mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: Extra argument '6' passed to 'sleep' +mysqltest: At line 1: Extra argument '6' passed to 'sleep' +mysqltest: At line 1: Extra argument 'A comment +show status' passed to 'sleep' mysqltest: At line 1: End of line junk detected: "sleep 7 # Another comment " @@ -216,6 +217,12 @@ source database echo message echo message mysqltest: At line 1: Missing argument in exec +1 +1 +2 +2 +X +3 MySQL "MySQL" MySQL: The @@ -348,8 +355,10 @@ here is the sourced script here is the sourced script "hello" "hello" -mysqltest: At line 1: Missing argument to sleep -mysqltest: At line 1: Missing argument to real_sleep +mysqltest: At line 2: Invalid argument to sleep "xyz" +mysqltest: At line 2: Invalid argument to real_sleep "xyz" +mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'sleep' +mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'real_sleep' mysqltest: At line 1: Invalid argument to sleep "abc" mysqltest: At line 1: Invalid argument to real_sleep "abc" 1 @@ -377,6 +386,10 @@ test test2 test3 test4 +outer +true-inner +true-inner again +true-outer Counter is greater than 0, (counter=10) Counter is not 0, (counter=0) 1 @@ -417,6 +430,9 @@ mysqltest: At line 1: Wrong number of arguments to replace_column in 'replace_co mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a b' mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a 1' mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 b c ' +select "LONG_STRING" as x; +x +LONG_STRING mysqltest: At line 1: Invalid integer argument "10!" mysqltest: At line 1: Invalid integer argument "a" mysqltest: At line 1: Missing required argument 'connection name' to command 'connect' @@ -523,7 +539,28 @@ a D 1 1 1 4 drop table t1; +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); +select * from t1; +f1 +Abcd +select * from t2;; +ERROR 42S02: Table 'test.t2' doesn't exist +select * from t1; +f1 +Abcd +select * from t1;; +Result coming up +f1 +Abcd +select * from t1;; +f1 +Abcd +mysqltest: At line 2: Cannot run query on connection between send and reap +select * from t1;; +drop table t1; mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file' +mysqltest: At line 1: Missing required argument 'directory' to command 'remove_files_wildcard' mysqltest: At line 1: Missing required argument 'filename' to command 'write_file' mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found Content for test_file1 @@ -553,6 +590,8 @@ hello mysqltest: At line 1: Max delimiter length(16) exceeded hello hello +val is 5 +val is 5 mysqltest: At line 1: test of die Some output create table t1( a int, b char(255), c timestamp); @@ -680,6 +719,29 @@ INSERT INTO t1 SELECT f1 - 256 FROM t1; INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; DROP TABLE t1; +select "500g blåbærsyltetøy" as "will be lower cased"; +will be lower cased +500g blåbærsyltetøy +SELECT "UPPER" AS "WILL NOT BE lower cased"; +WILL NOT BE lower cased +UPPER +UP +SELECT 0 as "UP AGAIN"; +UP AGAIN +0 +select "abcdef" as "uvwxyz"; +uvwxyz +abcdef +select "xyz" as name union select "abc" as name order by name desc; +name +abc +xyz +select 1 as "some new text"; +some new text +1 +select 0 as "will not lower case ÄËÐ"; +will not lower case ÄËÐ +0 CREATE TABLE t1( a int, b varchar(255), c datetime ); @@ -726,6 +788,8 @@ mysqltest: At line 1: change user failed: Access denied for user 'root'@'localho file1.txt file1.txt file2.txt +file11.txt +dir-list.txt SELECT 'c:\\a.txt' AS col; col z diff --git a/mysql-test/r/variables+c.result b/mysql-test/r/variables_community.result index 7a2976d1267..7a2976d1267 100644 --- a/mysql-test/r/variables+c.result +++ b/mysql-test/r/variables_community.result diff --git a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test index 6638a20c926..330addd6b3b 100644 --- a/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test +++ b/mysql-test/suite/sys_vars/t/innodb_table_locks_func.test @@ -78,6 +78,7 @@ COMMIT; --echo 'CONNECTION con2' CONNECTION con2; +reap; UNLOCK tables; DROP TABLE t1; diff --git a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test index 87813a958e0..03f56f1fe16 100644 --- a/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test +++ b/mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test @@ -128,6 +128,7 @@ connection con0; SET SESSION low_priority_updates = OFF; --echo ** Connection con1 ** connection con1; +reap; SET SESSION low_priority_updates = OFF; --echo ** Connection default** connection default; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index bcf33aa8c27..25293ff29e7 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -605,6 +605,15 @@ echo ; --error 1 --exec echo "--exec " | $MYSQL_TEST 2>&1 +# Multi-line exec +exec $MYSQL + test -e "select 1"; +exec $MYSQL test -e "select + 2"; +let $query = select 3 + as X; +exec $MYSQL test -e "$query"; + # ---------------------------------------------------------------------------- # Test let command # ---------------------------------------------------------------------------- @@ -911,6 +920,28 @@ sleep 0.5; sleep 1; real_sleep 1; +# Parameter from variable, legal and illegal +let $sleep_var= 0.1; +sleep $sleep_var; +let $sleep_var= 1; +--real_sleep $sleep_var + +--write_file $MYSQL_TMP_DIR/sleep.inc +let $sleep_var= xyz; +--sleep $sleep_var +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1 +--remove_file $MYSQL_TMP_DIR/sleep.inc + +--write_file $MYSQL_TMP_DIR/sleep.inc +let $sleep_var= xyz; +real_sleep $sleep_var; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQL_TMP_DIR/sleep.inc 2>&1 +--remove_file $MYSQL_TMP_DIR/sleep.inc + # Missing parameter --error 1 --exec echo "sleep ;" | $MYSQL_TEST 2>&1 @@ -1006,6 +1037,37 @@ echo test3stop --delimiter ; echo test4; +# ---------------------------------------------------------------------------- +# Test that delimiter within if() works in in various combinations +# ---------------------------------------------------------------------------- + +if (0) +{ + delimiter ||; + echo false-inner|| + if (0) + { + delimiter *|| + echo false-innerer* + delimiter ||* + } + echo false-inner again|| +} +echo outer; +if (1) +{ + delimiter /; + echo true-inner/ + if (0) + { + delimiter %/ + echo true-innerer% + } + echo true-inner again/ +} +echo true-outer/ +delimiter ;/ + # ---------------------------------------------------------------------------- # Test if @@ -1285,6 +1347,17 @@ select "a" as col1, "c" as col2; --error 1 --exec echo "--replace_column 1 b c " | $MYSQL_TEST 2>&1 +let $long_rep= 1234567890123456789012345678901234567890; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; +let $long_rep= $long_rep,$long_rep; + +# This tests from strings > 1024 (here 1311) + +--replace_result $long_rep LONG_STRING +eval select "$long_rep" as x; # ---------------------------------------------------------------------------- # Test sync_with_master @@ -1606,6 +1679,57 @@ select * from t1; drop table t1; # ---------------------------------------------------------------------------- +# Tests of send +# ---------------------------------------------------------------------------- + +create table t1 ( f1 char(10)); +insert into t1 values ("Abcd"); + +# 1. Basic test + +send select * from t1; +reap; + +# 2. Test with error + +--send select * from t2; +--error ER_NO_SUCH_TABLE +--reap + +# 3. test send of next stmt + +--send +select * from t1; +--reap + +# 4. Non-query stmt betwen send and reap allowed + +--send select * from t1; +--sleep 0.05 +--echo Result coming up +--reap + +# 5. Test of send_eval + +--let $my_stmt= select * from t1; +--send_eval $my_stmt +--reap + +# 6. Test that mysqltest does not allow query stmt between send and reap +# Untestable directly as it causes mysqltest to fail + +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.in +--send select * from t1; +select 1; +--reap +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.in 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.in; + +drop table t1; + +# ---------------------------------------------------------------------------- # test for remove_file # ---------------------------------------------------------------------------- @@ -1616,6 +1740,19 @@ drop table t1; remove_file non_existing_file; # ---------------------------------------------------------------------------- +# test for remove_files_wildcard +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "remove_files_wildcard ;" | $MYSQL_TEST 2>&1 + +--error 1 +remove_files_wildcard non_existing_dir; + +--error 1 +remove_files_wildcard non_existing_dir non_existing_file; + +# ---------------------------------------------------------------------------- # test for write_file # ---------------------------------------------------------------------------- --error 1 @@ -1905,6 +2042,20 @@ perl; print "hello\n"; EOF +# Test perl within while, also with if being false first iteration +let $outer= 3; +let $ifval= 0; +while ($outer) { + if ($ifval) { + perl UNTIL; + my $val= 5; + print "val is $val\n"; +UNTIL + } + inc $ifval; + dec $outer; +} + # ---------------------------------------------------------------------------- # test for die # ---------------------------------------------------------------------------- @@ -2045,6 +2196,44 @@ INSERT INTO t1 SELECT f1 - 512 FROM t1; SELECT * FROM t1; --enable_result_log DROP TABLE t1; + +# ---------------------------------------------------------------------------- +# test for lowercase_result +# ---------------------------------------------------------------------------- + +# 1. Basic test +--lowercase_result +SELECT "500g BLÅBÆRSYLTETØY" AS "WILL BE lower cased"; + +# 2. test that it does not apply to next statement +SELECT "UPPER" AS "WILL NOT BE lower cased"; + +# 3. test that it does not affect non-SQL or the following statement +--lowercase_result +--echo UP +SELECT 0 as "UP AGAIN"; + +# 4. test that it works with eval and variables +let $lower_stmt=SELECT "ABCdef" AS "uvwXYZ"; +--lowercase_result +eval $lower_stmt; + +# 5. test that it works in combination with sort +sorted_result; +lowercase_result; +SELECT "Xyz" AS Name UNION SELECT "Abc" as Name ORDER BY Name DESC; + +# 6. Test combination with replace, and that lower casing is done first +--lowercase_result +--replace_result old new +SELECT 1 as "SOME OLD TEXT"; + +# 7. Test missing lower casing of "unknown" characters +--character_set utf8 +--lowercase_result +SELECT 0 as "WILL NOT lower case ÄËÐ"; +--character_set latin1 + # ---------------------------------------------------------------------------- # Some coverage tests # ---------------------------------------------------------------------------- @@ -2230,9 +2419,14 @@ rmdir $MYSQLTEST_VARDIR/tmp/testdir; cat_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file1.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file2.txt; -remove_file $MYSQLTEST_VARDIR/tmp/testdir/file3.txt; +list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/file11.txt $MYSQLTEST_VARDIR/tmp/testdir file?.txt; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file?.txt; +list_files_write_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt $MYSQLTEST_VARDIR/tmp/testdir file*.txt; +cat_file $MYSQLTEST_VARDIR/tmp/testdir/dir-list.txt; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir file*.txt; +list_files $MYSQLTEST_VARDIR/tmp/testdir; +remove_files_wildcard $MYSQLTEST_VARDIR/tmp/testdir; +list_files $MYSQLTEST_VARDIR/tmp/testdir; rmdir $MYSQLTEST_VARDIR/tmp/testdir; # diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 2bf879603a4..294521a45d5 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -187,6 +187,7 @@ SELECT * FROM t1; --echo # Switch to connection con2 connection con2; +reap; SELECT * FROM t1; connection default; diff --git a/mysql-test/t/variables+c.test b/mysql-test/t/variables_community.test index aa4bc6c631c..aa4bc6c631c 100644 --- a/mysql-test/t/variables+c.test +++ b/mysql-test/t/variables_community.test diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index b4cfc054b35..be594b42ea2 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -416,8 +416,7 @@ else echo "Try 'mysqld --help' if you have problems with paths. Using --log" echo "gives you a log in $ldata that may be helpful." echo - echo "The latest information about MySQL is available on the web at" - echo "http://www.mysql.com/. Please consult the MySQL manual section" + echo "Please consult the MySQL manual section" echo "'Problems running mysql_install_db', and the manual section that" echo "describes problems on your OS. Another information source are the" echo "MySQL email archives available at http://lists.mysql.com/." @@ -476,9 +475,6 @@ then echo echo "Please report any problems with the $scriptdir/mysqlbug script!" echo - echo "The latest information about MySQL is available at http://www.mysql.com/" - echo "Support MySQL by buying support/licenses from http://shop.mysql.com/" - echo fi exit 0 |