AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Helper to clear the mutex methods in global config */6static void clearGlobalMutexMethods(void){7 memset(&sqlite3GlobalConfig.mutex, 0, sizeof(sqlite3GlobalConfig.mutex));8}9 10/* Helper to compare two sqlite3_mutex_methods structures */11static void assertMutexMethodsEqual(const sqlite3_mutex_methods *a,12 const sqlite3_mutex_methods *b){13 TEST_ASSERT_EQUAL_PTR(a->xMutexInit, b->xMutexInit);14 TEST_ASSERT_EQUAL_PTR(a->xMutexEnd, b->xMutexEnd);15 TEST_ASSERT_EQUAL_PTR(a->xMutexFree, b->xMutexFree);16 TEST_ASSERT_EQUAL_PTR(a->xMutexEnter, b->xMutexEnter);17 TEST_ASSERT_EQUAL_PTR(a->xMutexTry, b->xMutexTry);18 TEST_ASSERT_EQUAL_PTR(a->xMutexLeave, b->xMutexLeave);19 TEST_ASSERT_EQUAL_PTR(a->xMutexHeld, b->xMutexHeld);20 TEST_ASSERT_EQUAL_PTR(a->xMutexNotheld, b->xMutexNotheld);21 TEST_ASSERT_EQUAL_PTR(a->xMutexAlloc, b->xMutexAlloc);22}23 24/* Custom preconfigured methods to test "already configured" branch */25static int g_customInitCalled = 0;26static int custom_xMutexInit(void){ g_customInitCalled++; return 123; }27static int custom_xMutexEnd(void){ return 0; }28static sqlite3_mutex *custom_xMutexAlloc(int id){ (void)id; return (sqlite3_mutex*)0x1; }29static void custom_xMutexFree(sqlite3_mutex *p){ (void)p; }30static void custom_xMutexEnter(sqlite3_mutex *p){ (void)p; }31static int custom_xMutexTry(sqlite3_mutex *p){ (void)p; return SQLITE_BUSY; }32static void custom_xMutexLeave(sqlite3_mutex *p){ (void)p; }33static int custom_xMutexHeld(sqlite3_mutex *p){ (void)p; return 1; }34static int custom_xMutexNotheld(sqlite3_mutex *p){ (void)p; return 1; }35 36/* Unity fixtures */37void setUp(void) {38 /* Ensure we start each test with no configured mutex methods and no side-effects */39 sqlite3MutexEnd(); /* Use any existing end method if set */40 clearGlobalMutexMethods();41 sqlite3GlobalConfig.bCoreMutex = 0;42 g_customInitCalled = 0;43}44void tearDown(void) {45 sqlite3MutexEnd();46 clearGlobalMutexMethods();47}48 49/* Test: When bCoreMutex==0 and no preconfiguration, use the no-op mutex methods */50void test_sqlite3MutexInit_uses_noop_methods_when_bCoreMutex_false(void){51#ifndef SQLITE_MUTEX_OMIT52 sqlite3GlobalConfig.bCoreMutex = 0;53 clearGlobalMutexMethods();54 55 int rc = sqlite3MutexInit();56 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);57 58 const sqlite3_mutex_methods *expected = sqlite3NoopMutex();59 60 assertMutexMethodsEqual(&sqlite3GlobalConfig.mutex, expected);61#else62 TEST_IGNORE_MESSAGE("SQLITE_MUTEX_OMIT defined, mutex subsystem omitted.");63#endif64}65 66/* Test: When bCoreMutex==1 and no preconfiguration, use default or multithread-check methods */67void test_sqlite3MutexInit_uses_default_or_mtcheck_methods_when_bCoreMutex_true(void){68#ifndef SQLITE_MUTEX_OMIT69 sqlite3GlobalConfig.bCoreMutex = 1;70 clearGlobalMutexMethods();71 72 int rc = sqlite3MutexInit();73 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);74 75 const sqlite3_mutex_methods *expected;76#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS77 expected = multiThreadedCheckMutex();78#else79 expected = sqlite3DefaultMutex();80#endif81 82 assertMutexMethodsEqual(&sqlite3GlobalConfig.mutex, expected);83#else84 TEST_IGNORE_MESSAGE("SQLITE_MUTEX_OMIT defined, mutex subsystem omitted.");85#endif86}87 88/* Test: If methods are already configured (xMutexAlloc non-NULL), do not overwrite; call existing xMutexInit and return its rc */89void test_sqlite3MutexInit_respects_preconfigured_methods_and_returns_rc(void){90#ifndef SQLITE_MUTEX_OMIT91 /* Preconfigure with custom methods */92 sqlite3GlobalConfig.bCoreMutex = 1; /* Irrelevant when already configured */93 sqlite3GlobalConfig.mutex.xMutexInit = custom_xMutexInit;94 sqlite3GlobalConfig.mutex.xMutexEnd = custom_xMutexEnd;95 sqlite3GlobalConfig.mutex.xMutexFree = custom_xMutexFree;96 sqlite3GlobalConfig.mutex.xMutexEnter = custom_xMutexEnter;97 sqlite3GlobalConfig.mutex.xMutexTry = custom_xMutexTry;98 sqlite3GlobalConfig.mutex.xMutexLeave = custom_xMutexLeave;99 sqlite3GlobalConfig.mutex.xMutexHeld = custom_xMutexHeld;100 sqlite3GlobalConfig.mutex.xMutexNotheld = custom_xMutexNotheld;101 sqlite3GlobalConfig.mutex.xMutexAlloc = custom_xMutexAlloc; /* Non-NULL so init() will not copy defaults */102 103 int rc = sqlite3MutexInit();104 105 TEST_ASSERT_EQUAL_INT(123, rc);106 TEST_ASSERT_EQUAL_INT(1, g_customInitCalled);107 108 /* Ensure our preconfigured function pointers were not overwritten */109 TEST_ASSERT_EQUAL_PTR(custom_xMutexInit, sqlite3GlobalConfig.mutex.xMutexInit);110 TEST_ASSERT_EQUAL_PTR(custom_xMutexEnd, sqlite3GlobalConfig.mutex.xMutexEnd);111 TEST_ASSERT_EQUAL_PTR(custom_xMutexFree, sqlite3GlobalConfig.mutex.xMutexFree);112 TEST_ASSERT_EQUAL_PTR(custom_xMutexEnter, sqlite3GlobalConfig.mutex.xMutexEnter);113 TEST_ASSERT_EQUAL_PTR(custom_xMutexTry, sqlite3GlobalConfig.mutex.xMutexTry);114 TEST_ASSERT_EQUAL_PTR(custom_xMutexLeave, sqlite3GlobalConfig.mutex.xMutexLeave);115 TEST_ASSERT_EQUAL_PTR(custom_xMutexHeld, sqlite3GlobalConfig.mutex.xMutexHeld);116 TEST_ASSERT_EQUAL_PTR(custom_xMutexNotheld, sqlite3GlobalConfig.mutex.xMutexNotheld);117 TEST_ASSERT_EQUAL_PTR(custom_xMutexAlloc, sqlite3GlobalConfig.mutex.xMutexAlloc);118#else119 TEST_IGNORE_MESSAGE("SQLITE_MUTEX_OMIT defined, mutex subsystem omitted.");120#endif121}122 123/* Test: Idempotence - calling sqlite3MutexInit twice should not change methods once configured */124void test_sqlite3MutexInit_idempotent_after_first_init(void){125#ifndef SQLITE_MUTEX_OMIT126 /* First init with bCoreMutex=0 (noop) */127 sqlite3GlobalConfig.bCoreMutex = 0;128 clearGlobalMutexMethods();129 int rc1 = sqlite3MutexInit();130 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc1);131 sqlite3_mutex_methods saved = sqlite3GlobalConfig.mutex;132 133 /* Change bCoreMutex and call again, expect methods unchanged and rc still OK */134 sqlite3GlobalConfig.bCoreMutex = 1;135 int rc2 = sqlite3MutexInit();136 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc2);137 138 assertMutexMethodsEqual(&sqlite3GlobalConfig.mutex, &saved);139#else140 TEST_IGNORE_MESSAGE("SQLITE_MUTEX_OMIT defined, mutex subsystem omitted.");141#endif142}143 144int main(void) {145 UNITY_BEGIN();146 RUN_TEST(test_sqlite3MutexInit_uses_noop_methods_when_bCoreMutex_false);147 RUN_TEST(test_sqlite3MutexInit_uses_default_or_mtcheck_methods_when_bCoreMutex_true);148 RUN_TEST(test_sqlite3MutexInit_respects_preconfigured_methods_and_returns_rc);149 RUN_TEST(test_sqlite3MutexInit_idempotent_after_first_init);150 return UNITY_END();151}