Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_sqlite3PagerCacheStat.c214 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <string.h>6 7/* Unity setUp/tearDown */8void setUp(void) {9  /* No global setup required */10}11void tearDown(void) {12  /* No global teardown required */13}14 15/* Helper to open an in-memory database and return Pager* for main db */16static int open_memdb_and_get_pager(sqlite3 **ppDb, Pager **ppPager){17  int rc = sqlite3_open(":memory:", ppDb);18  if( rc!=SQLITE_OK ) return rc;19 20  /* Ensure the main database/pager is initialized by creating a table. */21  rc = sqlite3_exec(*ppDb, "CREATE TABLE IF NOT EXISTS t_init(x);", 0, 0, 0);22  if( rc!=SQLITE_OK ){23    sqlite3_close(*ppDb);24    *ppDb = 0;25    return rc;26  }27 28  /* Obtain the Pager* from the main database Btree */29  if( (*ppDb)->aDb==0 || (*ppDb)->aDb[0].pBt==0 ){30    /* Force initialization if somehow not yet done */31    rc = sqlite3_exec(*ppDb, "SELECT name FROM sqlite_master LIMIT 1;", 0, 0, 0);32    if( rc!=SQLITE_OK ){33      sqlite3_close(*ppDb);34      *ppDb = 0;35      return rc;36    }37  }38 39  *ppPager = sqlite3BtreePager((*ppDb)->aDb[0].pBt);40  return SQLITE_OK;41}42 43/* Convenience wrapper around sqlite3PagerCacheStat */44static u64 pager_stat_value(Pager *pPager, int eStat, int reset){45  u64 v = 0;46  sqlite3PagerCacheStat(pPager, eStat, reset, &v);47  return v;48}49 50static void reset_stat(Pager *pPager, int eStat){51  (void)pager_stat_value(pPager, eStat, 1);52}53 54/* Test: HIT accumulates into pnVal and resets correctly */55void test_sqlite3PagerCacheStat_hit_accumulates_and_resets(void){56  sqlite3 *db = 0;57  Pager *pPager = 0;58  int rc = open_memdb_and_get_pager(&db, &pPager);59  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);60  TEST_ASSERT_NOT_NULL(pPager);61 62  /* Reset HIT counter */63  reset_stat(pPager, SQLITE_DBSTATUS_CACHE_HIT);64 65  /* Run a query twice to create at least one cache hit on the second run */66  rc = sqlite3_exec(db, "SELECT name FROM sqlite_master WHERE type='table' LIMIT 10;", 0, 0, 0);67  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);68  rc = sqlite3_exec(db, "SELECT name FROM sqlite_master WHERE type='table' LIMIT 10;", 0, 0, 0);69  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);70 71  u64 v1 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_HIT, 0);72  TEST_ASSERT_TRUE(v1 >= 1); /* Expect at least one hit */73 74  /* Calling again with reset=1 should report same number and then clear */75  u64 v2 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_HIT, 1);76  TEST_ASSERT_TRUE(v2 >= 1);77  TEST_ASSERT_EQUAL_UINT64(v1, v2);78 79  /* Now the counter should be zero */80  u64 v3 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_HIT, 0);81  TEST_ASSERT_EQUAL_UINT64(0, v3);82 83  sqlite3_close(db);84}85 86/* Test: MISS counter increases after first access to schema */87void test_sqlite3PagerCacheStat_miss_counter_increases_after_first_access(void){88  sqlite3 *db = 0;89  Pager *pPager = 0;90  int rc = open_memdb_and_get_pager(&db, &pPager);91  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);92  TEST_ASSERT_NOT_NULL(pPager);93 94  /* Reset MISS counter */95  reset_stat(pPager, SQLITE_DBSTATUS_CACHE_MISS);96 97  /* First access to schema should cause at least one miss */98  rc = sqlite3_exec(db, "SELECT name FROM sqlite_master LIMIT 5;", 0, 0, 0);99  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);100 101  u64 miss = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_MISS, 0);102  TEST_ASSERT_TRUE(miss >= 1);103 104  /* Reset and verify zero */105  u64 beforeReset = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_MISS, 1);106  TEST_ASSERT_TRUE(beforeReset >= 1);107  u64 afterReset = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_MISS, 0);108  TEST_ASSERT_EQUAL_UINT64(0, afterReset);109 110  sqlite3_close(db);111}112 113/* Test: WRITE counter increases after DDL/INSERT and accumulation works */114void test_sqlite3PagerCacheStat_write_counter_increases_after_ddl(void){115  sqlite3 *db = 0;116  Pager *pPager = 0;117  int rc = open_memdb_and_get_pager(&db, &pPager);118  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);119  TEST_ASSERT_NOT_NULL(pPager);120 121  /* Reset WRITE counter */122  reset_stat(pPager, SQLITE_DBSTATUS_CACHE_WRITE);123 124  /* Perform writes: create a table and insert rows */125  rc = sqlite3_exec(db,126      "CREATE TABLE t1(a);"127      "INSERT INTO t1(a) VALUES(1),(2),(3),(4),(5);", 0, 0, 0);128  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);129 130  /* Get current write count */131  u64 w1 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 0);132  TEST_ASSERT_TRUE(w1 >= 1);133 134  /* Verify accumulation into a non-zero pnVal */135  u64 pn = 5;136  sqlite3PagerCacheStat(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 0, &pn);137  TEST_ASSERT_EQUAL_UINT64(5 + w1, pn);138 139  /* Reset and verify cleared */140  u64 w2 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 1);141  TEST_ASSERT_TRUE(w2 >= 1);142  u64 w3 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 0);143  TEST_ASSERT_EQUAL_UINT64(0, w3);144 145  sqlite3_close(db);146}147 148/* Test: Resetting one stat does not affect others (HIT vs WRITE) */149void test_sqlite3PagerCacheStat_reset_is_per_statistic(void){150  sqlite3 *db = 0;151  Pager *pPager = 0;152  int rc = open_memdb_and_get_pager(&db, &pPager);153  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);154  TEST_ASSERT_NOT_NULL(pPager);155 156  /* Reset both counters first */157  reset_stat(pPager, SQLITE_DBSTATUS_CACHE_HIT);158  reset_stat(pPager, SQLITE_DBSTATUS_CACHE_WRITE);159 160  /* Generate some writes and hits */161  rc = sqlite3_exec(db,162      "CREATE TABLE t2(x);"163      "INSERT INTO t2 VALUES(10),(20);", 0, 0, 0);164  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);165  rc = sqlite3_exec(db, "SELECT name FROM sqlite_master WHERE type='table' LIMIT 10;", 0, 0, 0);166  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);167  rc = sqlite3_exec(db, "SELECT name FROM sqlite_master WHERE type='table' LIMIT 10;", 0, 0, 0);168  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);169 170  u64 w_before = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 0);171  TEST_ASSERT_TRUE(w_before >= 1);172 173  /* Reset HIT only */174  (void)pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_HIT, 1);175 176  /* WRITE should be unaffected */177  u64 w_after = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE, 0);178  TEST_ASSERT_EQUAL_UINT64(w_before, w_after);179 180  sqlite3_close(db);181}182 183/* Test: SPILL stat can be queried/reset without error */184void test_sqlite3PagerCacheStat_spill_stat_access_and_reset(void){185  sqlite3 *db = 0;186  Pager *pPager = 0;187  int rc = open_memdb_and_get_pager(&db, &pPager);188  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);189  TEST_ASSERT_NOT_NULL(pPager);190 191  /* Read current SPILL count (may be 0) */192  u64 s0 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE + 1, 0);193  TEST_ASSERT_TRUE(s0 >= 0);194 195  /* Reset SPILL count */196  u64 sReset = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE + 1, 1);197  TEST_ASSERT_TRUE(sReset >= 0);198 199  /* Now it should be zero */200  u64 s1 = pager_stat_value(pPager, SQLITE_DBSTATUS_CACHE_WRITE + 1, 0);201  TEST_ASSERT_EQUAL_UINT64(0, s1);202 203  sqlite3_close(db);204}205 206int main(void){207  UNITY_BEGIN();208  RUN_TEST(test_sqlite3PagerCacheStat_hit_accumulates_and_resets);209  RUN_TEST(test_sqlite3PagerCacheStat_miss_counter_increases_after_first_access);210  RUN_TEST(test_sqlite3PagerCacheStat_write_counter_increases_after_ddl);211  RUN_TEST(test_sqlite3PagerCacheStat_reset_is_per_statistic);212  RUN_TEST(test_sqlite3PagerCacheStat_spill_stat_access_and_reset);213  return UNITY_END();214}