From e9c37a3f67f00821b998aec8443797c710703474 Mon Sep 17 00:00:00 2001 From: Rahila Syed Date: Fri, 28 Nov 2025 14:46:38 +0530 Subject: [PATCH 2/2] Test module to test memory context reporting with injection points --- src/test/modules/Makefile | 1 + .../test_memcontext_reporting/Makefile | 29 ++++ .../t/001_memcontext_inj.pl | 150 ++++++++++++++++++ .../test_memcontext_reporting.c | 12 ++ .../test_memcontext_reporting.control | 4 + 5 files changed, 196 insertions(+) create mode 100644 src/test/modules/test_memcontext_reporting/Makefile create mode 100644 src/test/modules/test_memcontext_reporting/t/001_memcontext_inj.pl create mode 100644 src/test/modules/test_memcontext_reporting/test_memcontext_reporting.c create mode 100644 src/test/modules/test_memcontext_reporting/test_memcontext_reporting.control diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 4c6d56d97d8..1156d731014 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -34,6 +34,7 @@ SUBDIRS = \ test_json_parser \ test_lfind \ test_lwlock_tranches \ + test_memcontext_reporting \ test_misc \ test_oat_hooks \ test_parser \ diff --git a/src/test/modules/test_memcontext_reporting/Makefile b/src/test/modules/test_memcontext_reporting/Makefile new file mode 100644 index 00000000000..0a2dfc44f1c --- /dev/null +++ b/src/test/modules/test_memcontext_reporting/Makefile @@ -0,0 +1,29 @@ +# src/test/modules/test_memcontext_reporting/Makefile + +EXTRA_INSTALL = src/test/modules/injection_points + +export enable_injection_points +MODULE_big = test_memcontext_reporting +OBJS = \ + $(WIN32RES) \ + test_memcontext_reporting.o +PGFILEDESC = "test_memcontext_reporting - test code for memory context reporting" + +REGRESS = test_memcontext_reporting + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_memcontext_reporting +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif + +check: + $(prove_check) + +installcheck: + $(prove_installcheck) diff --git a/src/test/modules/test_memcontext_reporting/t/001_memcontext_inj.pl b/src/test/modules/test_memcontext_reporting/t/001_memcontext_inj.pl new file mode 100644 index 00000000000..b491d6ebc0a --- /dev/null +++ b/src/test/modules/test_memcontext_reporting/t/001_memcontext_inj.pl @@ -0,0 +1,150 @@ +# Copyright (c) 2025, PostgreSQL Global Development Group + +# Test suite for testing memory context statistics reporting + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} +my $psql_err; +my $psql_out; +# Create and start a cluster with one node +my $node = PostgreSQL::Test::Cluster->new('main'); +$node->init; +$node->append_conf( + 'postgresql.conf', + qq[ +max_connections = 100 +log_statement = none +restart_after_crash = false +]); +$node->start; +$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;'); + +# Attaching to a client process's injection point that throws an error +$node->safe_psql('postgres', + "select injection_points_attach('memcontext-client-injection', 'error');" +); + +my $pid = $node->safe_psql('postgres', + "SELECT pid from pg_stat_activity where backend_type='checkpointer'"); + +#Client should have thrown error +$node->psql( + 'postgres', + qq(select pg_get_process_memory_contexts($pid, true);), + stderr => \$psql_err); +like($psql_err, + qr/error triggered for injection point memcontext-client-injection/); + +#Query the same process after detaching the injection point, using some other client and it should succeed. +$node->safe_psql('postgres', + "select injection_points_detach('memcontext-client-injection');"); +my $topcontext_name = $node->safe_psql('postgres', + "select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';" +); +ok($topcontext_name = 'TopMemoryContext'); + +# Attaching to a target process injection point that throws an error +$node->safe_psql('postgres', + "select injection_points_attach('memcontext-server-injection', 'error');" +); + +#Server should have thrown error +$node->psql( + 'postgres', + qq(select pg_get_process_memory_contexts($pid, true);), + stderr => \$psql_err); + +#Query the same process after detaching the injection point, using some other client and it should succeed. +$node->safe_psql('postgres', + "select injection_points_detach('memcontext-server-injection');"); +$topcontext_name = $node->safe_psql('postgres', + "select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';" +); +ok($topcontext_name = 'TopMemoryContext'); + +# Test that two concurrent requests to the same process results in a warning for +# one of those + +$node->safe_psql('postgres', + "SELECT injection_points_attach('memcontext-client-injection', 'wait');"); +$node->safe_psql('postgres', + "SELECT injection_points_attach('memcontext-server-wait', 'wait');"); +my $psql_session1 = $node->background_psql('postgres'); +$psql_session1->query_until( + qr//, + qq( + SELECT pg_get_process_memory_contexts($pid, true); +)); +$node->wait_for_event('client backend', 'memcontext-client-injection'); +$node->psql( + 'postgres', + qq(select pg_get_process_memory_contexts($pid, true);), + stderr => \$psql_err); +ok($psql_err =~ + /WARNING: server process $pid is processing previous request/); +#Wake the client up. +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('memcontext-client-injection');"); + +$node->safe_psql('postgres', + "select injection_points_detach('memcontext-client-injection');"); +$node->safe_psql('postgres', + "select injection_points_detach('memcontext-server-wait');"); + +# Test the client process exiting with timeout does not break the server process + +$node->safe_psql('postgres', + "SELECT injection_points_attach('memcontext-server-wait', 'wait');"); +# Following client query times out, returning NULL as output +$node->psql( + 'postgres', + qq(select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';), + stdout => \$psql_out); +ok($psql_out = 'NULL'); +#Wakeup the server process up and detach the injection point. +$node->safe_psql('postgres', + "SELECT injection_points_wakeup('memcontext-server-wait');"); +$node->safe_psql('postgres', + "select injection_points_detach('memcontext-server-wait');"); +#Query the same server process again and it should succeed. +$topcontext_name = $node->safe_psql('postgres', + "select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';" +); +ok($topcontext_name = 'TopMemoryContext'); + +# Test if the monitoring works fine, when the client backend crashes. +$node->safe_psql('postgres', + "select injection_points_attach('memcontext-client-injection', 'test_memcontext_reporting', 'crash', NULL);" +); + +#Client will crash +$node->psql( + 'postgres', + qq(select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';), + stderr => \$psql_err); +like($psql_err, + qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost|could not send data to server/ +); + +# Wait till server restarts +$node->restart; +$node->poll_query_until('postgres', "SELECT 1;", '1'); + +#Querying memory stats should succeed after server start +$pid = $node->safe_psql('postgres', + "SELECT pid from pg_stat_activity where backend_type='checkpointer'"); +$topcontext_name = $node->safe_psql('postgres', + "select name from pg_get_process_memory_contexts($pid, true) where path = '{1}';" +); +ok($topcontext_name = 'TopMemoryContext'); + +done_testing(); diff --git a/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.c b/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.c new file mode 100644 index 00000000000..d641f3616dc --- /dev/null +++ b/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.c @@ -0,0 +1,12 @@ +#include "postgres.h" +#include "funcapi.h" + +PG_MODULE_MAGIC; + +extern PGDLLEXPORT void crash(const char *name, const void *private_data, void *arg); + +void +crash(const char *name, const void *private_data, void *arg) +{ + abort(); +} diff --git a/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.control b/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.control new file mode 100644 index 00000000000..48b501682d5 --- /dev/null +++ b/src/test/modules/test_memcontext_reporting/test_memcontext_reporting.control @@ -0,0 +1,4 @@ +comment = 'Test code for memcontext reporting' +default_version = '1.0' +module_pathname = '$libdir/test_memcontext_reporting' +relocatable = true -- 2.34.1