Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_sqlite3PagerCheckpoint.c165 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <stdlib.h>5#include <string.h>6 7#if defined(_WIN32)8#  include <io.h>9#  define unlink _unlink10#endif11 12/* Forward declaration for internal function to fetch Pager from Btree. */13extern Pager *sqlite3BtreePager(Btree *p);14 15/* Simple helper to remove database and associated WAL/SHM files. */16static void remove_db_files(const char *zPath){17  if( zPath==0 ) return;18  char buf[1024];19  snprintf(buf, sizeof(buf), "%s", zPath);20  remove(buf);21  snprintf(buf, sizeof(buf), "%s-wal", zPath);22  remove(buf);23  snprintf(buf, sizeof(buf), "%s-shm", zPath);24  remove(buf);25}26 27/* Open a database connection at zPath and ensure "main" btree is initialized. */28static sqlite3* open_db_and_init(const char *zPath){29  sqlite3 *db = 0;30  int rc = sqlite3_open(zPath, &db);31  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);32  /* Execute a trivial statement to ensure the main btree is opened/initialized. */33  rc = sqlite3_exec(db, "SELECT 1", 0, 0, 0);34  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);35  return db;36}37 38/* Obtain the Pager* for the "main" database from an open sqlite3* handle. */39static Pager* get_main_pager(sqlite3 *db){40  TEST_ASSERT_NOT_NULL(db);41  /* aDb[0] is "main". Ensure Btree exists. */42  TEST_ASSERT_NOT_NULL(db->aDb);43  TEST_ASSERT_NOT_NULL(db->aDb[0].pBt);44  Pager *pPager = sqlite3BtreePager(db->aDb[0].pBt);45  TEST_ASSERT_NOT_NULL(pPager);46  return pPager;47}48 49/* Execute SQL and assert success. */50static void exec_ok(sqlite3 *db, const char *zSql){51  int rc = sqlite3_exec(db, zSql, 0, 0, 0);52  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, zSql);53}54 55void setUp(void) {56  /* No global setup required */57}58 59void tearDown(void) {60  /* No global teardown required */61}62 63/* Test 1: Not in WAL mode - outputs should remain unchanged and rc==SQLITE_OK. */64void test_sqlite3PagerCheckpoint_no_wal_outputs_unchanged(void){65  const char *zDb = "test_pc_no_wal.sqlite";66  remove_db_files(zDb);67  sqlite3 *db = open_db_and_init(zDb);68 69  Pager *pPager = get_main_pager(db);70 71  int nLog = 1111;72  int nCkpt = 2222;73  int rc = sqlite3PagerCheckpoint(pPager, db, SQLITE_CHECKPOINT_PASSIVE, &nLog, &nCkpt);74 75  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);76  /* Since not in WAL mode (default), pnLog/pnCkpt should be untouched. */77  TEST_ASSERT_EQUAL_INT(1111, nLog);78  TEST_ASSERT_EQUAL_INT(2222, nCkpt);79 80  sqlite3_close(db);81  remove_db_files(zDb);82}83 84/* Helper: create WAL with some frames by performing writes and committing. */85static void create_wal_with_frames(sqlite3 *db){86  exec_ok(db, "PRAGMA journal_mode=WAL;");87  /* Perform multiple writes to ensure WAL frames are generated. */88  exec_ok(db,89    "BEGIN;"90    "CREATE TABLE t1(x);"91    "WITH RECURSIVE c(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<100) "92    "INSERT INTO t1 SELECT i FROM c;"93    "COMMIT;"94  );95}96 97/* Test 2: In WAL mode with frames, PASSIVE checkpoint should checkpoint everything. */98void test_sqlite3PagerCheckpoint_wal_passive_full_checkpoint(void){99  const char *zDb = "test_pc_wal_passive.sqlite";100  remove_db_files(zDb);101  sqlite3 *db = open_db_and_init(zDb);102 103  create_wal_with_frames(db);104  Pager *pPager = get_main_pager(db);105 106  int nLog = -1;107  int nCkpt = -1;108  int rc = sqlite3PagerCheckpoint(pPager, db, SQLITE_CHECKPOINT_PASSIVE, &nLog, &nCkpt);109 110  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);111  TEST_ASSERT_TRUE(nLog >= 1);112  TEST_ASSERT_EQUAL_INT(nLog, nCkpt);113 114  sqlite3_close(db);115  remove_db_files(zDb);116}117 118/* Test 3: Special-case path: zero-byte db -> set WAL -> checkpoint with no transactions.119   Accept either outputs unchanged (if pWal remains NULL) or zeroed (if initialized). */120void test_sqlite3PagerCheckpoint_wal_specialcase_no_txn(void){121  const char *zDb = "test_pc_wal_special.sqlite";122  remove_db_files(zDb);123  sqlite3 *db = open_db_and_init(zDb);124 125  /* Switch to WAL without any DDL/DML. This can leave pPager->pWal==0. */126  exec_ok(db, "PRAGMA journal_mode=WAL;");127 128  Pager *pPager = get_main_pager(db);129 130  int nLog = -123;131  int nCkpt = -456;132  int rc = sqlite3PagerCheckpoint(pPager, db, SQLITE_CHECKPOINT_PASSIVE, &nLog, &nCkpt);133 134  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);135  /* Either untouched (still -123/-456) or zeroed (no frames to checkpoint). */136  TEST_ASSERT_TRUE((nLog == -123 && nCkpt == -456) || (nLog == 0 && nCkpt == 0));137 138  sqlite3_close(db);139  remove_db_files(zDb);140}141 142/* Test 4: In WAL mode with frames, allow NULL output pointers; must succeed without crashing. */143void test_sqlite3PagerCheckpoint_wal_null_outputs(void){144  const char *zDb = "test_pc_wal_null.sqlite";145  remove_db_files(zDb);146  sqlite3 *db = open_db_and_init(zDb);147 148  create_wal_with_frames(db);149  Pager *pPager = get_main_pager(db);150 151  int rc = sqlite3PagerCheckpoint(pPager, db, SQLITE_CHECKPOINT_FULL, NULL, NULL);152  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);153 154  sqlite3_close(db);155  remove_db_files(zDb);156}157 158int main(void) {159  UNITY_BEGIN();160  RUN_TEST(test_sqlite3PagerCheckpoint_no_wal_outputs_unchanged);161  RUN_TEST(test_sqlite3PagerCheckpoint_wal_passive_full_checkpoint);162  RUN_TEST(test_sqlite3PagerCheckpoint_wal_specialcase_no_txn);163  RUN_TEST(test_sqlite3PagerCheckpoint_wal_null_outputs);164  return UNITY_END();165}