Skip to content

Commit f6d6779

Browse files
author
Maksim Milyutin
committed
Integrate isolation tests for more granular testing
Many buggy cases require for their reproducing non-trivial scenarios with multiple sessions. The isolation test utility is a good choice to emulate these scenarios. Additionally isolation tests, in general, allow to perform more granular verification required to extension. Current patch adds two isolation test cases: one is for base case with queryId, another as bug fix verification for not working case of calculation queryId for relation lock waiting. Also Makefile and README were changed to account the possibility to run isolation tests.
1 parent af53205 commit f6d6779

File tree

8 files changed

+207
-49
lines changed

8 files changed

+207
-49
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ DATA_built = pg_wait_sampling--$(EXTVERSION).sql
99
DATA = pg_wait_sampling--1.0--1.1.sql
1010

1111
REGRESS = load queries
12+
ISOLATION = queryid bfv_queryid_for_relation_lock
1213

13-
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
1414
EXTRA_CLEAN = pg_wait_sampling--$(EXTVERSION).sql
1515

1616
ifdef USE_PGXS

README.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,43 @@ higher. Before build and install you should ensure following:
6464

6565
Typical installation procedure may look like this:
6666

67-
$ git clone https://github.com/postgrespro/pg_wait_sampling.git
68-
$ cd pg_wait_sampling
69-
$ make USE_PGXS=1
70-
$ sudo make USE_PGXS=1 install
71-
$ make USE_PGXS=1 installcheck
72-
$ psql DB -c "CREATE EXTENSION pg_wait_sampling;"
67+
```bash
68+
git clone https://github.com/postgrespro/pg_wait_sampling.git
69+
cd pg_wait_sampling
70+
make USE_PGXS=1 install
71+
72+
# Add `pg_wait_sampling` string to `shared_preload_libraries` parameter in
73+
# `postgresql.conf` and restart PostgreSQL instance
74+
psql DB -c "CREATE EXTENSION pg_wait_sampling;"
75+
```
7376

7477
Compilation on Windows is not supported, since the extension uses symbols from PostgreSQL
7578
that are not exported.
7679

80+
Running full test suite on already running instance:
81+
82+
```bash
83+
make USE_PGXS=1 installcheck
84+
```
85+
86+
> **_NOTE:_** isolation tests require `pg_stat_statements` extension as prerequisite
87+
88+
To run specific test cases use the following commands:
89+
90+
* for regression tests:
91+
92+
```bash
93+
/path/to/pgsrc/or/pgxs/src/test/regress/pg_regress --bindir=/path/to/pg/bin [OTHER_OPTS] TEST1 TEST2 ...
94+
```
95+
96+
* for isolation tests:
97+
98+
```bash
99+
/path/to/pgsrc/or/pgxs/src/test/isolation/pg_isolation_regress --bindir=/path/to/pg/bin [OTHER_OPTS] TEST1 TEST2 ...
100+
```
101+
102+
Some isolation tests have _bfv\_ (denoting "bugfix verification") prefix. They cover previously fixed buggy cases occurred in development of extension.
103+
77104
Usage
78105
-----
79106

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s1_acquire_lock_on_relation s2_wait_on_relation_lock s1_wait_one_sec s1_release_relation_lock s2_expose_wait_on_lock_in_profile
4+
pg_wait_sampling_reset_profile
5+
------------------------------
6+
7+
(1 row)
8+
9+
step s1_acquire_lock_on_relation:
10+
BEGIN;
11+
LOCK pg_class IN ACCESS EXCLUSIVE MODE;
12+
13+
step s2_wait_on_relation_lock:
14+
BEGIN;
15+
LOCK pg_class IN ACCESS SHARE MODE;
16+
ROLLBACK;
17+
<waiting ...>
18+
step s1_wait_one_sec:
19+
SELECT pg_sleep(1);
20+
21+
pg_sleep
22+
--------
23+
24+
(1 row)
25+
26+
step s1_release_relation_lock:
27+
ROLLBACK;
28+
29+
step s2_wait_on_relation_lock: <... completed>
30+
step s2_expose_wait_on_lock_in_profile:
31+
SELECT query
32+
FROM pg_wait_sampling_profile pgws
33+
LEFT JOIN pg_stat_statements pgss using (queryid)
34+
WHERE pid = pg_backend_pid()
35+
AND event_type = 'Lock' AND event = 'relation'
36+
AND count between 90 and 110;
37+
38+
query
39+
-----
40+
41+
(1 row)
42+

