summaryrefslogtreecommitdiff
path: root/t/40-serializable.t
blob: 1c9b17e8b5f68e2100170ae4f4cb0ad8ced75385 (plain)
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
#!/usr/bin/perl -w

use strict;
use warnings;
use lib 't';
use Test::More;
use BucardoTesting;
use Data::Dumper;


my $bct = BucardoTesting->new({location => 'postgres'})
    or BAIL_OUT 'Creation of BucardoTesting object failed';

END { $bct->stop_bucardo if $bct }

my $dbh = $bct->empty_cluster('A');
END { $dbh->disconnect if $dbh }

# Skip the tests if we can't mock the serialization failure.
plan skip_all => "Cannot mock serialization failure on Postgres $dbh->{pg_server_version}"
    if $dbh->{pg_server_version} < 80400;

# We are a go!
plan tests => 45;
$dbh->disconnect;
$dbh = undef;

ok my $dbhA = $bct->repopulate_cluster('A'), 'Populate cluster A';
ok my $dbhB = $bct->repopulate_cluster('B'), 'Populate cluster B';
ok my $dbhX = $bct->setup_bucardo('A'), 'Set up Bucardo';

END { $_->disconnect for grep { $_ } $dbhA, $dbhB, $dbhX }

# Teach Bucardo about the databases.
for my $db (qw(A B)) {
    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 and bucardo_test2.
for my $num (1, 2) {
    like $bct->ctl("bucardo add table bucardo_test$num db=A relgroup=myrels"),
        qr/Added the following tables/, "Add table bucardo_test$num";
}

# Create a new dbgroup going from A to B
like $bct->ctl('bucardo add dbgroup serial1 A:source B:target'),
    qr/Created dbgroup "serial1"/, 'Create relgroup serial1';

# Create a sync for this group.
like $bct->ctl('bucardo add sync serialtest1 relgroup=myrels dbs=serial1'),
    qr/Added sync "serialtest1"/, 'Create sync "serialtest1"';

# Set up a rule to mock a serialization failure on B.bucardo_test2.
ok $bct->mock_serialization_failure($dbhB, 'bucardo_test2'),
    'Mock serialization failure on bucardo_test2';
END {
    $bct->unmock_serialization_failure($dbhB, 'bucardo_test2')
        if $bct && $dbhB;
}

# Listen in on things.
ok $dbhX->do('LISTEN bucardo_syncdone_serialtest1'),
    'Listen for syncdone';
ok $dbhX->do('LISTEN bucardo_syncsleep_serialtest1'),
    'Listen for syncsleep';

# Start up Bucardo.
ok $bct->restart_bucardo($dbhX), 'Bucardo should start';

ok $bct->wait_for_notice($dbhX, 'bucardo_syncdone_serialtest1'),
    'The sync should finish';

# Should have no rows.
$bct->check_for_row([], [qw(A B)], undef, 'test[12]$');

# Make sure the sync was recorded.
ok my $runs = $dbhX->selectall_arrayref(
    'SELECT * FROM syncrun ORDER BY started',
    { Slice => {} },
), 'Get list of syncruns';
is @{ $runs }, 1, 'Should have one syncrun';
ok $runs->[0]{ended}, 'It should have an "ended" value';
ok $runs->[0]{lastempty}, 'It should be marked "last empty"';
like $runs->[0]{status}, qr/^No delta rows found/,
    'Its status should be "No delta rows found"';

# Let's add some data into A.bucardo_test1.
$dbhX->commit;
ok $dbhA->do(q{INSERT INTO bucardo_test1 (id, data1) VALUES (1, 'foo')}),
    'Insert a row into test1';
$dbhA->commit;

ok $bct->wait_for_notice($dbhX, 'bucardo_syncdone_serialtest1'),
    'Second sync should finish';

# The row should be in both databases.
is_deeply $dbhB->selectall_arrayref(
    'SELECT id, data1 FROM bucardo_test1'
), [[1, 'foo']], 'Should have the test1 row in B';

# Should have two syncrun records now.
ok $runs = $dbhX->selectall_arrayref(
    'SELECT * FROM syncrun ORDER BY started',
    { Slice => {} },
), 'Get list of syncruns';
is @{ $runs }, 2, 'Should have two syncruns';
ok $runs->[1]{ended}, 'New run should have an "ended" value';
ok $runs->[1]{lastgood}, 'It should be marked "last good"';
like $runs->[1]{status}, qr/^Complete/, 'Its status should be "Complete"';

# Excellent. Now let's insert into test2.
$dbhX->commit;
ok $dbhA->do(q{INSERT INTO bucardo_test2 (id, data1) VALUES (2, 'foo')}),
    'Insert a row into test2';
$dbhA->commit;

ok $bct->wait_for_notice($dbhX, 'bucardo_syncsleep_serialtest1'),
    'Should get a syncsleep message';

ok $bct->wait_for_notice($dbhX, 'bucardo_syncdone_serialtest1'),
    'Then the third sync should finish';

is_deeply $dbhB->selectall_arrayref(
    'SELECT id, data1 FROM bucardo_test2'
), [[2, 'foo']], 'Should have the B test2 row despite serialization failure';

# Should have four syncrun records now.
ok $runs = $dbhX->selectall_arrayref(
    'SELECT * FROM syncrun ORDER BY started',
    { Slice => {} },
), 'Get list of syncruns';
is @{ $runs }, 4, 'Should have four syncruns';
ok $runs->[2]{ended}, 'Third run should have an "ended" value';
ok $runs->[2]{lastbad}, 'Third run should be marked "last bad"';
like $runs->[2]{status}, qr/^Failed/, 'Third run status should be "Bad"';

ok $runs->[3]{ended}, 'Fourth run should have an "ended" value';
ok $runs->[3]{lastgood}, 'Fourth run should be marked "last good"';
like $runs->[3]{status}, qr/^Complete/, 'Fourth run status should be "Complete"';