Add test_dsa module.
authorHeikki Linnakangas <[email protected]>
Wed, 15 Nov 2023 09:34:31 +0000 (10:34 +0100)
committerHeikki Linnakangas <[email protected]>
Wed, 15 Nov 2023 10:03:49 +0000 (11:03 +0100)
This covers basic calls within a single backend process, and also
calling dsa_allocate() or dsa_get_address() while in a different
resource owners. The latter case was fixed by the previous commit.

Discussion: https://www.postgresql.org/message-id/11b70743-c5f3-3910-8e5b-dd6c115ff829%40gmail.com

src/test/modules/Makefile
src/test/modules/meson.build
src/test/modules/test_dsa/Makefile [new file with mode: 0644]
src/test/modules/test_dsa/expected/test_dsa.out [new file with mode: 0644]
src/test/modules/test_dsa/meson.build [new file with mode: 0644]
src/test/modules/test_dsa/sql/test_dsa.sql [new file with mode: 0644]
src/test/modules/test_dsa/test_dsa--1.0.sql [new file with mode: 0644]
src/test/modules/test_dsa/test_dsa.c [new file with mode: 0644]
src/test/modules/test_dsa/test_dsa.control [new file with mode: 0644]

index 738b715e7928497de82b4ffbaf7d1bb5c572202d..a18e4d28a04c4554fbde1879473c71314187b73b 100644 (file)
@@ -17,6 +17,7 @@ SUBDIRS = \
                  test_copy_callbacks \
                  test_custom_rmgrs \
                  test_ddl_deparse \
+                 test_dsa \
                  test_extensions \
                  test_ginpostinglist \
                  test_integerset \
index d4828dc44d5a8bc75f57aae1cd255e4c791130c7..4e83c0f8d748081ef4cf5988056a87881df0ceda 100644 (file)
@@ -14,6 +14,7 @@ subdir('test_bloomfilter')
 subdir('test_copy_callbacks')
 subdir('test_custom_rmgrs')
 subdir('test_ddl_deparse')
+subdir('test_dsa')
 subdir('test_extensions')
 subdir('test_ginpostinglist')
 subdir('test_integerset')
diff --git a/src/test/modules/test_dsa/Makefile b/src/test/modules/test_dsa/Makefile
new file mode 100644 (file)
index 0000000..7758346
--- /dev/null
@@ -0,0 +1,23 @@
+# src/test/modules/test_dsa/Makefile
+
+MODULE_big = test_dsa
+OBJS = \
+       $(WIN32RES) \
+       test_dsa.o
+PGFILEDESC = "test_dsa - test code for dynamic shared memory areas"
+
+EXTENSION = test_dsa
+DATA = test_dsa--1.0.sql
+
+REGRESS = test_dsa
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_dsa
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_dsa/expected/test_dsa.out b/src/test/modules/test_dsa/expected/test_dsa.out
new file mode 100644 (file)
index 0000000..266010e
--- /dev/null
@@ -0,0 +1,13 @@
+CREATE EXTENSION test_dsa;
+SELECT test_dsa_basic();
+ test_dsa_basic 
+----------------
+(1 row)
+
+SELECT test_dsa_resowners();
+ test_dsa_resowners 
+--------------------
+(1 row)
+
diff --git a/src/test/modules/test_dsa/meson.build b/src/test/modules/test_dsa/meson.build
new file mode 100644 (file)
index 0000000..2173829
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (c) 2022-2023, PostgreSQL Global Development Group
+
+test_dsa_sources = files(
+  'test_dsa.c',
+)
+
+if host_system == 'windows'
+  test_dsa_sources += rc_lib_gen.process(win32ver_rc, extra_args: [
+    '--NAME', 'test_dsa',
+    '--FILEDESC', 'test_dsa - test code for dynamic shared memory areas',])
+endif
+
+test_dsa = shared_module('test_dsa',
+  test_dsa_sources,
+  kwargs: pg_test_mod_args,
+)
+test_install_libs += test_dsa
+
+test_install_data += files(
+  'test_dsa.control',
+  'test_dsa--1.0.sql',
+)
+
+tests += {
+  'name': 'test_dsa',
+  'sd': meson.current_source_dir(),
+  'bd': meson.current_build_dir(),
+  'regress': {
+    'sql': [
+      'test_dsa',
+    ],
+  },
+}
diff --git a/src/test/modules/test_dsa/sql/test_dsa.sql b/src/test/modules/test_dsa/sql/test_dsa.sql
new file mode 100644 (file)
index 0000000..c3d8db9
--- /dev/null
@@ -0,0 +1,4 @@
+CREATE EXTENSION test_dsa;
+
+SELECT test_dsa_basic();
+SELECT test_dsa_resowners();
diff --git a/src/test/modules/test_dsa/test_dsa--1.0.sql b/src/test/modules/test_dsa/test_dsa--1.0.sql
new file mode 100644 (file)
index 0000000..2904cb2
--- /dev/null
@@ -0,0 +1,12 @@
+/* src/test/modules/test_dsa/test_dsa--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION test_dsa" to load this file. \quit
+
+CREATE FUNCTION test_dsa_basic()
+       RETURNS pg_catalog.void
+       AS 'MODULE_PATHNAME' LANGUAGE C;
+
+CREATE FUNCTION test_dsa_resowners()
+       RETURNS pg_catalog.void
+       AS 'MODULE_PATHNAME' LANGUAGE C;
diff --git a/src/test/modules/test_dsa/test_dsa.c b/src/test/modules/test_dsa/test_dsa.c
new file mode 100644 (file)
index 0000000..a8616fa
--- /dev/null
@@ -0,0 +1,113 @@
+/*--------------------------------------------------------------------------
+ *
+ * test_dsa.c
+ *             Test dynamic shared memory areas (DSAs)
+ *
+ * Copyright (c) 2022-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *             src/test/modules/test_dsa/test_dsa.c
+ *
+ * -------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "utils/dsa.h"
+#include "storage/lwlock.h"
+#include "utils/resowner.h"
+
+PG_MODULE_MAGIC;
+
+/* Test basic DSA functionality */
+PG_FUNCTION_INFO_V1(test_dsa_basic);
+Datum
+test_dsa_basic(PG_FUNCTION_ARGS)
+{
+       int                     tranche_id;
+       dsa_area   *a;
+       dsa_pointer p[100];
+
+       /* XXX: this tranche is leaked */
+       tranche_id = LWLockNewTrancheId();
+       LWLockRegisterTranche(tranche_id, "test_dsa");
+
+       a = dsa_create(tranche_id);
+       for (int i = 0; i < 100; i++)
+       {
+               p[i] = dsa_allocate(a, 1000);
+               snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
+       }
+
+       for (int i = 0; i < 100; i++)
+       {
+               char            buf[100];
+
+               snprintf(buf, 100, "foobar%d", i);
+               if (strcmp(dsa_get_address(a, p[i]), buf) != 0)
+                       elog(ERROR, "no match");
+       }
+
+       for (int i = 0; i < 100; i++)
+       {
+               dsa_free(a, p[i]);
+       }
+
+       dsa_detach(a);
+
+       PG_RETURN_VOID();
+}
+
+/* Test using DSA across different resource owners */
+PG_FUNCTION_INFO_V1(test_dsa_resowners);
+Datum
+test_dsa_resowners(PG_FUNCTION_ARGS)
+{
+       int                     tranche_id;
+       dsa_area   *a;
+       dsa_pointer p[10000];
+       ResourceOwner oldowner;
+       ResourceOwner childowner;
+
+       /* XXX: this tranche is leaked */
+       tranche_id = LWLockNewTrancheId();
+       LWLockRegisterTranche(tranche_id, "test_dsa");
+
+       /* Create DSA in parent resource owner */
+       a = dsa_create(tranche_id);
+
+       /*
+        * Switch to child resource owner, and do a bunch of allocations in the
+        * DSA
+        */
+       oldowner = CurrentResourceOwner;
+       childowner = ResourceOwnerCreate(oldowner, "test_dsa temp owner");
+       CurrentResourceOwner = childowner;
+
+       for (int i = 0; i < 10000; i++)
+       {
+               p[i] = dsa_allocate(a, 1000);
+               snprintf(dsa_get_address(a, p[i]), 1000, "foobar%d", i);
+       }
+
+       /* Also test freeing, by freeing some of the allocations. */
+       for (int i = 0; i < 500; i++)
+               dsa_free(a, p[i]);
+
+       /* Release the child resource owner */
+       CurrentResourceOwner = oldowner;
+       ResourceOwnerRelease(childowner,
+                                                RESOURCE_RELEASE_BEFORE_LOCKS,
+                                                true, false);
+       ResourceOwnerRelease(childowner,
+                                                RESOURCE_RELEASE_LOCKS,
+                                                true, false);
+       ResourceOwnerRelease(childowner,
+                                                RESOURCE_RELEASE_AFTER_LOCKS,
+                                                true, false);
+       ResourceOwnerDelete(childowner);
+
+       dsa_detach(a);
+
+       PG_RETURN_VOID();
+}
diff --git a/src/test/modules/test_dsa/test_dsa.control b/src/test/modules/test_dsa/test_dsa.control
new file mode 100644 (file)
index 0000000..ac9674b
--- /dev/null
@@ -0,0 +1,4 @@
+comment = 'Test code for dynamic shared memory areas'
+default_version = '1.0'
+module_pathname = '$libdir/test_dsa'
+relocatable = true