worker_spi: Switch to TAP tests
authorMichael Paquier <michael@paquier.xyz>
Thu, 27 Jul 2023 04:30:07 +0000 (13:30 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 27 Jul 2023 04:30:07 +0000 (13:30 +0900)
This commit moves worker_spi to use TAP tests.  sql/worker_spi.sql is
gone, replaced by an equivalent set of queries in a TAP script, without
worker_spi loaded in shared_preload_libraries:
- One query to launch a worker dynamically, relying now on "postgres" as
the default database to connect to.
- Two wait queries with poll_query_until(), one to wait for the worker
schema to be initialized and a second to wait for a tuple processed by
the worker.
- Server reload to accelerate the main loop of the spawned worker.

More coverage is added for workers registered when the library is loaded
with shared_preload_libraries, while on it, checking that these are
connecting to the database set in the GUC worker_spi.database.

A local run of these test is showing that TAP is slightly faster than
the original, while providing more coverage (3.7s vs 4.4s).  There was
also some discussions about keeping the SQL tests, but this would
require initializing twice a cluster, increasing the runtime of the
tests up to 5.6s here.

These tests will be expanded more in an upcoming patch aimed at adding
support for custom wait events for the Extension class, still under
discussion, to check the new in-core APIs with and without a library set
in shared_preload_libraries.

Bharath has written the part where shared_preload_libraries is used,
while I have migrated the existing SQL tests to TAP.

Author: Bharath Rupireddy, Michael Paquier
Reviewed-by: Masahiro Ikeda
Discussion: https://postgr.es/m/CALj2ACWR9ncAiDF73unqdJF1dmsA2R0efGXX2624X+YVxcAVWg@mail.gmail.com

src/test/modules/worker_spi/.gitignore
src/test/modules/worker_spi/Makefile
src/test/modules/worker_spi/dynamic.conf [deleted file]
src/test/modules/worker_spi/expected/worker_spi.out [deleted file]
src/test/modules/worker_spi/meson.build
src/test/modules/worker_spi/sql/worker_spi.sql [deleted file]
src/test/modules/worker_spi/t/001_worker_spi.pl [new file with mode: 0644]

index 5dcb3ff9723501c3fe639bee1c1435e47a580a6f..716e17f5a2ad4e3e55639700d60cdff2eddd3f98 100644 (file)
@@ -1,4 +1,2 @@
 # Generated subdirectories
-/log/
-/results/
 /tmp_check/
index cbf9b2e37fd6da99b9250481f903eec1940e54ae..024b34cdbb356e104469c0b893a930e8a839c8df 100644 (file)
@@ -6,13 +6,7 @@ EXTENSION = worker_spi
 DATA = worker_spi--1.0.sql
 PGFILEDESC = "worker_spi - background worker example"
 
-REGRESS = worker_spi
-
-# enable our module in shared_preload_libraries for dynamic bgworkers
-REGRESS_OPTS = --temp-config $(top_srcdir)/src/test/modules/worker_spi/dynamic.conf
-
-# Disable installcheck to ensure we cover dynamic bgworkers.
-NO_INSTALLCHECK = 1
+TAP_TESTS = 1
 
 ifdef USE_PGXS
 PG_CONFIG = pg_config
diff --git a/src/test/modules/worker_spi/dynamic.conf b/src/test/modules/worker_spi/dynamic.conf
deleted file mode 100644 (file)
index bfe015f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-shared_preload_libraries = worker_spi
-worker_spi.database = contrib_regression
diff --git a/src/test/modules/worker_spi/expected/worker_spi.out b/src/test/modules/worker_spi/expected/worker_spi.out
deleted file mode 100644 (file)
index dc0a79b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-CREATE EXTENSION worker_spi;
-SELECT worker_spi_launch(4) IS NOT NULL;
- ?column? 
-----------
- t
-(1 row)
-
--- wait until the worker completes its initialization
-DO $$
-DECLARE
-       visible bool;
-       loops int := 0;
-BEGIN
-       LOOP
-               visible := table_name IS NOT NULL
-                       FROM information_schema.tables
-                       WHERE table_schema = 'schema4' AND table_name = 'counted';
-               IF visible OR loops > 120 * 10 THEN EXIT; END IF;
-               PERFORM pg_sleep(0.1);
-               loops := loops + 1;
-       END LOOP;
-END
-$$;
-INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1);
-SELECT pg_reload_conf();
- pg_reload_conf 
-----------------
- t
-(1 row)
-
--- wait until the worker has processed the tuple we just inserted
-DO $$
-DECLARE
-       count int;
-       loops int := 0;
-BEGIN
-       LOOP
-               count := count(*) FROM schema4.counted WHERE type = 'delta';
-               IF count = 0 OR loops > 120 * 10 THEN EXIT; END IF;
-               PERFORM pg_sleep(0.1);
-               loops := loops + 1;
-       END LOOP;
-END
-$$;
-SELECT * FROM schema4.counted;
- type  | value 
--------+-------
- total |     1
-(1 row)
-
index a8cdfdeb36b8b3c188f6a217f0117a4613584b2a..68870324c9e68075ce4e92358de2652252b9a757 100644 (file)
@@ -25,12 +25,9 @@ tests += {
   'name': 'worker_spi',
   'sd': meson.current_source_dir(),
   'bd': meson.current_build_dir(),
-  'regress': {
-    'sql': [
-      'worker_spi',
+  'tap': {
+    'tests': [
+      't/001_worker_spi.pl',
     ],
-    'dbname': 'contrib_regression',
-    'regress_args': ['--temp-config', files('dynamic.conf')],
-    'runningcheck': false,
   },
 }
diff --git a/src/test/modules/worker_spi/sql/worker_spi.sql b/src/test/modules/worker_spi/sql/worker_spi.sql
deleted file mode 100644 (file)
index 4683523..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-CREATE EXTENSION worker_spi;
-SELECT worker_spi_launch(4) IS NOT NULL;
--- wait until the worker completes its initialization
-DO $$
-DECLARE
-       visible bool;
-       loops int := 0;
-BEGIN
-       LOOP
-               visible := table_name IS NOT NULL
-                       FROM information_schema.tables
-                       WHERE table_schema = 'schema4' AND table_name = 'counted';
-               IF visible OR loops > 120 * 10 THEN EXIT; END IF;
-               PERFORM pg_sleep(0.1);
-               loops := loops + 1;
-       END LOOP;
-END
-$$;
-INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1);
-SELECT pg_reload_conf();
--- wait until the worker has processed the tuple we just inserted
-DO $$
-DECLARE
-       count int;
-       loops int := 0;
-BEGIN
-       LOOP
-               count := count(*) FROM schema4.counted WHERE type = 'delta';
-               IF count = 0 OR loops > 120 * 10 THEN EXIT; END IF;
-               PERFORM pg_sleep(0.1);
-               loops := loops + 1;
-       END LOOP;
-END
-$$;
-SELECT * FROM schema4.counted;
diff --git a/src/test/modules/worker_spi/t/001_worker_spi.pl b/src/test/modules/worker_spi/t/001_worker_spi.pl
new file mode 100644 (file)
index 0000000..c293871
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright (c) 2023, PostgreSQL Global Development Group
+
+# Test worker_spi module.
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+my $node = PostgreSQL::Test::Cluster->new('mynode');
+$node->init;
+$node->start;
+
+note "testing dynamic bgworkers";
+
+$node->safe_psql('postgres', 'CREATE EXTENSION worker_spi;');
+
+# Launch one dynamic worker, then wait for its initialization to complete.
+# This consists in making sure that a table name "counted" is created
+# on a new schema whose name includes the index defined in input argument
+# of worker_spi_launch().
+# By default, dynamic bgworkers connect to the "postgres" database.
+my $result =
+  $node->safe_psql('postgres', 'SELECT worker_spi_launch(4) IS NOT NULL;');
+is($result, 't', "dynamic bgworker launched");
+$node->poll_query_until(
+       'postgres',
+       qq[SELECT count(*) > 0 FROM information_schema.tables
+           WHERE table_schema = 'schema4' AND table_name = 'counted';]);
+$node->safe_psql('postgres',
+       "INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1);");
+# Issue a SIGHUP on the node to force the worker to loop once, accelerating
+# this test.
+$node->reload;
+# Wait until the worker has processed the tuple that has just been inserted.
+$node->poll_query_until('postgres',
+       qq[SELECT count(*) FROM schema4.counted WHERE type = 'delta';], '0');
+$result = $node->safe_psql('postgres', 'SELECT * FROM schema4.counted;');
+is($result, qq(total|1), 'dynamic bgworker correctly consumed tuple data');
+
+note "testing bgworkers loaded with shared_preload_libraries";
+
+# Create the database first so as the workers can connect to it when
+# the library is loaded.
+$node->safe_psql('postgres', q(CREATE DATABASE mydb;));
+$node->safe_psql('mydb', 'CREATE EXTENSION worker_spi;');
+
+# Now load the module as a shared library.
+$node->append_conf(
+       'postgresql.conf', q{
+shared_preload_libraries = 'worker_spi'
+worker_spi.database = 'mydb'
+worker_spi.total_workers = 3
+});
+$node->restart;
+
+# Check that bgworkers have been registered and launched.
+ok( $node->poll_query_until(
+               'mydb',
+               qq[SELECT datname, count(datname) FROM pg_stat_activity
+            WHERE backend_type = 'worker_spi' GROUP BY datname;],
+               'mydb|3'),
+       'bgworkers all launched'
+) or die "Timed out while waiting for bgworkers to be launched";
+
+# Ask worker_spi to launch dynamic bgworkers with the library loaded, then
+# check their existence.
+my $worker1_pid = $node->safe_psql('mydb', 'SELECT worker_spi_launch(1);');
+my $worker2_pid = $node->safe_psql('mydb', 'SELECT worker_spi_launch(2);');
+ok( $node->poll_query_until(
+               'mydb',
+               qq[SELECT datname, count(datname)  FROM pg_stat_activity
+            WHERE backend_type = 'worker_spi dynamic' AND
+            pid IN ($worker1_pid, $worker2_pid) GROUP BY datname;],
+               'mydb|2'),
+       'dynamic bgworkers all launched'
+) or die "Timed out while waiting for dynamic bgworkers to be launched";
+
+done_testing();