expected/queries.out

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,21 @@
11
CREATE EXTENSION pg_wait_sampling;
2-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_current)
3-
SELECT sum(0) FROM generate_series(1, 2), t;
4-
sum
5-
-----
6-
0
7-
(1 row)
8-
9-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_history)
10-
SELECT sum(0) FROM generate_series(1, 2), t;
11-
sum
12-
-----
13-
0
14-
(1 row)
15-
16-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_profile)
17-
SELECT sum(0) FROM generate_series(1, 2), t;
18-
sum
19-
-----
20-
0
21-
(1 row)
22-
23-
-- Some dummy checks just to be sure that all our functions work and return something.
2+
-- Some dummy checks just to be sure that all our functions work and return something
243
SELECT count(*) = 1 as test FROM pg_wait_sampling_get_current(pg_backend_pid());
254
test
265
------
276
t
287
(1 row)
298

30-
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_profile();
9+
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_history();
3110
test
3211
------
3312
t
3413
(1 row)
3514

36-
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_history();
15+
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_profile();
3716
test
3817
------
3918
t
4019
(1 row)
4120

42-
SELECT pg_wait_sampling_reset_profile();
43-
pg_wait_sampling_reset_profile
44-
--------------------------------
45-
46-
(1 row)
47-
4821
DROP EXTENSION pg_wait_sampling;

expected/queryid.out

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s1_update_tuple s2_try_to_concurrently_update_tuple s1_wait_one_sec s1_rollback_txn s2_expose_wait_on_txn_in_profile
4+
step s1_update_tuple:
5+
BEGIN;
6+
UPDATE test SET i = i+1;
7+
8+
step s2_try_to_concurrently_update_tuple:
9+
BEGIN;
10+
UPDATE test SET i = i+1;
11+
ROLLBACK;
12+
<waiting ...>
13+
step s1_wait_one_sec:
14+
SELECT pg_sleep(1);
15+
16+
pg_sleep
17+
--------
18+
19+
(1 row)
20+
21+
step s1_rollback_txn:
22+
ROLLBACK;
23+
24+
step s2_try_to_concurrently_update_tuple: <... completed>
25+
step s2_expose_wait_on_txn_in_profile:
26+
SELECT query
27+
FROM pg_wait_sampling_profile pgws
28+
JOIN pg_stat_statements pgss using (queryid)
29+
WHERE pid = pg_backend_pid()
30+
AND event_type = 'Lock' AND event = 'transactionid'
31+
AND count between 90 and 110;
32+
33+
query
34+
------------------------
35+
UPDATE test SET i = i+$1
36+
(1 row)
37+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
setup {
2+
CREATE EXTENSION pg_wait_sampling;
3+
CREATE EXTENSION pg_stat_statements;
4+
SELECT pg_stat_statements_reset();
5+
SELECT pg_wait_sampling_reset_profile();
6+
}
7+
8+
teardown {
9+
DROP EXTENSION pg_stat_statements;
10+
DROP EXTENSION pg_wait_sampling;
11+
}
12+
13+
session "s1"
14+
step "s1_acquire_lock_on_relation" {
15+
BEGIN;
16+
LOCK pg_class IN ACCESS EXCLUSIVE MODE;
17+
}
18+
step "s1_wait_one_sec" {
19+
SELECT pg_sleep(1);
20+
}
21+
step "s1_release_relation_lock" {
22+
ROLLBACK;
23+
}
24+
25+
session "s2"
26+
step "s2_wait_on_relation_lock" {
27+
BEGIN;
28+
LOCK pg_class IN ACCESS SHARE MODE;
29+
ROLLBACK;
30+
}
31+
# FIXME: the profile have to expose not NULL query for wait on relation lock
32+
# After fix replace LEFT JOIN to INNER one
33+
step "s2_expose_wait_on_lock_in_profile" {
34+
SELECT query
35+
FROM pg_wait_sampling_profile pgws
36+
LEFT JOIN pg_stat_statements pgss using (queryid)
37+
WHERE pid = pg_backend_pid()
38+
AND event_type = 'Lock' AND event = 'relation'
39+
AND count between 90 and 110;
40+
}
41+
42+
permutation "s1_acquire_lock_on_relation" "s2_wait_on_relation_lock" "s1_wait_one_sec" "s1_release_relation_lock" "s2_expose_wait_on_lock_in_profile"

