Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_malloc_sqlite3ApiExit.c134 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4 5/* Unity fixtures */6void setUp(void) {7  /* No global setup required */8}9void tearDown(void) {10  /* No global teardown required */11}12 13/* Helper: open an in-memory DB and enter its mutex */14static sqlite3* open_and_lock_db(void){15  sqlite3 *db = 0;16  int rc = sqlite3_open(":memory:", &db);17  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);18  TEST_ASSERT_NOT_NULL(db);19  /* Ensure we hold the mutex as required by sqlite3ApiExit */20  sqlite3_mutex_enter(db->mutex);21  return db;22}23 24/* Helper: leave mutex and close DB */25static void unlock_and_close_db(sqlite3 *db){26  /* Leave the mutex before closing */27  sqlite3_mutex_leave(db->mutex);28  int rc = sqlite3_close(db);29  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);30}31 32/* Test 1: rc==0 and no mallocFailed -> return 0 */33void test_sqlite3ApiExit_returns_zero_when_ok(void){34  sqlite3 *db = open_and_lock_db();35 36  /* Ensure clean state */37  db->mallocFailed = 0;38 39  int rcOut = sqlite3ApiExit(db, 0);40  TEST_ASSERT_EQUAL_INT(0, rcOut);41 42  unlock_and_close_db(db);43}44 45/* Test 2: rc non-zero (not SQLITE_IOERR_NOMEM), no mallocFailed -> rc & errMask */46void test_sqlite3ApiExit_masks_rc(void){47  sqlite3 *db = open_and_lock_db();48 49  db->mallocFailed = 0;50  /* Choose a mask that will alter the returned value to verify masking */51  db->errMask = 0x03; /* Only low 2 bits should pass through */52  int inputRc = SQLITE_BUSY; /* 5 -> 0b0101 */53  int expected = inputRc & db->errMask; /* 5 & 3 = 1 */54 55  int rcOut = sqlite3ApiExit(db, inputRc);56  TEST_ASSERT_EQUAL_INT(expected, rcOut);57 58  unlock_and_close_db(db);59}60 61/* Test 3: mallocFailed==1 and rc==0 -> clears OOM (if no VDBE running), sets error, returns SQLITE_NOMEM */62void test_sqlite3ApiExit_handles_mallocFailed_clears_state_and_sets_error(void){63  sqlite3 *db = open_and_lock_db();64 65  /* Put DB in a consistent OOM state (sets mallocFailed=1 and disables lookaside) */66  sqlite3OomFault(db);67  TEST_ASSERT_EQUAL_INT(1, db->mallocFailed);68 69  int rcOut = sqlite3ApiExit(db, 0);70  /* Should map to NOMEM and clear mallocFailed when no VDBE is executing */71  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, rcOut);72  TEST_ASSERT_EQUAL_INT(0, db->mallocFailed);73 74  sqlite3_mutex_leave(db->mutex); /* Use API to read error code without holding mutex */75  int err = sqlite3_errcode(db);76  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, err);77  /* Re-enter to match unlock_and_close_db */78  sqlite3_mutex_enter(db->mutex);79 80  unlock_and_close_db(db);81}82 83/* Test 4: rc==SQLITE_IOERR_NOMEM (no mallocFailed) -> sets error, returns SQLITE_NOMEM, mallocFailed unchanged */84void test_sqlite3ApiExit_handles_ioerr_nomem_sets_error(void){85  sqlite3 *db = open_and_lock_db();86 87  db->mallocFailed = 0;88 89  int rcOut = sqlite3ApiExit(db, SQLITE_IOERR_NOMEM);90  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, rcOut);91  TEST_ASSERT_EQUAL_INT(0, db->mallocFailed);92 93  sqlite3_mutex_leave(db->mutex);94  int err = sqlite3_errcode(db);95  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, err);96  sqlite3_mutex_enter(db->mutex);97 98  unlock_and_close_db(db);99}100 101/* Test 5: mallocFailed==1 but VDBE running (nVdbeExec>0) -> return NOMEM, do not clear mallocFailed */102void test_sqlite3ApiExit_does_not_clear_oom_if_vdbe_running(void){103  sqlite3 *db = open_and_lock_db();104 105  /* Simulate a running VDBE before fault so OomFault sets interrupt flag too */106  db->nVdbeExec = 1;107  sqlite3OomFault(db);108  TEST_ASSERT_EQUAL_INT(1, db->mallocFailed);109 110  int rcOut = sqlite3ApiExit(db, 0);111  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, rcOut);112  /* Since a VDBE is "running", sqlite3OomClear should not clear mallocFailed */113  TEST_ASSERT_EQUAL_INT(1, db->mallocFailed);114 115  /* Restore to avoid side-effects on close */116  db->nVdbeExec = 0;117 118  sqlite3_mutex_leave(db->mutex);119  int err = sqlite3_errcode(db);120  TEST_ASSERT_EQUAL_INT(SQLITE_NOMEM, err);121  sqlite3_mutex_enter(db->mutex);122 123  unlock_and_close_db(db);124}125 126int main(void){127  UNITY_BEGIN();128  RUN_TEST(test_sqlite3ApiExit_returns_zero_when_ok);129  RUN_TEST(test_sqlite3ApiExit_masks_rc);130  RUN_TEST(test_sqlite3ApiExit_handles_mallocFailed_clears_state_and_sets_error);131  RUN_TEST(test_sqlite3ApiExit_handles_ioerr_nomem_sets_error);132  RUN_TEST(test_sqlite3ApiExit_does_not_clear_oom_if_vdbe_running);133  return UNITY_END();134}