|
| 1 | +# Copyright (c) 2023, PostgreSQL Global Development Group |
| 2 | + |
| 3 | +# Test worker_spi module. |
| 4 | + |
| 5 | +use strict; |
| 6 | +use warnings; |
| 7 | +use PostgreSQL::Test::Cluster; |
| 8 | +use PostgreSQL::Test::Utils; |
| 9 | +use Test::More; |
| 10 | + |
| 11 | +my $node = PostgreSQL::Test::Cluster->new('mynode'); |
| 12 | +$node->init; |
| 13 | +$node->start; |
| 14 | + |
| 15 | +note "testing dynamic bgworkers"; |
| 16 | + |
| 17 | +$node->safe_psql('postgres', 'CREATE EXTENSION worker_spi;'); |
| 18 | + |
| 19 | +# Launch one dynamic worker, then wait for its initialization to complete. |
| 20 | +# This consists in making sure that a table name "counted" is created |
| 21 | +# on a new schema whose name includes the index defined in input argument |
| 22 | +# of worker_spi_launch(). |
| 23 | +# By default, dynamic bgworkers connect to the "postgres" database. |
| 24 | +my $result = |
| 25 | + $node->safe_psql('postgres', 'SELECT worker_spi_launch(4) IS NOT NULL;'); |
| 26 | +is($result, 't', "dynamic bgworker launched"); |
| 27 | +$node->poll_query_until( |
| 28 | + 'postgres', |
| 29 | + qq[SELECT count(*) > 0 FROM information_schema.tables |
| 30 | + WHERE table_schema = 'schema4' AND table_name = 'counted';]); |
| 31 | +$node->safe_psql('postgres', |
| 32 | + "INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1);"); |
| 33 | +# Issue a SIGHUP on the node to force the worker to loop once, accelerating |
| 34 | +# this test. |
| 35 | +$node->reload; |
| 36 | +# Wait until the worker has processed the tuple that has just been inserted. |
| 37 | +$node->poll_query_until('postgres', |
| 38 | + qq[SELECT count(*) FROM schema4.counted WHERE type = 'delta';], '0'); |
| 39 | +$result = $node->safe_psql('postgres', 'SELECT * FROM schema4.counted;'); |
| 40 | +is($result, qq(total|1), 'dynamic bgworker correctly consumed tuple data'); |
| 41 | + |
| 42 | +note "testing bgworkers loaded with shared_preload_libraries"; |
| 43 | + |
| 44 | +# Create the database first so as the workers can connect to it when |
| 45 | +# the library is loaded. |
| 46 | +$node->safe_psql('postgres', q(CREATE DATABASE mydb;)); |
| 47 | +$node->safe_psql('mydb', 'CREATE EXTENSION worker_spi;'); |
| 48 | + |
| 49 | +# Now load the module as a shared library. |
| 50 | +$node->append_conf( |
| 51 | + 'postgresql.conf', q{ |
| 52 | +shared_preload_libraries = 'worker_spi' |
| 53 | +worker_spi.database = 'mydb' |
| 54 | +worker_spi.total_workers = 3 |
| 55 | +}); |
| 56 | +$node->restart; |
| 57 | + |
| 58 | +# Check that bgworkers have been registered and launched. |
| 59 | +ok( $node->poll_query_until( |
| 60 | + 'mydb', |
| 61 | + qq[SELECT datname, count(datname) FROM pg_stat_activity |
| 62 | + WHERE backend_type = 'worker_spi' GROUP BY datname;], |
| 63 | + 'mydb|3'), |
| 64 | + 'bgworkers all launched' |
| 65 | +) or die "Timed out while waiting for bgworkers to be launched"; |
| 66 | + |
| 67 | +# Ask worker_spi to launch dynamic bgworkers with the library loaded, then |
| 68 | +# check their existence. |
| 69 | +my $worker1_pid = $node->safe_psql('mydb', 'SELECT worker_spi_launch(1);'); |
| 70 | +my $worker2_pid = $node->safe_psql('mydb', 'SELECT worker_spi_launch(2);'); |
| 71 | +ok( $node->poll_query_until( |
| 72 | + 'mydb', |
| 73 | + qq[SELECT datname, count(datname) FROM pg_stat_activity |
| 74 | + WHERE backend_type = 'worker_spi dynamic' AND |
| 75 | + pid IN ($worker1_pid, $worker2_pid) GROUP BY datname;], |
| 76 | + 'mydb|2'), |
| 77 | + 'dynamic bgworkers all launched' |
| 78 | +) or die "Timed out while waiting for dynamic bgworkers to be launched"; |
| 79 | + |
| 80 | +done_testing(); |
0 commit comments