1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
#!/usr/bin/env perl
# -*-mode:cperl; indent-tabs-mode: nil-*-
## Test makedelta functionality
use 5.008003;
use strict;
use warnings;
use lib 't','.';
use DBD::Pg;
use Test::More;
use BucardoTesting;
my $bct = BucardoTesting->new({ location => 'makedelta' })
or BAIL_OUT "Creation of BucardoTesting object failed\n";
END { $bct->stop_bucardo if $bct }
ok my $dbhA = $bct->repopulate_cluster('A'), 'Populate cluster A';
ok my $dbhB = $bct->repopulate_cluster('B'), 'Populate cluster B';
ok my $dbhC = $bct->repopulate_cluster('C'), 'Populate cluster C';
ok my $dbhX = $bct->setup_bucardo('A'), 'Set up Bucardo';
END { $_->disconnect for grep { $_ } $dbhA, $dbhB, $dbhC, $dbhX }
# Teach Bucardo about the databases.
for my $db (qw(A B C)) {
my ($user, $port, $host) = $bct->add_db_args($db);
like $bct->ctl(
"bucardo add db $db dbname=bucardo_test user=$user port=$port host=$host"
), qr/Added database "$db"/, qq{Add database "$db" to Bucardo};
}
# Let's just deal with table bucardo_test1 (single column primary key)
# and bucardo_test2 (multi-column primary key).
# Create bucardo_test4 with makedelta off.
for my $num (1, 2, 4) {
my $md = $num == 4 ? 'off' : 'on';
like $bct->ctl("bucardo add table bucardo_test$num db=A relgroup=myrels makedelta=$md"),
qr/Added the following tables/, "Add table bucardo_test$num";
}
# Create a sync for multi-master replication between A and B
like $bct->ctl('bucardo add sync deltatest1 relgroup=myrels dbs=A:source,B:source'),
qr/Added sync "deltatest1"/, 'Create sync "deltatest1"';
# Create a sync for replication from B to C
like $bct->ctl('bucardo add sync deltatest2 relgroup=myrels dbs=B,C autokick=no'),
qr/Added sync "deltatest2"/, 'Create sync "deltatest2"';
# Create an inactive sync from C to A. This is so makedelta on C tables works
like $bct->ctl('bucardo add sync deltafake relgroup=myrels dbs=C,A status=inactive autokick=no'),
qr/Added sync "deltafake"/, 'Create sync "deltafake"';
# Listen in on things.
ok $dbhX->do('LISTEN bucardo_syncdone_deltatest1'),
'Listen for syncdone_deltatest1';
ok $dbhX->do('LISTEN bucardo_syncdone_deltatest2'),
'Listen for syncdone_deltatest2';
ok $dbhX->do('LISTEN bucardo_syncdone_deltatest3'), ## created below
'Listen for syncdone_deltatest3';
# Start up Bucardo and wait for initial active sync to finish.
ok $bct->restart_bucardo($dbhX), 'Bucardo should start';
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest1
)]), 'The deltatest1 sync finished';
# Should have no rows.
$bct->check_for_row([], [qw(A B C)], undef, 'test[124]$');
# Let's add some data into A.bucardo_test1.
ok $dbhA->do(q{INSERT INTO bucardo_test1 (id, data1) VALUES (1, 'foo')}),
'Insert a row into test1 on A';
$dbhA->commit;
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest1
)]), 'The deltatest1 sync has finished';
## The data should only go as far as B
$bct->check_for_row([], ['C'], undef, 'test[124]$');
## Bucardo will not fire off deltatest2 itself, so we kick it
$bct->ctl('bucardo kick sync deltatest2 0');
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest2
)]), 'The deltatest2 sync has finished';
# The row should be in A and B, as well as C!
is_deeply $dbhB->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test1'
), [[1, 'foo']], 'Should have the test1 row in B';
is_deeply $dbhC->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test1'
), [[1, 'foo']], 'Second sync moved row from B to C';
# Now let's insert into test2 on B.
# This will cause both syncs to fire
# deltatest1 (A<=>B) will copy the row from B to A
# deltatest2 (B=>C) will copy the row from B to C
ok $dbhB->do(q{INSERT INTO bucardo_test2 (id, data1) VALUES (2, 'foo')}),
'Insert a row into test2 on B';
$dbhB->commit;
## Sync deltatest2 is not automatic, so we need to kick it
# Kick off the second sync
$bct->ctl('bucardo kick sync deltatest2 0');
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest1
syncdone_deltatest2
)]), 'The deltatest1 and deltatest2 syncs finished';
is_deeply $dbhA->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test2'
), [[2, 'foo']], 'Should have the A test2 row in A';
is_deeply $dbhC->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test2'
), [[2, 'foo']], 'Should have the A test2 row in C';
# Finally, try table 4, which has no makedelta.
ok $dbhA->do(q{INSERT INTO bucardo_test4 (id, data1) VALUES (3, 'foo')}),
'Insert a row into test4 on A';
$dbhA->commit;
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest1
)]), 'The deltatest1 sync finished';
# Kick off the second sync
$bct->ctl('bucardo kick sync deltatest2 0');
is_deeply $dbhB->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test4'
), [[3, 'foo']], 'Should have the test4 row in B';
is_deeply $dbhC->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test4'
), [], 'Should have no test4 row row in C';
$dbhA->commit();
$dbhB->commit();
$dbhC->commit();
##############################################################################
# Okay, what if we have C be a target from either A or B?
like $bct->ctl('bucardo remove sync deltatest2'),
qr/Removed sync "deltatest2"/, 'Remove sync "deltatest2"';
like $bct->ctl('bucardo add sync deltatest3 relgroup=myrels dbs=A:source,B:source,C'),
qr/Added sync "deltatest3"/, 'Created sync "deltatest3"';
ok $bct->restart_bucardo($dbhX), 'Bucardo restarted';
ok $dbhA->do(q{INSERT INTO bucardo_test2 (id, data1) VALUES (3, 'howdy')}),
'Insert a row into test2 on A';
$dbhA->commit;
ok $bct->wait_for_notice($dbhX, [qw(
syncdone_deltatest1
syncdone_deltatest3
)]), 'Syncs deltatest1 and deltatest3 finished';
is_deeply $dbhB->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test2'
), [[2, 'foo'], [3, 'howdy']], 'Should have the A test2 row in B';
is_deeply $dbhC->selectall_arrayref(
'SELECT id, data1 FROM bucardo_test2'
), [[2, 'foo'], [3, 'howdy']], 'Should have the A test2 row in C';
done_testing();
|