1#!/usr/bin/perl -w
2
3BEGIN {
4   die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
5      unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
6   unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
7};
8
9# RowDiff-custom.t tests some of the basic RowDiff functionalities
10# as RowDiff.t but uses a different Perl lib if the PT_PERL_LIB
11# environment var is set. This allows us to test these functionalities
12# against custom versions of DBI, DBD::mysql, etc. If PT_PERL_LIB
13# is not set, then all these tests are skipped.
14
15package MockSync;
16sub new {
17   return bless [], shift;
18}
19
20sub same_row {
21   my ( $self, $lr, $rr ) = @_;
22   push @$self, 'same';
23}
24
25sub not_in_right {
26   my ( $self, $lr ) = @_;
27   push @$self, [ 'not in right', $lr];
28}
29
30sub not_in_left {
31   my ( $self, $rr ) = @_;
32   push @$self, [ 'not in left', $rr];
33}
34
35sub done_with_rows {
36   my ( $self ) = @_;
37   push @$self, 'done';
38}
39
40sub key_cols {
41   return [qw(a)];
42}
43
44# #############################################################################
45
46package main;
47
48BEGIN {
49   if ( defined $ENV{PT_PERL_LIB} ) {
50      die "The PT_PERL_LIB environment variable is not a valid directory: "
51         . $ENV{PT_PERL_LIB} unless -d $ENV{PT_PERL_LIB};
52      print "# Using Perl lib $ENV{PT_PERL_LIB}\n";
53      use lib ($ENV{PT_PERL_LIB} ? "$ENV{PT_PERL_LIB}" : ());
54   }
55};
56
57use strict;
58use warnings FATAL => 'all';
59
60use Test::More;
61use English qw(-no_match_vars);
62use DBI;
63use DBD::mysql;  # so we can print $DBD::mysql::VERSION
64use PerconaTest;
65
66plan skip_all => "PT_PERL_LIB env var is not set", 4
67   unless defined $ENV{PT_PERL_LIB};
68
69print "# DBI v$DBI::VERSION\n"
70   . "# DBD::mysql v$DBD::mysql::VERSION\n";
71
72use RowDiff;
73use Sandbox;
74use DSNParser;
75use TableParser;
76use Quoter;
77
78my $d  = new RowDiff(dbh => 1);
79my $s  = new MockSync();
80my $q  = new Quoter();
81my $tp = new TableParser(Quoter => $q);
82my $dp = new DSNParser(opts=>$dsn_opts);
83
84# Connect to sandbox now to make sure it's running.
85my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
86my $master_dbh = $sb->get_dbh_for('master');
87my $slave_dbh  = $sb->get_dbh_for('slave1');
88if ( !$master_dbh ) {
89   plan skip_all => "Cannot connect to sandbox master";
90}
91elsif ( !$slave_dbh ) {
92   plan skip_all => "Cannot connect to sandbox slave";
93}
94else {
95   plan tests => 5;
96}
97
98
99$sb->create_dbs($master_dbh, [qw(test)]);
100$sb->load_file('master', 't/lib/samples/issue_11.sql');
101
102my $tbl = $tp->parse(
103   $tp->get_create_table($master_dbh, 'test', 'issue_11'));
104
105my $left_sth  = $master_dbh->prepare('SELECT * FROM test.issue_11');
106my $right_sth = $slave_dbh->prepare('SELECT * FROM test.issue_11');
107$left_sth->execute();
108$right_sth->execute();
109$s = new MockSync();
110$d->compare_sets(
111   left  => $left_sth,
112   right => $right_sth,
113   syncer => $s,
114   tbl => $tbl,
115);
116is_deeply(
117   $s,
118   ['done',],
119   'no rows (real DBI sth)',
120);
121
122$slave_dbh->do('INSERT INTO test.issue_11 VALUES (1,2,3)');
123$left_sth  = $master_dbh->prepare('SELECT * FROM test.issue_11');
124$right_sth = $slave_dbh->prepare('SELECT * FROM test.issue_11');
125$left_sth->execute();
126$right_sth->execute();
127$s = new MockSync();
128$d->compare_sets(
129   left   => $left_sth,
130   right  => $right_sth,
131   syncer => $s,
132   tbl    => $tbl,
133);
134is_deeply(
135   $s,
136   [
137      ['not in left', { a => 1, b => 2, c => 3 },],
138      'done',
139   ],
140   'right only (real DBI sth)',
141);
142
143$slave_dbh->do('TRUNCATE TABLE test.issue_11');
144$master_dbh->do('SET SQL_LOG_BIN=0;');
145$master_dbh->do('INSERT INTO test.issue_11 VALUES (1,2,3)');
146$left_sth  = $master_dbh->prepare('SELECT * FROM test.issue_11');
147$right_sth = $slave_dbh->prepare('SELECT * FROM test.issue_11');
148$left_sth->execute();
149$right_sth->execute();
150$s = new MockSync();
151$d->compare_sets(
152   left   => $left_sth,
153   right  => $right_sth,
154   syncer => $s,
155   tbl    => $tbl,
156);
157is_deeply(
158   $s,
159   [
160      [ 'not in right', { a => 1, b => 2, c => 3 },],
161      'done',
162   ],
163   'left only (real DBI sth)',
164);
165
166$slave_dbh->do('INSERT INTO test.issue_11 VALUES (1,2,3)');
167$left_sth  = $master_dbh->prepare('SELECT * FROM test.issue_11');
168$right_sth = $slave_dbh->prepare('SELECT * FROM test.issue_11');
169$left_sth->execute();
170$right_sth->execute();
171$s = new MockSync();
172$d->compare_sets(
173   left   => $left_sth,
174   right  => $right_sth,
175   syncer => $s,
176   tbl    => $tbl,
177);
178is_deeply(
179   $s,
180   [
181      'same',
182      'done',
183   ],
184   'one identical row (real DBI sth)',
185);
186
187$sb->wipe_clean($master_dbh);
188$sb->wipe_clean($slave_dbh);
189
190ok($sb->ok(), "Sandbox servers") or BAIL_OUT(__FILE__ . " broke the sandbox");
191exit;
192