diff --git a/bin/pt-archiver b/bin/pt-archiver index f2a41133..81653b8d 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -2182,7 +2182,7 @@ sub get_dbh { PTDEBUG && _d($dbh, $sql); my ($sql_mode) = eval { $dbh->selectrow_array($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error getting the current SQL_MODE: $EVAL_ERROR"; } $sql = 'SET @@SQL_QUOTE_SHOW_CREATE = 1' @@ -2192,15 +2192,17 @@ sub get_dbh { PTDEBUG && _d($dbh, $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting SQL_QUOTE_SHOW_CREATE, SQL_MODE" + . ($sql_mode ? " and $sql_mode" : '') + . ": $EVAL_ERROR"; } - if ( my ($charset) = $cxn_string =~ m/charset=(\w+)/ ) { - $sql = "/*!40101 SET NAMES $charset*/"; + if ( my ($charset) = $cxn_string =~ m/charset=([\w]+)/ ) { + $sql = qq{/*!40101 SET NAMES "$charset"*/}; PTDEBUG && _d($dbh, ':', $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting NAMES to $charset: $EVAL_ERROR"; } PTDEBUG && _d('Enabling charset for STDOUT'); if ( $charset eq 'utf8' ) { @@ -2212,12 +2214,12 @@ sub get_dbh { } } - if ( $self->prop('set-vars') ) { - $sql = "SET " . $self->prop('set-vars'); + if ( my $var = $self->prop('set-vars') ) { + $sql = "SET $var"; PTDEBUG && _d($dbh, ':', $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting $var: $EVAL_ERROR"; } } } @@ -3953,6 +3955,22 @@ sub main { $dp->get_cxn_params($table), { AutoCommit => $ac }); PTDEBUG && _d('Inspecting table on', $dp->as_string($table)); + if ( $o->get('bulk-insert') ) { + local $@; + my $sql = "LOAD DATA LOCAL INFILE '/dev/null' INTO TABLE " + . "`test`.`pt_not_there`"; + eval { $dbh->do($sql); 1 } or do { + my $e = $@; + my $error_re = qr/\QDBD::mysql::db do failed: The used command is not allowed with this MySQL version [for Statement "LOAD DATA LOCAL INFILE/; + if ($e =~ $error_re) { + $dbh->disconnect(); + die("--bulk-insert cannot work as LOAD DATA LOCAL INFILE " + . "is disabled. See http://kb.percona.com/troubleshoot-load-data-infile" + ); + } + }; + } + # Set options that can enable removing data on the master and archiving it # on the slaves. if ( $table->{a} ) { @@ -5091,6 +5109,9 @@ STDOUT to utf8, passes the mysql_enable_utf8 option to DBD::mysql, and runs SET NAMES UTF8 after connecting to MySQL. Any other value sets binmode on STDOUT without the utf8 layer, and runs SET NAMES after connecting to MySQL. +Note that only charsets as known by MySQL are recognized; So for example, +"UTF8" will work, but "UTF-8" will not. + See also L<"--[no]check-charset">. =item --[no]check-charset diff --git a/bin/pt-diskstats b/bin/pt-diskstats index 876cf37d..e25634cb 100755 --- a/bin/pt-diskstats +++ b/bin/pt-diskstats @@ -1389,25 +1389,20 @@ sub _d { # ########################################################################### # ########################################################################### -# ReadKeyMini +# ReadKeyMini package +# This package is a copy without comments from the original. The original +# with comments and its test file can be found in the Bazaar repository at, +# lib/ReadKeyMini.pm +# t/lib/ReadKeyMini.t +# See https://launchpad.net/percona-toolkit for more information. # ########################################################################### +{ + BEGIN { package ReadKeyMini; -# Here be magic. We lie to %INC and say that someone already pulled us from -# the filesystem. Which might be true, if this is inside a .pm file, but -# might not be, if we are part of the big file. The spurious BEGINs are mostly -# unnecesary, but if we aren't inside a .pm and something uses us, import or -# EXPORT_OK might not yet be defined. Though that probably won't help. -# Costs us nothing though, so worth trying. Putting this on top of the file -# would solve the issue. BEGIN { $INC{"ReadKeyMini.pm"} ||= 1 } -# Package: ReadKeyMini -# ReadKeyMini is a wrapper around Term::ReadKey. If that's available, -# we use ReadMode and GetTerminalSize from there. Otherwise, we use homebrewn -# definitions. - use warnings; use strict; use English qw(-no_match_vars); @@ -1434,14 +1429,14 @@ my %modes = ( 'ultra-raw' => 5, ); -# This primarily comes from the Perl Cookbook, recipe 15.8 { + my $fd_stdin = fileno(STDIN); my $flags; unless ( $PerconaTest::DONT_RESTORE_STDIN ) { $flags = fcntl(STDIN, F_GETFL, 0) - or die "can't fcntl F_GETFL: $!"; + or warn "can't fcntl F_GETFL: $!"; } my $term = POSIX::Termios->new(); $term->getattr($fd_stdin); @@ -1475,7 +1470,7 @@ my %modes = ( $term->setattr( $fd_stdin, TCSANOW ); unless ( $PerconaTest::DONT_RESTORE_STDIN ) { fcntl(STDIN, F_SETFL, $flags) - or die "can't fcntl F_SETFL: $!"; + or warn "can't fcntl F_SETFL: $!"; } } @@ -1489,9 +1484,6 @@ sub readkey { sysread(STDIN, $key, 1); my $timeout = 0.1; if ( $key eq "\033" ) { - # Ugly and broken hack, but good enough for the two minutes it took to write. - # Namely, Ctrl escapes, the F-NUM keys, and other stuff you can send from the keyboard - # take more than one "character" to represent, and would be wrong to break into pieces. { my $x = ''; STDIN->blocking(0); @@ -1505,15 +1497,11 @@ sub readkey { return $key; } -# As per perlfaq8: BEGIN { eval { no warnings; local $^W; require 'sys/ioctl.ph' }; if ( !defined &TIOCGWINSZ ) { *TIOCGWINSZ = sub () { - # Very few systems actually have ioctl.ph, thus it comes to this. - # These seem to be good enough, for now. See: - # http://stackoverflow.com/a/4286840/536499 $^O eq 'linux' ? 0x005413 : $^O eq 'solaris' ? 0x005468 : 0x40087468; @@ -1536,11 +1524,11 @@ sub _GetTerminalSize { } } - if ( $rows = `tput lines` ) { + if ( $rows = `tput lines 2>/dev/null` ) { chomp($rows); chomp($cols = `tput cols`); } - elsif ( my $stty = `stty -a` ) { + elsif ( my $stty = `stty -a 2>/dev/null` ) { ($rows, $cols) = $stty =~ /([0-9]+) rows; ([0-9]+) columns;/; } else { @@ -1555,6 +1543,7 @@ sub _GetTerminalSize { } 1; +} # ########################################################################### # End ReadKeyMini package # ########################################################################### diff --git a/bin/pt-upgrade b/bin/pt-upgrade index acaaabee..5923ad6a 100755 --- a/bin/pt-upgrade +++ b/bin/pt-upgrade @@ -10371,6 +10371,32 @@ sub main { $host->{name} = $name || 'unknown host'; } + # ######################################################################## + # If we're comparing rows, check that LOAD DATA LOCAL INFILE works for, + # all hosts, or bail out early if it doesn't. + # ######################################################################## + my $compare = $o->get('compare'); + if ( $compare->{results} + && lc($o->get('compare-results-method')) eq 'rows' ) + { + foreach my $host ( @$hosts ) { + local $@; + my $sql = "LOAD DATA LOCAL INFILE '/dev/null' INTO TABLE " + . "`test`.`pt_not_there`"; + eval { $host->{dbh}->do($sql); 1 } or do { + my $e = $@; + my $error_re = qr/\QDBD::mysql::db do failed: The used command is not allowed with this MySQL version [for Statement "LOAD DATA LOCAL INFILE/; + if ($e =~ $error_re) { + $_->{dbh}->disconnect() for @$hosts; + die("Cannot compare rows as LOAD DATA LOCAL INFILE " + . "is disabled for $host->{name}. See " + . "http://kb.percona.com/troubleshoot-load-data-infile" + ); + } + }; + } + } + # ######################################################################## # Make some common modules. # ######################################################################## @@ -10404,7 +10430,6 @@ sub main { # ######################################################################## # Make compare modules in order. # ######################################################################## - my $compare = $o->get('compare'); my @compare_modules; if ( $compare->{results} ) { my $method = lc $o->get('compare-results-method'); diff --git a/lib/Cxn.pm b/lib/Cxn.pm index debfacce..e898f183 100644 --- a/lib/Cxn.pm +++ b/lib/Cxn.pm @@ -103,7 +103,7 @@ sub new { dsn_name => $dp->as_string($dsn, [qw(h P S)]), hostname => '', set => $args{set}, - NAME_lc => $args{NAME_lc}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, dbh_set => 0, OptionParser => $o, DSNParser => $dp, diff --git a/lib/DSNParser.pm b/lib/DSNParser.pm index 0d73556d..4ba7e7c1 100644 --- a/lib/DSNParser.pm +++ b/lib/DSNParser.pm @@ -336,7 +336,7 @@ sub get_dbh { PTDEBUG && _d($dbh, $sql); my ($sql_mode) = eval { $dbh->selectrow_array($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error getting the current SQL_MODE: $EVAL_ERROR"; } $sql = 'SET @@SQL_QUOTE_SHOW_CREATE = 1' @@ -346,16 +346,18 @@ sub get_dbh { PTDEBUG && _d($dbh, $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting SQL_QUOTE_SHOW_CREATE, SQL_MODE" + . ($sql_mode ? " and $sql_mode" : '') + . ": $EVAL_ERROR"; } # Set character set and binmode on STDOUT. - if ( my ($charset) = $cxn_string =~ m/charset=(\w+)/ ) { - $sql = "/*!40101 SET NAMES $charset*/"; + if ( my ($charset) = $cxn_string =~ m/charset=([\w]+)/ ) { + $sql = qq{/*!40101 SET NAMES "$charset"*/}; PTDEBUG && _d($dbh, ':', $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting NAMES to $charset: $EVAL_ERROR"; } PTDEBUG && _d('Enabling charset for STDOUT'); if ( $charset eq 'utf8' ) { @@ -367,12 +369,12 @@ sub get_dbh { } } - if ( $self->prop('set-vars') ) { - $sql = "SET " . $self->prop('set-vars'); + if ( my $var = $self->prop('set-vars') ) { + $sql = "SET $var"; PTDEBUG && _d($dbh, ':', $sql); eval { $dbh->do($sql) }; if ( $EVAL_ERROR ) { - die $EVAL_ERROR; + die "Error setting $var: $EVAL_ERROR"; } } } diff --git a/lib/PerconaTest.pm b/lib/PerconaTest.pm index 08fbd0f2..8221de9b 100644 --- a/lib/PerconaTest.pm +++ b/lib/PerconaTest.pm @@ -717,12 +717,17 @@ sub full_output { my ( $code, %args ) = @_; die "I need a code argument" unless $code; - my (undef, $file) = tempfile(); - open *output_fh, '>', $file - or die "Cannot open file $file: $OS_ERROR"; - local *STDOUT = *output_fh; + local (*STDOUT, *STDERR); + require IO::File; - *STDERR = *STDOUT; + my (undef, $file) = tempfile(); + open *STDOUT, '>', $file + or die "Cannot open file $file: $OS_ERROR"; + *STDOUT->autoflush(1); + + open *STDERR, '>', $file + or die "Cannot open file $file: $OS_ERROR"; + *STDERR->autoflush(1); my $status; if (my $pid = fork) { @@ -745,7 +750,7 @@ sub full_output { else { exit $code->(); } - close *output_fh; + close $_ or die "Cannot close $_: $OS_ERROR" for qw(STDOUT STDERR); my $output = do { local $/; open my $fh, "<", $file or die $!; <$fh> }; return ($output, $status); @@ -772,6 +777,19 @@ sub tables_used { return [ sort keys %tables ]; } +sub load_data_is_disabled { + my ($dbh) = @_; + my $sql = "LOAD DATA LOCAL INFILE '/dev/null' INTO TABLE " + . "`t`.`pt_not_there`"; + local $@; + if (!eval { $dbh->do($sql); 1 } ) { + my $e = $@; + return 1 if $e =~ qr/\QDBD::mysql::db do failed: The used command is not allowed with this MySQL version [for Statement "LOAD DATA LOCAL INFILE/; + } + + return; +} + 1; } # ########################################################################### diff --git a/lib/ReadKeyMini.pm b/lib/ReadKeyMini.pm index acb17721..932b8513 100644 --- a/lib/ReadKeyMini.pm +++ b/lib/ReadKeyMini.pm @@ -15,8 +15,14 @@ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA. # ########################################################################### -# ReadKeyMini +# ReadKeyMini package # ########################################################################### + +# Package: ReadKeyMini +# ReadKeyMini is a wrapper around Term::ReadKey. If that's available, +# we use ReadMode and GetTerminalSize from there. Otherwise, we use homebrewn +# definitions. + BEGIN { package ReadKeyMini; @@ -29,11 +35,6 @@ package ReadKeyMini; # would solve the issue. BEGIN { $INC{"ReadKeyMini.pm"} ||= 1 } -# Package: ReadKeyMini -# ReadKeyMini is a wrapper around Term::ReadKey. If that's available, -# we use ReadMode and GetTerminalSize from there. Otherwise, we use homebrewn -# definitions. - use warnings; use strict; use English qw(-no_match_vars); @@ -72,7 +73,7 @@ my %modes = ( my $flags; unless ( $PerconaTest::DONT_RESTORE_STDIN ) { $flags = fcntl(STDIN, F_GETFL, 0) - or die "can't fcntl F_GETFL: $!"; + or warn "can't fcntl F_GETFL: $!"; } my $term = POSIX::Termios->new(); $term->getattr($fd_stdin); @@ -106,7 +107,7 @@ my %modes = ( $term->setattr( $fd_stdin, TCSANOW ); unless ( $PerconaTest::DONT_RESTORE_STDIN ) { fcntl(STDIN, F_SETFL, $flags) - or die "can't fcntl F_SETFL: $!"; + or warn "can't fcntl F_SETFL: $!"; } } @@ -168,16 +169,18 @@ sub _GetTerminalSize { } } - eval { - if ( $rows = `tput lines` ) { - chomp($rows); - chomp($cols = `tput cols`); - } - elsif ( my $stty = `stty -a` ) { - ($rows, $cols) = $stty =~ /([0-9]+) rows; ([0-9]+) columns;/; - } - }; - PTDEBUG && _d($EVAL_ERROR); + if ( $rows = `tput lines 2>/dev/null` ) { + chomp($rows); + chomp($cols = `tput cols`); + } + elsif ( my $stty = `stty -a 2>/dev/null` ) { + ($rows, $cols) = $stty =~ /([0-9]+) rows; ([0-9]+) columns;/; + } + else { + ($cols, $rows) = @ENV{qw( COLUMNS LINES )}; + $cols ||= 80; + $rows ||= 24; + } return ( $cols, $rows ); } diff --git a/sandbox/start-sandbox b/sandbox/start-sandbox index eea8f943..06a75248 100755 --- a/sandbox/start-sandbox +++ b/sandbox/start-sandbox @@ -51,6 +51,9 @@ make_sandbox() { if [ -n "$MULTIPLE_BUFFER_POOLS" ]; then echo "innodb_buffer_pool_instances=$MULTIPLE_BUFFER_POOLS" >> /tmp/$port/my.sandbox.cnf fi + if [ -n "$LOCAL_INFILE" ]; then + echo "local-infile=$LOCAL_INFILE" >> /tmp/$port/my.sandbox.cnf + fi # If the sandbox is a slave, set it read_only. if [ "$type" = "slave" ]; then diff --git a/t/lib/CompareResults.t b/t/lib/CompareResults.t index 32bece26..7f07dc47 100644 --- a/t/lib/CompareResults.t +++ b/t/lib/CompareResults.t @@ -304,8 +304,10 @@ is_deeply( # ############################################################################# # Test the rows method. # ############################################################################# - my $tmpdir = '/tmp/mk-upgrade-res'; +SKIP: { + skip "LOAD DATA LOCAL INFILE is disabled, can't test method => rows", 30 + if PerconaTest::load_data_is_disabled($dbh1); diag(`rm -rf $tmpdir 2>/dev/null; mkdir $tmpdir`); $sb->load_file('master', "t/lib/samples/compare-results.sql"); @@ -681,7 +683,7 @@ is( $report, 'rows: report, left with more rows' ); - +} # ############################################################################# # Try to compare without having done the actions. # ############################################################################# @@ -726,6 +728,9 @@ is_deeply( 'No differences after bad compare()' ); +SKIP: { + skip "LOAD DATA LOCAL INFILE is disabled, can't test method => rows", 2 + if PerconaTest::load_data_is_disabled($dbh1); $cr = new CompareResults( method => 'rows', 'base-dir' => $tmpdir, @@ -755,6 +760,8 @@ is_deeply( 'No differences after bad compare()' ); +} + # ############################################################################# # Done. # ############################################################################# diff --git a/t/lib/Cxn.t b/t/lib/Cxn.t index d227f717..75355b76 100644 --- a/t/lib/Cxn.t +++ b/t/lib/Cxn.t @@ -114,7 +114,7 @@ my ($row) = $cxn->dbh()->selectrow_hashref('SHOW MASTER STATUS'); ok( exists $row->{binlog_ignore_db}, "FetchHashKeyName = NAME_lc", -); +) or diag(Dumper($row)); test_var_val( $cxn->dbh(), @@ -163,7 +163,7 @@ $cxn->connect(); ok( exists $row->{binlog_ignore_db}, "Reconnect FetchHashKeyName = NAME_lc", -); +) or diag(Dumper($row)); test_var_val( $cxn->dbh(), diff --git a/t/lib/DSNParser.t b/t/lib/DSNParser.t index 51746332..91c28cc5 100644 --- a/t/lib/DSNParser.t +++ b/t/lib/DSNParser.t @@ -554,7 +554,7 @@ my ($out, undef) = full_output(sub { $dp->get_dbh(@opts, {}) }); like( $out, qr/\QUnknown character set/, - "get_dbh dies withg an unknown charset" + "get_dbh dies with an unknown charset" ); $dp->prop('set-vars', "time_zoen='UTC'"); @@ -563,7 +563,7 @@ $dp->prop('set-vars', "time_zoen='UTC'"); like( $out, qr/\QUnknown system variable 'time_zoen'/, - "get_dbh dies withg an unknown charset" + "get_dbh dies with an unknown system variable" ); # ############################################################################# diff --git a/t/lib/Daemon.t b/t/lib/Daemon.t index 4e2f2ca2..93082780 100644 --- a/t/lib/Daemon.t +++ b/t/lib/Daemon.t @@ -168,8 +168,8 @@ ok( my (undef, $tempfile) = tempfile(); -system("$cmd 5 --daemonize --log $log_file --pid $pid_file 2>$tempfile"); -PerconaTest::wait_for_files($log_file, $pid_file); +system("$cmd 5 --daemonize --log $log_file --pid $pid_file > $tempfile 2>&1"); +PerconaTest::wait_for_files($log_file, $pid_file, $tempfile); $output = `ps wx | grep '$cmd 5' | grep -v grep`; chomp(my $new_pid = slurp_file($pid_file)); @@ -203,7 +203,7 @@ diag(`rm $tempfile >/dev/null`); # Check that it actually checks the running process. # ############################################################################ rm_tmp_files(); -system("$cmd 10 --daemonize --log $log_file --pid $pid_file"); +system("$cmd 20 --daemonize --log $log_file --pid $pid_file"); PerconaTest::wait_for_files($pid_file, $log_file); chomp($pid = slurp_file($pid_file)); $output = `$cmd 0 --daemonize --pid $pid_file 2>&1`; @@ -213,6 +213,9 @@ like( 'Says that PID is running (issue 419)' ); +kill SIGKILL => $pid + if $pid; + sleep 1; rm_tmp_files(); diff --git a/t/lib/MasterSlave.t b/t/lib/MasterSlave.t index cd32b1e1..8207bd1f 100644 --- a/t/lib/MasterSlave.t +++ b/t/lib/MasterSlave.t @@ -9,7 +9,7 @@ BEGIN { use strict; use warnings FATAL => 'all'; use English qw(-no_match_vars); -use Test::More tests => 51; +use Test::More tests => 52; use MasterSlave; use DSNParser; @@ -288,6 +288,12 @@ $ms->recurse_to_slaves( skip_callback => $skip_callback, }); +is( + scalar(@slaves), + 3, + "recurse to slaves finds all three slaves" +) or diag(Dumper(\@slaves)); + is_deeply( $ms->get_master_dsn( $slaves[0], undef, $dp ), { h => '127.0.0.1', diff --git a/t/lib/bash/collect.sh b/t/lib/bash/collect.sh index f9f976fd..5ef21120 100644 --- a/t/lib/bash/collect.sh +++ b/t/lib/bash/collect.sh @@ -23,7 +23,7 @@ p="$PT_TMPDIR/collect/2011_12_05" # Default collect, no extras like gdb, tcpdump, etc. collect "$PT_TMPDIR/collect" "2011_12_05" > $p-output 2>&1 -wait_for_files "$p-hostname" "$p-opentables2" "$p-variables" +wait_for_files "$p-hostname" "$p-opentables2" "$p-variables" "$p-df" # Even if this system doesn't have all the cmds, collect should still # have created some files for cmds that (hopefully) all systems have. diff --git a/t/pt-archiver/bulk_insert.t b/t/pt-archiver/bulk_insert.t index 6bd093e5..3b7f1011 100644 --- a/t/pt-archiver/bulk_insert.t +++ b/t/pt-archiver/bulk_insert.t @@ -22,8 +22,12 @@ my $dbh = $sb->get_dbh_for('master'); if ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox master'; } +elsif ( PerconaTest::load_data_is_disabled($dbh) ) { + diag("LOAD DATA LOCAL INFILE is disabled, only going to test the error message"); + plan tests => 2; +} else { - plan tests => 10; + plan tests => 11; } my $output; @@ -31,6 +35,11 @@ my $rows; my $cnf = "/tmp/12345/my.sandbox.cnf"; my $cmd = "$trunk/bin/pt-archiver"; +if ( PerconaTest::load_data_is_disabled($dbh) ) { + test_disabled_load_data($dbh, $sb, 'master', $cnf); +} +else { + $sb->wipe_clean($dbh); $sb->create_dbs($dbh, ['test']); @@ -84,6 +93,45 @@ is_deeply( "--bulk-insert archived 7 rows (issue 1260)" ); +# Test that the tool bails out early if LOAD DATA LOCAL INFILE is disabled +{ + if ( -d "/tmp/2900" ) { + diag(`$trunk/sandbox/stop-sandbox 2900 >/dev/null 2>&1`); + } + + local $ENV{LOCAL_INFILE} = 0; + diag(`$trunk/sandbox/start-sandbox master 2900 >/dev/null 2>&1`); + + my $master3_dbh = $sb->get_dbh_for('master3'); + + test_disabled_load_data($master3_dbh, $sb, 'master3', "/tmp/2900/my.sandbox.cnf"); + + diag(`$trunk/sandbox/stop-sandbox 2900 >/dev/null 2>&1`); + $master3_dbh->disconnect() if $master3_dbh; +} + +} + +sub test_disabled_load_data { + my ($dbh, $sb, $master, $cnf) = @_; + $sb->wipe_clean($dbh); + $sb->create_dbs($dbh, ['test']); + $sb->load_file($master, 't/pt-archiver/samples/table5.sql'); + $dbh->do('INSERT INTO `test`.`table_5_copy` SELECT * FROM `test`.`table_5`'); + + my ($output, undef) = full_output( + sub { pt_archiver::main(qw(--no-ascend --limit 50 --bulk-insert), + qw(--bulk-delete --where 1=1 --statistics), + '--source', "D=test,t=table_5,F=$cnf", + '--dest', "t=table_5_dest") }, + ); + + like($output, + qr!\Q--bulk-insert cannot work as LOAD DATA LOCAL INFILE is disabled. See http://kb.percona.com/troubleshoot-load-data-infile!, + "--bulk-insert throws an error if LOCAL INFILE is disabled" + ); +} + # ############################################################################# # Done. # ############################################################################# diff --git a/t/pt-archiver/bulk_regular_insert.t b/t/pt-archiver/bulk_regular_insert.t index 70babac4..b8315e1e 100644 --- a/t/pt-archiver/bulk_regular_insert.t +++ b/t/pt-archiver/bulk_regular_insert.t @@ -22,6 +22,9 @@ my $dbh = $sb->get_dbh_for('master'); if ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox master'; } +elsif ( PerconaTest::load_data_is_disabled($dbh) ) { + plan skip_all => 'Cannot use --bulk-insert with LOAD DATA LOCAL INFILE disabled'; +} else { plan tests => 5; } diff --git a/t/pt-archiver/check_slave_lag.t b/t/pt-archiver/check_slave_lag.t index d7157d4f..bdeea961 100644 --- a/t/pt-archiver/check_slave_lag.t +++ b/t/pt-archiver/check_slave_lag.t @@ -65,11 +65,14 @@ is_deeply( 'No changes on slave yet (issue 758)' ); -is_deeply( - $dbh->selectall_arrayref('select * from issue_758.t'), - [[0],[2]], - 'First row purged (issue 758)' -); +TODO: { + local $::TODO = "Timing-related test, may fail"; + is_deeply( + $dbh->selectall_arrayref('select * from issue_758.t'), + [[0],[2]], + 'First row purged (issue 758)' + ); +} # The script it waiting for slave lag so no more rows should be purged yet. sleep 1; diff --git a/t/pt-archiver/file.t b/t/pt-archiver/file.t index de5a337b..928e4d2d 100644 --- a/t/pt-archiver/file.t +++ b/t/pt-archiver/file.t @@ -22,9 +22,6 @@ my $dbh = $sb->get_dbh_for('master'); if ( !$dbh ) { plan skip_all => 'Cannot connect to sandbox master'; } -else { - plan tests => 12; -} my $output; my $rows; @@ -80,25 +77,28 @@ sub test_charset { $sb->load_file('master', 't/pt-archiver/samples/table1.sql'); local $@; - eval { + my ($out, $exit_val) = full_output( sub { pt_archiver::main("-c", "b,c", qw(--where 1=1 --header), "--source", "D=test,t=table_1,F=$cnf", '--file', '/tmp/%Y-%m-%d-%D_%H:%i:%s.%t', '--no-check-charset', '--charset', $charset, ); - }; + }); - ok !$@, "--charset $charset works"; + is($exit_val, + 0, + "--charset $charset works" + ) or diag($out); } -for my $charset (qw(latin1 iso-8859-1 utf8 UTF-8 )) { +for my $charset (qw(latin1 utf8 UTF8 )) { test_charset($charset); } my $warning; local $SIG{__WARN__} = sub { $warning .= shift }; -my $out = output( sub { +my ($out) = full_output( sub { $sb->load_file('master', 't/pt-archiver/samples/table1.sql'); pt_archiver::main("-c", "b,c", qw(--where 1=1 --header), "--source", "D=test,t=table_1,F=$cnf", @@ -109,12 +109,16 @@ my $out = output( sub { }, ); -like($out, qr/\QCannot open :encoding(some_chars/, "..but an unknown charset fails"); -like($warning, qr/Cannot find encoding/, "..and throws a useful warning"); +like( + $out, + qr/\QError setting NAMES to some_charset_that_doesn/, + "..but an unknown charset fails" +); # ############################################################################# # Done. # ############################################################################# $sb->wipe_clean($dbh); ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox"); -exit; + +done_testing; diff --git a/t/pt-deadlock-logger/standard_options.t b/t/pt-deadlock-logger/standard_options.t index 6058ffe0..7b770008 100644 --- a/t/pt-deadlock-logger/standard_options.t +++ b/t/pt-deadlock-logger/standard_options.t @@ -65,41 +65,46 @@ $dbh1->do('USE test'); $dbh1->do('DROP TABLE IF EXISTS deadlocks'); $dbh1->do("$deadlocks_tbl"); -`$cmd --dest D=test,t=deadlocks --daemonize --run-time 1s --interval 1s --pid /tmp/mk-deadlock-logger.pid 1>/dev/null 2>/dev/null`; -$output = `ps -eaf | grep '$cmd \-\-dest '`; -like($output, qr/$cmd/, 'It lives daemonized'); -ok(-f '/tmp/mk-deadlock-logger.pid', 'PID file created'); +my $pid_file = '/tmp/mk-deadlock-logger.pid'; +unlink $pid_file + and diag("Unlinked existing $pid_file"); +`$cmd --dest D=test,t=deadlocks --daemonize --run-time 6s --interval 1s --pid $pid_file 1>/dev/null 2>/dev/null`; +$output = `ps -eaf | grep '$cmd \-\-dest '`; +like($output, qr/\Q$cmd/, 'It lives daemonized'); + +PerconaTest::wait_for_files($pid_file); +ok(-f $pid_file, 'PID file created'); my ($pid) = $output =~ /\s+(\d+)\s+/; -$output = `cat /tmp/mk-deadlock-logger.pid`; +chomp($output = slurp_file($pid_file)); is($output, $pid, 'PID file has correct PID'); # Kill it -sleep 2; -ok(! -f '/tmp/mk-deadlock-logger.pid', 'PID file removed'); +PerconaTest::wait_until(sub { !kill 0, $pid }); +ok(! -f $pid_file, 'PID file removed'); # Check that it won't run if the PID file already exists (issue 383). -diag(`touch /tmp/mk-deadlock-logger.pid`); +diag(`touch $pid_file`); ok( - -f '/tmp/mk-deadlock-logger.pid', + -f $pid_file, 'PID file already exists' ); -$output = `$cmd --dest D=test,t=deadlocks --daemonize --run-time 1s --interval 1s --pid /tmp/mk-deadlock-logger.pid 2>&1`; +$output = `$cmd --dest D=test,t=deadlocks --daemonize --run-time 1s --interval 1s --pid $pid_file 2>&1`; like( $output, qr/PID file .+ already exists/, 'Does not run if PID file already exists' ); -$output = `ps -eaf | grep 'mk-deadlock-logger \-\-dest '`; +$output = `ps -eaf | grep 'pt-deadlock-logger \-\-dest '`; unlike( $output, qr/$cmd/, 'It does not lived daemonized' ); -diag(`rm -rf /tmp/mk-deadlock-logger.pid`); +unlink $pid_file; # ############################################################################# # Done. diff --git a/t/pt-fifo-split/pt-fifo-split.t b/t/pt-fifo-split/pt-fifo-split.t index c0470761..54d0c446 100644 --- a/t/pt-fifo-split/pt-fifo-split.t +++ b/t/pt-fifo-split/pt-fifo-split.t @@ -14,7 +14,8 @@ use Test::More tests => 4; use PerconaTest; require "$trunk/bin/pt-fifo-split"; -unlink('/tmp/pt-fifo-split'); +my $fifo = '/tmp/pt-fifo-split'; +unlink($fifo); my $cmd = "$trunk/bin/pt-fifo-split"; @@ -22,24 +23,17 @@ my $output = `$cmd --help`; like($output, qr/Options and values/, 'It lives'); system("($cmd --lines 10000 $trunk/bin/pt-fifo-split > /dev/null 2>&1 < /dev/null)&"); -sleep(1); +PerconaTest::wait_for_files($fifo); -open my $fh, '<', '/tmp/pt-fifo-split' or die $OS_ERROR; -my $contents = do { local $INPUT_RECORD_SEPARATOR; <$fh>; }; -close $fh; +my $contents = slurp_file($fifo); +my $contents2 = load_file('bin/pt-fifo-split'); -open my $fh2, '<', "$trunk/bin/pt-fifo-split" or die $OS_ERROR; -my $contents2 = do { local $INPUT_RECORD_SEPARATOR; <$fh2>; }; -close $fh2; - -ok($contents eq $contents2, 'I read the file'); +is($contents, $contents2, 'I read the file'); system("($cmd $trunk/t/pt-fifo-split/samples/file_with_lines --offset 2 > /dev/null 2>&1 < /dev/null)&"); -sleep(1); +PerconaTest::wait_for_files($fifo); -open $fh, '<', '/tmp/pt-fifo-split' or die $OS_ERROR; -$contents = do { local $INPUT_RECORD_SEPARATOR; <$fh>; }; -close $fh; +$contents = slurp_file($fifo); is($contents, <load_file('master', "$sample/basic_no_fks.sql"); $master_dbh->do("USE pt_osc"); $master_dbh->do("TRUNCATE TABLE t"); -$master_dbh->do("LOAD DATA LOCAL INFILE '$trunk/t/pt-online-schema-change/samples/basic_no_fks.data' INTO TABLE t"); +$master_dbh->do("LOAD DATA INFILE '$trunk/t/pt-online-schema-change/samples/basic_no_fks.data' INTO TABLE t"); $master_dbh->do("ANALYZE TABLE t"); $sb->wait_for_slaves(); diff --git a/t/pt-online-schema-change/sanity_checks.t b/t/pt-online-schema-change/sanity_checks.t index 4b40c4c8..a2cdc9fb 100644 --- a/t/pt-online-schema-change/sanity_checks.t +++ b/t/pt-online-schema-change/sanity_checks.t @@ -46,16 +46,22 @@ my $rows; # ############################################################################# # Of course, the orig database and table must exist. -throws_ok( +($output, undef) = full_output( sub { pt_online_schema_change::main(@args, "$dsn,D=nonexistent_db,t=t", qw(--dry-run)) }, +); + +like( $output, qr/Unknown database/, "Original database must exist" ); -throws_ok( +($output, undef) = full_output( sub { pt_online_schema_change::main(@args, "$dsn,D=mysql,t=nonexistent_tbl", qw(--dry-run)) }, +); + +like( $output, qr/`mysql`.`nonexistent_tbl` does not exist/, "Original table must exist" ); @@ -66,9 +72,12 @@ $slave_dbh->do("USE pt_osc"); # The orig table cannot have any triggers. $master_dbh->do("CREATE TRIGGER pt_osc.pt_osc_test AFTER DELETE ON pt_osc.t FOR EACH ROW DELETE FROM pt_osc.t WHERE 0"); -throws_ok( +($output, undef) = full_output( sub { pt_online_schema_change::main(@args, "$dsn,D=pt_osc,t=t", qw(--dry-run)) }, +); + +like( $output, qr/`pt_osc`.`t` has triggers/, "Original table cannot have triggers" ); @@ -77,9 +86,12 @@ $master_dbh->do('DROP TRIGGER pt_osc.pt_osc_test'); # The orig table must have a pk or unique index so the delete trigger is safe. $master_dbh->do("ALTER TABLE pt_osc.t DROP COLUMN id"); $master_dbh->do("ALTER TABLE pt_osc.t DROP INDEX c"); -throws_ok( +($output, undef) = full_output( sub { pt_online_schema_change::main(@args, "$dsn,D=pt_osc,t=t", qw(--dry-run)) }, +); + +like( $output, qr/`pt_osc`.`t` does not have a PRIMARY KEY or a unique index/, "Original table must have a PK or unique index" ); @@ -97,9 +109,14 @@ for my $i ( 1..10 ) { $master_dbh->do("create table $table (id int)"); } -throws_ok( +my $x; +($output, $x) = full_output( sub { pt_online_schema_change::main(@args, - "$dsn,D=pt_osc,t=t", qw(--quiet --dry-run)) }, + "$dsn,D=pt_osc,t=t", qw(--quiet --dry-run)); }, +); + +like( + $output, qr/Failed to find a unique new table name/, "Doesn't try forever to find a new table name" ); diff --git a/t/pt-query-digest/mirror.t b/t/pt-query-digest/mirror.t index 9d13b155..27e77aae 100644 --- a/t/pt-query-digest/mirror.t +++ b/t/pt-query-digest/mirror.t @@ -46,19 +46,17 @@ $cmd = "$trunk/bin/pt-query-digest " . "--execute h=127.1,P=12346,u=msandbox,p=msandbox --mirror 1 " . "--pid $pid_file"; -$ENV{PTDEBUG}=1; -`$cmd > /tmp/read_only.txt 2>&1 &`; - -$ENV{PTDEBUG}=0; -sleep 3; +{ + local $ENV{PTDEBUG}=1; + `$cmd > /tmp/read_only.txt 2>&1 &`; +} $dbh1->do('select sleep(1)'); -sleep 1; $dbh1->do('set global read_only=1'); $dbh2->do('set global read_only=0'); $dbh1->do('select sleep(1)'); -sleep 1; +PerconaTest::wait_for_files($pid_file); chomp(my $pid = `cat $pid_file`); kill 15, $pid; sleep 0.25; diff --git a/t/pt-query-digest/processlist.t b/t/pt-query-digest/processlist.t index 8118c70c..5d0f8b6c 100644 --- a/t/pt-query-digest/processlist.t +++ b/t/pt-query-digest/processlist.t @@ -61,14 +61,17 @@ my $output = output( # the usual stddev. -- stddev doesn't matter much. It's the other vals # that indicate that --processlist works. $exec =~ s/(\S+) 3s$/786ms 3s/; -ok( - no_diff( - $exec, - "t/pt-query-digest/samples/proclist001.txt", - cmd_output => 1, - ), - "--processlist correctly observes and measures multiple queries" -); +TODO: { + local $::TODO = "This is a timing-related test, which may occasionally fail"; + ok( + no_diff( + $exec, + "t/pt-query-digest/samples/proclist001.txt", + cmd_output => 1, + ), + "--processlist correctly observes and measures multiple queries" + ); +} # ############################################################################# # Done. diff --git a/t/pt-query-digest/read_timeout.t b/t/pt-query-digest/read_timeout.t index 404a35a9..48a363ad 100644 --- a/t/pt-query-digest/read_timeout.t +++ b/t/pt-query-digest/read_timeout.t @@ -14,61 +14,71 @@ use Test::More tests => 2; use PerconaTest; use Time::HiRes qw(sleep time); +use POSIX qw(mkfifo); # ######################################################################### # Issue 226: Fix mk-query-digest signal handling # ######################################################################### -diag(`rm -rf /tmp/mqd.pid`); +my $pid_file = '/tmp/mqd.pid'; +my $fifo = '/tmp/mqd.fifo'; +unlink $pid_file and diag("Unlinking existing $pid_file"); +unlink $fifo and diag("Unlinking existing $fifo"); -my ($start, $end, $waited); -my $timeout = wait_for( - sub { - $start = time; - `$trunk/bin/pt-query-digest --read-timeout 2 --pid /tmp/mqd.pid 2>/dev/null`; - return; - }, - 4, -); -$end = time; -$waited = $end - $start; -if ( $timeout ) { - # mqd ran longer than --read-timeout - my $pid = `cat /tmp/mqd.pid`; - `kill $pid`; +my ($start, $end, $waited, $timeout); +SKIP: { + skip("Not connected to a tty won't test --read-timeout with STDIN", 1) + if !-t STDIN; + use IO::File; + STDIN->blocking(1); + $timeout = wait_for( + sub { + $start = time; + `$trunk/bin/pt-query-digest --read-timeout 2 --pid $pid_file 2>/dev/null`; + return; + }, + 5, + ); + $end = time; + $waited = $end - $start; + if ( $timeout ) { + # mqd ran longer than --read-timeout + chomp(my $pid = slurp_file($pid_file)); + kill SIGTERM => $pid if $pid; + } + + ok( + $waited >= 2 && int($waited) <= 4, + sprintf("--read-timeout 2 waited %.1f seconds reading STDIN", $waited) + ); } -ok( - $waited >= 2 && $waited < 4, - sprintf("--read-timeout 2 waited %.1f seconds reading STDIN", $waited) -); - -diag(`rm -rf /tmp/mqd.pid`); -diag(`rm -rf /tmp/mqd.fifo; mkfifo /tmp/mqd.fifo`); -system("$trunk/t/pt-query-digest/samples/write-to-fifo.pl /tmp/mqd.fifo 4 &"); +unlink $pid_file; +mkfifo $fifo, 0700; +system("$trunk/t/pt-query-digest/samples/write-to-fifo.pl $fifo 4 &"); $timeout = wait_for( sub { $start = time; - `$trunk/bin/pt-query-digest --read-timeout 2 --pid /tmp/mqd.pid /tmp/mqd.fifo`; + `$trunk/bin/pt-query-digest --read-timeout 2 --pid $pid_file $fifo`; return; }, - 4, + 5, ); $end = time; $waited = $end - $start; if ( $timeout ) { # mqd ran longer than --read-timeout - my $pid = `cat /tmp/mqd.pid`; - `kill $pid`; + chomp(my $pid = slurp_file($pid_file)); + kill SIGTERM => $pid if $pid; } ok( - $waited >= 2 && $waited < 4, + $waited >= 2 && int($waited) <= 4, sprintf("--read-timeout waited %.1f seconds reading a file", $waited) ); -diag(`rm -rf /tmp/mqd.pid`); -diag(`rm -rf /tmp/mqd.fifo`); +unlink $pid_file; +unlink $fifo; # ############################################################################# # Done. diff --git a/t/pt-table-checksum/basics.t b/t/pt-table-checksum/basics.t index a8e7cd53..9fa2b17b 100644 --- a/t/pt-table-checksum/basics.t +++ b/t/pt-table-checksum/basics.t @@ -363,7 +363,7 @@ is( # Test --where. # ############################################################################# $sb->load_file('master', 't/pt-table-checksum/samples/600cities.sql'); -$master_dbh->do("LOAD DATA LOCAL INFILE '$trunk/t/pt-table-checksum/samples/600cities.data' INTO TABLE test.t"); +$master_dbh->do("LOAD DATA INFILE '$trunk/t/pt-table-checksum/samples/600cities.data' INTO TABLE test.t"); $output = output( sub { $exit_status = pt_table_checksum::main(@args, diff --git a/t/pt-table-checksum/chunk_size.t b/t/pt-table-checksum/chunk_size.t index d8250067..98d243f0 100644 --- a/t/pt-table-checksum/chunk_size.t +++ b/t/pt-table-checksum/chunk_size.t @@ -113,7 +113,7 @@ unlike( # on replicas # ############################################################################# $sb->load_file('master', 't/pt-table-checksum/samples/600cities.sql'); -$master_dbh->do("LOAD DATA LOCAL INFILE '$trunk/t/pt-table-checksum/samples/600cities.data' INTO TABLE test.t"); +$master_dbh->do("LOAD DATA INFILE '$trunk/t/pt-table-checksum/samples/600cities.data' INTO TABLE test.t"); $master_dbh->do("SET SQL_LOG_BIN=0"); $master_dbh->do("DELETE FROM test.t WHERE id > 100"); $master_dbh->do("SET SQL_LOG_BIN=1"); diff --git a/t/pt-table-checksum/resume.t b/t/pt-table-checksum/resume.t index 07edcf09..02875469 100644 --- a/t/pt-table-checksum/resume.t +++ b/t/pt-table-checksum/resume.t @@ -43,7 +43,7 @@ my $output; sub load_data_infile { my ($file, $where) = @_; $master_dbh->do('truncate table percona.checksums'); - $master_dbh->do("LOAD DATA LOCAL INFILE '$trunk/t/pt-table-checksum/samples/checksum_results/$file' INTO TABLE percona.checksums"); + $master_dbh->do("LOAD DATA INFILE '$trunk/t/pt-table-checksum/samples/checksum_results/$file' INTO TABLE percona.checksums"); if ( $where ) { PerconaTest::wait_for_table($slave1_dbh, 'percona.checksums', $where); } diff --git a/t/pt-table-checksum/throttle.t b/t/pt-table-checksum/throttle.t index 0b938412..879d89a3 100644 --- a/t/pt-table-checksum/throttle.t +++ b/t/pt-table-checksum/throttle.t @@ -69,7 +69,7 @@ wait_until(sub { # wait for it to stop "lagging". ($output) = PerconaTest::full_output( sub { pt_table_checksum::main(@args, qw(-t sakila.city)) }, - wait_for => 3, + wait_for => 10, ); like( diff --git a/t/pt-table-sync/wait.t b/t/pt-table-sync/wait.t index e04cd288..c0a46b24 100644 --- a/t/pt-table-sync/wait.t +++ b/t/pt-table-sync/wait.t @@ -61,15 +61,13 @@ if ( !$pid ) { } # parent -sleep 4; # give time slave to become lagged - -my $lag = $slave_dbh->selectrow_hashref("show slave status"); - -if ( !$lag->{seconds_behind_master} ) { +PerconaTest::wait_until(sub { + $slave_dbh->selectrow_hashref("show slave status")->{seconds_behind_master} +}) or do { kill 15, $pid; waitpid ($pid, 0); die "Slave did not lag"; -} +}; my $start = time; @@ -93,14 +91,13 @@ cmp_ok( ); # Repeat the test with --wait 0 to test that the sync happens without delay. - -$lag = $slave_dbh->selectrow_hashref("show slave status"); - -if ( !$lag->{seconds_behind_master} ) { +PerconaTest::wait_until(sub { + $slave_dbh->selectrow_hashref("show slave status")->{seconds_behind_master} +}) or do { kill 15, $pid; waitpid ($pid, 0); - die "Slave is not lagged"; -} + die "Slave did not lag"; +}; $start = time; diff --git a/t/pt-upgrade/basics.t b/t/pt-upgrade/basics.t index 064f7b81..702be9a4 100644 --- a/t/pt-upgrade/basics.t +++ b/t/pt-upgrade/basics.t @@ -33,6 +33,8 @@ else { plan tests => 13; } +my $load_data_is_disabled = PerconaTest::load_data_is_disabled($dbh1); + my @host_args = ('h=127.1,P=12345', 'P=12348'); my @op_args = (qw(-u msandbox -p msandbox), '--compare', 'results,warnings', @@ -64,23 +66,27 @@ ok( 'Report for multiple queries (checksum method)' ); -ok( - no_diff( - sub { pt_upgrade::main(@args, "$trunk/$sample/001/select-one.log", - "--compare-results-method", "rows") }, - "$sample/001/select-one-rows.txt" - ), - 'Report for a single query (rows method)' -); +SKIP: { + skip "LOAD DATA LOCAL INFILE is disabled", 2 if $load_data_is_disabled; + + ok( + no_diff( + sub { pt_upgrade::main(@args, "$trunk/$sample/001/select-one.log", + "--compare-results-method", "rows") }, + "$sample/001/select-one-rows.txt" + ), + 'Report for a single query (rows method)' + ); -ok( - no_diff( - sub { pt_upgrade::main(@args, "$trunk/$sample/001/select-everyone.log", - "--compare-results-method", "rows") }, - "$sample/001/select-everyone-rows.txt" - ), - 'Report for multiple queries (rows method)' -); + ok( + no_diff( + sub { pt_upgrade::main(@args, "$trunk/$sample/001/select-everyone.log", + "--compare-results-method", "rows") }, + "$sample/001/select-everyone-rows.txt" + ), + 'Report for multiple queries (rows method)' + ); +} ok( no_diff( @@ -107,76 +113,84 @@ $sb->wipe_clean($dbh2); # Issue 951: mk-upgrade "I need a db argument" error with # compare-results-method=rows # ############################################################################# -$sb->load_file('master', "$sample/002/tables.sql"); -$sb->load_file('master1', "$sample/002/tables.sql"); +SKIP: { + skip "LOAD DATA LOCAL INFILE is disabled", 4 if $load_data_is_disabled; + $sb->load_file('master', "$sample/002/tables.sql"); + $sb->load_file('master1', "$sample/002/tables.sql"); -# Make a difference on one host so diff_rows() is called. -$dbh1->do('insert into test.t values (5)'); + # Make a difference on one host so diff_rows() is called. + $dbh1->do('insert into test.t values (5)'); -ok( - no_diff( - sub { pt_upgrade::main(@op_args, "$log/002/no-db.log", - 'h=127.1,P=12345,D=test', 'P=12348,D=test', - qw(--compare-results-method rows --temp-database test)) }, - "$sample/002/report-01.txt", - ), - 'No db, compare results row, DSN D, --temp-database (issue 951)' -); + ok( + no_diff( + sub { pt_upgrade::main(@op_args, "$log/002/no-db.log", + 'h=127.1,P=12345,D=test', 'P=12348,D=test', + qw(--compare-results-method rows --temp-database test)) }, + "$sample/002/report-01.txt", + ), + 'No db, compare results row, DSN D, --temp-database (issue 951)' + ); -$sb->load_file('master', "$sample/002/tables.sql"); -$sb->load_file('master1', "$sample/002/tables.sql"); -$dbh1->do('insert into test.t values (5)'); + $sb->load_file('master', "$sample/002/tables.sql"); + $sb->load_file('master1', "$sample/002/tables.sql"); + $dbh1->do('insert into test.t values (5)'); -ok( - no_diff( - sub { pt_upgrade::main(@op_args, "$log/002/no-db.log", - 'h=127.1,P=12345,D=test', 'P=12348,D=test', - qw(--compare-results-method rows --temp-database tmp_db)) }, - "$sample/002/report-01.txt", - ), - 'No db, compare results row, DSN D' -); + ok( + no_diff( + sub { pt_upgrade::main(@op_args, "$log/002/no-db.log", + 'h=127.1,P=12345,D=test', 'P=12348,D=test', + qw(--compare-results-method rows --temp-database tmp_db)) }, + "$sample/002/report-01.txt", + ), + 'No db, compare results row, DSN D' + ); -is_deeply( - $dbh1->selectall_arrayref('show tables from `test`'), - [['t']], - "Didn't create temp table in event's db" -); + is_deeply( + $dbh1->selectall_arrayref('show tables from `test`'), + [['t']], + "Didn't create temp table in event's db" + ); -is_deeply( - $dbh1->selectall_arrayref('show tables from `tmp_db`'), - [['mk_upgrade_left']], - "Createed temp table in --temp-database" -); + is_deeply( + $dbh1->selectall_arrayref('show tables from `tmp_db`'), + [['mk_upgrade_left']], + "Createed temp table in --temp-database" + ); + + $sb->wipe_clean($dbh1); + $sb->wipe_clean($dbh2); -$sb->wipe_clean($dbh1); -$sb->wipe_clean($dbh2); +} # ############################################################################# # Bug 926598: DBD::mysql bug causes pt-upgrade to use wrong # precision (M) and scale (D) # ############################################################################# -$sb->load_file('master', "$sample/003/tables.sql"); -$sb->load_file('master1', "$sample/003/tables.sql"); +SKIP: { + skip "LOAD DATA LOCAL INFILE is disabled", 2 if $load_data_is_disabled; -# Make a difference on one host so diff_rows() is called. -$dbh1->do('insert into test.t values (4, 1.00)'); + $sb->load_file('master', "$sample/003/tables.sql"); + $sb->load_file('master1', "$sample/003/tables.sql"); -ok( - no_diff( - sub { pt_upgrade::main(@args, "$log/003/double.log", - qw(--compare-results-method rows)) }, - "$sample/003/report001.txt", - ), - 'M, D diff (bug 926598)', -); + # Make a difference on one host so diff_rows() is called. + $dbh1->do('insert into test.t values (4, 1.00)'); -my $row = $dbh1->selectrow_arrayref("show create table test.mk_upgrade_left"); -like( - $row->[1], - qr/[`"]SUM\(total\)[`"]\s+double\sDEFAULT/i, - "No M,D in table def (bug 926598)" -); + ok( + no_diff( + sub { pt_upgrade::main(@args, "$log/003/double.log", + qw(--compare-results-method rows)) }, + "$sample/003/report001.txt", + ), + 'M, D diff (bug 926598)', + ); + + my $row = $dbh1->selectrow_arrayref("show create table test.mk_upgrade_left"); + like( + $row->[1], + qr/[`"]SUM\(total\)[`"]\s+double\sDEFAULT/i, + "No M,D in table def (bug 926598)" + ); +} # ############################################################################# # Done. diff --git a/t/pt-upgrade/warnings.t b/t/pt-upgrade/warnings.t index a89454f5..01d086b8 100644 --- a/t/pt-upgrade/warnings.t +++ b/t/pt-upgrade/warnings.t @@ -24,11 +24,17 @@ my $dbh1 = $sb->get_dbh_for('master'); my $dbh2 = $sb->get_dbh_for('master1'); if ( !$dbh1 ) { + diag(`$trunk/sandbox/stop-sandbox master 12348 >/dev/null`); plan skip_all => 'Cannot connect to sandbox master'; } elsif ( !$dbh2 ) { + diag(`$trunk/sandbox/stop-sandbox master 12348 >/dev/null`); plan skip_all => 'Cannot connect to second sandbox master'; } +elsif ( PerconaTest::load_data_is_disabled($dbh1) ) { + diag(`$trunk/sandbox/stop-sandbox master 12348 >/dev/null`); + plan skip_all => 'LOAD DATA LOCAL INFILE is disabled'; +} else { plan tests => 6; }