mirror of
https://github.com/postgres/postgres.git
synced 2025-10-19 15:49:24 +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_integerset \
|
||||||
test_json_parser \
|
test_json_parser \
|
||||||
test_lfind \
|
test_lfind \
|
||||||
|
test_lwlock_tranches \
|
||||||
test_misc \
|
test_misc \
|
||||||
test_oat_hooks \
|
test_oat_hooks \
|
||||||
test_parser \
|
test_parser \
|
||||||
|
@@ -28,6 +28,7 @@ subdir('test_int128')
|
|||||||
subdir('test_integerset')
|
subdir('test_integerset')
|
||||||
subdir('test_json_parser')
|
subdir('test_json_parser')
|
||||||
subdir('test_lfind')
|
subdir('test_lfind')
|
||||||
|
subdir('test_lwlock_tranches')
|
||||||
subdir('test_misc')
|
subdir('test_misc')
|
||||||
subdir('test_oat_hooks')
|
subdir('test_oat_hooks')
|
||||||
subdir('test_parser')
|
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