From 973b4fc4c72d23f9303dbb2832f8241c58d163e8 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Mon, 19 Dec 2022 18:39:53 +1100 Subject: [PATCH v2] isolationtester - allow conninfo to be specified --- src/test/isolation/Makefile | 3 + src/test/isolation/expected/pub-sub.out | 251 ++++++++++++++++++++++++++++++++ src/test/isolation/isolationtester.c | 36 ++++- src/test/isolation/isolationtester.h | 2 + src/test/isolation/specparse.y | 36 +++-- src/test/isolation/specs/pub-sub.spec | 86 +++++++++++ src/test/isolation/specscanner.l | 1 + 7 files changed, 400 insertions(+), 15 deletions(-) create mode 100644 src/test/isolation/expected/pub-sub.out create mode 100644 src/test/isolation/specs/pub-sub.spec diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index b8738b7..fe7e8cb 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -78,3 +78,6 @@ installcheck-prepared-txns: all temp-install check-prepared-txns: all temp-install $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule prepared-transactions prepared-transactions-cic + +check-pub-sub: temp-install + $(pg_isolation_regress_check) pub-sub diff --git a/src/test/isolation/expected/pub-sub.out b/src/test/isolation/expected/pub-sub.out new file mode 100644 index 0000000..f9ee376 --- /dev/null +++ b/src/test/isolation/expected/pub-sub.out @@ -0,0 +1,251 @@ +Parsed test spec with 3 sessions +control connection conninfo 'host=localhost port=7651' +ps1 conninfo 'host=localhost port=7651' +ps2 conninfo 'host=localhost port=7651' +sub conninfo 'host=localhost port=7652' + WARNING: session sub is not using same connection as the controller + +starting permutation: ps1_begin ps1_ins ps1_commit ps1_sel ps2_sel sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps1_commit: COMMIT; +step ps1_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +(1 row) + +step ps2_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +(1 row) + +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +(1 row) + + +starting permutation: ps2_begin ps2_ins ps2_commit ps1_sel ps2_sel sub_sleep sub_sel +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps2_commit: COMMIT; +step ps1_sel: SELECT * FROM tbl ORDER BY id; + id +--- +222 +(1 row) + +step ps2_sel: SELECT * FROM tbl ORDER BY id; + id +--- +222 +(1 row) + +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +222 +(1 row) + + +starting permutation: ps1_begin ps1_ins ps1_rollback ps1_sel sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps1_rollback: ROLLBACK; +step ps1_sel: SELECT * FROM tbl ORDER BY id; +id +-- +(0 rows) + +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; +id +-- +(0 rows) + + +starting permutation: ps1_begin ps1_ins ps2_begin ps2_ins ps1_rollback ps2_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_rollback: ROLLBACK; +step ps2_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +222 +(1 row) + + +starting permutation: ps1_begin ps1_ins ps2_begin ps2_ins ps1_commit ps2_rollback sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_commit: COMMIT; +step ps2_rollback: ROLLBACK; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +(1 row) + + +starting permutation: ps1_begin ps1_ins ps2_begin ps2_ins ps2_commit ps1_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps2_commit: COMMIT; +step ps1_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + + +starting permutation: ps1_begin ps1_ins ps2_begin ps2_ins ps1_commit ps2_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_commit: COMMIT; +step ps2_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + + +starting permutation: ps1_begin ps2_begin ps1_ins ps2_ins ps2_commit ps1_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps2_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps2_commit: COMMIT; +step ps1_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + + +starting permutation: ps1_begin ps2_begin ps1_ins ps2_ins ps1_commit ps2_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps2_begin: BEGIN; +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_commit: COMMIT; +step ps2_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + + +starting permutation: ps1_begin ps2_begin ps2_ins ps1_ins ps2_commit ps1_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps2_commit: COMMIT; +step ps1_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + + +starting permutation: ps1_begin ps2_begin ps2_ins ps1_ins ps1_commit ps2_commit sub_sleep sub_sel +step ps1_begin: BEGIN; +step ps2_begin: BEGIN; +step ps2_ins: INSERT INTO tbl VALUES (222); +step ps1_ins: INSERT INTO tbl VALUES (111); +step ps1_commit: COMMIT; +step ps2_commit: COMMIT; +step sub_sleep: SELECT pg_sleep(3); +pg_sleep +-------- + +(1 row) + +step sub_sel: SELECT * FROM tbl ORDER BY id; + id +--- +111 +222 +(2 rows) + diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c index 0a66235..4bac830 100644 --- a/src/test/isolation/isolationtester.c +++ b/src/test/isolation/isolationtester.c @@ -119,6 +119,8 @@ main(int argc, char **argv) * as the conninfo string; otherwise default to setting dbname=postgres * and using environment variables or defaults for all other connection * parameters. + * + * Note, this will be overridden by any session specific 'conninfo'. */ if (argc > optind) conninfo = argv[optind]; @@ -153,15 +155,47 @@ main(int argc, char **argv) for (i = 0; i < nconns; i++) { const char *sessionname; + const char *sessionconninfo; if (i == 0) + { sessionname = "control connection"; + sessionconninfo = NULL; + if (testspec->controllerconninfo) + conninfo = testspec->controllerconninfo; + } else + { sessionname = testspec->sessions[i - 1]->name; + sessionconninfo = testspec->sessions[i - 1]->conninfo; + } conns[i].sessionname = sessionname; - conns[i].conn = PQconnectdb(conninfo); + /* + * If this spec session has specified a conninfo to use then that + * overrides any other conninfo (e.g. passed as an argument or + * the controller's conninfo) + * + * Note - the necessary instance to connect to is assumed to exist + * already manually setup by the user. + */ + if (sessionconninfo) + { + fprintf(stderr, "%s conninfo '%s'\n", sessionname, sessionconninfo); + + if (strcmp(sessionconninfo, conninfo) != 0) + fprintf(stderr, "\tWARNING: session %s is not using same connection as the controller\n", sessionname); + + conns[i].conn = PQconnectdb(sessionconninfo); + } + else + { + if (testspec->controllerconninfo) + fprintf(stderr, "%s conninfo '%s'\n", sessionname, conninfo); + + conns[i].conn = PQconnectdb(conninfo); + } if (PQstatus(conns[i].conn) != CONNECTION_OK) { fprintf(stderr, "Connection %d failed: %s", diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h index 77134b0..8c75f6b 100644 --- a/src/test/isolation/isolationtester.h +++ b/src/test/isolation/isolationtester.h @@ -24,6 +24,7 @@ typedef struct Step Step; typedef struct { char *name; + char *conninfo; char *setupsql; char *teardownsql; Step **steps; @@ -74,6 +75,7 @@ typedef struct typedef struct { + char *controllerconninfo; char **setupsqls; int nsetupsqls; char *teardownsql; diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y index 657285c..a79a699 100644 --- a/src/test/isolation/specparse.y +++ b/src/test/isolation/specparse.y @@ -39,7 +39,7 @@ TestSpec parseresult; /* result of parsing is left here */ } %type setup_list -%type opt_setup opt_teardown +%type opt_conninfo opt_setup opt_teardown %type setup %type step_list session_list permutation_list opt_permutation_list %type permutation_step_list blocker_list @@ -51,23 +51,25 @@ TestSpec parseresult; /* result of parsing is left here */ %token sqlblock identifier %token INTEGER -%token NOTICES PERMUTATION SESSION SETUP STEP TEARDOWN TEST +%token NOTICES PERMUTATION SESSION CONNINFO SETUP STEP TEARDOWN TEST %% TestSpec: + opt_conninfo setup_list opt_teardown session_list opt_permutation_list { - parseresult.setupsqls = (char **) $1.elements; - parseresult.nsetupsqls = $1.nelements; - parseresult.teardownsql = $2; - parseresult.sessions = (Session **) $3.elements; - parseresult.nsessions = $3.nelements; - parseresult.permutations = (Permutation **) $4.elements; - parseresult.npermutations = $4.nelements; + parseresult.controllerconninfo = $1; + parseresult.setupsqls = (char **) $2.elements; + parseresult.nsetupsqls = $2.nelements; + parseresult.teardownsql = $3; + parseresult.sessions = (Session **) $4.elements; + parseresult.nsessions = $4.nelements; + parseresult.permutations = (Permutation **) $5.elements; + parseresult.npermutations = $5.nelements; } ; @@ -86,6 +88,11 @@ setup_list: } ; +opt_conninfo: + /* EMPTY */ { $$ = NULL; } + | CONNINFO identifier { $$ = $2; } + ; + opt_setup: /* EMPTY */ { $$ = NULL; } | setup { $$ = $1; } @@ -117,14 +124,15 @@ session_list: ; session: - SESSION identifier opt_setup step_list opt_teardown + SESSION identifier opt_conninfo opt_setup step_list opt_teardown { $$ = pg_malloc(sizeof(Session)); $$->name = $2; - $$->setupsql = $3; - $$->steps = (Step **) $4.elements; - $$->nsteps = $4.nelements; - $$->teardownsql = $5; + $$->conninfo = $3; + $$->setupsql = $4; + $$->steps = (Step **) $5.elements; + $$->nsteps = $5.nelements; + $$->teardownsql = $6; } ; diff --git a/src/test/isolation/specs/pub-sub.spec b/src/test/isolation/specs/pub-sub.spec new file mode 100644 index 0000000..0f81d0a --- /dev/null +++ b/src/test/isolation/specs/pub-sub.spec @@ -0,0 +1,86 @@ +# +# Test assumes there is already setup so +# +# PG server for publisher (running on port 7651) +# - has TABLE tbl +# - has PUBLICATION pub1 +# +# PG server for subscriber (running on port 7652) +# - has TABLE tbl +# - has SUBSCRIPTION sub1 subscribing to pub1 +# +# ~~~ +# +# Now the following spec tests are configured to have multiple sessions on the +# publisher so we can interleave the WAL records to see the effect for the +# subscription +# +# ~~~ +# +# How to run +# 1. Run . ./test_init.sh to create the PG instances, table, and publication/subscription +# 2. Run the isolation tester make check-pub-sub (runs this spec) +# 3. Check the logs of the PG instances +# + +# Set the isolationtester controller's conninfo. User sessions will also use +# this unless they specify otherwise. +conninfo "host=localhost port=7651" + +################ +# Publisher node +################ +session ps1 +setup +{ + TRUNCATE TABLE tbl; +} +step ps1_ins { INSERT INTO tbl VALUES (111); } +step ps1_sel { SELECT * FROM tbl ORDER BY id; } +step ps1_begin { BEGIN; } +step ps1_commit { COMMIT; } +step ps1_rollback { ROLLBACK; } + +session ps2 +step ps2_ins { INSERT INTO tbl VALUES (222); } +step ps2_sel { SELECT * FROM tbl ORDER BY id; } +step ps2_begin { BEGIN; } +step ps2_commit { COMMIT; } +step ps2_rollback { ROLLBACK; } + +################# +# Subscriber node +################# +session sub +conninfo "host=localhost port=7652" +setup +{ + TRUNCATE TABLE tbl; +} +step sub_sleep { SELECT pg_sleep(3); } +step sub_sel { SELECT * FROM tbl ORDER BY id; } + +####### +# Tests +####### + +# single tx +permutation ps1_begin ps1_ins ps1_commit ps1_sel ps2_sel sub_sleep sub_sel +permutation ps2_begin ps2_ins ps2_commit ps1_sel ps2_sel sub_sleep sub_sel + +# rollback +permutation ps1_begin ps1_ins ps1_rollback ps1_sel sub_sleep sub_sel + +# overlapping tx rollback and commit +permutation ps1_begin ps1_ins ps2_begin ps2_ins ps1_rollback ps2_commit sub_sleep sub_sel +permutation ps1_begin ps1_ins ps2_begin ps2_ins ps1_commit ps2_rollback sub_sleep sub_sel + +# overlapping tx commits +permutation ps1_begin ps1_ins ps2_begin ps2_ins ps2_commit ps1_commit sub_sleep sub_sel +permutation ps1_begin ps1_ins ps2_begin ps2_ins ps1_commit ps2_commit sub_sleep sub_sel + +permutation ps1_begin ps2_begin ps1_ins ps2_ins ps2_commit ps1_commit sub_sleep sub_sel +permutation ps1_begin ps2_begin ps1_ins ps2_ins ps1_commit ps2_commit sub_sleep sub_sel + +permutation ps1_begin ps2_begin ps2_ins ps1_ins ps2_commit ps1_commit sub_sleep sub_sel +permutation ps1_begin ps2_begin ps2_ins ps1_ins ps1_commit ps2_commit sub_sleep sub_sel diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l index b04696f..3174372 100644 --- a/src/test/isolation/specscanner.l +++ b/src/test/isolation/specscanner.l @@ -71,6 +71,7 @@ self [,()*] %} /* Keywords (must appear before the {identifier} rule!) */ +conninfo { return CONNINFO; } notices { return NOTICES; } permutation { return PERMUTATION; } session { return SESSION; } -- 1.8.3.1