Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_sqlite3PagerDirectReadOk.c184 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6#include <stdio.h>7 8/* Helpers */9 10static void cleanup_db_files(const char *path){11  if( path==0 ) return;12  /* Remove main db file */13  remove(path);14  /* Remove possible -wal and -shm sidecars */15  char buf[1024];16  sqlite3_snprintf(sizeof(buf), buf, "%s-wal", path);17  remove(buf);18  sqlite3_snprintf(sizeof(buf), buf, "%s-shm", path);19  remove(buf);20}21 22static void exec_sql_or_fail(sqlite3 *db, const char *sql){23  char *errmsg = 0;24  int rc = sqlite3_exec(db, sql, 0, 0, &errmsg);25  if( rc!=SQLITE_OK ){26    const char *em = errmsg ? errmsg : "sqlite3_exec failed";27    /* Ensure errmsg freed before failing */28    if( errmsg ) sqlite3_free(errmsg);29    TEST_FAIL_MESSAGE(em);30  }31  if( errmsg ) sqlite3_free(errmsg);32}33 34static int get_device_characteristics(sqlite3 *db){35  sqlite3_stmt *stmt = 0;36  int dev = 0;37  int rc = sqlite3_prepare_v2(db, "PRAGMA main.device_characteristics;", -1, &stmt, 0);38  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);39  if( sqlite3_step(stmt)==SQLITE_ROW ){40    dev = sqlite3_column_int(stmt, 0);41  }42  sqlite3_finalize(stmt);43  return dev;44}45 46static Pager *get_main_pager(sqlite3 *db){47  /* Ensure main database is opened by touching it */48  exec_sql_or_fail(db, "PRAGMA main.journal_mode;");49  Btree *pBt = db->aDb[0].pBt;50  TEST_ASSERT_NOT_NULL_MESSAGE(pBt, "Main database Btree not initialized");51  Pager *pPager = sqlite3BtreePager(pBt);52  TEST_ASSERT_NOT_NULL_MESSAGE(pPager, "Pager is NULL");53  return pPager;54}55 56static sqlite3* open_db_file(const char *path){57  sqlite3 *db = 0;58  int rc;59  cleanup_db_files(path);60  rc = sqlite3_open(path, &db);61  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");62  TEST_ASSERT_NOT_NULL(db);63  return db;64}65 66/* Unity fixtures */67 68void setUp(void) {69  /* No global setup required */70}71 72void tearDown(void) {73  /* No global teardown required */74}75 76/* Tests */77 78void test_sqlite3PagerDirectReadOk_clean_delete_mode(void){79  const char *path = "test_pager_directread_clean.sqlite";80  sqlite3 *db = open_db_file(path);81 82  /* Ensure DELETE mode (no WAL), and DB is clean (no dirty pages) */83  exec_sql_or_fail(db, "PRAGMA journal_mode=DELETE;");84  /* Touch the database minimally to ensure it exists and pager is initialized */85  exec_sql_or_fail(db, "CREATE TABLE IF NOT EXISTS tclean(x);");86  /* Ensure we're not in a transaction and cache is clean */87  exec_sql_or_fail(db, "COMMIT;");88 89  Pager *pPager = get_main_pager(db);90  int dev = get_device_characteristics(db);91  int expected = ( (dev & SQLITE_IOCAP_SUBPAGE_READ) ? 1 : 0 );92 93  int rc = sqlite3PagerDirectReadOk(pPager, (Pgno)1);94  TEST_ASSERT_EQUAL_INT(expected, rc);95 96  sqlite3_close(db);97  cleanup_db_files(path);98}99 100void test_sqlite3PagerDirectReadOk_dirty_cache_returns_zero(void){101  const char *path = "test_pager_directread_dirty.sqlite";102  sqlite3 *db = open_db_file(path);103 104  exec_sql_or_fail(db, "PRAGMA journal_mode=DELETE;");105  /* Begin a write txn and create a table to ensure dirty pages in cache */106  exec_sql_or_fail(db, "BEGIN IMMEDIATE;");107  exec_sql_or_fail(db, "CREATE TABLE tdirty(x);");108 109  Pager *pPager = get_main_pager(db);110  int rc = sqlite3PagerDirectReadOk(pPager, (Pgno)1);111  TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "Expected 0 when dirty pages are present");112 113  /* Cleanup transaction */114  exec_sql_or_fail(db, "ROLLBACK;");115 116  sqlite3_close(db);117  cleanup_db_files(path);118}119 120void test_sqlite3PagerDirectReadOk_wal_page1_in_wal_returns_zero(void){121  if( sqlite3_compileoption_used("OMIT_WAL") ){122    TEST_IGNORE_MESSAGE("SQLite compiled without WAL support; skipping WAL tests.");123  }124 125  const char *path = "test_pager_directread_wal.sqlite";126  sqlite3 *db = open_db_file(path);127 128  /* Enable WAL mode */129  exec_sql_or_fail(db, "PRAGMA journal_mode=WAL;");130 131  /* Perform a transaction that will put page 1 into the WAL (change-counter update) */132  exec_sql_or_fail(db, "BEGIN;");133  exec_sql_or_fail(db, "CREATE TABLE twal(x);");134  exec_sql_or_fail(db, "COMMIT;");135 136  /* Now cache should be clean, but page 1 should be present in WAL */137  Pager *pPager = get_main_pager(db);138  int rc = sqlite3PagerDirectReadOk(pPager, (Pgno)1);139  TEST_ASSERT_EQUAL_INT_MESSAGE(0, rc, "Expected 0 when requested page is present in WAL");140 141  sqlite3_close(db);142  cleanup_db_files(path);143}144 145void test_sqlite3PagerDirectReadOk_wal_page_not_present_matches_device_caps(void){146  if( sqlite3_compileoption_used("OMIT_WAL") ){147    TEST_IGNORE_MESSAGE("SQLite compiled without WAL support; skipping WAL tests.");148  }149 150  const char *path = "test_pager_directread_wal2.sqlite";151  sqlite3 *db = open_db_file(path);152 153  /* Enable WAL mode */154  exec_sql_or_fail(db, "PRAGMA journal_mode=WAL;");155  /* Make some changes and commit so cache is clean and WAL exists */156  exec_sql_or_fail(db, "BEGIN;");157  exec_sql_or_fail(db, "CREATE TABLE twal2(y);");158  exec_sql_or_fail(db, "COMMIT;");159 160  Pager *pPager = get_main_pager(db);161  int dev = get_device_characteristics(db);162  int expected = ( (dev & SQLITE_IOCAP_SUBPAGE_READ) ? 1 : 0 );163 164  /* Use a page number that is almost certainly not present in the WAL */165  Pgno farPg = (Pgno)999999u;166  int rc = sqlite3PagerDirectReadOk(pPager, farPg);167  TEST_ASSERT_EQUAL_INT(expected, rc);168 169  sqlite3_close(db);170  cleanup_db_files(path);171}172 173/* Main */174 175int main(void){176  UNITY_BEGIN();177 178  RUN_TEST(test_sqlite3PagerDirectReadOk_clean_delete_mode);179  RUN_TEST(test_sqlite3PagerDirectReadOk_dirty_cache_returns_zero);180  RUN_TEST(test_sqlite3PagerDirectReadOk_wal_page1_in_wal_returns_zero);181  RUN_TEST(test_sqlite3PagerDirectReadOk_wal_page_not_present_matches_device_caps);182 183  return UNITY_END();184}