Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_sqlite3PagerSetFlags.c241 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* A minimal fake sqlite3_file that allows controlling device characteristics6** returned by sqlite3OsDeviceCharacteristics(). This lets us exercise7** SQLITE_ENABLE_BATCH_ATOMIC_WRITE behavior safely.8*/9static int g_fake_devchar = 0;10 11static int fake_xClose(sqlite3_file *id){ (void)id; return SQLITE_OK; }12static int fake_xRead(sqlite3_file *id, void *p, int a, sqlite3_int64 o){ (void)id;(void)p;(void)a;(void)o; return SQLITE_OK; }13static int fake_xWrite(sqlite3_file *id, const void *p, int a, sqlite3_int64 o){ (void)id;(void)p;(void)a;(void)o; return SQLITE_OK; }14static int fake_xTruncate(sqlite3_file *id, sqlite3_int64 s){ (void)id;(void)s; return SQLITE_OK; }15static int fake_xSync(sqlite3_file *id, int f){ (void)id;(void)f; return SQLITE_OK; }16static int fake_xFileSize(sqlite3_file *id, sqlite3_int64 *pSz){ (void)id; if(pSz) *pSz = 0; return SQLITE_OK; }17static int fake_xLock(sqlite3_file *id, int e){ (void)id;(void)e; return SQLITE_OK; }18static int fake_xUnlock(sqlite3_file *id, int e){ (void)id;(void)e; return SQLITE_OK; }19static int fake_xCheckReservedLock(sqlite3_file *id, int *p){ (void)id; if(p) *p = 0; return SQLITE_OK; }20static int fake_xFileControl(sqlite3_file *id, int op, void *arg){ (void)id;(void)op;(void)arg; return SQLITE_OK; }21static int fake_xSectorSize(sqlite3_file *id){ (void)id; return 512; }22static int fake_xDeviceCharacteristics(sqlite3_file *id){ (void)id; return g_fake_devchar; }23 24/* Version 1 sqlite3_io_methods - only xDeviceCharacteristics is actually used */25static const sqlite3_io_methods g_fake_io_methods = {26  1,27  fake_xClose,28  fake_xRead,29  fake_xWrite,30  fake_xTruncate,31  fake_xSync,32  fake_xFileSize,33  fake_xLock,34  fake_xUnlock,35  fake_xCheckReservedLock,36  fake_xFileControl,37  fake_xSectorSize,38  fake_xDeviceCharacteristics39};40 41static sqlite3_file g_fake_file = { &g_fake_io_methods };42 43/* Helper to initialize a Pager for testing this function */44static void initPagerForTest(Pager *p, int isTemp){45  memset(p, 0, sizeof(*p));46  p->tempFile = (u8)isTemp;47  p->fd = &g_fake_file;48  g_fake_devchar = 0;49}50 51void setUp(void) {52  /* Setup code here, or leave empty */53  g_fake_devchar = 0;54}55void tearDown(void) {56  /* Cleanup code here, or leave empty */57}58 59/* Test: Temp file forces noSync and clears others, regardless of sync level */60void test_sqlite3PagerSetFlags_tempFile_forces_noSync(void){61  Pager p;62  initPagerForTest(&p, 1);63 64  unsigned levels[] = {65    (PAGER_SYNCHRONOUS_OFF & PAGER_SYNCHRONOUS_MASK) | 0,66    (2 & PAGER_SYNCHRONOUS_MASK), /* NORMAL */67    (PAGER_SYNCHRONOUS_FULL & PAGER_SYNCHRONOUS_MASK),68    (PAGER_SYNCHRONOUS_EXTRA & PAGER_SYNCHRONOUS_MASK)69  };70 71  for(unsigned i=0;i<sizeof(levels)/sizeof(levels[0]);i++){72    /* Toggle some flags just to ensure they are ignored for temp files */73    unsigned pgFlags = levels[i] | PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL;74    p.noSync = 0; p.fullSync = 1; p.extraSync = 1;75    p.syncFlags = 1234; p.walSyncFlags = 5678;76    p.doNotSpill = 0;77 78    sqlite3PagerSetFlags(&p, pgFlags);79 80    TEST_ASSERT_EQUAL_INT(1, p.noSync);81    TEST_ASSERT_EQUAL_INT(0, p.fullSync);82    TEST_ASSERT_EQUAL_INT(0, p.extraSync);83    TEST_ASSERT_EQUAL_INT(0, p.syncFlags);84    TEST_ASSERT_EQUAL_INT(0, p.walSyncFlags);85    /* With PAGER_CACHESPILL set, SPILLFLAG_OFF must be cleared */86    TEST_ASSERT_EQUAL_INT(0, (p.doNotSpill & SPILLFLAG_OFF));87  }88 89  /* And when PAGER_CACHESPILL not set, SPILLFLAG_OFF must be set */90  p.doNotSpill = 0;91  sqlite3PagerSetFlags(&p, (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK)); /* no CACHESPILL */92  TEST_ASSERT_NOT_EQUAL(0, (p.doNotSpill & SPILLFLAG_OFF));93}94 95/* Test: Level OFF (non-temp) behaves like temp/noSync */96void test_sqlite3PagerSetFlags_level_off_regular_file(void){97  Pager p;98  initPagerForTest(&p, 0);99  p.doNotSpill = SPILLFLAG_OFF; /* Will be cleared if CACHESPILL set */100  unsigned pgFlags = (PAGER_SYNCHRONOUS_OFF & PAGER_SYNCHRONOUS_MASK) | PAGER_CACHESPILL;101 102  sqlite3PagerSetFlags(&p, pgFlags);103 104  TEST_ASSERT_EQUAL_INT(1, p.noSync);105  TEST_ASSERT_EQUAL_INT(0, p.fullSync);106  TEST_ASSERT_EQUAL_INT(0, p.extraSync);107  TEST_ASSERT_EQUAL_INT(0, p.syncFlags);108  TEST_ASSERT_EQUAL_INT(0, p.walSyncFlags);109  TEST_ASSERT_EQUAL_INT(0, (p.doNotSpill & SPILLFLAG_OFF));110}111 112/* Test: NORMAL mode with default sync (no FULLFSYNC) and no CKPT flag */113void test_sqlite3PagerSetFlags_normal_default_syncflags(void){114  Pager p;115  initPagerForTest(&p, 0);116  p.doNotSpill = 0; /* SPILLFLAG_OFF should be set since no CACHESPILL */117  unsigned pgFlags = (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK);118 119  sqlite3PagerSetFlags(&p, pgFlags);120 121  TEST_ASSERT_EQUAL_INT(0, p.noSync);122  TEST_ASSERT_EQUAL_INT(0, p.fullSync);123  TEST_ASSERT_EQUAL_INT(0, p.extraSync);124  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_NORMAL, p.syncFlags);125  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_NORMAL<<2, p.walSyncFlags);126  TEST_ASSERT_NOT_EQUAL(0, (p.doNotSpill & SPILLFLAG_OFF));127}128 129/* Test: NORMAL mode with CKPT_FULLFSYNC (but not FULLFSYNC) augments walSyncFlags */130void test_sqlite3PagerSetFlags_normal_ckpt_fullfsync_only(void){131  Pager p;132  initPagerForTest(&p, 0);133  p.doNotSpill = 0;134  unsigned pgFlags = (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK) | PAGER_CKPT_FULLFSYNC;135 136  sqlite3PagerSetFlags(&p, pgFlags);137 138  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_NORMAL, p.syncFlags);139  /* walSyncFlags should include both (NORMAL<<2) and (FULL<<2) */140  int expectedWal = (SQLITE_SYNC_NORMAL<<2) | (SQLITE_SYNC_FULL<<2);141  TEST_ASSERT_EQUAL_INT(expectedWal, p.walSyncFlags);142}143 144/* Test: FULL mode without FULLFSYNC */145void test_sqlite3PagerSetFlags_full_mode_normal_sync(void){146  Pager p;147  initPagerForTest(&p, 0);148  unsigned pgFlags = (PAGER_SYNCHRONOUS_FULL & PAGER_SYNCHRONOUS_MASK);149 150  sqlite3PagerSetFlags(&p, pgFlags);151 152  TEST_ASSERT_EQUAL_INT(0, p.noSync);153  TEST_ASSERT_EQUAL_INT(1, p.fullSync);154  TEST_ASSERT_EQUAL_INT(0, p.extraSync);155  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_NORMAL, p.syncFlags);156  int expectedWal = (SQLITE_SYNC_NORMAL<<2) | SQLITE_SYNC_NORMAL;157  TEST_ASSERT_EQUAL_INT(expectedWal, p.walSyncFlags);158}159 160/* Test: FULL mode with FULLFSYNC */161void test_sqlite3PagerSetFlags_full_mode_fullfsync(void){162  Pager p;163  initPagerForTest(&p, 0);164  unsigned pgFlags = (PAGER_SYNCHRONOUS_FULL & PAGER_SYNCHRONOUS_MASK) | PAGER_FULLFSYNC;165 166  sqlite3PagerSetFlags(&p, pgFlags);167 168  TEST_ASSERT_EQUAL_INT(1, p.fullSync);169  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_FULL, p.syncFlags);170  int expectedWal = (SQLITE_SYNC_FULL<<2) | SQLITE_SYNC_FULL;171  TEST_ASSERT_EQUAL_INT(expectedWal, p.walSyncFlags);172}173 174/* Test: EXTRA mode sets extraSync */175void test_sqlite3PagerSetFlags_extra_mode_sets_extraSync(void){176  Pager p;177  initPagerForTest(&p, 0);178  unsigned pgFlags = (PAGER_SYNCHRONOUS_EXTRA & PAGER_SYNCHRONOUS_MASK);179 180  sqlite3PagerSetFlags(&p, pgFlags);181 182  TEST_ASSERT_EQUAL_INT(0, p.noSync);183  TEST_ASSERT_EQUAL_INT(1, p.fullSync);184  TEST_ASSERT_EQUAL_INT(1, p.extraSync);185  TEST_ASSERT_EQUAL_INT(SQLITE_SYNC_NORMAL, p.syncFlags);186  int expectedWal = (SQLITE_SYNC_NORMAL<<2) | SQLITE_SYNC_NORMAL;187  TEST_ASSERT_EQUAL_INT(expectedWal, p.walSyncFlags);188}189 190/* Test: PAGER_CACHESPILL toggles SPILLFLAG_OFF as specified */191void test_sqlite3PagerSetFlags_cachespill_bit_toggling(void){192  Pager p;193  initPagerForTest(&p, 0);194 195  /* Start with SPILLFLAG_OFF set, ensure it is cleared when CACHESPILL is set */196  p.doNotSpill = SPILLFLAG_OFF | 0xBEEF0000; /* preserve other bits */197  unsigned pgFlags = (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK) | PAGER_CACHESPILL;198  sqlite3PagerSetFlags(&p, pgFlags);199  TEST_ASSERT_EQUAL_INT(0, (p.doNotSpill & SPILLFLAG_OFF));200  TEST_ASSERT_EQUAL_INT(0xBEEF0000, (p.doNotSpill & ~SPILLFLAG_OFF));201 202  /* Now ensure it is set when CACHESPILL is not present */203  p.doNotSpill = 0xCAFE0000; /* SPILLFLAG_OFF currently clear */204  pgFlags = (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK); /* no CACHESPILL */205  sqlite3PagerSetFlags(&p, pgFlags);206  TEST_ASSERT_NOT_EQUAL(0, (p.doNotSpill & SPILLFLAG_OFF));207  TEST_ASSERT_EQUAL_INT(0xCAFE0000, (p.doNotSpill & ~SPILLFLAG_OFF));208}209 210#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE211/* Test: When device reports batch-atomic, extraSync is enabled for non-EXTRA levels */212void test_sqlite3PagerSetFlags_batch_atomic_enables_extraSync(void){213  Pager p;214  initPagerForTest(&p, 0);215  g_fake_devchar = SQLITE_IOCAP_BATCH_ATOMIC;216 217  /* NORMAL level but device supports batch-atomic */218  unsigned pgFlags = (PAGER_SYNCHRONOUS_NORMAL & PAGER_SYNCHRONOUS_MASK);219  sqlite3PagerSetFlags(&p, pgFlags);220 221  TEST_ASSERT_EQUAL_INT(0, p.noSync);222  TEST_ASSERT_EQUAL_INT(0, p.fullSync);223  TEST_ASSERT_EQUAL_INT(1, p.extraSync);224}225#endif226 227int main(void) {228  UNITY_BEGIN();229  RUN_TEST(test_sqlite3PagerSetFlags_tempFile_forces_noSync);230  RUN_TEST(test_sqlite3PagerSetFlags_level_off_regular_file);231  RUN_TEST(test_sqlite3PagerSetFlags_normal_default_syncflags);232  RUN_TEST(test_sqlite3PagerSetFlags_normal_ckpt_fullfsync_only);233  RUN_TEST(test_sqlite3PagerSetFlags_full_mode_normal_sync);234  RUN_TEST(test_sqlite3PagerSetFlags_full_mode_fullfsync);235  RUN_TEST(test_sqlite3PagerSetFlags_extra_mode_sets_extraSync);236  RUN_TEST(test_sqlite3PagerSetFlags_cachespill_bit_toggling);237  #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE238  RUN_TEST(test_sqlite3PagerSetFlags_batch_atomic_enables_extraSync);239  #endif240  return UNITY_END();241}