Skip to content

Commit 16c9923

Browse files
committed
TAP tests
1 parent 199b32c commit 16c9923

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

contrib/pg_tsdtm/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ top_builddir = ../..
1414
include $(top_builddir)/src/Makefile.global
1515
include $(top_srcdir)/contrib/contrib-global.mk
1616
endif
17+
18+
check:
19+
env DESTDIR='$(abs_top_builddir)'/tmp_install make install
20+
$(prove_check)
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
###############################################################################
2+
# Test of proper transaction isolation.
3+
# Based on Martin Kleppmann's set of tests (https://github.com/ept/hermitage)
4+
###############################################################################
5+
6+
use strict;
7+
use warnings;
8+
use PostgresNode;
9+
use TestLib;
10+
use Test::More tests => 2;
11+
use DBI();
12+
use DBD::Pg();
13+
14+
sub query_row
15+
{
16+
my ($dbi, $sql, @keys) = @_;
17+
my $sth = $dbi->prepare($sql) || die;
18+
$sth->execute(@keys) || die;
19+
my $ret = $sth->fetchrow_array;
20+
print "query_row('$sql') -> $ret \n";
21+
return $ret;
22+
}
23+
24+
sub query_exec
25+
{
26+
my ($dbi, $sql) = @_;
27+
print "query_exec('$sql')\n";
28+
my $rv = $dbi->do($sql) || die;
29+
return $rv;
30+
}
31+
32+
sub PostgresNode::psql_ok {
33+
my ($self, $sql, $comment) = @_;
34+
35+
$self->command_ok(['psql', '-A', '-t', '--no-psqlrc',
36+
'-d', $self->connstr, '-c', $sql], $comment);
37+
}
38+
39+
sub PostgresNode::psql_fails {
40+
my ($self, $sql, $comment) = @_;
41+
42+
$self->command_ok(['psql', '-A', '-t', '--no-psqlrc',
43+
'-d', $self->connstr, '-c', $sql], $comment);
44+
}
45+
46+
###############################################################################
47+
# Setup nodes
48+
###############################################################################
49+
50+
# Setup first node
51+
my $node1 = get_new_node("node1");
52+
$node1->init;
53+
$node1->append_conf('postgresql.conf', qq(
54+
max_prepared_transactions = 10
55+
shared_preload_libraries = 'pg_tsdtm'
56+
));
57+
$node1->start;
58+
59+
# Setup second node
60+
my $node2 = get_new_node("node2");
61+
$node2->init;
62+
$node2->append_conf('postgresql.conf', qq(
63+
max_prepared_transactions = 10
64+
shared_preload_libraries = 'pg_tsdtm'
65+
));
66+
$node2->start;
67+
68+
$node1->psql('postgres', "create extension pg_tsdtm;");
69+
$node1->psql('postgres', "create table t(u int primary key, v int)");
70+
$node1->psql('postgres', "insert into t (select generate_series(0, 9), 0)");
71+
72+
$node2->psql('postgres', "create extension pg_tsdtm;");
73+
$node2->psql('postgres', "create table t(u int primary key, v int)");
74+
$node2->psql('postgres', "insert into t (select generate_series(0, 9), 0)");
75+
76+
my $conn1 = DBI->connect('DBI:Pg:' . $node1->connstr('postgres'));
77+
my $conn2 = DBI->connect('DBI:Pg:' . $node2->connstr('postgres'));
78+
79+
sub count_total
80+
{
81+
# my ($c1, $c2) = @_;
82+
my $c1 = DBI->connect('DBI:Pg:' . $node1->connstr('postgres'));
83+
my $c2 = DBI->connect('DBI:Pg:' . $node2->connstr('postgres'));
84+
85+
query_exec($c1, "begin");
86+
query_exec($c2, "begin");
87+
88+
my $snapshot = query_row($c1, "select dtm_extend()");
89+
query_row($c2, "select dtm_access($snapshot)");
90+
91+
my $sum1 = query_row($c1, "select sum(v) from t");
92+
my $sum2 = query_row($c2, "select sum(v) from t");
93+
94+
query_exec($c1, "commit");
95+
query_exec($c2, "commit");
96+
97+
my $tot = $sum1 + $sum2;
98+
99+
print "total = $tot\n";
100+
return $tot;
101+
}
102+
103+
###############################################################################
104+
# Check for dirty reads
105+
###############################################################################
106+
107+
my $gtid = "tx1";
108+
109+
query_exec($conn1, "begin transaction");
110+
query_exec($conn2, "begin transaction");
111+
my $snapshot = query_row($conn1, "select dtm_extend('$gtid')");
112+
query_exec($conn2, "select dtm_access($snapshot, '$gtid')");
113+
query_exec($conn1, "update t set v = v - 10 where u=1");
114+
115+
my $intermediate_total = count_total();
116+
117+
query_exec($conn2, "update t set v = v + 10 where u=2");
118+
query_exec($conn1, "prepare transaction '$gtid'");
119+
query_exec($conn2, "prepare transaction '$gtid'");
120+
query_exec($conn1, "select dtm_begin_prepare('$gtid')");
121+
query_exec($conn2, "select dtm_begin_prepare('$gtid')");
122+
my $csn = query_row($conn1, "select dtm_prepare('$gtid', 0)");
123+
query_exec($conn2, "select dtm_prepare('$gtid', $csn)");
124+
query_exec($conn1, "select dtm_end_prepare('$gtid', $csn)");
125+
query_exec($conn2, "select dtm_end_prepare('$gtid', $csn)");
126+
query_exec($conn1, "commit prepared '$gtid'");
127+
query_exec($conn2, "commit prepared '$gtid'");
128+
129+
is($intermediate_total, 0, "Check for absence of dirty reads");
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+

0 commit comments

Comments
 (0)