Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btmutex_sqlite3BtreeEnter.c163 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Unity fixtures */7void setUp(void) {8  /* no-op */9}10void tearDown(void) {11  /* no-op */12}13 14/* Helper: open an in-memory DB and enter its mutex (if present) */15static sqlite3* open_db_and_lock(void){16  sqlite3 *db = 0;17  int rc = sqlite3_open(":memory:", &db);18  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);19  if( db && db->mutex ){20    sqlite3_mutex_enter(db->mutex);21  }22  return db;23}24 25/* Helper: leave db mutex (if held) and close DB */26static void close_db_and_unlock(sqlite3 *db){27  if( !db ) return;28  if( db->mutex ){29    sqlite3_mutex_leave(db->mutex);30  }31  sqlite3_close(db);32}33 34/* Helper: allocate and initialize a fabricated Btree + BtShared.35   sharable!=0 => p->sharable is true; otherwise false.36*/37static Btree* make_btree(sqlite3 *db, int sharable){38  Btree *p = (Btree*)sqlite3_malloc(sizeof(Btree));39  TEST_ASSERT_NOT_NULL(p);40  memset(p, 0, sizeof(Btree));41  p->db = db;42  p->sharable = sharable ? 1 : 0;43  p->pBt = (BtShared*)sqlite3_malloc(sizeof(BtShared));44  TEST_ASSERT_NOT_NULL(p->pBt);45  memset(p->pBt, 0, sizeof(BtShared));46  /* Allocate a mutex for BtShared. In single-thread builds this may be NULL,47     which is fine since we don't depend on it there. */48  p->pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);49  /* For non-sharable btrees, BtShared.db should already match p->db50     to satisfy preconditions in the threadsafe implementation. */51  if( !p->sharable ){52    p->pBt->db = db;53  }54  return p;55}56 57/* Helper: free fabricated Btree + BtShared; ensure unlocked first */58static void free_btree(Btree *p){59  if( !p ) return;60#if SQLITE_THREADSAFE61  if( p->sharable && p->locked ){62    /* Leave until fully unlocked */63    while( p->wantToLock > 0 ){64      sqlite3BtreeLeave(p);65    }66  }67#endif68  if( p->pBt ){69    if( p->pBt->mutex ){70      sqlite3_mutex_free(p->pBt->mutex);71    }72    sqlite3_free(p->pBt);73  }74  sqlite3_free(p);75}76 77/* Test: sharable Btree basic enter acquires lock, sets db, and updates counters */78void test_sqlite3BtreeEnter_sharable_basic(void){79  sqlite3 *db = open_db_and_lock();80  Btree *p = make_btree(db, 1);81 82  /* Preconditions */83  TEST_ASSERT_EQUAL_INT(0, p->wantToLock);84  TEST_ASSERT_EQUAL_INT(0, p->locked);85 86  sqlite3BtreeEnter(p);87 88#if SQLITE_THREADSAFE89  TEST_ASSERT_EQUAL_INT(1, p->wantToLock);90  TEST_ASSERT_EQUAL_INT(1, p->locked);91  TEST_ASSERT_EQUAL_PTR(db, p->pBt->db);92  if( p->pBt->mutex ){93    TEST_ASSERT_TRUE(sqlite3_mutex_held(p->pBt->mutex));94  }95  /* Clean up: leave once to drop the lock */96  sqlite3BtreeLeave(p);97  TEST_ASSERT_EQUAL_INT(0, p->wantToLock);98  TEST_ASSERT_EQUAL_INT(0, p->locked);99#else100  /* Non-threadsafe: only pBt->db is set/maintained */101  TEST_ASSERT_EQUAL_PTR(db, p->pBt->db);102  TEST_ASSERT_EQUAL_INT(0, p->wantToLock);103  TEST_ASSERT_EQUAL_INT(0, p->locked);104#endif105 106  free_btree(p);107  close_db_and_unlock(db);108}109 110/* Test: recursive enter increments wantToLock but does not re-lock */111void test_sqlite3BtreeEnter_recursive(void){112  sqlite3 *db = open_db_and_lock();113  Btree *p = make_btree(db, 1);114 115  sqlite3BtreeEnter(p);116  sqlite3BtreeEnter(p);117 118#if SQLITE_THREADSAFE119  TEST_ASSERT_EQUAL_INT(2, p->wantToLock);120  TEST_ASSERT_EQUAL_INT(1, p->locked);121  if( p->pBt->mutex ){122    TEST_ASSERT_TRUE(sqlite3_mutex_held(p->pBt->mutex));123  }124  /* Leave twice to unwind recursion */125  sqlite3BtreeLeave(p);126  TEST_ASSERT_EQUAL_INT(1, p->wantToLock);127  TEST_ASSERT_EQUAL_INT(1, p->locked);128  sqlite3BtreeLeave(p);129  TEST_ASSERT_EQUAL_INT(0, p->wantToLock);130  TEST_ASSERT_EQUAL_INT(0, p->locked);131#else132  /* In non-threadsafe builds, sqlite3BtreeEnter only sets pBt->db */133  TEST_ASSERT_EQUAL_PTR(db, p->pBt->db);134#endif135 136  free_btree(p);137  close_db_and_unlock(db);138}139 140/* Test: non-sharable Btree -> enter is a no-op for locking/counters */141void test_sqlite3BtreeEnter_unsharable_noop(void){142  sqlite3 *db = open_db_and_lock();143  Btree *p = make_btree(db, 0);144 145  sqlite3BtreeEnter(p);146 147#if SQLITE_THREADSAFE148  TEST_ASSERT_EQUAL_INT(0, p->wantToLock);149  TEST_ASSERT_EQUAL_INT(0, p->locked);150#endif151  TEST_ASSERT_EQUAL_PTR(db, p->pBt->db);152 153  free_btree(p);154  close_db_and_unlock(db);155}156 157int main(void){158  UNITY_BEGIN();159  RUN_TEST(test_sqlite3BtreeEnter_sharable_basic);160  RUN_TEST(test_sqlite3BtreeEnter_recursive);161  RUN_TEST(test_sqlite3BtreeEnter_unsharable_noop);162  return UNITY_END();163}