LCOV - differential code coverage report
Current view: top level - src/test/modules/test_slru - test_slru.c (source / functions) Coverage Total Hit UNC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 96.9 % 96 93 3 93
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 24 24 24
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*--------------------------------------------------------------------------
       2                 :  *
       3                 :  * test_slru.c
       4                 :  *      Test correctness of SLRU functions.
       5                 :  *
       6                 :  * Portions Copyright (c) 1996-2023, 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                 : 
      25 GNC           1 : PG_MODULE_MAGIC;
      26                 : 
      27                 : /*
      28                 :  * SQL-callable entry points
      29                 :  */
      30               2 : PG_FUNCTION_INFO_V1(test_slru_page_write);
      31               2 : PG_FUNCTION_INFO_V1(test_slru_page_writeall);
      32               2 : PG_FUNCTION_INFO_V1(test_slru_page_read);
      33               2 : PG_FUNCTION_INFO_V1(test_slru_page_readonly);
      34               2 : PG_FUNCTION_INFO_V1(test_slru_page_exists);
      35               2 : PG_FUNCTION_INFO_V1(test_slru_page_sync);
      36               2 : PG_FUNCTION_INFO_V1(test_slru_page_delete);
      37               2 : PG_FUNCTION_INFO_V1(test_slru_page_truncate);
      38               2 : PG_FUNCTION_INFO_V1(test_slru_delete_all);
      39                 : 
      40                 : /* Number of SLRU page slots */
      41                 : #define NUM_TEST_BUFFERS        16
      42                 : 
      43                 : /* SLRU control lock */
      44                 : LWLock      TestSLRULock;
      45                 : #define TestSLRULock (&TestSLRULock)
      46                 : 
      47                 : static SlruCtlData TestSlruCtlData;
      48                 : #define TestSlruCtl         (&TestSlruCtlData)
      49                 : 
      50                 : static shmem_request_hook_type prev_shmem_request_hook = NULL;
      51                 : static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
      52                 : 
      53                 : /* LWLock name */
      54                 : const char  test_tranche_name[] = "test_slru_tranche";
      55                 : 
      56                 : static bool
      57               1 : test_slru_scan_cb(SlruCtl ctl, char *filename, int segpage, void *data)
      58                 : {
      59               1 :     elog(NOTICE, "Calling test_slru_scan_cb()");
      60               1 :     return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
      61                 : }
      62                 : 
      63                 : Datum
      64              49 : test_slru_page_write(PG_FUNCTION_ARGS)
      65                 : {
      66              49 :     int         pageno = PG_GETARG_INT32(0);
      67              49 :     char       *data = text_to_cstring(PG_GETARG_TEXT_PP(1));
      68                 :     int         slotno;
      69                 : 
      70              49 :     LWLockAcquire(TestSLRULock, LW_EXCLUSIVE);
      71                 : 
      72              49 :     slotno = SimpleLruZeroPage(TestSlruCtl, pageno);
      73                 : 
      74                 :     /* these should match */
      75              49 :     Assert(TestSlruCtl->shared->page_number[slotno] == pageno);
      76                 : 
      77                 :     /* mark the page as dirty so as it would get written */
      78              49 :     TestSlruCtl->shared->page_dirty[slotno] = true;
      79              49 :     TestSlruCtl->shared->page_status[slotno] = SLRU_PAGE_VALID;
      80                 : 
      81                 :     /* write given data to the page, up to the limit of the page */
      82              49 :     strncpy(TestSlruCtl->shared->page_buffer[slotno], data,
      83                 :             BLCKSZ - 1);
      84                 : 
      85              49 :     SimpleLruWritePage(TestSlruCtl, slotno);
      86              49 :     LWLockRelease(TestSLRULock);
      87                 : 
      88              49 :     PG_RETURN_VOID();
      89                 : }
      90                 : 
      91                 : Datum
      92               1 : test_slru_page_writeall(PG_FUNCTION_ARGS)
      93                 : {
      94               1 :     SimpleLruWriteAll(TestSlruCtl, true);
      95               1 :     PG_RETURN_VOID();
      96                 : }
      97                 : 
      98                 : Datum
      99               2 : test_slru_page_read(PG_FUNCTION_ARGS)
     100                 : {
     101               2 :     int         pageno = PG_GETARG_INT32(0);
     102               2 :     bool        write_ok = PG_GETARG_BOOL(1);
     103               2 :     char       *data = NULL;
     104                 :     int         slotno;
     105                 : 
     106                 :     /* find page in buffers, reading it if necessary */
     107               2 :     LWLockAcquire(TestSLRULock, LW_EXCLUSIVE);
     108               2 :     slotno = SimpleLruReadPage(TestSlruCtl, pageno,
     109                 :                                write_ok, InvalidTransactionId);
     110               2 :     data = (char *) TestSlruCtl->shared->page_buffer[slotno];
     111               2 :     LWLockRelease(TestSLRULock);
     112                 : 
     113               2 :     PG_RETURN_TEXT_P(cstring_to_text(data));
     114                 : }
     115                 : 
     116                 : Datum
     117               2 : test_slru_page_readonly(PG_FUNCTION_ARGS)
     118                 : {
     119               2 :     int         pageno = PG_GETARG_INT32(0);
     120               2 :     char       *data = NULL;
     121                 :     int         slotno;
     122                 : 
     123                 :     /* find page in buffers, reading it if necessary */
     124               2 :     slotno = SimpleLruReadPage_ReadOnly(TestSlruCtl,
     125                 :                                         pageno,
     126                 :                                         InvalidTransactionId);
     127               2 :     Assert(LWLockHeldByMe(TestSLRULock));
     128               2 :     data = (char *) TestSlruCtl->shared->page_buffer[slotno];
     129               2 :     LWLockRelease(TestSLRULock);
     130                 : 
     131               2 :     PG_RETURN_TEXT_P(cstring_to_text(data));
     132                 : }
     133                 : 
     134                 : Datum
     135               9 : test_slru_page_exists(PG_FUNCTION_ARGS)
     136                 : {
     137               9 :     int         pageno = PG_GETARG_INT32(0);
     138                 :     bool        found;
     139                 : 
     140               9 :     LWLockAcquire(TestSLRULock, LW_EXCLUSIVE);
     141               9 :     found = SimpleLruDoesPhysicalPageExist(TestSlruCtl, pageno);
     142               9 :     LWLockRelease(TestSLRULock);
     143                 : 
     144               9 :     PG_RETURN_BOOL(found);
     145                 : }
     146                 : 
     147                 : Datum
     148               1 : test_slru_page_sync(PG_FUNCTION_ARGS)
     149                 : {
     150               1 :     int         pageno = PG_GETARG_INT32(0);
     151                 :     FileTag     ftag;
     152                 :     char        path[MAXPGPATH];
     153                 : 
     154                 :     /* note that this flushes the full file a segment is located in */
     155               1 :     ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
     156               1 :     SlruSyncFileTag(TestSlruCtl, &ftag, path);
     157                 : 
     158               1 :     elog(NOTICE, "Called SlruSyncFileTag() for segment %u on path %s",
     159                 :          ftag.segno, path);
     160                 : 
     161               1 :     PG_RETURN_VOID();
     162                 : }
     163                 : 
     164                 : Datum
     165               1 : test_slru_page_delete(PG_FUNCTION_ARGS)
     166                 : {
     167               1 :     int         pageno = PG_GETARG_INT32(0);
     168                 :     FileTag     ftag;
     169                 : 
     170               1 :     ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
     171               1 :     SlruDeleteSegment(TestSlruCtl, ftag.segno);
     172                 : 
     173               1 :     elog(NOTICE, "Called SlruDeleteSegment() for segment %u", ftag.segno);
     174                 : 
     175               1 :     PG_RETURN_VOID();
     176                 : }
     177                 : 
     178                 : Datum
     179               1 : test_slru_page_truncate(PG_FUNCTION_ARGS)
     180                 : {
     181               1 :     int         pageno = PG_GETARG_INT32(0);
     182                 : 
     183               1 :     SimpleLruTruncate(TestSlruCtl, pageno);
     184               1 :     PG_RETURN_VOID();
     185                 : }
     186                 : 
     187                 : Datum
     188               1 : test_slru_delete_all(PG_FUNCTION_ARGS)
     189                 : {
     190                 :     /* this calls SlruScanDirCbDeleteAll() internally, ensuring deletion */
     191               1 :     SlruScanDirectory(TestSlruCtl, test_slru_scan_cb, NULL);
     192                 : 
     193               1 :     PG_RETURN_VOID();
     194                 : }
     195                 : 
     196                 : /*
     197                 :  * Module load callbacks and initialization.
     198                 :  */
     199                 : 
     200                 : static void
     201               1 : test_slru_shmem_request(void)
     202                 : {
     203               1 :     if (prev_shmem_request_hook)
     204 UNC           0 :         prev_shmem_request_hook();
     205                 : 
     206                 :     /* reserve shared memory for the test SLRU */
     207 GNC           1 :     RequestAddinShmemSpace(SimpleLruShmemSize(NUM_TEST_BUFFERS, 0));
     208               1 : }
     209                 : 
     210                 : static bool
     211              11 : test_slru_page_precedes_logically(int page1, int page2)
     212                 : {
     213              11 :     return page1 < page2;
     214                 : }
     215                 : 
     216                 : static void
     217               1 : test_slru_shmem_startup(void)
     218                 : {
     219               1 :     const char  slru_dir_name[] = "pg_test_slru";
     220                 :     int         test_tranche_id;
     221                 : 
     222               1 :     if (prev_shmem_startup_hook)
     223 UNC           0 :         prev_shmem_startup_hook();
     224                 : 
     225                 :     /*
     226                 :      * Create the SLRU directory if it does not exist yet, from the root of
     227                 :      * the data directory.
     228                 :      */
     229 GNC           1 :     (void) MakePGDirectory(slru_dir_name);
     230                 : 
     231                 :     /* initialize the SLRU facility */
     232               1 :     test_tranche_id = LWLockNewTrancheId();
     233               1 :     LWLockRegisterTranche(test_tranche_id, "test_slru_tranche");
     234               1 :     LWLockInitialize(TestSLRULock, test_tranche_id);
     235                 : 
     236               1 :     TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically;
     237               1 :     SimpleLruInit(TestSlruCtl, "TestSLRU",
     238                 :                   NUM_TEST_BUFFERS, 0, TestSLRULock, slru_dir_name,
     239                 :                   test_tranche_id, SYNC_HANDLER_NONE);
     240               1 : }
     241                 : 
     242                 : void
     243               1 : _PG_init(void)
     244                 : {
     245               1 :     if (!process_shared_preload_libraries_in_progress)
     246 UNC           0 :         ereport(ERROR,
     247                 :                 (errmsg("cannot load \"%s\" after startup", "test_slru"),
     248                 :                  errdetail("\"%s\" must be loaded with shared_preload_libraries.",
     249                 :                            "test_slru")));
     250                 : 
     251 GNC           1 :     prev_shmem_request_hook = shmem_request_hook;
     252               1 :     shmem_request_hook = test_slru_shmem_request;
     253                 : 
     254               1 :     prev_shmem_startup_hook = shmem_startup_hook;
     255               1 :     shmem_startup_hook = test_slru_shmem_startup;
     256               1 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a