8000 [PGPRO-3690] Tests for progress_bar. · postgrespro/pg_query_state@d296678 · GitHub
[go: up one dir, main page]

Skip to content

Commit d296678

Browse files
author
Ekaterina Sokolova
committed
[PGPRO-3690] Tests for progress_bar.
Tags: pg_query_state.
1 parent ad88ee9 commit d296678

File tree

5 files changed

+153
-0
lines changed

5 files changed

+153
-0
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ submake-isolation:
4242
$(MAKE) -C $(top_builddir)/src/test/isolation all
4343

4444
temp-install: EXTRA_INSTALL=contrib/pg_query_state
45+
46+
submake-progress_bar:
47+
$(MAKE) -C $(top_builddir)/contrib/pg_query_state
48+
49+
check_progress_bar: submake-progress_bar temp-install
50+
$(prove_check)

t/test_bad_progress_bar.pl

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# pg_query_state/t/test_bad_progress_bar.pl
2+
#
3+
# Check uncorrect launches of functions progress_bar(pid)
4+
# and progress_bar_visual(pid, delay)
5+
6+
use strict;
7+
use warnings;
8+
use PostgresNode;
9+
use TestLib;
10+
use Test::More tests => 2;
11+
12+
# List of checks for bad cases:
13+
# 1) appealing to a bad pid
14+
# ------- requires DBI and DBD::Pg modules -------
15+
# 2) extracting the state of the process itself
16+
17+
# Test whether we have both DBI and DBD::pg
18+
my $dbdpg_rc = eval
19+
{
20+
require DBI;
21+
require DBD::Pg;
22+
DBD::Pg->import(':async');
23+
1;
24+
};
25+
26+
# start backend for function progress_bar
27+
my $node = PostgresNode->get_new_node('master');
28+
$node->init;
29+
$node->start;
30+
$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_query_state'");
31+
$node->restart;
32+
$node->psql('postgres', 'CREATE EXTENSION pg_query_state;');
33+
34+
subtest 'Extracting from bad pid' => sub {
35+
my $stderr;
36+
$node->psql('postgres', 'SELECT * from progress_bar(-1)', stderr => \$stderr);
37+
is ($stderr, 'psql:<stdin>:1: ERROR: backend with pid=-1 not found', "appealing to a bad pid for progress_bar");
38+
$node->psql('postgres', 'SELECT * from progress_bar(-1)_visual', stderr => \$stderr);
39+
is ($stderr, 'psql:<stdin>:1: ERROR: backend with pid=-1 not found', "appealing to a bad pid for progress_bar_visual");
40+
};
41+
42+
if ( not $dbdpg_rc) {
43+
diag('DBI and DBD::Pg are not available, skip 2/3 tests');
44+
}
45+
46+
SKIP: {
47+
skip "DBI and DBD::Pg are not available", 2 if not $dbdpg_rc;
48+
49+
my $dbh_status = DBI->connect('DBI:Pg:' . $node->connstr($_));
50+
if ( !defined $dbh_status )
51+
{
52+
die "Cannot connect to database for dbh with progress_bar\n";
53+
}
54+
55+
my $pid_status = $dbh_status->{pg_pid};
56+
57+
subtest 'Extracting your own status' => sub {
58+
$dbh_status->do('SELECT * from progress_bar(' . $pid_status . ')');
59+
is($dbh_status->errstr, 'ERROR: attempt to extract state of current process', "extracting the state of the process itself for progress_bar");
60+
$dbh_status->do('SELECT * from progress_bar_visual(' . $pid_status . ')');
61+
is($dbh_status->errstr, 'ERROR: attempt to extract state of current process', "extracting the state of the process itself for progress_bar_visual");
62+
};
63+
64+
$dbh_status->disconnect;
65+
}
66+
67+
$node->stop('fast');

tests/common.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,58 @@ def onetime_query_state(config, async_conn, query, args={}, num_workers=0):
161161
set_guc(async_conn, 'enable_mergejoin', 'on')
162162
return result, notices
163163

164+
def progress_bar(config, pid, visual):
165+
conn = psycopg2.connect(**config)
166+
curs = conn.cursor()
167+
168+
if visual:
169+
curs.callproc('progress_bar_visual', (pid, 1))
170+
else:
171+
curs.callproc('progress_bar', (pid,))
172+
result = curs.fetchall()
173+
notices = conn.notices[:]
174+
conn.close()
175+
176+
return result, notices
177+
178+
def onetime_progress_bar(config, async_conn, query, args={}, num_workers=0, visual=0):
179+
"""
180+
Get intermediate state of 'query' on connection 'async_conn' after number of 'steps'
181+
of node executions from start of query
182+
"""
183+
184+
acurs = async_conn.cursor()
185+
186+
set_guc(async_conn, 'enable_mergejoin', 'off')
187+
set_guc(async_conn, 'max_parallel_workers_per_gather', num_workers)
188+
acurs.execute(query)
189+
190+
# extract progress of current query
191+
MAX_PG_QS_RETRIES = 10
192+
DELAY_BETWEEN_RETRIES = 0.1
193+
pg_qs_args = {
194+
'config': config,
195+
'pid': async_conn.get_backend_pid(),
196+
'visual': visual
197+
}
198+
for k, v in args.items():
199+
pg_qs_args[k] = v
200+
n_retries = 0
201+
while True:
202+
result, notices = progress_bar(**pg_qs_args)
203+
n_retries += 1
204+
if len(result) > 0:
205+
break
206+
if n_retries >= MAX_PG_QS_RETRIES:
207+
# pg_query_state callings don't return any result, more likely run
208+
# query has completed
209+
break
210+
time.sleep(DELAY_BETWEEN_RETRIES)
211+
wait(async_conn)
212+
213+
set_guc(async_conn, 'enable_mergejoin', 'on')
214+
return result, notices
215+
164216
def set_guc(async_conn, param, value):
165217
acurs = async_conn.cursor()
166218
acurs.execute('set %s to %s' % (param, value))

tests/pg_qs_test_runner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class TeardownException(Exception): pass
6868
test_formats,
6969
test_timing_buffers_conflicts,
7070
test_insert_on_conflict,
71+
test_progress_bar,
72+
test_progress_bar_visual,
7173
]
7274

7375
def setup(con):

tests/test_cases.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,29 @@ def test_timing_buffers_conflicts(config):
386386
and 'WARNING: buffers statistics disabled\n' in notices
387387

388388
common.n_close((acon,))
389+
390+
def test_progress_bar(config):
391+
"""test progress_bar of simple query"""
392+
393+
acon, = common.n_async_connect(config)
394+
query = 'select * from foo join bar on foo.c1=bar.c1'
395+
396+
qs, notices = common.onetime_progress_bar(config, acon, query)
397+
assert qs[0][0] >= 0 and qs[0][0] < 1
398+
first_qs = qs[0][0]
399+
400+
qs, _ = common.onetime_progress_bar(config, acon, query)
401+
assert qs[0][0] >= first_qs and qs[0][0] < 1
402+
403+
common.n_close((acon,))
404+
405+
def test_progress_bar_visual(config):
406+
"""test progress_bar_visual of simple query"""
407+
408+
acon, = common.n_async_connect(config)
409+
query = 'select count(*) from foo join bar on foo.c1=bar.c1'
410+
411+
qs, _ = common.onetime_progress_bar(config, acon, query, visual=1)
412+
assert qs[0][0] == 1.0
413+
414+
common.n_close((acon,))

0 commit comments

Comments
 (0)
0