Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_pager_write.c301 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* The wrapper made available by the module for the static function */7extern int test_pager_write(PgHdr *pPg);8 9/* Minimal stubbed IO methods so that isOpen(jfd) is true and writes succeed */10static int stub_xClose(sqlite3_file* p){ (void)p; return SQLITE_OK; }11static int stub_xRead(sqlite3_file* p, void* b, int a, sqlite3_int64 o){ (void)p;(void)b;(void)a;(void)o; return SQLITE_OK; }12static int stub_xWrite(sqlite3_file* p, const void* b, int a, sqlite3_int64 o){ (void)p;(void)b;(void)a;(void)o; return SQLITE_OK; }13static int stub_xTruncate(sqlite3_file* p, sqlite3_int64 s){ (void)p;(void)s; return SQLITE_OK; }14static int stub_xSync(sqlite3_file* p, int f){ (void)p;(void)f; return SQLITE_OK; }15static int stub_xFileSize(sqlite3_file* p, sqlite3_int64* sz){ (void)p; if(sz)*sz=0; return SQLITE_OK; }16static int stub_xLock(sqlite3_file* p, int l){ (void)p;(void)l; return SQLITE_OK; }17static int stub_xUnlock(sqlite3_file* p, int l){ (void)p;(void)l; return SQLITE_OK; }18static int stub_xCheckReservedLock(sqlite3_file* p, int* r){ (void)p; if(r)*r=0; return SQLITE_OK; }19static int stub_xFileControl(sqlite3_file* p, int op, void* a){ (void)p;(void)op;(void)a; return SQLITE_OK; }20static int stub_xSectorSize(sqlite3_file* p){ (void)p; return 512; }21static int stub_xDeviceCharacteristics(sqlite3_file* p){ (void)p; return 0; }22static int stub_xShmMap(sqlite3_file* p, int a, int b, int c, void volatile** d){ (void)p;(void)a;(void)b;(void)c;(void)d; return SQLITE_OK; }23static int stub_xShmLock(sqlite3_file* p, int a, int b, int c){ (void)p;(void)a;(void)b;(void)c; return SQLITE_OK; }24static void stub_xShmBarrier(sqlite3_file* p){ (void)p; }25static int stub_xShmUnmap(sqlite3_file* p, int d){ (void)p;(void)d; return SQLITE_OK; }26static int stub_xFetch(sqlite3_file* p, sqlite3_int64 o, int a, void** pp){ (void)p;(void)o;(void)a; if(pp)*pp=0; return SQLITE_OK; }27static int stub_xUnfetch(sqlite3_file* p, sqlite3_int64 o, void* q){ (void)p;(void)o;(void)q; return SQLITE_OK; }28 29static const sqlite3_io_methods gStubIoMethods = {30  3, /* iVersion */31  stub_xClose,32  stub_xRead,33  stub_xWrite,34  stub_xTruncate,35  stub_xSync,36  stub_xFileSize,37  stub_xLock,38  stub_xUnlock,39  stub_xCheckReservedLock,40  stub_xFileControl,41  stub_xSectorSize,42  stub_xDeviceCharacteristics,43  stub_xShmMap,44  stub_xShmLock,45  stub_xShmBarrier,46  stub_xShmUnmap,47  stub_xFetch,48  stub_xUnfetch49};50 51static void setup_pcache_and_page(int pageSize, Pgno pgno, PCache **ppCache, PgHdr **ppPg){52  PCache *pCache = 0;53  PgHdr *pPg = 0;54 55  sqlite3PcacheOpen(pageSize, 0, 0, 0, 0, &pCache);56  TEST_ASSERT_NOT_NULL(pCache);57 58  /* createFlag=1 to create if not exists */59  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3PcacheFetch(pCache, pgno, 1, &pPg));60  TEST_ASSERT_NOT_NULL(pPg);61  /* Ensure pgno is set */62  pPg->pgno = pgno;63 64  *ppCache = pCache;65  *ppPg = pPg;66}67 68static Pager* alloc_clear_pager(void){69  Pager *pPager = (Pager*)sqlite3MallocZero(sizeof(Pager));70  TEST_ASSERT_NOT_NULL(pPager);71  return pPager;72}73 74static sqlite3_file* alloc_closed_filehandle(void){75  sqlite3_file *f = (sqlite3_file*)sqlite3MallocZero(sizeof(sqlite3_file));76  TEST_ASSERT_NOT_NULL(f);77  /* pMethods left NULL => isOpen() is false */78  return f;79}80 81static sqlite3_file* alloc_open_stub_filehandle(void){82  sqlite3_file *f = (sqlite3_file*)sqlite3MallocZero(sizeof(sqlite3_file));83  TEST_ASSERT_NOT_NULL(f);84  f->pMethods = &gStubIoMethods; /* isOpen() true, operations succeed */85  return f;86}87 88static void release_pcache_and_page(PCache *pCache, PgHdr *pPg){89  if( pPg ) sqlite3PcacheRelease(pPg);90  if( pCache ) sqlite3PcacheClose(pCache);91}92 93void setUp(void) {94  /* Initialize SQLite global state to ensure pcache/mem are ready */95  sqlite3_initialize();96}97 98void tearDown(void) {99  /* No global teardown necessary here */100}101 102/* Test 1: From WRITER_LOCKED with journal OFF -> transitions to CACHEMOD,103   marks WRITEABLE, updates dbSize, and returns OK. */104void test_pager_write_locked_off_transitions_and_writable(void){105  const int pageSize = 1024;106  const Pgno pgno = 7;107 108  PCache *pCache = 0; PgHdr *pPg = 0;109  setup_pcache_and_page(pageSize, pgno, &pCache, &pPg);110 111  Pager *pPager = alloc_clear_pager();112  pPager->pPCache = pCache;113  pPager->pageSize = pageSize;114  pPager->eState = PAGER_WRITER_LOCKED;115  pPager->errCode = SQLITE_OK;116  pPager->readOnly = 0;117  pPager->tempFile = 0;118  pPager->eLock = RESERVED_LOCK;119  pPager->journalMode = PAGER_JOURNALMODE_OFF;120  pPager->useJournal = 0;121  pPager->pInJournal = 0;122  pPager->setSuper = 0;123  pPager->dbSize = 3;124  pPager->dbOrigSize = 3;125  pPager->dbFileSize = 3;126  pPager->dbHintSize = 3;127  pPager->changeCountDone = 0;128  pPager->jfd = alloc_closed_filehandle(); /* isOpen=false to match pInJournal==0 */129  pPager->nSavepoint = 0;130 131  pPg->pPager = pPager;132  pPg->flags = 0;133 134  int rc = test_pager_write(pPg);135  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);136  TEST_ASSERT_EQUAL_INT(PAGER_WRITER_CACHEMOD, pPager->eState);137  TEST_ASSERT_TRUE(pPg->flags & PGHDR_WRITEABLE);138  TEST_ASSERT_EQUAL_UINT(pgno, pPager->dbSize); /* dbSize grows to pgno */139 140  /* Cleanup */141  sqlite3_free(pPager->jfd);142  sqlite3_free(pPager);143  release_pcache_and_page(pCache, pPg);144}145 146/* Test 2: With pInJournal set and open jfd, pgno>dbOrigSize in CACHEMOD:147   NEED_SYNC is set; WRITEABLE set; dbSize updated; returns OK. */148void test_pager_write_sets_need_sync_on_append_with_journal_cachemod(void){149  const int pageSize = 1024;150  const Pgno pgno = 10;151 152  PCache *pCache = 0; PgHdr *pPg = 0;153  setup_pcache_and_page(pageSize, pgno, &pCache, &pPg);154 155  Pager *pPager = alloc_clear_pager();156  pPager->pPCache = pCache;157  pPager->pageSize = pageSize;158  pPager->eState = PAGER_WRITER_CACHEMOD;159  pPager->errCode = SQLITE_OK;160  pPager->readOnly = 0;161  pPager->tempFile = 0;162  pPager->eLock = RESERVED_LOCK;163  pPager->journalMode = PAGER_JOURNALMODE_MEMORY; /* not OFF -> require useJournal=1 */164  pPager->useJournal = 1;165  pPager->pInJournal = sqlite3BitvecCreate(100);166  TEST_ASSERT_NOT_NULL(pPager->pInJournal);167  pPager->setSuper = 0;168  pPager->dbSize = 2;169  pPager->dbOrigSize = 5;170  pPager->dbFileSize = 5;171  pPager->dbHintSize = 5;172  pPager->changeCountDone = 0;173  pPager->jfd = alloc_open_stub_filehandle(); /* isOpen=true to match pInJournal!=0 */174  pPager->nSavepoint = 0;175 176  pPg->pPager = pPager;177  pPg->flags = 0;178 179  /* Sanity: page not in journal bitvec yet */180  TEST_ASSERT_EQUAL_INT(0, sqlite3BitvecTestNotNull(pPager->pInJournal, pgno));181 182  int rc = test_pager_write(pPg);183  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);184  TEST_ASSERT_TRUE(pPg->flags & PGHDR_WRITEABLE);185  TEST_ASSERT_TRUE(pPg->flags & PGHDR_NEED_SYNC);186  TEST_ASSERT_EQUAL_UINT(pgno, pPager->dbSize);187 188  /* Cleanup */189  sqlite3BitvecDestroy(pPager->pInJournal);190  sqlite3_free(pPager->jfd);191  sqlite3_free(pPager);192  release_pcache_and_page(pCache, pPg);193}194 195/* Test 3: In DBMOD state with journal and pgno>dbOrigSize:196   NEED_SYNC is NOT set (because eState==PAGER_WRITER_DBMOD), but WRITEABLE is set. */197void test_pager_write_no_need_sync_in_dbmod_on_append(void){198  const int pageSize = 1024;199  const Pgno pgno = 12;200 201  PCache *pCache = 0; PgHdr *pPg = 0;202  setup_pcache_and_page(pageSize, pgno, &pCache, &pPg);203 204  Pager *pPager = alloc_clear_pager();205  pPager->pPCache = pCache;206  pPager->pageSize = pageSize;207  pPager->eState = PAGER_WRITER_DBMOD;208  pPager->errCode = SQLITE_OK;209  pPager->readOnly = 0;210  pPager->tempFile = 0;211  pPager->eLock = EXCLUSIVE_LOCK; /* Required for DBMOD */212  pPager->journalMode = PAGER_JOURNALMODE_MEMORY;213  pPager->useJournal = 1;214  pPager->pInJournal = sqlite3BitvecCreate(200);215  TEST_ASSERT_NOT_NULL(pPager->pInJournal);216  pPager->setSuper = 0;217  pPager->dbSize = 4;218  pPager->dbOrigSize = 6;219  pPager->dbFileSize = 6;220  pPager->dbHintSize = 6;221  pPager->changeCountDone = 0;222  pPager->jfd = alloc_open_stub_filehandle();223  pPager->nSavepoint = 0;224 225  pPg->pPager = pPager;226  pPg->flags = 0;227 228  int rc = test_pager_write(pPg);229  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);230  TEST_ASSERT_TRUE(pPg->flags & PGHDR_WRITEABLE);231  TEST_ASSERT_FALSE((pPg->flags & PGHDR_NEED_SYNC) != 0);232  TEST_ASSERT_EQUAL_UINT(pgno, pPager->dbSize);233 234  sqlite3BitvecDestroy(pPager->pInJournal);235  sqlite3_free(pPager->jfd);236  sqlite3_free(pPager);237  release_pcache_and_page(pCache, pPg);238}239 240/* Test 4: With journal and pgno<=dbOrigSize -> page added to rollback journal.241   Verify journal bit set, nRec incremented, journalOff advanced, NEED_SYNC set, and WRITEABLE set. */242void test_pager_write_journals_existing_page_and_sets_bit(void){243  const int pageSize = 1024;244  const Pgno pgno = 5;245 246  PCache *pCache = 0; PgHdr *pPg = 0;247  setup_pcache_and_page(pageSize, pgno, &pCache, &pPg);248 249  Pager *pPager = alloc_clear_pager();250  pPager->pPCache = pCache;251  pPager->pageSize = pageSize;252  pPager->eState = PAGER_WRITER_CACHEMOD;253  pPager->errCode = SQLITE_OK;254  pPager->readOnly = 0;255  pPager->tempFile = 0;256  pPager->eLock = RESERVED_LOCK;257  pPager->journalMode = PAGER_JOURNALMODE_MEMORY;258  pPager->useJournal = 1;259  pPager->pInJournal = sqlite3BitvecCreate(100);260  TEST_ASSERT_NOT_NULL(pPager->pInJournal);261  pPager->setSuper = 0;262  pPager->dbSize = 20;       /* dbSize can exceed dbOrigSize */263  pPager->dbOrigSize = 10;   /* existing page */264  pPager->dbFileSize = 10;265  pPager->dbHintSize = 10;266  pPager->changeCountDone = 0;267  pPager->jfd = alloc_open_stub_filehandle();268  pPager->nSavepoint = 0;269  pPager->journalOff = 0;270  pPager->nRec = 0;271 272  pPg->pPager = pPager;273  pPg->flags = 0;274 275  /* Pre-conditions */276  TEST_ASSERT_EQUAL_INT(0, sqlite3BitvecTestNotNull(pPager->pInJournal, pgno));277  TEST_ASSERT_EQUAL_INT(0, pPager->nRec);278  TEST_ASSERT_EQUAL_INT(0, pPager->journalOff);279 280  int rc = test_pager_write(pPg);281  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);282  TEST_ASSERT_TRUE(pPg->flags & PGHDR_WRITEABLE);283  TEST_ASSERT_TRUE(pPg->flags & PGHDR_NEED_SYNC);284  TEST_ASSERT_EQUAL_INT(1, pPager->nRec);285  TEST_ASSERT_EQUAL_INT(8 + pageSize, (int)pPager->journalOff);286  TEST_ASSERT_NOT_EQUAL(0, sqlite3BitvecTestNotNull(pPager->pInJournal, pgno));287 288  sqlite3BitvecDestroy(pPager->pInJournal);289  sqlite3_free(pPager->jfd);290  sqlite3_free(pPager);291  release_pcache_and_page(pCache, pPg);292}293 294int main(void){295  UNITY_BEGIN();296  RUN_TEST(test_pager_write_locked_off_transitions_and_writable);297  RUN_TEST(test_pager_write_sets_need_sync_on_append_with_journal_cachemod);298  RUN_TEST(test_pager_write_no_need_sync_in_dbmod_on_append);299  RUN_TEST(test_pager_write_journals_existing_page_and_sets_bit);300  return UNITY_END();301}