#!/usr/bin/perl -w # # Run various unit tests. # use Getopt::Long; $|= 1; $VER= "1.1"; $opt_version= 0; $opt_help= 0; $opt_verbose= 0; $opt_maria_path= undef(); $opt_valgrind= "valgrind --alignment=8 --leak-check=yes"; $opt_suffix= ""; $opt_silent= "-s"; my $maria_path= $ENV{'maria_path'}; my $my_progname= $0; $my_progname=~ s/.*[\/]//; my $runtime_error= 0; # Return 1 if error(s) occur during run my $NEW_TEST= 0; # Test group separator in an array of tests run_tests(); #### #### Initialise variables, clean temporary files and run the tests #### sub run_tests { my $nr_tests= 0; my $flag_exit= 0; if (!GetOptions("help", "version", "verbose", "maria-path=s", "valgrind=s", "suffix=s", "silent=s")) { $flag_exit= 1; } if ($opt_version) { print "$my_progname version $VER\n"; exit(0); } if (defined($opt_maria_path)) { $maria_path= $opt_maria_path; } if (!defined($maria_path) || !length($maria_path)) { $maria_path= "."; } usage() if ($opt_help || $flag_exit); # # clean-up # unlink <*.TMD maria_log*>; # Delete temporary files # # IMPORTANT: If you modify this file, please read this: # # Count total number of tests. Make sure that the functions return # number of unit tests correctly, e.g. calls to ok(). The last argument # for each function is a flag counter and will return the number of # unit tests in each. Please see comments on function ok() at the end. # # If you modify any functions or add any new ones, please make sure the # unit tests are appropriately detected here. A wrong count will # make the unit test fail during 'make test'. $nr_tests must be right. # $nr_tests+= run_check_tests(0, 0, 0, 0, 1) * 4; # $nr_tests+= run_repair_tests(0, 0, 0, 0, 1) * 4; # called 4 times $nr_tests+= run_pack_tests(0, 0, 0, 0, 1) * 4; # $nr_tests+= run_tests_on_warnings_and_errors(0, 0, 0, 1); $nr_tests+= run_ma_test_recovery(0, 1); $nr_tests+= run_tests_on_clrs(0, 1); # # Run tests # if (!$opt_verbose) { print "1..$nr_tests\n"; } else { print "Total tests: $nr_tests\n"; } if ($opt_verbose) { print "Running tests with dynamic row format\n" } run_check_tests($opt_suffix, $opt_silent, "", $opt_verbose, 0); run_repair_tests($opt_suffix, $opt_silent, "", $opt_verbose, 0); run_pack_tests($opt_suffix, $opt_silent, "", $opt_verbose, 0); if ($opt_verbose) { print "\nRunning tests with static row format\n"; } run_check_tests($opt_suffix, $opt_silent, "-S", $opt_verbose, 0); run_repair_tests($opt_suffix, $opt_silent, "-S", $opt_verbose, 0); run_pack_tests($opt_suffix, $opt_silent, "-S", $opt_verbose, 0); if ($opt_verbose) { print "\nRunning tests with block row format\n"; } run_check_tests($opt_suffix, $opt_silent, "-M", $opt_verbose, 0); run_repair_tests($opt_suffix, $opt_silent, "-M", $opt_verbose, 0); run_pack_tests($opt_suffix, $opt_silent, "-M", $opt_verbose, 0); if ($opt_verbose) { print "\nRunning tests with block row format and transactions\n"; } run_check_tests($opt_suffix, $opt_silent, "-M -T", $opt_verbose, 0); run_repair_tests($opt_suffix, $opt_silent, "-M -T", $opt_verbose, 0); run_pack_tests($opt_suffix, $opt_silent, "-M -T", $opt_verbose, 0); run_tests_on_warnings_and_errors($opt_suffix, $opt_silent, $opt_verbose, 0); run_ma_test_recovery($opt_verbose, 0); run_tests_on_clrs($opt_verbose, 0); exit($runtime_error); } #### #### regular tests #### sub run_check_tests { my ($suffix, $silent, $row_type, $verbose, $count)= @_; my ($i, $nr_tests); my @ma_test1_opt= ( ["","-se"], ["-N","-se"], ["-P --checksum","-se"], ["-P -N","-se"], ["-B -N -R2","-sm"], ["-a -k 480 --unique","-sm"], ["-a -N -R1 ","-sm"], ["-p","-sm"], ["-p -N --unique","-sm"], ["-p -N --key_length=127 --checksum","-sm"], ["-p -N --key_length=128","-sm"], ["-p --key_length=480","-sm"], ["-a -B","-sm"], ["-a -B --key_length=64 --unique","-sm"], ["-a -B -k 480 --checksum","-sm"], ["-a -B -k 480 -N --unique --checksum","-sm"], ["-a -m","-sm"], ["-a -m -P --unique --checksum","-sm"], ["-a -m -P --key_length=480 --key_cache","-sm"], ["-m -p","-sm"], ["-w --unique","-sm"], ["-a -w --key_length=64 --checksum","-sm"], ["-a -w -N --key_length=480","-sm"], ["-a -w --key_length=480 --checksum","-sm"], ["-a -b -N","-sm"], ["-a -b --key_length=480","-sm"], ["-p -B --key_length=480","-sm"], ["--checksum --unique","-se"], ["--unique","-se"], ["--key_multiple -N -S","-sm"], ["--key_multiple -a -p --key_length=480","-sm"], ["--key_multiple -a -B --key_length=480","-sm"], ["--key_multiple -P -S","-sm"] ); my @ma_test2_opt= ( ["-L -K -W -P","-sm"], ["-L -K -W -P -A","-sm"], ["-L -K -P -R3 -m50 -b1000000","-sm"], ["-L -B","-sm"], ["-D -B -c","-sm"], ["-m10000 -e4096 -K","-sm"], ["-m10000 -e8192 -K","-sm"], ["-m10000 -e16384 -E16384 -K -L","-sm"], ["-L -K -W -P -b32768", "-se"], ["-c -b65000","-se"] ); if ($count) { $nr_tests= 2; # Number of tests outside loops for ($i= 0; defined($ma_test1_opt[$i]); $i++) { $nr_tests+=2; } for ($i= 0; defined($ma_test2_opt[$i]); $i++) { $nr_tests+=2; } return $nr_tests; } for ($i= 0; defined($ma_test1_opt[$i]); $i++) { unlink ; ok("$maria_path/ma_test1$suffix $silent $ma_test1_opt[$i][0] $row_type", $verbose, $i + 1); ok("$maria_path/maria_chk$suffix $ma_test1_opt[$i][1] test1", $verbose, $i + 1); } # # These tests are outside the loops. Make sure to include them in # nr_tests manually # ok("$maria_path/maria_pack$suffix --force -s test1", $verbose, 0); ok("$maria_path/maria_chk$suffix -ess test1", $verbose, 0); for ($i= 0; defined($ma_test2_opt[$i]); $i++) { unlink ; ok("$maria_path/ma_test2$suffix $silent $ma_test2_opt[$i][0] $row_type", $verbose, $i + 1); ok("$maria_path/maria_chk$suffix $ma_test2_opt[$i][1] test2", $verbose, $i + 1); } unlink ; return 0; } #### #### repair tests #### sub run_repair_tests() { my ($suffix, $silent, $row_type, $verbose, $count)= @_; my ($i); my @t= ($NEW_TEST, "$maria_path/ma_test1$suffix $silent --checksum $row_type", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix --silent -re --transaction-log test1", "$maria_path/maria_chk$suffix -rs test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -rqs test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -rs --correct-checksum test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -rqs --correct-checksum test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -ros --correct-checksum test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -rqos --correct-checksum test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -sz test1", "$maria_path/maria_chk$suffix -se test1", "$maria_path/ma_test2$suffix $silent -c -d1 $row_type", "$maria_path/maria_chk$suffix -s --parallel-recover test2", "$maria_path/maria_chk$suffix -se test2", "$maria_path/maria_chk$suffix -s --parallel-recover --quick test2", "$maria_path/maria_chk$suffix -se test2", "$maria_path/ma_test2$suffix $silent -c $row_type", "$maria_path/maria_chk$suffix -se test2", "$maria_path/maria_chk$suffix -sr test2", "$maria_path/maria_chk$suffix -se test2", "$maria_path/ma_test2$suffix $silent -c -t4 $row_type", "$maria_path/maria_chk$suffix -sz test1", "$maria_path/maria_chk$suffix -se test1" ); return &count_tests(\@t) if ($count); &run_test_bunch(\@t, $verbose, 0); return 0; } #### #### pack tests #### sub run_pack_tests() { my ($suffix, $silent, $row_type, $verbose, $count)= @_; my ($i); my @t= ($NEW_TEST, "$maria_path/ma_test1$suffix $silent --checksum $row_type", "$maria_path/maria_pack$suffix --force -s test1", "$maria_path/maria_chk$suffix -ess test1", "$maria_path/maria_chk$suffix -rqs test1", "$maria_path/maria_chk$suffix -es test1", "$maria_path/maria_chk$suffix -rs test1", "$maria_path/maria_chk$suffix -es test1", "$maria_path/maria_chk$suffix -rus test1", "$maria_path/maria_chk$suffix -es test1", $NEW_TEST, "$maria_path/ma_test1$suffix $silent --checksum $row_type", "$maria_path/maria_pack$suffix --force -s test1", "$maria_path/maria_chk$suffix -rus --safe-recover test1", "$maria_path/maria_chk$suffix -es test1", $NEW_TEST, "$maria_path/ma_test1$suffix $silent --checksum -S $row_type", "$maria_path/maria_chk$suffix -se test1", "$maria_path/maria_chk$suffix -ros test1", "$maria_path/maria_chk$suffix -rqs test1", "$maria_path/maria_chk$suffix -se test1", $NEW_TEST, "$maria_path/maria_pack$suffix --force -s test1", "$maria_path/maria_chk$suffix -rqs test1", "$maria_path/maria_chk$suffix -es test1", "$maria_path/maria_chk$suffix -rus test1", "$maria_path/maria_chk$suffix -es test1", $NEW_TEST, "$maria_path/ma_test2$suffix $silent -c -d1 $row_type", "$maria_path/maria_chk$suffix -s --parallel-recover test2", "$maria_path/maria_chk$suffix -se test2", "$maria_path/maria_chk$suffix -s --unpack --parallel-recover test2", "$maria_path/maria_chk$suffix -se test2", "$maria_path/maria_pack$suffix --force -s test1", "$maria_path/maria_chk$suffix -s --unpack --parallel-recover test2", "$maria_path/maria_chk$suffix -se test2" ); return &count_tests(\@t) if ($count); &run_test_bunch(\@t, $verbose, 0); return 0; } #### #### Tests that gives warnings or errors #### sub run_tests_on_warnings_and_errors { my ($suffix, $silent, $verbose, $count)= @_; my ($com); return 9 if ($count); # Number of tests in this function, e.g. calls to ok() ok("$maria_path/ma_test2$suffix $silent -L -K -W -P -S -R1 -m500", $verbose, 0); ok("$maria_path/maria_chk$suffix -sm test2", $verbose, 0); # ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135\n # In the following a failure is a success and success is a failure $com= "$maria_path/ma_test2$suffix $silent -L -K -R1 -m2000 "; $com.= ">ma_test2_message.txt 2>&1 && false"; ok($com, $verbose, 0, 1); ok("cat ma_test2_message.txt", $verbose, 0); ok("grep \"Error: 135\" ma_test2_message.txt > /dev/null", $verbose, 0); # maria_path/maria_chk$suffix -sm test2 will warn that # Datafile is almost full ok("$maria_path/maria_chk$suffix -sm test2 >ma_test2_message.txt 2>&1", $verbose, 0); ok("cat ma_test2_message.txt", $verbose, 0); ok("grep \"warning: Datafile is almost full\" ma_test2_message.txt>/dev/null", $verbose, 0); unlink ; ok("$maria_path/maria_chk$suffix -ssm test2", $verbose, 0); return 0; } #### #### Test that removing tables and applying the log leads to identical tables #### sub run_ma_test_recovery { my ($verbose, $count)= @_; return 1 if ($count); # Number of tests in this function ok("$maria_path/ma_test_recovery", $verbose, 0); return 0; } #### #### Tests on CLR's #### sub run_tests_on_clrs { my ($verbose, $count)= @_; my ($i); my @t= ($NEW_TEST, "$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -A1", "cp maria_log_control tmp", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -s -e test2", "cp tmp/maria_log_control .", "rm test2.MA?", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -s -e test2", "rm test2.MA?", $NEW_TEST, "$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -A1", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -s -e test2", "rm test2.MA?", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -e -s test2", "rm test2.MA?", $NEW_TEST, "$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b32768 -t4 -A1", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -es test2", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -es test2", "rm test2.MA?", "$maria_path/maria_read_log -a -s", "$maria_path/maria_chk -es test2", "rm test2.MA?" ); return &count_tests(\@t) if ($count); &run_test_bunch(\@t, $verbose, 1); return 0; } # # Print "ok" on success and "not ok" on error # # Note: Every time this function is called it will be counted # as a unit test. # # Args: $com: The actual command run. Will be printed on a failure # $verbose: Be more verbose. # $iteration: Number of iterations in a loop when the error # occurred. If not in loop, this should be blank # (e.g. send zero). # $expected_error: Optional; put here expected error code. Test # will pass with this result only. # # Return value: Will return 1 on success and 0 on an error # sub ok { my ($com, $verbose, $iteration, $expected_error)= @_; my ($msg, $output, $err, $len); $msg= ""; $expected_error= 0 if (!defined($expected_error)); if ($verbose) { print "$com "; } $output= `$com 2>&1`; $len= length($com); if ($verbose) { print " " x (65 - $len); print " "; } $err= $? >> 8; if ($err == $expected_error) { print "[ " if ($verbose); print "ok"; print " ]" if ($verbose); print "\n"; return 1; } print "[ " if ($verbose); print "not ok"; print " ]" if ($verbose); print "\n"; if ($verbose && length($output)) { print "$output\n"; } if (!$verbose) { $msg= "\n"; # Get a nicer output in perl unit test mode } $msg.= "Failed test '$com' "; if ($iteration) { $msg.= "(loop iteration $iteration.) "; } $msg.= "at line "; $msg.= (caller)[2]; $msg.= " (errcode: $err)\n"; if ($expected_error) { $msg.= "Was expecting errcode: $expected_error\n"; } warn $msg; $runtime_error= 1; return 0; } #### #### Count tests #### Arguments: $t: an array of the tests #### sub count_tests { my ($t)= @_; my ($i, $nr_tests); $nr_tests= 0; for ($i= 0; defined(@$t[$i]); $i++) { $nr_tests++ if (@$t[$i]); } return $nr_tests; } #### #### Run a bunch of tests #### Arguments: $t: an array of the tests #### $verbose: to be passed to ok() #### $clear: clear log files if set #### sub run_test_bunch { my ($t, $verbose, $clear)= @_; my ($i); for ($i= 0; defined(@$t[$i]); $i++) { if ($clear && @$t[$i] eq $NEW_TEST) { unlink ; } if (@$t[$i] ne $NEW_TEST) { ok(@$t[$i], $verbose, $i + 1); } } } #### #### usage #### sub usage { print <