mirror of
https://github.com/postgres/postgres.git
synced 2025-10-18 04:29:09 +03:00
Add a test harness for the LWLock tranche code.
This code is heavily used and already has decent test coverage, but it lacks a dedicated test suite. This commit changes that. Author: Sami Imseih <samimseih@gmail.com> Co-authored-by: Nathan Bossart <nathandbossart@gmail.com> Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com> Discussion: https://postgr.es/m/CAA5RZ0tQ%2BEYSTOd2hQ8RXdsNfGBLAtOe-YmnsTE6ZVg0E-4qew%40mail.gmail.com Discussion: https://postgr.es/m/CAA5RZ0vpr0P2rbA%3D_K0_SCHM7bmfVX4wEO9FAyopN1eWCYORhA%40mail.gmail.com
This commit is contained in:
@@ -29,6 +29,7 @@ SUBDIRS = \
|
||||
test_integerset \
|
||||
test_json_parser \
|
||||
test_lfind \
|
||||
test_lwlock_tranches \
|
||||
test_misc \
|
||||
test_oat_hooks \
|
||||
test_parser \
|
||||
|
@@ -28,6 +28,7 @@ subdir('test_int128')
|
||||
subdir('test_integerset')
|
||||
subdir('test_json_parser')
|
||||
subdir('test_lfind')
|
||||
subdir('test_lwlock_tranches')
|
||||
subdir('test_misc')
|
||||
subdir('test_oat_hooks')
|
||||
subdir('test_parser')
|
||||
|
4
src/test/modules/test_lwlock_tranches/.gitignore
vendored
Normal file
4
src/test/modules/test_lwlock_tranches/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Generated subdirectories
|
||||
/log/
|
||||
/results/
|
||||
/tmp_check/
|
25
src/test/modules/test_lwlock_tranches/Makefile
Normal file
25
src/test/modules/test_lwlock_tranches/Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
# src/test/modules/test_lwlock_tranches/Makefile
|
||||
|
||||
MODULE_big = test_lwlock_tranches
|
||||
OBJS = \
|
||||
$(WIN32RES) \
|
||||
test_lwlock_tranches.o
|
||||
PGFILEDESC = "test_lwlock_tranches - test code for LWLock tranches allocated by extensions"
|
||||
|
||||
EXTENSION = test_lwlock_tranches
|
||||
DATA = test_lwlock_tranches--1.0.sql
|
||||
|
||||
REGRESS_OPTS = --temp-config $(top_srcdir)/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf
|
||||
REGRESS = test_lwlock_tranches
|
||||
NO_INSTALLCHECK = 1
|
||||
|
||||
ifdef USE_PGXS
|
||||
PG_CONFIG = pg_config
|
||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||
include $(PGXS)
|
||||
else
|
||||
subdir = src/test/modules/test_lwlock_tranches
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
include $(top_srcdir)/contrib/contrib-global.mk
|
||||
endif
|
@@ -0,0 +1,25 @@
|
||||
CREATE EXTENSION test_lwlock_tranches;
|
||||
SELECT test_lwlock_tranches();
|
||||
test_lwlock_tranches
|
||||
----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT test_lwlock_tranche_creation(NULL);
|
||||
ERROR: tranche name cannot be NULL
|
||||
SELECT test_lwlock_tranche_creation(repeat('a', 64));
|
||||
ERROR: tranche name too long
|
||||
DETAIL: LWLock tranche names must be no longer than 63 bytes.
|
||||
SELECT test_lwlock_tranche_creation('test');
|
||||
ERROR: maximum number of tranches already registered
|
||||
DETAIL: No more than 256 tranches may be registered.
|
||||
SELECT test_lwlock_tranche_lookup('test_lwlock_tranches_startup');
|
||||
test_lwlock_tranche_lookup
|
||||
----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT test_lwlock_tranche_lookup('bogus');
|
||||
ERROR: requested tranche is not registered
|
||||
SELECT test_lwlock_initialize(65535);
|
||||
ERROR: tranche 65535 is not registered
|
35
src/test/modules/test_lwlock_tranches/meson.build
Normal file
35
src/test/modules/test_lwlock_tranches/meson.build
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2025, PostgreSQL Global Development Group
|
||||
|
||||
test_lwlock_tranches_sources = files(
|
||||
'test_lwlock_tranches.c',
|
||||
)
|
||||
|
||||
if host_system == 'windows'
|
||||
test_lwlock_tranches_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
|
||||
'--NAME', 'test_lwlock_tranches',
|
||||
'--FILEDESC', 'test_lwlock_tranches - test code for LWLock tranches allocated by extensions',])
|
||||
endif
|
||||
|
||||
test_lwlock_tranches = shared_module('test_lwlock_tranches',
|
||||
test_lwlock_tranches_sources,
|
||||
kwargs: pg_test_mod_args,
|
||||
)
|
||||
test_install_libs += test_lwlock_tranches
|
||||
|
||||
test_install_data += files(
|
||||
'test_lwlock_tranches.control',
|
||||
'test_lwlock_tranches--1.0.sql',
|
||||
)
|
||||
|
||||
tests += {
|
||||
'name': 'test_lwlock_tranches',
|
||||
'sd': meson.current_source_dir(),
|
||||
'bd': meson.current_build_dir(),
|
||||
'regress': {
|
||||
'sql': [
|
||||
'test_lwlock_tranches',
|
||||
],
|
||||
'regress_args': ['--temp-config', files('test_lwlock_tranches.conf')],
|
||||
'runningcheck': false,
|
||||
},
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
CREATE EXTENSION test_lwlock_tranches;
|
||||
SELECT test_lwlock_tranches();
|
||||
SELECT test_lwlock_tranche_creation(NULL);
|
||||
SELECT test_lwlock_tranche_creation(repeat('a', 64));
|
||||
SELECT test_lwlock_tranche_creation('test');
|
||||
SELECT test_lwlock_tranche_lookup('test_lwlock_tranches_startup');
|
||||
SELECT test_lwlock_tranche_lookup('bogus');
|
||||
SELECT test_lwlock_initialize(65535);
|
@@ -0,0 +1,16 @@
|
||||
/* src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql */
|
||||
|
||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "CREATE EXTENSION test_lwlock_tranches" to load this file. \quit
|
||||
|
||||
CREATE FUNCTION test_lwlock_tranches() RETURNS VOID
|
||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||
|
||||
CREATE FUNCTION test_lwlock_tranche_creation(tranche_name TEXT) RETURNS VOID
|
||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||
|
||||
CREATE FUNCTION test_lwlock_tranche_lookup(tranche_name TEXT) RETURNS VOID
|
||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||
|
||||
CREATE FUNCTION test_lwlock_initialize(tranche_id INT) RETURNS VOID
|
||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
123
src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c
Normal file
123
src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
*
|
||||
* test_lwlock_tranches.c
|
||||
* Test code for LWLock tranches allocated by extensions.
|
||||
*
|
||||
* Copyright (c) 2025, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "fmgr.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/wait_classes.h"
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
#define STARTUP_TRANCHE_NAME "test_lwlock_tranches_startup"
|
||||
#define DYNAMIC_TRANCHE_NAME "test_lwlock_tranches_dynamic"
|
||||
|
||||
#define NUM_STARTUP_TRANCHES (32)
|
||||
#define NUM_DYNAMIC_TRANCHES (256 - NUM_STARTUP_TRANCHES)
|
||||
|
||||
#define GET_TRANCHE_NAME(a) GetLWLockIdentifier(PG_WAIT_LWLOCK, (a))
|
||||
|
||||
static shmem_request_hook_type prev_shmem_request_hook;
|
||||
static void test_lwlock_tranches_shmem_request(void);
|
||||
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
prev_shmem_request_hook = shmem_request_hook;
|
||||
shmem_request_hook = test_lwlock_tranches_shmem_request;
|
||||
}
|
||||
|
||||
static void
|
||||
test_lwlock_tranches_shmem_request(void)
|
||||
{
|
||||
if (prev_shmem_request_hook)
|
||||
prev_shmem_request_hook();
|
||||
|
||||
for (int i = 0; i < NUM_STARTUP_TRANCHES; i++)
|
||||
RequestNamedLWLockTranche(STARTUP_TRANCHE_NAME, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks that GetLWLockIdentifier() returns the expected value for tranches
|
||||
* registered via RequestNamedLWLockTranche() and LWLockNewTrancheId().
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(test_lwlock_tranches);
|
||||
Datum
|
||||
test_lwlock_tranches(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int dynamic_tranches[NUM_DYNAMIC_TRANCHES];
|
||||
|
||||
for (int i = 0; i < NUM_DYNAMIC_TRANCHES; i++)
|
||||
dynamic_tranches[i] = LWLockNewTrancheId(DYNAMIC_TRANCHE_NAME);
|
||||
|
||||
for (int i = 0; i < NUM_STARTUP_TRANCHES; i++)
|
||||
{
|
||||
if (strcmp(GET_TRANCHE_NAME(LWTRANCHE_FIRST_USER_DEFINED + i),
|
||||
STARTUP_TRANCHE_NAME) != 0)
|
||||
elog(ERROR, "incorrect startup lock tranche name");
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_DYNAMIC_TRANCHES; i++)
|
||||
{
|
||||
if (strcmp(GET_TRANCHE_NAME(dynamic_tranches[i]),
|
||||
DYNAMIC_TRANCHE_NAME) != 0)
|
||||
elog(ERROR, "incorrect dynamic lock tranche name");
|
||||
}
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for LWLockNewTrancheId().
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(test_lwlock_tranche_creation);
|
||||
Datum
|
||||
test_lwlock_tranche_creation(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *tranche_name = PG_ARGISNULL(0) ? NULL : TextDatumGetCString(PG_GETARG_DATUM(0));
|
||||
|
||||
(void) LWLockNewTrancheId(tranche_name);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for GetNamedLWLockTranche().
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(test_lwlock_tranche_lookup);
|
||||
Datum
|
||||
test_lwlock_tranche_lookup(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *tranche_name = TextDatumGetCString(PG_GETARG_DATUM(0));
|
||||
|
||||
(void) GetNamedLWLockTranche(tranche_name);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for LWLockInitialize().
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(test_lwlock_initialize);
|
||||
Datum
|
||||
test_lwlock_initialize(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int tranche_id = PG_GETARG_INT32(0);
|
||||
LWLock lock;
|
||||
|
||||
LWLockInitialize(&lock, tranche_id);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
@@ -0,0 +1 @@
|
||||
shared_preload_libraries = 'test_lwlock_tranches'
|
@@ -0,0 +1,4 @@
|
||||
comment = 'Test code for LWLock tranches allocated by extensions'
|
||||
default_version = '1.0'
|
||||
module_pathname = '$libdir/test_lwlock_tranches'
|
||||
relocatable = true
|
Reference in New Issue
Block a user