Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btmutex_sqlite3SchemaMutexHeld.c165 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Unity setup/teardown */7void setUp(void) {8  /* No global setup required */9}10void tearDown(void) {11  /* No global teardown required */12}13 14/* Helper: open an in-memory db and assert success */15static sqlite3* open_memdb(void){16  sqlite3 *db = 0;17  int rc = sqlite3_open(":memory:", &db);18  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open(:memory:) failed");19  TEST_ASSERT_NOT_NULL(db);20  return db;21}22 23#ifndef NDEBUG  /* The target function is only available in non-NDEBUG builds */24 25void test_sqlite3SchemaMutexHeld_uninitialized_db_returns_1(void){26  /* Create a zeroed sqlite3 struct to simulate uninitialized db. */27  sqlite3 *db = (sqlite3*)sqlite3_malloc(sizeof(sqlite3));28  TEST_ASSERT_NOT_NULL(db);29  memset(db, 0, sizeof(sqlite3));30 31  int rc = sqlite3SchemaMutexHeld(db, 0, NULL);32  TEST_ASSERT_EQUAL_INT(1, rc);33 34  sqlite3_free(db);35}36 37void test_sqlite3SchemaMutexHeld_returns_0_without_db_mutex_main(void){38#if SQLITE_THREADSAFE39  sqlite3 *db = open_memdb();40 41  /* Do not enter db->mutex. Expect 0 for main schema (iDb==0). */42  int held = sqlite3SchemaMutexHeld(db, 0, NULL);43  TEST_ASSERT_EQUAL_INT(0, held);44 45  sqlite3_close(db);46#else47  TEST_IGNORE_MESSAGE("Skipping: SQLITE_THREADSAFE==0, sqlite3_mutex_held may always be true");48#endif49}50 51void test_sqlite3SchemaMutexHeld_returns_0_without_db_mutex_temp(void){52#if SQLITE_THREADSAFE53  sqlite3 *db = open_memdb();54 55  /* Do not enter db->mutex. Even for temp (iDb==1), expect 0 because db mutex not held. */56  int held = sqlite3SchemaMutexHeld(db, 1, NULL);57  TEST_ASSERT_EQUAL_INT(0, held);58 59  sqlite3_close(db);60#else61  TEST_IGNORE_MESSAGE("Skipping: SQLITE_THREADSAFE==0, sqlite3_mutex_held may always be true");62#endif63}64 65void test_sqlite3SchemaMutexHeld_temp_schema_returns_1_with_db_mutex_held(void){66  sqlite3 *db = open_memdb();67 68  /* Hold db mutex, expect 1 for TEMP schema (iDb==1). */69  sqlite3_mutex_enter(db->mutex);70  int held = sqlite3SchemaMutexHeld(db, 1, NULL);71  sqlite3_mutex_leave(db->mutex);72 73  TEST_ASSERT_EQUAL_INT(1, held);74 75  sqlite3_close(db);76}77 78void test_sqlite3SchemaMutexHeld_pSchema_overrides_iDb_temp(void){79  sqlite3 *db = open_memdb();80 81  /* Use pSchema for TEMP (index 1), but pass bogus iDb. With db->mutex held, expect 1. */82  Schema *tempSchema = db->aDb[1].pSchema;83  TEST_ASSERT_NOT_NULL(tempSchema);84 85  sqlite3_mutex_enter(db->mutex);86  int held = sqlite3SchemaMutexHeld(db, 9999, tempSchema); /* iDb overridden to 1 */87  sqlite3_mutex_leave(db->mutex);88 89  TEST_ASSERT_EQUAL_INT(1, held);90 91  sqlite3_close(db);92}93 94void test_sqlite3SchemaMutexHeld_main_schema_returns_1_after_btree_enter(void){95  sqlite3 *db = open_memdb();96 97  /* Hold db mutex, then explicitly enter main Btree. Expect return 1. */98  sqlite3_mutex_enter(db->mutex);99 100  /* main schema index is 0; ensure pBt exists */101  TEST_ASSERT_TRUE(db->nDb >= 1);102  TEST_ASSERT_NOT_NULL(db->aDb[0].pBt);103 104  /* Before locking the btree, result may be 0 (shared-cache) or 1 (non-sharable). */105  int beforeHeld = sqlite3SchemaMutexHeld(db, 0, db->aDb[0].pSchema);106 107  /* Lock the btree for main schema, which guarantees the condition for return 1 */108  sqlite3BtreeEnter(db->aDb[0].pBt);109  int afterHeld = sqlite3SchemaMutexHeld(db, 0, db->aDb[0].pSchema);110  sqlite3BtreeLeave(db->aDb[0].pBt);111 112  sqlite3_mutex_leave(db->mutex);113 114  /* After locking, the function must return 1 */115  TEST_ASSERT_EQUAL_INT(1, afterHeld);116  /* The "before" value should be less-or-equal to "after" (0->1 or 1->1) */117  TEST_ASSERT_TRUE(beforeHeld == 0 || beforeHeld == 1);118  TEST_ASSERT_LESS_OR_EQUAL_INT(afterHeld, afterHeld); /* trivially true; keeps Unity happy on types */119  TEST_ASSERT_TRUE_MESSAGE(beforeHeld <= afterHeld, "Result after BtreeEnter should not decrease");120}121 122void test_sqlite3SchemaMutexHeld_pSchema_overrides_iDb_main_with_btree_enter(void){123  sqlite3 *db = open_memdb();124 125  Schema *mainSchema = db->aDb[0].pSchema;126  TEST_ASSERT_NOT_NULL(mainSchema);127 128  sqlite3_mutex_enter(db->mutex);129 130  /* Enter the main btree to ensure the function returns 1 for main schema */131  sqlite3BtreeEnter(db->aDb[0].pBt);132  int held = sqlite3SchemaMutexHeld(db, -12345, mainSchema); /* iDb overridden to 0 */133  sqlite3BtreeLeave(db->aDb[0].pBt);134 135  sqlite3_mutex_leave(db->mutex);136 137  TEST_ASSERT_EQUAL_INT(1, held);138 139  sqlite3_close(db);140}141 142#else143/* If NDEBUG is defined, the target function is not available. */144void test_sqlite3SchemaMutexHeld_unavailable_in_release_build(void){145  TEST_IGNORE_MESSAGE("sqlite3SchemaMutexHeld is compiled only in non-NDEBUG builds");146}147#endif /* NDEBUG */148 149int main(void){150  UNITY_BEGIN();151 152#ifndef NDEBUG153  RUN_TEST(test_sqlite3SchemaMutexHeld_uninitialized_db_returns_1);154  RUN_TEST(test_sqlite3SchemaMutexHeld_returns_0_without_db_mutex_main);155  RUN_TEST(test_sqlite3SchemaMutexHeld_returns_0_without_db_mutex_temp);156  RUN_TEST(test_sqlite3SchemaMutexHeld_temp_schema_returns_1_with_db_mutex_held);157  RUN_TEST(test_sqlite3SchemaMutexHeld_pSchema_overrides_iDb_temp);158  RUN_TEST(test_sqlite3SchemaMutexHeld_main_schema_returns_1_after_btree_enter);159  RUN_TEST(test_sqlite3SchemaMutexHeld_pSchema_overrides_iDb_main_with_btree_enter);160#else161  RUN_TEST(test_sqlite3SchemaMutexHeld_unavailable_in_release_build);162#endif163 164  return UNITY_END();165}