Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pcache_sqlite3PcacheMakeClean.c177 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Helpers */7static PCache* helperCreateCache(int bPurgeable){8  int rc;9  PCache *p = (PCache*)sqlite3_malloc(sqlite3PcacheSize());10  TEST_ASSERT_NOT_NULL(p);11  rc = sqlite3PcacheOpen(1024, 8, bPurgeable, 0, 0, p);12  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);13  return p;14}15 16static void helperDestroyCache(PCache *p){17  if( p ){18    /* Discard any remaining contents to be safe */19    sqlite3PcacheClear(p);20    sqlite3PcacheClose(p);21    sqlite3_free(p);22  }23}24 25static PgHdr* helperFetchPage(PCache *pCache, Pgno pgno){26  sqlite3_pcache_page *pLower = sqlite3PcacheFetch(pCache, pgno, 3);27  TEST_ASSERT_NOT_NULL(pLower);28  PgHdr *pPg = sqlite3PcacheFetchFinish(pCache, pgno, pLower);29  TEST_ASSERT_NOT_NULL(pPg);30  TEST_ASSERT_EQUAL_INT(pgno, (int)pPg->pgno);31  return pPg;32}33 34static int helperCountDirty(PCache *pCache){35  int n = 0;36  PgHdr *p;37  p = sqlite3PcacheDirtyList(pCache);38  while( p ){39    n++;40    p = p->pDirty;41  }42  return n;43}44 45static int helperDirtyListContains(PCache *pCache, PgHdr *pWant){46  PgHdr *p = sqlite3PcacheDirtyList(pCache);47  while( p ){48    if( p==pWant ) return 1;49    p = p->pDirty;50  }51  return 0;52}53 54void setUp(void) {55  int rc;56  rc = sqlite3_initialize();57  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);58  rc = sqlite3PcacheInitialize();59  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);60}61 62void tearDown(void) {63  sqlite3PcacheShutdown();64  sqlite3_shutdown();65}66 67/* Test that MakeClean clears flags and removes page from dirty list (single dirty page) */68void test_sqlite3PcacheMakeClean_clears_flags_and_removes_single_dirty(void){69  PCache *pc = helperCreateCache(1);70 71  PgHdr *p1 = helperFetchPage(pc, 1);72  PgHdr *p2 = helperFetchPage(pc, 2);73 74  /* Make page 1 dirty and add extra flags */75  sqlite3PcacheMakeDirty(p1);76  p1->flags |= (PGHDR_NEED_SYNC | PGHDR_WRITEABLE);77 78  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p1));79  TEST_ASSERT_FALSE(helperDirtyListContains(pc, p2));80  TEST_ASSERT_TRUE((p1->flags & PGHDR_DIRTY)!=0);81 82  /* Clean page 1 */83  sqlite3PcacheMakeClean(p1);84 85  /* Flags updated */86  TEST_ASSERT_TRUE((p1->flags & PGHDR_CLEAN)!=0);87  TEST_ASSERT_FALSE((p1->flags & PGHDR_DIRTY)!=0);88  TEST_ASSERT_FALSE((p1->flags & PGHDR_NEED_SYNC)!=0);89  TEST_ASSERT_FALSE((p1->flags & PGHDR_WRITEABLE)!=0);90 91  /* Removed from dirty list */92  TEST_ASSERT_FALSE(helperDirtyListContains(pc, p1));93  TEST_ASSERT_EQUAL_INT(0, helperCountDirty(pc));94 95  /* Release pages */96  sqlite3PcacheRelease(p1);97  sqlite3PcacheRelease(p2);98 99  helperDestroyCache(pc);100}101 102/* Test that MakeClean removes a page from the middle of the dirty list */103void test_sqlite3PcacheMakeClean_removes_middle_from_dirty_list(void){104  PCache *pc = helperCreateCache(1);105 106  PgHdr *p1 = helperFetchPage(pc, 1);107  PgHdr *p2 = helperFetchPage(pc, 2);108  PgHdr *p3 = helperFetchPage(pc, 3);109 110  sqlite3PcacheMakeDirty(p1);111  sqlite3PcacheMakeDirty(p2);112  sqlite3PcacheMakeDirty(p3);113 114  TEST_ASSERT_EQUAL_INT(3, helperCountDirty(pc));115  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p1));116  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p2));117  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p3));118 119  /* Clean middle page (pgno 2) */120  sqlite3PcacheMakeClean(p2);121 122  TEST_ASSERT_TRUE((p2->flags & PGHDR_CLEAN)!=0);123  TEST_ASSERT_FALSE(helperDirtyListContains(pc, p2));124  TEST_ASSERT_EQUAL_INT(2, helperCountDirty(pc));125  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p1));126  TEST_ASSERT_TRUE(helperDirtyListContains(pc, p3));127 128  /* Clean remaining dirty pages then release */129  sqlite3PcacheMakeClean(p1);130  sqlite3PcacheMakeClean(p3);131 132  sqlite3PcacheRelease(p1);133  sqlite3PcacheRelease(p2);134  sqlite3PcacheRelease(p3);135 136  helperDestroyCache(pc);137}138 139/* Test MakeClean when nRef==0 (page is dirty but unreferenced): should succeed and page remains fetchable */140void test_sqlite3PcacheMakeClean_unref_zero_path_fetchable_after_clean(void){141  PCache *pc = helperCreateCache(1);142 143  PgHdr *p = helperFetchPage(pc, 10);144  sqlite3PcacheMakeDirty(p);145 146  /* Drop our ref to make nRef==0 while still dirty */147  sqlite3PcacheRelease(p);148  TEST_ASSERT_EQUAL_INT64(0, sqlite3PcachePageRefcount(p));149 150  /* Now clean it; this exercises the path that unpins the lower-level page */151  sqlite3PcacheMakeClean(p);152 153  /* Flags updated and no longer dirty */154  TEST_ASSERT_TRUE((p->flags & PGHDR_CLEAN)!=0);155  TEST_ASSERT_FALSE(helperDirtyListContains(pc, p));156  TEST_ASSERT_EQUAL_INT(0, helperCountDirty(pc));157 158  /* Page remains fetchable and should be the same PgHdr */159  sqlite3_pcache_page *pLower = sqlite3PcacheFetch(pc, 10, 0);160  TEST_ASSERT_NOT_NULL(pLower);161  PgHdr *pAgain = sqlite3PcacheFetchFinish(pc, 10, pLower);162  TEST_ASSERT_NOT_NULL(pAgain);163  TEST_ASSERT_EQUAL_PTR(p, pAgain);164 165  /* Release */166  sqlite3PcacheRelease(pAgain);167 168  helperDestroyCache(pc);169}170 171int main(void){172  UNITY_BEGIN();173  RUN_TEST(test_sqlite3PcacheMakeClean_clears_flags_and_removes_single_dirty);174  RUN_TEST(test_sqlite3PcacheMakeClean_removes_middle_from_dirty_list);175  RUN_TEST(test_sqlite3PcacheMakeClean_unref_zero_path_fetchable_after_clean);176  return UNITY_END();177}