From bf1197f2d555810ce7db06195c93216fd3d50f27 Mon Sep 17 00:00:00 2001 From: Greg Sabino Mullane Date: Tue, 24 Feb 2009 12:50:21 -0500 Subject: [PATCH] New test for replicate_row. --- t/02replicate_row.t | 166 ++++++++++++++++++++++++++++++++++++++++++++ t/CP_Testing.pm | 30 +++++++- 2 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 t/02replicate_row.t diff --git a/t/02replicate_row.t b/t/02replicate_row.t new file mode 100644 index 000000000..3c3ac7b73 --- /dev/null +++ b/t/02replicate_row.t @@ -0,0 +1,166 @@ +#!perl + +## Test the "replicate_row" action + +use strict; +use warnings; +use Data::Dumper; +use DBI; +use Cwd; +use Test::More tests => 19; +use lib 't','.'; +use CP_Testing; + +use vars qw/$dbh $dbh2 $SQL $count $host $t $result $info/; + +my $cp = CP_Testing->new(); + +$dbh = $cp->test_database_handle(); +$dbh2 = $cp->get_fresh_dbh({dbname=>'ardala'}); + +$SQL = q{CREATE TABLE reptest(id INT, foo TEXT)}; +if (! $cp->table_exists($dbh, 'reptest')) { + $dbh->do($SQL); +} +if (! $cp->table_exists($dbh2, 'reptest')) { + $dbh2->do($SQL); +} +$SQL = q{TRUNCATE TABLE reptest; INSERT INTO reptest VALUES (1,'yin'), (2,'yang')}; +$dbh->do($SQL); +$dbh2->do($SQL); + +$dbh->commit(); +$dbh2->commit(); + +my $S = q{Action 'replicate_rows'}; + +$t=qq{$S fails when called with an invalid option}; +like ($cp->run('replicate-row', 'foobar=12'), qr{^\s*Usage:}, $t); + +$t=qq{$S fails when called without warning or critical}; +like ($cp->run('replicate-row', ''), qr{Must provide a warning and/or critical}, $t); + +$t=qq{$S fails when called with invalid warning}; +like ($cp->run('replicate-row', '-w foo'), qr{ERROR:.+'warning' must be a valid time}, $t); + +$t=qq{$S fails when called with invalid critical}; +like ($cp->run('replicate-row', '-c foo'), qr{ERROR:.+'critical' must be a valid time}, $t); + +$t=qq{$S fails when critical is greater than warning time}; +like ($cp->run('replicate-row', '-w 22 -c 44'), qr{ERROR:.+'warning' option cannot be less}, $t); + +$t=qq{$S fails when called with no repinfo argument}; +like ($cp->run('replicate-row', '-w 2'), qr{ERROR: Need a repinfo}, $t); + +$t=qq{$S fails when called with bad repinfo argument}; +like ($cp->run('replicate-row', '-w 2 -repinfo=abc'), qr{ERROR: Invalid repinfo}, $t); + +# table, pk, id, col, val1, val2 +$t=qq{$S fails when supplied values are equal}; +like ($cp->run('replicate-row', '-w 2 -repinfo=reptest,id,2,foo,yin,yin'), qr{ERROR: .+same values}, $t); + +$t=qq{$S fails when no matching source row is found}; +like ($cp->run('DB2replicate-row', '-w 2 -repinfo=reptest,id,4,foo,yin,yang'), qr{ERROR: .+not the right ones}, $t); + +$t=qq{$S gives correct warning when rows do not match}; +$SQL = q{UPDATE reptest SET foo = 'baz' WHERE id = 1}; +$dbh2->do($SQL); +$dbh2->commit(); +like ($cp->run('DB2replicate-row', '-w 2 -repinfo=reptest,id,1,foo,yin,yang'), qr{ERROR: .+values are not the same}, $t); + +$t=qq{$S gives correct warning when row values are not known ones}; +$dbh->do($SQL); +$dbh->commit(); +like ($cp->run('DB2replicate-row', '-w 2 -repinfo=reptest,id,1,foo,yin,yang'), qr{ERROR: .+values are not the right ones}, $t); + +$t=qq{$S reports error when we time out via warning}; +$SQL = q{UPDATE reptest SET foo = 'yin' WHERE id = 1}; +$dbh->do($SQL); +$dbh2->do($SQL); +$dbh->commit(); +$dbh2->commit(); +like ($cp->run('DB2replicate-row', '-w 1 -repinfo=reptest,id,1,foo,yin,yang'), qr{WARNING: .+not replicated}, $t); + +$t=qq{$S reports error when we time out via critical}; +$SQL = q{UPDATE reptest SET foo = 'yang' WHERE id = 1}; +$dbh->do($SQL); +$dbh2->do($SQL); +$dbh->commit(); +$dbh2->commit(); +like ($cp->run('DB2replicate-row', '-c 1 -repinfo=reptest,id,1,foo,yin,yang'), qr{CRITICAL: .+not replicated}, $t); + +$t=qq{$S reports error when we time out via critical with MRTG}; +$SQL = q{UPDATE reptest SET foo = 'yang' WHERE id = 1}; +$dbh->do($SQL); +$dbh->commit(); +like ($cp->run('DB2replicate-row', '-c 1 --output=MRTG --repinfo=reptest,id,1,foo,yin,yang'), qr{^0}, $t); + +$t=qq{$S works when rows match}; +$SQL = q{UPDATE reptest SET foo = 'yang' WHERE id = 1}; +$dbh->do($SQL); +$dbh->commit(); +$dbh->{InactiveDestroy} = 1; +$dbh2->{InactiveDestroy} = 1; +## Use fork to 'replicate' behind the back of the other process +if (fork) { + like ($cp->run('DB2replicate-row', '-c 5 -repinfo=reptest,id,1,foo,yin,yang'), + qr{^POSTGRES_REPLICATE_ROW OK:.+Row was replicated}, $t); +} +else { + sleep 1; + $SQL = q{UPDATE reptest SET foo = 'yin' WHERE id = 1}; + $dbh2->do($SQL); + $dbh2->commit(); + exit; +} + +$t=qq{$S works when rows match, reports proper delay}; +$dbh->commit(); +if (fork) { + $result = $cp->run('DB2replicate-row', '-c 10 -repinfo=reptest,id,1,foo,yin,yang'); + like ($result, qr{^POSTGRES_REPLICATE_ROW OK:.+Row was replicated}, $t); + $result =~ /time=(\d+)/ or die "No time?"; + my $time = $1; + cmp_ok ($time, '>=', 3, $t); +} +else { + sleep 3; + $SQL = q{UPDATE reptest SET foo = 'yang' WHERE id = 1}; + $dbh2->do($SQL); + $dbh2->commit(); + exit; +} + +$t=qq{$S works when rows match, with MRTG output}; +$dbh->commit(); +if (fork) { + is ($cp->run('DB2replicate-row', '-c 10 --output=MRTG -repinfo=reptest,id,1,foo,yin,yang'), + qq{1\n0\n\n\n}, $t); +} +else { + sleep 1; + $SQL = q{UPDATE reptest SET foo = 'yin' WHERE id = 1}; + $dbh2->do($SQL); + $dbh2->commit(); + exit; +} + +$t=qq{$S works when rows match, with simple output}; +$dbh->commit(); +if (fork) { + $result = $cp->run('DB2replicate-row', '-c 10 --output=simple -repinfo=reptest,id,1,foo,yin,yang'); + $result =~ /^(\d+)/ or die "No time?"; + my $time = $1; + cmp_ok ($time, '>=', 3, $t); +} +else { + sleep 3; + $SQL = q{UPDATE reptest SET foo = 'yang' WHERE id = 1}; + $dbh2->do($SQL); + $dbh2->commit(); + exit; +} + +$dbh2->disconnect(); + +exit; diff --git a/t/CP_Testing.pm b/t/CP_Testing.pm index 63451c5e5..1bf8c4522 100644 --- a/t/CP_Testing.pm +++ b/t/CP_Testing.pm @@ -133,6 +133,7 @@ sub test_database_handle { $dbh->do("CREATE USER readonly NOSUPERUSER NOCREATEDB"); $dbh->do("ALTER USER readonly SET default_transaction_read_only = 1"); $dbh->do("CREATE DATABASE beedeebeedee"); + $dbh->do("CREATE DATABASE ardala"); $dbh->{AutoCommit} = 0; $dbh->{RaiseError} = 1; @@ -158,12 +159,18 @@ sub run { my $action = shift or die "First arg must be the command\n"; my $extra = shift || ''; - my $dbhost = $self->{dbhost}; - my $dbuser = $self->{testuser}; - my $dbname = $self->{dbname}; + my $double = $action =~ s/DB2// ? 1 : 0; + + my $dbhost = $self->{dbhost} || die "No dbhost?"; + my $dbuser = $self->{testuser} || die "No testuser?"; + my $dbname = $self->{dbname} || die "No dbname?"; my $com = "perl check_postgres.pl --action=$action --dbhost=$dbhost --dbname=$dbname --dbuser=$dbuser"; + if ($double) { + $com .= " --dbhost2=$dbhost --dbname2=ardala --dbuser2=$dbuser"; + } + $extra and $com .= " $extra"; $DEBUG and warn "DEBUG RUN: $com\n"; @@ -193,8 +200,14 @@ sub get_dbh { sub get_fresh_dbh { my $self = shift; + my $opt = shift || {}; + my $superdsn = $self->{superdsn} || die; + if ($opt->{dbname}) { + $superdsn->[0] =~ s/dbname=\w+/dbname=$opt->{dbname}/; + } + my $dbh = DBI->connect(@$superdsn); return $dbh; @@ -234,5 +247,16 @@ sub remove_fake_pg_table { } ## end of remove_fake_pg_table +sub table_exists { + + my ($self,$dbh,$table) = @_; + + my $SQL = 'SELECT count(1) FROM pg_class WHERE relname = ?'; + my $sth = $dbh->prepare($SQL); + $sth->execute($table); + my $count = $sth->fetchall_arrayref()->[0][0]; + return $count; + +} ## end of table_exists 1; -- 2.39.5