Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btree_clearAllSharedCacheTableLocks.c143 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* External wrapper added for testing static function */6extern void test_clearAllSharedCacheTableLocks(Btree *p);7 8/* Helpers to create minimal objects */9static Btree *allocBtreeWithShared(sqlite3_mutex *pMutex){10  Btree *p = (Btree*)sqlite3MallocZero(sizeof(Btree));11  BtShared *pBt = (BtShared*)sqlite3MallocZero(sizeof(BtShared));12  TEST_ASSERT_NOT_NULL(p);13  TEST_ASSERT_NOT_NULL(pBt);14  p->pBt = pBt;15  p->inTrans = TRANS_WRITE; /* >= any eLock */16  p->sharable = 1;17  pBt->mutex = pMutex;18  pBt->pLock = NULL;19  pBt->nTransaction = 0;20  pBt->btsFlags = 0;21  pBt->pWriter = NULL;22  return p;23}24 25static BtLock *makeLock(Btree *owner, Pgno iTable, u8 eLock){26  BtLock *pL = (BtLock*)sqlite3MallocZero(sizeof(BtLock));27  TEST_ASSERT_NOT_NULL(pL);28  pL->pBtree = owner;29  pL->iTable = iTable;30  pL->eLock = eLock;31  pL->pNext = NULL;32  return pL;33}34 35/* Global for setUp/tearDown */36static sqlite3_mutex *gFastMutex = NULL;37 38void setUp(void) {39  /* Initialize SQLite mutex system */40  sqlite3_initialize();41  gFastMutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);42  TEST_ASSERT_NOT_NULL(gFastMutex);43}44 45void tearDown(void) {46  /* Note: SQLite core owns the fast static mutex; do not free it here. */47  gFastMutex = NULL;48}49 50/* Test 1: Remove only target Btree locks; keep others; clear pending when nTransaction==2 and p is not writer */51void test_clearAllSharedCacheTableLocks_removes_target_and_clears_pending(void){52  Btree *p = allocBtreeWithShared(gFastMutex);53  Btree *pOther = allocBtreeWithShared(gFastMutex);54  pOther->pBt = p->pBt; /* Share the same BtShared */55  p->pBt->nTransaction = 2;56  p->pBt->btsFlags |= BTS_PENDING;57 58  /* Build lock list: other -> p (t2) -> p (t3) */59  BtLock *lockA = makeLock(pOther, 5, READ_LOCK);60  BtLock *lockB = makeLock(p, 2, READ_LOCK);61  BtLock *lockC = makeLock(p, 3, WRITE_LOCK);62  p->pBt->pLock = lockA;63  lockA->pNext = lockB;64  lockB->pNext = lockC;65 66  /* Preconditions */67  TEST_ASSERT_NOT_NULL(p->pBt->pLock);68  TEST_ASSERT_TRUE( (p->pBt->btsFlags & BTS_PENDING)!=0 );69 70  sqlite3_mutex_enter(p->pBt->mutex);71  test_clearAllSharedCacheTableLocks(p);72  sqlite3_mutex_leave(p->pBt->mutex);73 74  /* Postconditions:75     - locks belonging to p are gone; only lockA remains76     - pending flag cleared (nTransaction==2 case)77     - writer unchanged (NULL) */78  TEST_ASSERT_EQUAL_PTR(lockA, p->pBt->pLock);79  TEST_ASSERT_NULL(lockA->pNext);80  TEST_ASSERT_TRUE( (p->pBt->btsFlags & BTS_PENDING)==0 );81  TEST_ASSERT_NULL(p->pBt->pWriter);82 83  /* Cleanup */84  sqlite3_free(lockA);85  sqlite3_free(pOther->pBt); sqlite3_free(pOther);86  sqlite3_free(p->pBt); sqlite3_free(p);87}88 89/* Test 2: When p is writer, writer and flags cleared; schema lock (iTable==1) removed without freeing */90void test_clearAllSharedCacheTableLocks_writer_and_schema_lock(void){91  Btree *p = allocBtreeWithShared(gFastMutex);92  p->pBt->pWriter = p;93  p->pBt->btsFlags |= (BTS_EXCLUSIVE | BTS_PENDING);94  p->lock.pBtree = p;95  p->lock.iTable = 1; /* schema table */96  p->lock.eLock = READ_LOCK;97  p->lock.pNext = NULL;98 99  /* p->lock is embedded; add to list */100  p->pBt->pLock = &p->lock;101 102  sqlite3_mutex_enter(p->pBt->mutex);103  test_clearAllSharedCacheTableLocks(p);104  sqlite3_mutex_leave(p->pBt->mutex);105 106  /* Postconditions:107     - lock list empty108     - writer cleared; flags cleared109     - embedded lock still accessible and unchanged */110  TEST_ASSERT_NULL(p->pBt->pLock);111  TEST_ASSERT_NULL(p->pBt->pWriter);112  TEST_ASSERT_TRUE( (p->pBt->btsFlags & (BTS_EXCLUSIVE|BTS_PENDING))==0 );113  TEST_ASSERT_EQUAL_UINT(1, p->lock.iTable);114  TEST_ASSERT_EQUAL_PTR(p, p->lock.pBtree);115 116  sqlite3_free(p->pBt); sqlite3_free(p);117}118 119/* Test 3: Non-sharable with no locks: clears pending when nTransaction==2; no crash */120void test_clearAllSharedCacheTableLocks_nonsharable_no_locks(void){121  Btree *p = allocBtreeWithShared(gFastMutex);122  p->sharable = 0; /* Non-sharable */123  p->pBt->pLock = NULL;124  p->pBt->nTransaction = 2;125  p->pBt->btsFlags |= BTS_PENDING;126 127  sqlite3_mutex_enter(p->pBt->mutex);128  test_clearAllSharedCacheTableLocks(p);129  sqlite3_mutex_leave(p->pBt->mutex);130 131  TEST_ASSERT_TRUE( (p->pBt->btsFlags & BTS_PENDING)==0 );132  TEST_ASSERT_NULL(p->pBt->pLock);133 134  sqlite3_free(p->pBt); sqlite3_free(p);135}136 137int main(void) {138  UNITY_BEGIN();139  RUN_TEST(test_clearAllSharedCacheTableLocks_removes_target_and_clears_pending);140  RUN_TEST(test_clearAllSharedCacheTableLocks_writer_and_schema_lock);141  RUN_TEST(test_clearAllSharedCacheTableLocks_nonsharable_no_locks);142  return UNITY_END();143}