AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity hooks */7void setUp(void) {8 /* Setup code here, or leave empty */9}10void tearDown(void) {11 /* Cleanup code here, or leave empty */12}13 14/* Helper: pick a valid page size different from 'current' and <= SQLITE_MAX_PAGE_SIZE */15static u32 pickDifferentPageSize(u32 current){16 static const u32 candidates[] = {512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};17 size_t i;18 for(i = 0; i < sizeof(candidates)/sizeof(candidates[0]); i++){19 if( candidates[i] != current && candidates[i] <= SQLITE_MAX_PAGE_SIZE ){20 return candidates[i];21 }22 }23 /* Fallback: if all same (should not happen), just return current */24 return current;25}26 27/* Helper: open an in-memory database and return its Pager pointer via Btree */28static Pager* open_memdb_and_get_pager(sqlite3 **ppDb){29 sqlite3 *db = 0;30 int rc = sqlite3_open(":memory:", &db);31 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);32 TEST_ASSERT_NOT_NULL(db);33 34 /* Access the main database Btree (index 0) and obtain its Pager */35 TEST_ASSERT_TRUE(db->nDb > 0);36 Btree *pBt = db->aDb[0].pBt;37 TEST_ASSERT_NOT_NULL(pBt);38 Pager *pPager = sqlite3BtreePager(pBt);39 TEST_ASSERT_NOT_NULL(pPager);40 41 if( ppDb ) *ppDb = db;42 return pPager;43}44 45/* Helper: create a minimal standalone Pager ensuring page-size-change code path is avoided */46static Pager* alloc_minimal_pager(u32 pageSize, int memDb, Pgno dbSize, int nReserve){47 Pager *p = (Pager*)sqlite3_malloc(sizeof(Pager));48 TEST_ASSERT_NOT_NULL(p);49 memset(p, 0, sizeof(Pager));50 p->pageSize = (int)pageSize;51 p->memDb = (u8)memDb;52 p->dbSize = dbSize;53 p->nReserve = (i16)nReserve;54 /* Ensure fd is NULL so pagerFixMaplimit() does nothing */55 p->fd = 0;56 /* eState default 0 (PAGER_OPEN) from memset */57 return p;58}59 60/* Test: Successful page size change on a freshly opened in-memory pager with zero db size */61void test_sqlite3PagerSetPagesize_change_inmemory_zero_dbsize(void){62 sqlite3 *db = 0;63 Pager *pPager = open_memdb_and_get_pager(&db);64 65 /* Choose a new pagesize different from current */66 u32 origSz = (u32)pPager->pageSize;67 u32 newSz = pickDifferentPageSize(origSz);68 if( newSz == origSz ){69 /* If pickDifferent returned same due to constraints, flip between 1024 and 2048 */70 newSz = (origSz == 1024 ? 2048 : 1024);71 }72 73 /* Ensure database size is 0 to permit change for memDb pager */74 /* We should not directly modify dbSize if already non-zero, but for a fresh :memory:75 it should be 0. Assert that fact to keep the test robust. */76 TEST_ASSERT_EQUAL_UINT32(0u, (u32)pPager->dbSize);77 78 /* Call target */79 int rc;80 u32 argSz = newSz;81 int nReserve = 42;82 rc = sqlite3PagerSetPagesize(pPager, &argSz, nReserve);83 84 /* Validate */85 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);86 TEST_ASSERT_EQUAL_UINT(newSz, argSz);87 TEST_ASSERT_EQUAL_INT((int)newSz, pPager->pageSize);88 TEST_ASSERT_EQUAL_INT16((i16)nReserve, pPager->nReserve);89 90 /* pTmpSpace allocated and has 8 zero bytes after page buffer */91 TEST_ASSERT_NOT_NULL(pPager->pTmpSpace);92 {93 unsigned char *p = (unsigned char*)pPager->pTmpSpace;94 for(int i = 0; i < 8; i++){95 TEST_ASSERT_EQUAL_UINT8(0, p[newSz + i]);96 }97 }98 99 /* dbSize recomputed from file size; for :memory: path, expect 0 */100 TEST_ASSERT_EQUAL_UINT32(0u, (u32)pPager->dbSize);101 102 /* lckPgno computed as (PENDING_BYTE/newSz)+1 */103 Pgno expectedLck = (Pgno)(PENDING_BYTE / newSz) + 1;104 TEST_ASSERT_EQUAL_UINT32(expectedLck, (u32)pPager->lckPgno);105 106 sqlite3_close(db);107}108 109/* Test: No change when pageSize input equals current size */110void test_sqlite3PagerSetPagesize_no_change_when_equal_size(void){111 sqlite3 *db = 0;112 Pager *pPager = open_memdb_and_get_pager(&db);113 114 u32 origSz = (u32)pPager->pageSize;115 char *origTmp = (char*)pPager->pTmpSpace;116 Pgno origLck = pPager->lckPgno;117 int origReserve = pPager->nReserve;118 119 u32 argSz = origSz; /* equal to current */120 int rc = sqlite3PagerSetPagesize(pPager, &argSz, origReserve);121 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);122 123 /* Output arg set to retained page size */124 TEST_ASSERT_EQUAL_UINT(origSz, argSz);125 /* No change to pageSize, pTmpSpace, or lckPgno */126 TEST_ASSERT_EQUAL_INT((int)origSz, pPager->pageSize);127 TEST_ASSERT_EQUAL_PTR(origTmp, pPager->pTmpSpace);128 TEST_ASSERT_EQUAL_UINT32((u32)origLck, (u32)pPager->lckPgno);129 130 sqlite3_close(db);131}132 133/* Test: No change branch due to (memDb==1 && dbSize>0). Also verify nReserve set. */134void test_sqlite3PagerSetPagesize_no_change_memdb_nonzero_dbsize(void){135 /* Create a minimal pager that will short-circuit the change path */136 Pager *p = alloc_minimal_pager(4096, 1, 10, 17);137 TEST_ASSERT_NOT_NULL(p);138 139 u32 inSz = 2048; /* different from current */140 int rc = sqlite3PagerSetPagesize(p, &inSz, 33);141 142 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);143 /* pageSize unchanged; output updated to old size */144 TEST_ASSERT_EQUAL_UINT(4096u, (unsigned)inSz);145 TEST_ASSERT_EQUAL_INT(4096, p->pageSize);146 /* nReserve updated since rc==OK and nReserve>=0 */147 TEST_ASSERT_EQUAL_INT16((i16)33, p->nReserve);148 /* pTmpSpace should remain NULL (no allocation) */149 TEST_ASSERT_NULL(p->pTmpSpace);150 151 sqlite3_free(p);152}153 154/* Test: nReserve negative retains existing reserve when no page-size change occurs */155void test_sqlite3PagerSetPagesize_nReserve_negative_retains(void){156 Pager *p = alloc_minimal_pager(1024, 1, 10, 77);157 158 u32 inSz = 2048; /* would be different, but change path is short-circuited */159 int rc = sqlite3PagerSetPagesize(p, &inSz, -1);160 161 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);162 TEST_ASSERT_EQUAL_UINT(1024u, (unsigned)inSz);163 TEST_ASSERT_EQUAL_INT(1024, p->pageSize);164 /* nReserve should remain the same when nReserve<0 is passed */165 TEST_ASSERT_EQUAL_INT16((i16)77, p->nReserve);166 167 sqlite3_free(p);168}169 170/* Test: pageSize input 0 causes function to return current page size without changes */171void test_sqlite3PagerSetPagesize_query_with_zero_input(void){172 Pager *p = alloc_minimal_pager(2048, 1, 10, 5);173 174 u32 inSz = 0; /* Query current size */175 int rc = sqlite3PagerSetPagesize(p, &inSz, 9);176 177 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);178 TEST_ASSERT_EQUAL_UINT(2048u, (unsigned)inSz);179 TEST_ASSERT_EQUAL_INT(2048, p->pageSize);180 /* nReserve updated since provided non-negative value */181 TEST_ASSERT_EQUAL_INT16((i16)9, p->nReserve);182 TEST_ASSERT_NULL(p->pTmpSpace);183 184 sqlite3_free(p);185}186 187int main(void){188 UNITY_BEGIN();189 RUN_TEST(test_sqlite3PagerSetPagesize_change_inmemory_zero_dbsize);190 RUN_TEST(test_sqlite3PagerSetPagesize_no_change_when_equal_size);191 RUN_TEST(test_sqlite3PagerSetPagesize_no_change_memdb_nonzero_dbsize);192 RUN_TEST(test_sqlite3PagerSetPagesize_nReserve_negative_retains);193 RUN_TEST(test_sqlite3PagerSetPagesize_query_with_zero_input);194 return UNITY_END();195}