📄 mysql-stress-test.pl
字号:
{ if ($opt_stress_init_file eq '') { #Default location of file with set of tests for current test run $tests_files{initdb}->{filename}= File::Spec->catfile($opt_stress_suite_basedir, "testslist_initdb.txt"); } else { $tests_files{initdb}->{filename}= $opt_stress_init_file; } if (!-f $tests_files{initdb}->{filename}) { die <<EOF;File '$tests_files{initdb}->{filename}' with list of tests for initialization of databasefor stress test not exists. Please ensure that this file exists, readable or specify another one with --stress-init-file option.EOF }}if ($opt_stress_mode !~ /^(random|seq)$/){ die <<EOFWas specified wrong --stress-mode. Correct values 'random' and 'seq'.EOF}if (open(TEST, "$opt_mysqltest -V |")){ $mysqltest_version=join("",<TEST>); close(TEST); print "FOUND MYSQLTEST BINARY: ", $mysqltest_version,"\n";}else{ die <<EOF;ERROR: mysqltest binary $opt_mysqltest not found $!.You must either specify file location explicitly using --mysqltestoption, or make sure path to mysqltest binary is listed in your PATH environment variable.EOF}# #Adding mysql server specific command line options for mysqltest binary#$opt_server_host= $opt_server_host ? $opt_server_host : "localhost";$opt_server_port= $opt_server_port ? $opt_server_port : "3306";$opt_server_user= $opt_server_user ? $opt_server_user : "root";$opt_server_socket= $opt_server_socket ? $opt_server_socket : "/tmp/mysql.sock";$opt_server_database= $opt_server_database ? $opt_server_database : "test";unshift @mysqltest_args, "--host=$opt_server_host";unshift @mysqltest_args, "--port=$opt_server_port";unshift @mysqltest_args, "--user=$opt_server_user";unshift @mysqltest_args, "--password=$opt_server_password";unshift @mysqltest_args, "--socket=$opt_server_socket";unshift @mysqltest_args, "--database=$opt_server_database";#Export variables that could be used in tests$ENV{MYSQL_TEST_DIR}=$test_dataset_dir;$ENV{MASTER_MYPORT}=$opt_server_port;$ENV{MASTER_MYSOCK}=$opt_server_socket;print <<EOF;TEST-SUITE-BASEDIR: $opt_stress_suite_basedirSUITE: $opt_suiteTEST-BASE-DIR: $opt_stress_basedirTEST-DATADIR: $test_dataset_dirSERVER-LOGS-DIR: $opt_server_logs_dirTHREADS: $opt_threadsTEST-MODE: $opt_stress_modeEOF#-------------------------------------------------------------------------------#At this stage we've already checked all needed pathes/files #and ready to start the test#-------------------------------------------------------------------------------if (defined($opt_stress_tests_file) || defined($opt_stress_init_file)){ print <<EOF;############################################################# PREPARATION STAGE#############################################################EOF #Copy Test files from network share to 't' folder print "\nCopying Test files from $test_suite_t_path to $test_t_path folder..."; find({wanted=>\©_test_files, bydepth=>1}, "$test_suite_t_path"); print "Done\n"; #$test_r_path/r0 dir reserved for initdb $count_start= defined($opt_stress_init_file) ? 0 : 1; our $r_folder=''; print "\nCreating 'r' folder and copying Protocol files to each 'r#' sub-folder..."; for($count=$count_start; $count <= $opt_threads; $count++) { $r_folder = File::Spec->catdir($test_r_path, "r".$count); mkpath("$r_folder", 0, 0777); find(\©_result_files,"$test_suite_r_path"); } print "Done\n\n";}if (defined($opt_stress_init_file)){ print <<EOF;############################################################# INITIALIZATION STAGE#############################################################EOF #Set limits for stress db initialization %limits=(loop_count => 1, test_count => undef); #Read list of tests from $opt_stress_init_file read_tests_names($tests_files{initdb}); test_loop($client_ip, 0, 'seq', $tests_files{initdb}); #print Dumper($tests_files{initdb}),"\n"; print <<EOF;Done initialization of stress database by tests from $tests_files{initdb}->{filename} file.EOF}if (defined($opt_stress_tests_file)){ print <<EOF;############################################################# STRESS TEST RUNNING STAGE#############################################################EOF $exiting=0; #Read list of tests from $opt_stress_tests_file read_tests_names($tests_files{client}); #Reset current counter and set limits %test_counters=( loop_count => 0, test_count=>0); %limits=(loop_count => $opt_loop_count, test_count => $opt_test_count); if (($opt_loop_count && $opt_threads > $opt_loop_count) || ($opt_test_count && $opt_threads > $opt_test_count)) { warn <<EOF;WARNING: Possible inaccuracies in number of executed loops or tests because number of threads bigger than number of loops or tests: Threads will be started: $opt_threads Loops will be executed: $opt_loop_count Tests will be executed: $opt_test_count EOF } #Create threads (number depending on the variable ) for ($id=1; $id<=$opt_threads && !$exiting; $id++) { $thrd[$id] = threads->create("test_loop", $client_ip, $id, $opt_stress_mode, $tests_files{client}); print "main: Thread ID $id TID ",$thrd[$id]->tid," started\n"; select(undef, undef, undef, 0.5); } if ($opt_test_duration) { sleep($opt_test_duration); kill INT, $$; #Interrupt child threads } #Let other threads to process INT signal sleep(1); for ($id=1; $id<=$opt_threads;$id++) { if (defined($thrd[$id])) { $thrd[$id]->join(); } } print "EXIT\n";}sub test_init{ my ($env)=@_; $env->{session_id}=$env->{ip}."_".$env->{thread_id}; $env->{r_folder}='r'.$env->{thread_id}; $env->{screen_logs}=File::Spec->catdir($opt_server_logs_dir, $test_dirname, "screen_logs", $env->{session_id}); $env->{reject_logs}=File::Spec->catdir($opt_server_logs_dir, $test_dirname, "reject_logs", $env->{session_id}); mkpath($env->{screen_logs}, 0, 0755) unless (-d $env->{screen_logs}); mkpath($env->{reject_logs}, 0, 0755) unless (-d $env->{reject_logs}); $env->{session_log}= File::Spec->catfile($env->{screen_logs}, $env->{session_id}.".log"); }sub test_execute{ my $env= shift; my $test_name= shift; my $g_start= ""; my $g_end= ""; my $mysqltest_cmd= ""; my @mysqltest_test_args=(); my @stderr=(); #Get time stamp $g_start = get_timestamp(); $env->{errors}={}; @{$env->{test_status}}=(); my $test_file= $test_name.".test"; my $result_file= $test_name.".result"; my $reject_file = $test_name.'.reject'; my $output_file = $env->{session_id}.'_'.$test_name.'_'.$g_start."_".$env->{test_count}.'.txt'; my $test_filename = File::Spec->catfile($test_t_path, $test_file); my $result_filename = File::Spec->catdir($test_r_path, $env->{r_folder}, $result_file); my $reject_filename = File::Spec->catdir($test_r_path, $env->{r_folder}, $reject_file); my $output_filename = File::Spec->catfile($env->{screen_logs}, $output_file); push @mysqltest_test_args, "--basedir=$opt_stress_suite_basedir/", "--tmpdir=$opt_stress_basedir", "-x $test_filename", "-R $result_filename", "2>$output_filename"; $cmd= "$opt_mysqltest --no-defaults ".join(" ", @mysqltest_args)." ". join(" ", @mysqltest_test_args); system($cmd); $exit_value = $? >> 8; $signal_num = $? & 127; $dumped_core = $? & 128; my $tid= threads->self->tid; if (-s $output_filename > 0) { #Read stderr for further analysis open (STDERR_LOG, $output_filename) or warn "Can't open file $output_filename"; @stderr=<STDERR_LOG>; close(STDERR_LOG); if ($opt_verbose) { $session_debug_file="$opt_stress_basedir/error$tid.txt"; stress_log($session_debug_file, "Something wrong happened during execution of this command line:"); stress_log($session_debug_file, "MYSQLTEST CMD - $cmd"); stress_log($session_debug_file, "STDERR:".join("",@stderr)); stress_log($session_debug_file, "EXIT STATUS:\n1. EXIT: $exit_value \n". "2. SIGNAL: $signal_num\n". "3. CORE: $dumped_core\n"); } } #If something wrong trying to analyse stderr if ($exit_value || $signal_num) { if (@stderr) { foreach my $line (@stderr) { #FIXME: we should handle case when for one sub-string/code # we have several different error messages # Now for both codes/substrings we assume that # first found message will represent error #Check line for error codes if (($err_msg, $err_code)= $line=~/failed: ((\d+):.+?$)/) { if (!exists($error_codes{$err_code})) { $severity="S3"; $err_code=0; } else { $severity=$error_codes{$err_code}; } if (!exists($env->{errors}->{$severity}->{$err_code})) { $env->{errors}->{$severity}->{$err_code}=[0, $err_msg]; } $env->{errors}->{$severity}->{$err_code}->[0]++; $env->{errors}->{$severity}->{total}++; } #Check line for error patterns foreach $err_string (keys %error_strings) { $pattern= quotemeta $err_string; if ($line =~ /$pattern/i) { my $severity= $error_strings{$err_string}; if (!exists($env->{errors}->{$severity}->{$err_string})) { $env->{errors}->{$severity}->{$err_string}=[0, $line]; } $env->{errors}->{$severity}->{$err_string}->[0]++; $env->{errors}->{$severity}->{total}++; } } } } else { $env->{errors}->{S3}->{'Unknown error'}= [1,"Unknown error. Nothing was output to STDERR"]; $env->{errors}->{S3}->{total}=1; } } # #FIXME: Here we can perform further analysis of recognized # error codes # foreach my $severity (sort {$a cmp $b} keys %{$env->{errors}}) { my $total=$env->{errors}->{$severity}->{total}; if ($total) { push @{$env->{test_status}}, "Severity $severity: $total"; $env->{errors}->{total}=+$total; } } #FIXME: Should we take into account $exit_value here? # Now we assume that all stringified errors(i.e. errors without # error codes) which are not exist in %error_string structure # are OK if (!$env->{errors}->{total}) { push @{$env->{test_status}},"No Errors. Test Passed OK"; } log_session_errors($env, $test_file); if (!$exiting && ($signal_num == 2 || $signal_num == 15 || ($opt_abort_on_error && $env->{errors}->{S1} > 0))) { #mysqltest was interrupted with INT or TERM signals or test was #ran with --abort-on-error option and we got errors with severity S1 #so we assume that we should cancel testing and exit $exiting=1; print STDERR<<EOF;WARNING: mysqltest was interrupted with INT or TERM signals or test was ran with --abort-on-error option and we got errors with severity S1 (test cann't connect to the server or server crashed) so we assume that we should cancel testing and exit. Please check log file for this thread in $stress_log_file or inspect below output of the last test case executed with mysqltest to find out cause of error. Output of mysqltest:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -