LCOV - differential code coverage report
Current view: top level - src/test/modules/test_slru - test_slru.c (source / functions) Coverage Total Hit UBC GNC CBC ECB DUB DCB
Current: bed3ffbf9d952be6c7d739d068cdce44c046dfb7 vs 574581b50ac9c63dd9e4abebb731a3b67e5b50f6 Lines: 98.9 % 89 88 1 11 77 1 2 21
Current Date: 2026-05-05 10:23:31 +0900 Functions: 100.0 % 24 24 5 19 3
Baseline: lcov-20260505-025707-baseline Branches: 42.9 % 14 6 8 6 2 2
Baseline Date: 2026-05-05 10:27:06 +0900 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 87.5 % 8 7 1 5 2
(30,360] days: 100.0 % 5 5 5 1
(360..) days: 100.0 % 76 76 1 75
Function coverage date bins:
(7,30] days: 100.0 % 3 3 3
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 20 20 1 19
Branch coverage date bins:
(7,30] days: 25.0 % 4 1 3 1
(360..) days: 50.0 % 10 5 5 5

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*--------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * test_slru.c
                                  4                 :                :  *      Test correctness of SLRU functions.
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  * IDENTIFICATION
                                 10                 :                :  *      src/test/modules/test_slru/test_slru.c
                                 11                 :                :  *
                                 12                 :                :  * -------------------------------------------------------------------------
                                 13                 :                :  */
                                 14                 :                : 
                                 15                 :                : #include "postgres.h"
                                 16                 :                : 
                                 17                 :                : #include "access/slru.h"
                                 18                 :                : #include "access/transam.h"
                                 19                 :                : #include "miscadmin.h"
                                 20                 :                : #include "storage/fd.h"
                                 21                 :                : #include "storage/ipc.h"
                                 22                 :                : #include "storage/shmem.h"
                                 23                 :                : #include "utils/builtins.h"
                                 24                 :                : 
 1266 michael@paquier.xyz        25                 :CBC           4 : PG_MODULE_MAGIC;
                                 26                 :                : 
                                 27                 :                : /*
                                 28                 :                :  * SQL-callable entry points
                                 29                 :                :  */
                                 30                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_write);
                                 31                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_writeall);
                                 32                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_read);
                                 33                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_readonly);
                                 34                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_exists);
                                 35                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_sync);
                                 36                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_delete);
                                 37                 :              4 : PG_FUNCTION_INFO_V1(test_slru_page_truncate);
                                 38                 :              4 : PG_FUNCTION_INFO_V1(test_slru_delete_all);
                                 39                 :                : 
                                 40                 :                : /* Number of SLRU page slots */
                                 41                 :                : #define NUM_TEST_BUFFERS        16
                                 42                 :                : 
                                 43                 :                : static void test_slru_shmem_request(void *arg);
                                 44                 :                : static bool test_slru_page_precedes_logically(int64 page1, int64 page2);
                                 45                 :                : static int  test_slru_errdetail_for_io_error(const void *opaque_data);
                                 46                 :                : 
                                 47                 :                : static const char *TestSlruDir = "pg_test_slru";
                                 48                 :                : 
                                 49                 :                : static SlruDesc TestSlruDesc;
                                 50                 :                : 
                                 51                 :                : static const ShmemCallbacks test_slru_shmem_callbacks = {
                                 52                 :                :     .request_fn = test_slru_shmem_request
                                 53                 :                : };
                                 54                 :                : 
                                 55                 :                : #define TestSlruCtl         (&TestSlruDesc)
                                 56                 :                : 
                                 57                 :                : static bool
   29 heikki.linnakangas@i       58                 :GNC           1 : test_slru_scan_cb(SlruDesc *ctl, char *filename, int64 segpage, void *data)
                                 59                 :                : {
 1266 michael@paquier.xyz        60         [ +  - ]:CBC           1 :     elog(NOTICE, "Calling test_slru_scan_cb()");
                                 61                 :              1 :     return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
                                 62                 :                : }
                                 63                 :                : 
                                 64                 :                : Datum
                                 65                 :             98 : test_slru_page_write(PG_FUNCTION_ARGS)
                                 66                 :                : {
  888 akorotkov@postgresql       67                 :             98 :     int64       pageno = PG_GETARG_INT64(0);
 1266 michael@paquier.xyz        68                 :             98 :     char       *data = text_to_cstring(PG_GETARG_TEXT_PP(1));
                                 69                 :                :     int         slotno;
  797 alvherre@alvh.no-ip.       70                 :             98 :     LWLock     *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
                                 71                 :                : 
                                 72                 :             98 :     LWLockAcquire(lock, LW_EXCLUSIVE);
 1266 michael@paquier.xyz        73                 :             98 :     slotno = SimpleLruZeroPage(TestSlruCtl, pageno);
                                 74                 :                : 
                                 75                 :                :     /* these should match */
                                 76         [ -  + ]:             98 :     Assert(TestSlruCtl->shared->page_number[slotno] == pageno);
                                 77                 :                : 
                                 78                 :                :     /* mark the page as dirty so as it would get written */
                                 79                 :             98 :     TestSlruCtl->shared->page_dirty[slotno] = true;
                                 80                 :             98 :     TestSlruCtl->shared->page_status[slotno] = SLRU_PAGE_VALID;
                                 81                 :                : 
                                 82                 :                :     /* write given data to the page, up to the limit of the page */
                                 83                 :             98 :     strncpy(TestSlruCtl->shared->page_buffer[slotno], data,
                                 84                 :                :             BLCKSZ - 1);
                                 85                 :                : 
                                 86                 :             98 :     SimpleLruWritePage(TestSlruCtl, slotno);
  797 alvherre@alvh.no-ip.       87                 :             98 :     LWLockRelease(lock);
                                 88                 :                : 
 1266 michael@paquier.xyz        89                 :             98 :     PG_RETURN_VOID();
                                 90                 :                : }
                                 91                 :                : 
                                 92                 :                : Datum
                                 93                 :              2 : test_slru_page_writeall(PG_FUNCTION_ARGS)
                                 94                 :                : {
                                 95                 :              2 :     SimpleLruWriteAll(TestSlruCtl, true);
                                 96                 :              2 :     PG_RETURN_VOID();
                                 97                 :                : }
                                 98                 :                : 
                                 99                 :                : Datum
                                100                 :              5 : test_slru_page_read(PG_FUNCTION_ARGS)
                                101                 :                : {
  888 akorotkov@postgresql      102                 :              5 :     int64       pageno = PG_GETARG_INT64(0);
 1266 michael@paquier.xyz       103                 :              5 :     bool        write_ok = PG_GETARG_BOOL(1);
   53 heikki.linnakangas@i      104                 :GNC           5 :     TransactionId xid = PG_GETARG_TRANSACTIONID(2);
 1266 michael@paquier.xyz       105                 :CBC           5 :     char       *data = NULL;
                                106                 :                :     int         slotno;
  797 alvherre@alvh.no-ip.      107                 :              5 :     LWLock     *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
                                108                 :                : 
                                109                 :                :     /* find page in buffers, reading it if necessary */
                                110                 :              5 :     LWLockAcquire(lock, LW_EXCLUSIVE);
   53 heikki.linnakangas@i      111                 :GNC           5 :     slotno = SimpleLruReadPage(TestSlruCtl, pageno, write_ok, &xid);
 1266 michael@paquier.xyz       112                 :CBC           4 :     data = (char *) TestSlruCtl->shared->page_buffer[slotno];
  797 alvherre@alvh.no-ip.      113                 :              4 :     LWLockRelease(lock);
                                114                 :                : 
 1266 michael@paquier.xyz       115                 :              4 :     PG_RETURN_TEXT_P(cstring_to_text(data));
                                116                 :                : }
                                117                 :                : 
                                118                 :                : Datum
                                119                 :              4 : test_slru_page_readonly(PG_FUNCTION_ARGS)
                                120                 :                : {
  888 akorotkov@postgresql      121                 :              4 :     int64       pageno = PG_GETARG_INT64(0);
 1266 michael@paquier.xyz       122                 :              4 :     char       *data = NULL;
                                123                 :                :     int         slotno;
  797 alvherre@alvh.no-ip.      124                 :              4 :     LWLock     *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
                                125                 :                : 
                                126                 :                :     /* find page in buffers, reading it if necessary */
 1266 michael@paquier.xyz       127                 :              4 :     slotno = SimpleLruReadPage_ReadOnly(TestSlruCtl,
                                128                 :                :                                         pageno,
                                129                 :                :                                         NULL);
  797 alvherre@alvh.no-ip.      130         [ -  + ]:              4 :     Assert(LWLockHeldByMe(lock));
 1266 michael@paquier.xyz       131                 :              4 :     data = (char *) TestSlruCtl->shared->page_buffer[slotno];
  797 alvherre@alvh.no-ip.      132                 :              4 :     LWLockRelease(lock);
                                133                 :                : 
 1266 michael@paquier.xyz       134                 :              4 :     PG_RETURN_TEXT_P(cstring_to_text(data));
                                135                 :                : }
                                136                 :                : 
                                137                 :                : Datum
                                138                 :             18 : test_slru_page_exists(PG_FUNCTION_ARGS)
                                139                 :                : {
  888 akorotkov@postgresql      140                 :             18 :     int64       pageno = PG_GETARG_INT64(0);
                                141                 :                :     bool        found;
  797 alvherre@alvh.no-ip.      142                 :             18 :     LWLock     *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
                                143                 :                : 
                                144                 :             18 :     LWLockAcquire(lock, LW_EXCLUSIVE);
 1266 michael@paquier.xyz       145                 :             18 :     found = SimpleLruDoesPhysicalPageExist(TestSlruCtl, pageno);
  797 alvherre@alvh.no-ip.      146                 :             18 :     LWLockRelease(lock);
                                147                 :                : 
 1266 michael@paquier.xyz       148                 :             18 :     PG_RETURN_BOOL(found);
                                149                 :                : }
                                150                 :                : 
                                151                 :                : Datum
                                152                 :              2 : test_slru_page_sync(PG_FUNCTION_ARGS)
                                153                 :                : {
  888 akorotkov@postgresql      154                 :              2 :     int64       pageno = PG_GETARG_INT64(0);
                                155                 :                :     FileTag     ftag;
                                156                 :                :     char        path[MAXPGPATH];
                                157                 :                : 
                                158                 :                :     /* note that this flushes the full file a segment is located in */
 1266 michael@paquier.xyz       159                 :              2 :     ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
                                160                 :              2 :     SlruSyncFileTag(TestSlruCtl, &ftag, path);
                                161                 :                : 
  371 peter@eisentraut.org      162         [ +  - ]:              2 :     elog(NOTICE, "Called SlruSyncFileTag() for segment %" PRIu64 " on path %s",
                                163                 :                :          ftag.segno, path);
                                164                 :                : 
 1266 michael@paquier.xyz       165                 :              2 :     PG_RETURN_VOID();
                                166                 :                : }
                                167                 :                : 
                                168                 :                : Datum
                                169                 :              2 : test_slru_page_delete(PG_FUNCTION_ARGS)
                                170                 :                : {
  888 akorotkov@postgresql      171                 :              2 :     int64       pageno = PG_GETARG_INT64(0);
                                172                 :                :     FileTag     ftag;
                                173                 :                : 
 1266 michael@paquier.xyz       174                 :              2 :     ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
                                175                 :              2 :     SlruDeleteSegment(TestSlruCtl, ftag.segno);
                                176                 :                : 
  371 peter@eisentraut.org      177         [ +  - ]:              2 :     elog(NOTICE, "Called SlruDeleteSegment() for segment %" PRIu64,
                                178                 :                :          ftag.segno);
                                179                 :                : 
 1266 michael@paquier.xyz       180                 :              2 :     PG_RETURN_VOID();
                                181                 :                : }
                                182                 :                : 
                                183                 :                : Datum
                                184                 :              2 : test_slru_page_truncate(PG_FUNCTION_ARGS)
                                185                 :                : {
  888 akorotkov@postgresql      186                 :              2 :     int64       pageno = PG_GETARG_INT64(0);
                                187                 :                : 
 1266 michael@paquier.xyz       188                 :              2 :     SimpleLruTruncate(TestSlruCtl, pageno);
                                189                 :              2 :     PG_RETURN_VOID();
                                190                 :                : }
                                191                 :                : 
                                192                 :                : Datum
                                193                 :              2 : test_slru_delete_all(PG_FUNCTION_ARGS)
                                194                 :                : {
                                195                 :                :     /* this calls SlruScanDirCbDeleteAll() internally, ensuring deletion */
                                196                 :              2 :     SlruScanDirectory(TestSlruCtl, test_slru_scan_cb, NULL);
                                197                 :                : 
                                198                 :              2 :     PG_RETURN_VOID();
                                199                 :                : }
                                200                 :                : 
                                201                 :                : static bool
  888 akorotkov@postgresql      202                 :             15 : test_slru_page_precedes_logically(int64 page1, int64 page2)
                                203                 :                : {
 1266 michael@paquier.xyz       204                 :             15 :     return page1 < page2;
                                205                 :                : }
                                206                 :                : 
                                207                 :                : static int
   53 heikki.linnakangas@i      208                 :GNC           1 : test_slru_errdetail_for_io_error(const void *opaque_data)
                                209                 :                : {
                                210                 :              1 :     TransactionId xid = *(const TransactionId *) opaque_data;
                                211                 :                : 
                                212                 :              1 :     return errdetail("Could not access test_slru entry %u.", xid);
   53 heikki.linnakangas@i      213                 :ECB         (3) : }
                                214                 :                : 
                                215                 :                : void
   29 heikki.linnakangas@i      216                 :CBC           4 : _PG_init(void)
                                217                 :                : {
                                218         [ -  + ]:              4 :     if (!process_shared_preload_libraries_in_progress)
   29 heikki.linnakangas@i      219         [ #  # ]:UBC           0 :         ereport(ERROR,
                                220                 :                :                 (errmsg("cannot load \"%s\" after startup", "test_slru"),
                                221                 :                :                  errdetail("\"%s\" must be loaded with \"shared_preload_libraries\".",
                                222                 :                :                            "test_slru")));
                                223                 :                : 
                                224                 :                :     /*
                                225                 :                :      * Create the SLRU directory if it does not exist yet, from the root of
                                226                 :                :      * the data directory.
                                227                 :                :      */
   29 heikki.linnakangas@i      228                 :GNC           4 :     (void) MakePGDirectory(TestSlruDir);
                                229                 :                : 
                                230                 :              4 :     RegisterShmemCallbacks(&test_slru_shmem_callbacks);
 1266 michael@paquier.xyz       231                 :              4 : }
                                232                 :                : 
                                233                 :                : static void
   29 heikki.linnakangas@i      234                 :              4 : test_slru_shmem_request(void *arg)
                                235                 :                : {
                                236                 :              4 :     SimpleLruRequest(.desc = &TestSlruDesc,
                                237                 :                :                      .name = "TestSLRU",
                                238                 :                :                      .Dir = TestSlruDir,
                                239                 :                : 
                                240                 :                :     /*
                                241                 :                :      * Short segments names are well tested elsewhere so in this test we are
                                242                 :                :      * focusing on long names.
                                243                 :                :      */
                                244                 :                :                      .long_segment_names = true,
                                245                 :                : 
                                246                 :                :                      .nslots = NUM_TEST_BUFFERS,
                                247                 :                :                      .nlsns = 0,
                                248                 :                : 
                                249                 :                :                      .sync_handler = SYNC_HANDLER_NONE,
                                250                 :                :                      .PagePrecedes = test_slru_page_precedes_logically,
                                251                 :                :                      .errdetail_for_io_error = test_slru_errdetail_for_io_error,
                                252                 :                : 
                                253                 :                :     /* let slru.c assign these */
                                254                 :                :                      .buffer_tranche_id = 0,
                                255                 :                :                      .bank_tranche_id = 0,
                                256                 :                :         );
 1266 michael@paquier.xyz       257                 :CBC           4 : }
        

Generated by: LCOV version 2.5.0-beta