Update progress.t, option_sanity.t, and standard_options.t. Make test env always have slave2 (12347, slave of 12346). Add PerconaTest::count_checksum_results(). Add util/wait-to-exec.

This commit is contained in:
Daniel Nichter
2011-10-14 11:45:11 -06:00
parent 48fb4baa7c
commit 4ad88ddd93
11 changed files with 294 additions and 73 deletions

View File

@@ -224,11 +224,11 @@ sub wait_until {
my $slept = 0;
while ( $slept <= $max_t ) {
return if $code->();
return 1 if $code->();
sleep $t;
$slept += $t;
}
return;
return 0;
}
# Wait t seconds for code to return.
@@ -558,6 +558,41 @@ sub test_bash_tool {
return;
}
my %checksum_result_col = (
ts => 0,
errors => 1,
diffs => 2,
rows => 3,
chunks => 4,
skipped => 5,
time => 6,
table => 7,
);
sub count_checksum_results {
my ($output, $column, $table) = @_;
my (@res) = map {
my $line = $_;
my (@cols) = $line =~ m/(\S+)/g;
\@cols;
}
grep {
my $line = $_;
if ( !$table ) {
$line;
}
else {
$line =~ m/$table$/m ? $line : '';
}
}
grep { m/^\d+\-\d+T/ } split /\n/, $output;
my $colno = $checksum_result_col{lc $column};
die "Invalid checksum result column: $column" unless defined $colno;
my $total = 0;
map { $total += $_->[$colno] } @res;
return $total;
}
1;
}
# ###########################################################################

View File

@@ -46,7 +46,4 @@ exit_status=$((exit_status | $?))
/tmp/$PORT/use < sakila-db/sakila-data.sql
exit_status=$((exit_status | $?))
$PERCONA_TOOLKIT_BRANCH/sandbox/test-env reset
exit_status=$((exit_status | $?))
exit $exit_status

View File

@@ -291,6 +291,7 @@ case $opt in
exit_status=$?
if [ $exit_status -eq 0 ]; then
./start-sandbox slave 12346 12345
./start-sandbox slave 12347 12346
exit_status=$?
if [ "$version" != "4.0" ] && [ "$version" != "4.1" ]; then
if [ $? -eq 0 ]; then
@@ -353,11 +354,18 @@ case $opt in
# don't replicate to new sandbox servers. This makes creating new
# sandbox servers a lot faster. There's no check if this works or
# not, so... yeah.
/tmp/12345/use -e "RESET MASTER"
/tmp/12346/use -e "RESET MASTER"
/tmp/12347/use -e "STOP SLAVE"
/tmp/12346/use -e "STOP SLAVE"
/tmp/12346/use -e "RESET MASTER"
/tmp/12345/use -e "RESET MASTER"
/tmp/12347/use -e "change master to master_host='127.0.0.1', master_user='msandbox', master_password='msandbox', master_port=12346, master_log_file='mysql-bin.000001', master_log_pos=0"
/tmp/12346/use -e "change master to master_host='127.0.0.1', master_user='msandbox', master_password='msandbox', master_port=12345, master_log_file='mysql-bin.000001', master_log_pos=0"
/tmp/12347/use -e "START SLAVE"
/tmp/12346/use -e "START SLAVE"
exit_status=0
;;
version)

View File

