AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <stdlib.h>6#include <string.h>7 8/* Helper: remove a base database file and its WAL/SHM companions */9static void removeDbFiles(const char *zBase){10 if( zBase==0 ) return;11 char zWal[1024];12 char zShm[1024];13 /* Construct companion filenames safely */14 snprintf(zWal, sizeof(zWal), "%s-wal", zBase);15 snprintf(zShm, sizeof(zShm), "%s-shm", zBase);16 /* Best-effort removal */17 remove(zBase);18 remove(zWal);19 remove(zShm);20}21 22/* Unity setup/teardown */23void setUp(void) {24 /* No global setup required */25}26void tearDown(void) {27 /* No global teardown required */28}29 30/* Obtain Pager* from an open database handle */31static Pager* getPagerFromDb(sqlite3 *db){32 TEST_ASSERT_NOT_NULL(db);33 /* Main database is index 0 ("main") */34 TEST_ASSERT_TRUE_MESSAGE(db->nDb > 0, "Database should have at least one attached db");35 TEST_ASSERT_NOT_NULL(db->aDb[0].pBt);36 /* sqlite3BtreePager is an internal API exposed via SQLITE_PRIVATE */37 return sqlite3BtreePager(db->aDb[0].pBt);38}39 40/* Test: When the database is NOT using WAL, sqlite3PagerSnapshotOpen should return SQLITE_ERROR. */41void test_sqlite3PagerSnapshotOpen_returns_error_when_not_wal(void){42 const char *zDb = "test_pager_snapopen_notwal.db";43 sqlite3 *db = NULL;44 int rc;45 46 removeDbFiles(zDb);47 48 rc = sqlite3_open(zDb, &db);49 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);50 TEST_ASSERT_NOT_NULL(db);51 52 /* Ensure journal_mode is DELETE (no WAL) */53 rc = sqlite3_exec(db, "PRAGMA journal_mode=DELETE;", 0, 0, 0);54 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55 56 Pager *pPager = getPagerFromDb(db);57 TEST_ASSERT_NOT_NULL(pPager);58 59 /* Call with NULL snapshot pointer; expect SQLITE_ERROR (since pPager->pWal==NULL) */60 rc = sqlite3PagerSnapshotOpen(pPager, NULL);61 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);62 63 sqlite3_close(db);64 removeDbFiles(zDb);65}66 67/* Test: When the database IS using WAL and a (stack-allocated) snapshot is supplied, expect SQLITE_OK. */68void test_sqlite3PagerSnapshotOpen_ok_with_wal_and_snapshot(void){69 const char *zDb = "test_pager_snapopen_wal.db";70 sqlite3 *db = NULL;71 int rc;72 73 removeDbFiles(zDb);74 75 rc = sqlite3_open(zDb, &db);76 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);77 TEST_ASSERT_NOT_NULL(db);78 79 /* Switch to WAL mode */80 rc = sqlite3_exec(db, "PRAGMA journal_mode=WAL;", 0, 0, 0);81 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);82 83 /* Create a simple table to ensure the database file is properly initialized */84 rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS t(x); INSERT INTO t(x) VALUES(1);", 0, 0, 0);85 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);86 87 /* Obtain Pager* */88 Pager *pPager = getPagerFromDb(db);89 TEST_ASSERT_NOT_NULL(pPager);90 91 /* Prepare a stack-allocated snapshot object. The public header defines sqlite3_snapshot,92 so we can allocate it directly. Zero-initialize to avoid undefined contents. */93 sqlite3_snapshot snap;94 memset(&snap, 0, sizeof(snap));95 96 rc = sqlite3PagerSnapshotOpen(pPager, &snap);97 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);98 99 /* Do not trigger a read transaction here; we only verify sqlite3PagerSnapshotOpen behavior. */100 101 sqlite3_close(db);102 removeDbFiles(zDb);103}104 105/* Optional: Verify that toggling back to DELETE causes SQLITE_ERROR again. */106void test_sqlite3PagerSnapshotOpen_error_after_disabling_wal(void){107 const char *zDb = "test_pager_snapopen_toggle.db";108 sqlite3 *db = NULL;109 int rc;110 111 removeDbFiles(zDb);112 113 rc = sqlite3_open(zDb, &db);114 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);115 TEST_ASSERT_NOT_NULL(db);116 117 /* Enable WAL, then disable it to ensure pPager->pWal becomes NULL */118 rc = sqlite3_exec(db, "PRAGMA journal_mode=WAL;", 0, 0, 0);119 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);120 121 rc = sqlite3_exec(db, "PRAGMA journal_mode=DELETE;", 0, 0, 0);122 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);123 124 Pager *pPager = getPagerFromDb(db);125 TEST_ASSERT_NOT_NULL(pPager);126 127 /* Call with NULL snapshot pointer; expect SQLITE_ERROR since WAL is disabled */128 rc = sqlite3PagerSnapshotOpen(pPager, NULL);129 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);130 131 sqlite3_close(db);132 removeDbFiles(zDb);133}134 135int main(void){136 UNITY_BEGIN();137 RUN_TEST(test_sqlite3PagerSnapshotOpen_returns_error_when_not_wal);138 RUN_TEST(test_sqlite3PagerSnapshotOpen_ok_with_wal_and_snapshot);139 RUN_TEST(test_sqlite3PagerSnapshotOpen_error_after_disabling_wal);140 return UNITY_END();141}