specs/queryid.spec

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
setup {
2+
CREATE EXTENSION pg_wait_sampling;
3+
CREATE EXTENSION pg_stat_statements;
4+
SELECT pg_stat_statements_reset();
5+
SELECT pg_wait_sampling_reset_profile();
6+
7+
CREATE TABLE test(i int);
8+
INSERT INTO test VALUES (1);
9+
}
10+
11+
teardown {
12+
DROP TABLE test;
13+
DROP EXTENSION pg_stat_statements;
14+
DROP EXTENSION pg_wait_sampling;
15+
}
16+
17+
session "s1"
18+
step "s1_update_tuple" {
19+
BEGIN;
20+
UPDATE test SET i = i+1;
21+
}
22+
step "s1_wait_one_sec" {
23+
SELECT pg_sleep(1);
24+
}
25+
step "s1_rollback_txn" {
26+
ROLLBACK;
27+
}
28+
29+
session "s2"
30+
step "s2_try_to_concurrently_update_tuple" {
31+
BEGIN;
32+
UPDATE test SET i = i+1;
33+
ROLLBACK;
34+
}
35+
36+
# For GUC profile_period = 10ms we expect 100 samples in Lock event type
37+
# with some little deviation, e.g., 10 samples
38+
step "s2_expose_wait_on_txn_in_profile" {
39+
SELECT query
40+
FROM pg_wait_sampling_profile pgws
41+
JOIN pg_stat_statements pgss using (queryid)
42+
WHERE pid = pg_backend_pid()
43+
AND event_type = 'Lock' AND event = 'transactionid'
44+
AND count between 90 and 110;
45+
}
46+
47+
permutation "s1_update_tuple" "s2_try_to_concurrently_update_tuple" "s1_wait_one_sec" "s1_rollback_txn" "s2_expose_wait_on_txn_in_profile"

sql/queries.sql

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
11
CREATE EXTENSION pg_wait_sampling;
22

3-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_current)
4-
SELECT sum(0) FROM generate_series(1, 2), t;
5-
6-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_history)
7-
SELECT sum(0) FROM generate_series(1, 2), t;
8-
9-
WITH t as (SELECT sum(0) FROM pg_wait_sampling_profile)
10-
SELECT sum(0) FROM generate_series(1, 2), t;
11-
12-
-- Some dummy checks just to be sure that all our functions work and return something.
3+
-- Some dummy checks just to be sure that all our functions work and return something
134
SELECT count(*) = 1 as test FROM pg_wait_sampling_get_current(pg_backend_pid());
14-
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_profile();
155
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_history();
16-
SELECT pg_wait_sampling_reset_profile();
6+
SELECT count(*) >= 0 as test FROM pg_wait_sampling_get_profile();
177

188
DROP EXTENSION pg_wait_sampling;

0 commit comments

Comments
 (0)