From 02e3a28c48542789eaf9d9638fe94b535622f22a Mon Sep 17 00:00:00 2001
From: Asim R P <apraveen@pivotal.io>
Date: Mon, 19 Aug 2019 13:52:41 +0530
Subject: [PATCH 2/5] Add syntax to declare a step that is expected to block

The syntax is:

    blocking step "this_blocks" { SQL; }

This is useful for defining steps that are expected to block for reasons
other than waiting on a lock.  For example, an injected fault may cause
a backend to suspend until another event occurs.
---
 src/test/isolation/isolationtester.c | 26 +++++++++++++++-----------
 src/test/isolation/isolationtester.h |  1 +
 src/test/isolation/specparse.y       | 11 ++++++++++-
 src/test/isolation/specscanner.l     |  1 +
 4 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index f98bb1cf64..6aa2184a0f 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -726,19 +726,23 @@ try_complete_step(TestSpec *testspec, Step *step, int flags)
 			if (flags & STEP_NONBLOCK)
 			{
 				bool		waiting;
-
-				res = PQexecPrepared(conns[0], PREP_WAITING, 1,
-									 &backend_pid_strs[step->session + 1],
-									 NULL, NULL, 0);
-				if (PQresultStatus(res) != PGRES_TUPLES_OK ||
-					PQntuples(res) != 1)
+				if (step->blocks)
+					waiting = true;
+				else
 				{
-					fprintf(stderr, "lock wait query failed: %s",
-							PQerrorMessage(conns[0]));
-					exit(1);
+					res = PQexecPrepared(conns[0], PREP_WAITING, 1,
+										 &backend_pid_strs[step->session + 1],
+										 NULL, NULL, 0);
+					if (PQresultStatus(res) != PGRES_TUPLES_OK ||
+						PQntuples(res) != 1)
+					{
+						fprintf(stderr, "lock wait query failed: %s",
+								PQerrorMessage(conns[0]));
+						exit(1);
+					}
+					waiting = ((PQgetvalue(res, 0, 0))[0] == 't');
+					PQclear(res);
 				}
-				waiting = ((PQgetvalue(res, 0, 0))[0] == 't');
-				PQclear(res);
 
 				if (waiting)	/* waiting to acquire a lock */
 				{
diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h
index 7f91e6433f..31da1b1a72 100644
--- a/src/test/isolation/isolationtester.h
+++ b/src/test/isolation/isolationtester.h
@@ -29,6 +29,7 @@ struct Session
 struct Step
 {
 	int			session;
+	bool		blocks;
 	char	   *name;
 	char	   *sql;
 	char	   *errormsg;
diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y
index fb8a4d706c..c4a083fc98 100644
--- a/src/test/isolation/specparse.y
+++ b/src/test/isolation/specparse.y
@@ -45,7 +45,7 @@ TestSpec		parseresult;			/* result of parsing is left here */
 %type <permutation> permutation
 
 %token <str> sqlblock string_literal
-%token PERMUTATION SESSION SETUP STEP TEARDOWN TEST
+%token BLOCKING PERMUTATION SESSION SETUP STEP TEARDOWN TEST
 
 %%
 
@@ -143,10 +143,19 @@ step:
 			STEP string_literal sqlblock
 			{
 				$$ = pg_malloc(sizeof(Step));
+				$$->blocks = false;
 				$$->name = $2;
 				$$->sql = $3;
 				$$->errormsg = NULL;
 			}
+			| BLOCKING STEP string_literal sqlblock
+			{
+				$$ = pg_malloc(sizeof(Step));
+				$$->blocks = true;
+				$$->name = $3;
+				$$->sql = $4;
+				$$->errormsg = NULL;
+			}
 		;
 
 
diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l
index 3924c99294..70a3ea2ef5 100644
--- a/src/test/isolation/specscanner.l
+++ b/src/test/isolation/specscanner.l
@@ -48,6 +48,7 @@ comment			("#"{non_newline}*)
 	litbufsize = LITBUF_INIT;
 %}
 
+blocking		{ return BLOCKING; }
 permutation		{ return PERMUTATION; }
 session			{ return SESSION; }
 setup			{ return SETUP; }
-- 
2.17.2 (Apple Git-113)

