AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity setup/teardown */7void setUp(void) {8 /* No global setup required */9}10void tearDown(void) {11 /* No global teardown required */12}13 14/* Helper: initialize a minimally-consistent Pager and PgHdr that satisfy15** assert_pager_state() and enable sqlite3PagerWrite() fast-path.16*/17static void initPagerForFastPath(Pager *pPager, PgHdr *pPg, Pgno pgno, Pgno dbSize){18 memset(pPager, 0, sizeof(*pPager));19 memset(pPg, 0, sizeof(*pPg));20 21 /* Configure pager invariants to satisfy assert_pager_state() */22 pPager->eState = PAGER_WRITER_CACHEMOD; /* Writer state, avoids open_journal */23 pPager->journalMode = PAGER_JOURNALMODE_WAL; /* WAL mode to bypass jfd asserts */24 pPager->useJournal = 1; /* Required when journalMode != OFF */25 pPager->tempFile = 0; /* Not a temp file */26 pPager->changeCountDone = 0; /* Irrelevant since tempFile==0 */27 pPager->eLock = EXCLUSIVE_LOCK; /* Not UNKNOWN or PENDING */28 pPager->errCode = SQLITE_OK; /* Required in writer states */29 pPager->readOnly = 0; /* Must be able to write */30 pPager->dbOrigSize = 0; /* Must be equal among these three */31 pPager->dbFileSize = 0;32 pPager->dbHintSize = 0;33 pPager->dbSize = dbSize; /* Current db size used by fast-path */34 pPager->pageSize = 4096; /* Valid page size */35 pPager->sectorSize = 4096; /* Default equal or adjust per-test */36 /* Leave pPager->pPCache NULL: not used by fast-path */37 38 /* Configure page header */39 pPg->pPager = pPager;40 pPg->pgno = pgno;41 pPg->flags = PGHDR_WRITEABLE; /* Mark as already writeable */42}43 44/* Test 1: Fast-path returns SQLITE_OK when page is already writeable and dbSize > pgno */45void test_sqlite3PagerWrite_fastpath_ok_simple(void){46 Pager pager;47 PgHdr pg;48 int rc;49 50 initPagerForFastPath(&pager, &pg, /*pgno*/3, /*dbSize*/10);51 /* Pre-conditions sanity */52 TEST_ASSERT_TRUE(pager.eState >= PAGER_WRITER_LOCKED);53 TEST_ASSERT_TRUE((pg.flags & PGHDR_WRITEABLE)!=0);54 TEST_ASSERT_TRUE(pager.dbSize >= pg.pgno);55 56 /* Snapshot key fields to ensure no side-effects */57 int origFlags = pg.flags;58 Pgno origDbSize = pager.dbSize;59 int origState = pager.eState;60 61 rc = sqlite3PagerWrite(&pg);62 63 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);64 /* Ensure fast-path did not modify flags or sizes or state */65 TEST_ASSERT_EQUAL_INT(origFlags, pg.flags);66 TEST_ASSERT_EQUAL_UINT32(origDbSize, pager.dbSize);67 TEST_ASSERT_EQUAL_INT(origState, pager.eState);68}69 70/* Test 2: Fast-path boundary case when dbSize == pgno */71void test_sqlite3PagerWrite_fastpath_ok_dbsize_equals_pgno(void){72 Pager pager;73 PgHdr pg;74 int rc;75 76 initPagerForFastPath(&pager, &pg, /*pgno*/5, /*dbSize*/5);77 78 int origFlags = pg.flags;79 Pgno origDbSize = pager.dbSize;80 81 rc = sqlite3PagerWrite(&pg);82 83 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);84 TEST_ASSERT_EQUAL_INT(origFlags, pg.flags);85 TEST_ASSERT_EQUAL_UINT32(origDbSize, pager.dbSize);86}87 88/* Test 3: Even if sectorSize > pageSize, fast-path still returns SQLITE_OK89** when the page is already writeable and within dbSize (ensures branch90** precedence is as coded: the first condition short-circuits others).91*/92void test_sqlite3PagerWrite_fastpath_precedes_large_sector_branch(void){93 Pager pager;94 PgHdr pg;95 int rc;96 97 initPagerForFastPath(&pager, &pg, /*pgno*/2, /*dbSize*/7);98 99 /* Make sectorSize larger than pageSize; fast-path should still apply */100 pager.pageSize = 1024;101 pager.sectorSize = 4096;102 103 rc = sqlite3PagerWrite(&pg);104 105 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);106 /* Confirm no state change of interest */107 TEST_ASSERT_TRUE((pg.flags & PGHDR_WRITEABLE)!=0);108 TEST_ASSERT_TRUE(pager.dbSize >= pg.pgno);109}110 111/* Unity main */112int main(void) {113 UNITY_BEGIN();114 RUN_TEST(test_sqlite3PagerWrite_fastpath_ok_simple);115 RUN_TEST(test_sqlite3PagerWrite_fastpath_ok_dbsize_equals_pgno);116 RUN_TEST(test_sqlite3PagerWrite_fastpath_precedes_large_sector_branch);117 return UNITY_END();118}