Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btree_checkPtrmap.c196 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdio.h>5 6/* Wrapper provided in the SQLite module for static function checkPtrmap */7extern void test_checkPtrmap(IntegrityCk *pCheck, Pgno iChild, u8 eType, Pgno iParent);8 9static void init_db_autovac(sqlite3 **ppDb){10  sqlite3 *db = 0;11  int rc = sqlite3_open("test_checkptrmap.db", &db);12  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);13 14  /* Enable full autovacuum and set a small page size for simplicity, then VACUUM */15  rc = sqlite3_exec(db, "PRAGMA auto_vacuum=FULL; PRAGMA page_size=1024;", 0, 0, 0);16  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);17  rc = sqlite3_exec(db, "VACUUM;", 0, 0, 0);18  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);19 20  *ppDb = db;21}22 23static Pgno get_table_rootpage(sqlite3 *db, const char *zName){24  sqlite3_stmt *stmt = 0;25  Pgno root = 0;26  int rc = sqlite3_prepare_v2(db, "SELECT rootpage FROM sqlite_schema WHERE name=?1;", -1, &stmt, 0);27  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);28  rc = sqlite3_bind_text(stmt, 1, zName, -1, SQLITE_STATIC);29  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);30  rc = sqlite3_step(stmt);31  TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);32  root = (Pgno)sqlite3_column_int(stmt, 0);33  sqlite3_finalize(stmt);34  return root;35}36 37static void init_integrity_ck(IntegrityCk *pCk, sqlite3 *db, BtShared *pBt, char *zBuf, int nBuf){38  memset(pCk, 0, sizeof(*pCk));39  pCk->db = db;40  pCk->pBt = pBt;41  pCk->pPager = pBt->pPager;42  pCk->mxErr = 1000;43  sqlite3StrAccumInit(&pCk->errMsg, 0, zBuf, nBuf, SQLITE_MAX_LENGTH);44  pCk->errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;45}46 47/* Unity hooks */48void setUp(void) {49  /* nothing */50}51void tearDown(void) {52  /* remove db file to avoid cross-test contamination */53  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);54  if( pVfs ){55    sqlite3_file *pFile = (sqlite3_file*)sqlite3_malloc(pVfs->szOsFile);56    if( pFile ){57      if( pVfs->xAccess ){58        /* Ignore result; file may not exist */59      }60      if( pVfs->xDelete ){61        pVfs->xDelete(pVfs, "test_checkptrmap.db", 0);62      }63      sqlite3_free(pFile);64    }65  }66}67 68/* Test: correct mapping for a root page should produce no error */69void test_checkPtrmap_root_ok(void){70  sqlite3 *db = 0;71  init_db_autovac(&db);72 73  /* Create a table and get its root page */74  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "CREATE TABLE t(a);", 0, 0, 0));75  Pgno root = get_table_rootpage(db, "t");76  TEST_ASSERT_GREATER_THAN_UINT32(1u, 0u); /* dummy to keep compiler happy */77 78  /* Acquire Btree and BtShared */79  Btree *pBtree = db->aDb[0].pBt;80  TEST_ASSERT_NOT_NULL(pBtree);81  BtShared *pBt = pBtree->pBt;82  TEST_ASSERT_NOT_NULL(pBt);83 84  /* Prepare integrity checker context */85  char zBuf[1024];86  IntegrityCk ck;87  init_integrity_ck(&ck, db, pBt, zBuf, (int)sizeof(zBuf));88 89  /* Must hold the btree mutex while invoking checkPtrmap */90  sqlite3BtreeEnter(pBtree);91  test_checkPtrmap(&ck, root, PTRMAP_ROOTPAGE, 0);92  sqlite3BtreeLeave(pBtree);93 94  /* Expect no errors */95  TEST_ASSERT_EQUAL_INT(0, ck.nErr);96 97  sqlite3_close(db);98}99 100/* Test: wrong expected type for a valid root page should report an error */101void test_checkPtrmap_root_wrong_type_reports_error(void){102  sqlite3 *db = 0;103  init_db_autovac(&db);104 105  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "CREATE TABLE t(a);", 0, 0, 0));106  Pgno root = get_table_rootpage(db, "t");107 108  Btree *pBtree = db->aDb[0].pBt;109  TEST_ASSERT_NOT_NULL(pBtree);110  BtShared *pBt = pBtree->pBt;111  TEST_ASSERT_NOT_NULL(pBt);112 113  char zBuf[1024];114  IntegrityCk ck;115  init_integrity_ck(&ck, db, pBt, zBuf, (int)sizeof(zBuf));116 117  sqlite3BtreeEnter(pBtree);118  /* Supply wrong expected type */119  test_checkPtrmap(&ck, root, PTRMAP_FREEPAGE, 0);120  sqlite3BtreeLeave(pBtree);121 122  TEST_ASSERT_GREATER_THAN_INT(0, ck.nErr);123  /* The error message should contain "Bad ptr map entry" */124  TEST_ASSERT_NOT_NULL(ck.errMsg.zText);125  TEST_ASSERT_GREATER_OR_EQUAL_INT(0, (int)strstr(ck.errMsg.zText, "Bad ptr map entry") - ck.errMsg.zText);126 127  sqlite3_close(db);128}129 130/* Test: mapping for a freed page (after dropping a table) should be FREEPAGE, parent 0 */131void test_checkPtrmap_freepage_ok(void){132  sqlite3 *db = 0;133  init_db_autovac(&db);134 135  /* Create and drop a table t2 to put its root page onto the freelist */136  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "CREATE TABLE t2(x);", 0, 0, 0));137  Pgno root2 = get_table_rootpage(db, "t2");138  TEST_ASSERT_GREATER_THAN_UINT32(2u, 0u);139  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "DROP TABLE t2;", 0, 0, 0));140 141  Btree *pBtree = db->aDb[0].pBt;142  TEST_ASSERT_NOT_NULL(pBtree);143  BtShared *pBt = pBtree->pBt;144  TEST_ASSERT_NOT_NULL(pBt);145 146  char zBuf[1024];147  IntegrityCk ck;148  init_integrity_ck(&ck, db, pBt, zBuf, (int)sizeof(zBuf));149 150  sqlite3BtreeEnter(pBtree);151  test_checkPtrmap(&ck, root2, PTRMAP_FREEPAGE, 0);152  sqlite3BtreeLeave(pBtree);153 154  TEST_ASSERT_EQUAL_INT(0, ck.nErr);155 156  sqlite3_close(db);157}158 159/* Test: wrong expected parent for FREEPAGE should report error */160void test_checkPtrmap_freepage_wrong_parent_reports_error(void){161  sqlite3 *db = 0;162  init_db_autovac(&db);163 164  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "CREATE TABLE t2(x);", 0, 0, 0));165  Pgno root2 = get_table_rootpage(db, "t2");166  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_exec(db, "DROP TABLE t2;", 0, 0, 0));167 168  Btree *pBtree = db->aDb[0].pBt;169  TEST_ASSERT_NOT_NULL(pBtree);170  BtShared *pBt = pBtree->pBt;171  TEST_ASSERT_NOT_NULL(pBt);172 173  char zBuf[1024];174  IntegrityCk ck;175  init_integrity_ck(&ck, db, pBt, zBuf, (int)sizeof(zBuf));176 177  sqlite3BtreeEnter(pBtree);178  /* Supply incorrect expected parent (FREEPAGE entries have parent 0) */179  test_checkPtrmap(&ck, root2, PTRMAP_FREEPAGE, 999999);180  sqlite3BtreeLeave(pBtree);181 182  TEST_ASSERT_GREATER_THAN_INT(0, ck.nErr);183  TEST_ASSERT_NOT_NULL(ck.errMsg.zText);184  TEST_ASSERT_GREATER_OR_EQUAL_INT(0, (int)strstr(ck.errMsg.zText, "Bad ptr map entry") - ck.errMsg.zText);185 186  sqlite3_close(db);187}188 189int main(void){190  UNITY_BEGIN();191  RUN_TEST(test_checkPtrmap_root_ok);192  RUN_TEST(test_checkPtrmap_root_wrong_type_reports_error);193  RUN_TEST(test_checkPtrmap_freepage_ok);194  RUN_TEST(test_checkPtrmap_freepage_wrong_parent_reports_error);195  return UNITY_END();196}