@@ -42,21 +42,9 @@ $sb->load_file('master', 't/pt-table-checksum/samples/issue_94.sql');
PerconaTest::wait_for_table($slave_dbh, 'test.issue_94', 'a=11');
$slave_dbh->do("update test.issue_94 set c=''");
sub get_diffs {
my ($output) = @_;
my (@diffs) = $output =~ m/
^\S+\s+ # TS
\d+\s+ # ERRORS
(\d+) # DIFFS
/gmx;
my $total_diffs = 0;
map { $total_diffs += $_ } @diffs;
return $total_diffs;
}
$output = output(
sub { pt_table_checksum::main(@args, qw(-d test -t issue_94)) },
trf => \&get_diffs,
trf => sub { return PerconaTest::count_checksum_results(@_, 'DIFFS') },
);
is(
$output,
@@ -67,7 +55,7 @@ is(
$output = output(
sub { pt_table_checksum::main(@args, qw(-d test -t issue_94),
qw(--ignore-columns c)) },
trf => \&get_diffs,
trf => sub { return PerconaTest::count_checksum_results(@_, 'DIFFS') },
);
is(
$output,

View File

@@ -9,26 +9,132 @@ BEGIN {
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More tests => 2;
use Test::More tests => 16;
use PerconaTest;
require "$trunk/bin/pt-table-checksum";
my $output;
# Test DSN value inheritance
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate table`;
# Calling the tool pt_table_checksum::main() doesn't work when we're
# dealing with cmd line option error and --help because OptionParser
# exits on such things which would cause this test to exit too.
# ############################################################################
# Check default values for some options to ensure something wasn't
# changed accidentally. A lot of tests rely on these defaults, so
# if they change, it can have weird side-effects.
# ############################################################################
$output = `$trunk/bin/pt-table-checksum h=127.1 --help`;
like(
$output,
qr/^ --check-replication-filters\s+TRUE$/m,
"Default --check-replication-filters=TRUE"
);
like(
$output,
qr/^ --create-replicate-table\s+TRUE$/m,
"Default --create-replicate-table=TRUE"
);
like(
$output,
qr/^ --empty-replicate-table\s+TRUE$/m,
"Default --empty-replicate-table=TRUE"
);
like(
$output,
qr/^ --explain\s+0$/m,
"Default --explain=0"
);
like(
$output,
qr/^ --host\s+localhost$/m,
"Default --host=localhost"
);
like(
$output,
qr/^ --lock-wait-timeout\s+1$/m,
"Default --lock-wait-timeout=1"
);
like(
$output,
qr/^ --max-lag\s+1$/m,
"Default --max-lag=1"
);
like(
$output,
qr/^ --quiet\s+0$/m,
"Default --quiet=0"
);
like(
$output,
qr/^ --recheck\s+TRUE$/m,
"Default --recheck=TRUE"
);
like(
$output,
qr/^ --replicate\s+percona\.checksums$/m,
"Default --replicate=percona.checksums"
);
like(
$output,
qr/^ --replicate-check\s+TRUE$/m,
"Default --replicate-check=TRUE"
);
# ############################################################################
# Check opts that disable other opts.
# ############################################################################
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --explain`;
like(
$output,
qr/^ --empty-replicate-table\s+FALSE$/m,
"--explain disables --empty-replicate-table"
);
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --resume`;
like(
$output,
qr/^ --empty-replicate-table\s+FALSE$/m,
"--resume disables --empty-replicate-table"
);
$output = `$trunk/bin/pt-table-checksum h=127.1 --help --quiet`;
like(
$output,
qr/^ --progress\s+\(No value\)$/m,
"--quiet disables --progress"
);
# ############################################################################
# Only 1 DSN should be allowed on the command line; no extra args.
# ############################################################################
$output = `$trunk/bin/pt-table-checksum h=127.1 h=host1 h=host2`;
like(
$output,
qr/More than one host specified; only one allowed/,
"Only one DSN allowed on the command line"
);
# ############################################################################
# --replicate table must be db-qualified.
# ############################################################################
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate checksums`;
like(
$output,
qr/--replicate table must be database-qualified/,
"--replicate table must be db-qualified"
);
$output = `$trunk/bin/pt-table-checksum h=127.1 --replicate test.checksum --throttle-method foo`;
like(
$output,
qr/Invalid --throttle-method: foo/,
"Invalid --throttle-method"
"--replicate table must be database-qualified"
);
# #############################################################################

View File

@@ -15,10 +15,6 @@ use PerconaTest;
use Sandbox;
require "$trunk/bin/pt-table-checksum";
diag(`$trunk/sandbox/test-env reset`);
diag(`$trunk/sandbox/stop-sandbox 12347 >/dev/null`);
diag(`$trunk/sandbox/start-sandbox slave 12347 12346 >/dev/null`);
my $dp = new DSNParser(opts=>$dsn_opts);
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
my $master_dbh = $sb->get_dbh_for('master');
@@ -38,17 +34,21 @@ else {
plan tests => 3;
}
# Must have empty checksums table for these tests.
$master_dbh->do('drop table if exists percona.checksums');
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
# so we need to specify --lock-wait-timeout=3 else the tool will die.
my $master_dsn = 'h=127.1,P=12345,u=msandbox,p=msandbox';
my @args = ($master_dsn, qw(--lock-wait-timeout 3),
'--progress', 'time,1');
my $output;
my $row;
my $cnf ='/tmp/12345/my.sandbox.cnf';
my @args = (qw(--replicate test.checksum --empty-replicate-table -d test -t resume -q), '-F', $cnf, 'h=127.1', '--progress', 'time,1');
$sb->create_dbs($master_dbh, [qw(test)]);
$sb->load_file('master', 't/pt-table-checksum/samples/checksum_tbl.sql');
# We're not using resume table for anything specific, we just need
# any table to checksum.
$sb->load_file('master', 't/pt-table-checksum/samples/resume.sql');
my $scripts = "$trunk/t/pt-table-checksum/scripts/";
# ############################################################################
# Tool should check all slaves' lag, so slave2, not just slave1.
# ############################################################################
wait_until( # slaves aren't lagging
sub {
$row = $slave1_dbh->selectrow_hashref('show slave status');
@@ -56,47 +56,40 @@ wait_until( # slaves aren't lagging
$row = $slave2_dbh->selectrow_hashref('show slave status');
return 0 if $row->{Seconds_Behind_Master};
return 1;
}, 0.5, 10);
}
) or die "Slaves are still lagging";
$slave1_dbh->do('stop slave sql_thread');
$row = $slave1_dbh->selectrow_hashref('show slave status');
is(
$row->{slave_sql_running},
'No',
'Stopped slave SQL thread on slave1'
);
# This big fancy command waits until it sees the checksum for sakila.city
# in the repl table on the master, then it stops slave2 for 2 seconds,
# then starts it again.
system("$trunk/util/wait-to-exec '$scripts/wait-for-chunk.sh 12345 sakila city 1' '$scripts/exec-wait-exec.sh 12347 \"stop slave sql_thread\" 2 \"start slave sql_thread\"' 3 >/dev/null &");
$slave2_dbh->do('stop slave sql_thread');
$row = $slave2_dbh->selectrow_hashref('show slave status');
is(
$row->{slave_sql_running},
'No',
'Stopped slave SQL thread on slave2'
);
system("sleep 2 && /tmp/12346/use -e 'start slave sql_thread' >/dev/null 2>/dev/null &");
system("sleep 3 && /tmp/12347/use -e 'start slave sql_thread' >/dev/null 2>/dev/null &");
# This time we do not need to capture STDERR because mk-table-checksum
# should see slave2 come alive in 2 seconds then return before wait_for
# dies.
$output = output(
sub { pt_table_checksum::main(@args); },
sub { pt_table_checksum::main(@args, qw(-d sakila)); },
stderr => 1,
);
like(
$output,
qr/Waiting for slave.+?Still waiting/s,
"Progress reports while waiting for slaves"
qr/Replica h=127.0.0.1,P=12347 is stopped/,
"--progress for slave lag"
);
like(
$output,
qr/sakila.store$/m,
"Checksumming continues after waiting for slave lag"
);
is(
PerconaTest::count_checksum_results($output, 'errors'),
0,
"No errors after waiting for slave lag"
);
# #############################################################################
# Done.
# #############################################################################
diag(`$trunk/sandbox/stop-sandbox 12347 >/dev/null`);
diag(`/tmp/12346/stop >/dev/null`); # Start/stop clears SHOW SLAVE HOSTS.
diag(`/tmp/12346/start >/dev/null`);
$sb->wipe_clean($master_dbh);
diag(`$trunk/sandbox/test-env reset >/dev/null`);
exit;

View File

@@ -3,3 +3,8 @@ TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
sakila.city 1 0 1 PRIMARY 1 100
sakila.city 6 0 1 PRIMARY 501 600
Differences on h=127.0.0.1,P=12347
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
sakila.city 1 0 1 PRIMARY 1 100
sakila.city 6 0 1 PRIMARY 501 600

View File

@@ -0,0 +1,10 @@
#!/bin/sh
port=$1
query1=$2
t=$3
query2=$4
/tmp/$port/use -e "$query1"
sleep $t
/tmp/$port/use -e "$query2"

View File

@@ -0,0 +1,8 @@
#!/bin/sh
port=$1
db=$2
tbl=$3
chunk=$4
/tmp/$port/use -e "select 1 from percona.checksums where db='$db' and tbl='$tbl' and chunk=$chunk" 2>/dev/null | grep -q 1 2>/dev/null

View File

@@ -27,7 +27,7 @@ elsif ( !$slave_dbh ) {
plan skip_all => 'Cannot connect to sandbox slave1';
}
else {
plan tests => 4;
plan tests => 5;
}
# The sandbox servers run with lock_wait_timeout=3 and it's not dynamic
@@ -36,6 +36,37 @@ my @args = (qw(--lock-wait-timeout 3 --explain --tables sakila.country));
my $cnf = "/tmp/12345/my.sandbox.cnf";
my $pid_file = "/tmp/mk-table-checksum-test.pid";
my $output;
my $exit_status;
# ############################################################################
# Tool should connect to localhost without any options.
# ############################################################################
# This may not work because the sandbox servers aren't on localhost,
# but if your box has MySQL running on localhost then maybe it will,
# so we'll account for both of these possibilities.
eval {
$exit_status = pt_table_checksum::main(@args);
};
if ( $EVAL_ERROR ) {
# It's ok that this fails. It means that your box, like mine, doesn't
# have MySQL on localhost:3306:/tmp/mysql.socket/etc.
like(
$EVAL_ERROR,
qr/connect\(';host=localhost;/,
'Default DSN is h=localhost'
);
}
else {
# Apparently, your box is running MySQL on default ports. That
# means the tool ran, so it should run without errors.
is(
$exit_status,
0,
'Default DSN is h=localhost'
);
}
# ############################################################################
# DSN should inherit connection options (--port, etc.)

40
util/wait-to-exec Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Time::HiRes qw(sleep time);
if ( !@ARGV || @ARGV < 2 ) {
print STDERR "Usage: wait-to-exec WAIT EXEC [RUNTIME [INTERVAL]]\n",
"When the WAIT script exits 0, execute the EXEC script.\n";
exit 1;
}
my ($wait, $exec, $runtime, $interval) = @ARGV;
$runtime ||= 1.0;
$interval ||= 0.1;
#warn "wait: $wait\n";
#warn "exec: $exec\n";
my $t_start = time;
while ( time - $t_start < $runtime ) {
if ( exit_status($wait) ) {
sleep $interval;
}
else {
# exec does not return; this script becomes the exec process.
exec($exec);
}
}
warn "Never observed wait condition";
exit 1;
sub exit_status {
my ($wait) = @_;
system($wait);
# Like grep, exit status 0 means "match found", so stop waiting.
my $exit_status = $? >> 8;
return $exit_status;
}