AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdint.h>6 7static int custom_busy_handler(void *pArg, int count){8 /* Simple do-nothing busy handler */9 (void)pArg;10 (void)count;11 return 0;12}13 14void setUp(void) {15 /* No global setup needed */16}17 18void tearDown(void) {19 /* No global teardown needed */20}21 22/* Helper: open an in-memory DB and assert success */23static sqlite3* open_memory_db(void){24 sqlite3 *db = NULL;25 int rc = sqlite3_open(":memory:", &db);26 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");27 TEST_ASSERT_NOT_NULL_MESSAGE(db, "sqlite3_open returned NULL db");28 return db;29}30 31/* Helper: close DB and assert success */32static void close_db(sqlite3 *db){33 int rc = sqlite3_close(db);34 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");35}36 37/* Test: Setting a positive timeout installs default busy handler and sets timeouts */38void test_sqlite3_busy_timeout_set_positive_ms(void){39 sqlite3 *db = open_memory_db();40 41 int ms = 1500;42 int rc = sqlite3_busy_timeout(db, ms);43 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);44 45 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);46 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);47 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);48 TEST_ASSERT_EQUAL_INT(ms, db->busyTimeout);49#ifdef SQLITE_ENABLE_SETLK_TIMEOUT50 TEST_ASSERT_EQUAL_INT(ms, db->setlkTimeout);51#endif52 53 close_db(db);54}55 56/* Test: Calling with zero clears the busy handler and resets timeouts */57void test_sqlite3_busy_timeout_clear_with_zero(void){58 sqlite3 *db = open_memory_db();59 60 /* First, set a non-zero timeout to establish a handler */61 int rc = sqlite3_busy_timeout(db, 500);62 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);63 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);64 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);65 TEST_ASSERT_EQUAL_INT(500, db->busyTimeout);66 67 /* Now clear it */68 rc = sqlite3_busy_timeout(db, 0);69 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);70 TEST_ASSERT_NULL(db->busyHandler.xBusyHandler);71 TEST_ASSERT_NULL(db->busyHandler.pBusyArg);72 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);73 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);74#ifdef SQLITE_ENABLE_SETLK_TIMEOUT75 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);76#endif77 78 close_db(db);79}80 81/* Test: Calling with negative clears the busy handler and resets timeouts (same as zero) */82void test_sqlite3_busy_timeout_clear_with_negative(void){83 sqlite3 *db = open_memory_db();84 85 /* Set a non-zero timeout first */86 int rc = sqlite3_busy_timeout(db, 250);87 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);88 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);89 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);90 TEST_ASSERT_EQUAL_INT(250, db->busyTimeout);91 92 /* Now clear with negative value */93 rc = sqlite3_busy_timeout(db, -1);94 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);95 TEST_ASSERT_NULL(db->busyHandler.xBusyHandler);96 TEST_ASSERT_NULL(db->busyHandler.pBusyArg);97 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);98 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);99#ifdef SQLITE_ENABLE_SETLK_TIMEOUT100 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);101#endif102 103 close_db(db);104}105 106/* Test: Setting a timeout overwrites any previously installed custom busy handler */107void test_sqlite3_busy_timeout_overwrites_custom_handler(void){108 sqlite3 *db = open_memory_db();109 110 int dummyArg = 42;111 int rc;112 113 /* Install a custom handler using the API for setup purposes */114 rc = sqlite3_busy_handler(db, custom_busy_handler, &dummyArg);115 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);116 TEST_ASSERT_EQUAL_PTR((void*)custom_busy_handler, (void*)db->busyHandler.xBusyHandler);117 TEST_ASSERT_EQUAL_PTR(&dummyArg, db->busyHandler.pBusyArg);118 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);119 120 /* Now call sqlite3_busy_timeout to install the default handler and set timeout */121 rc = sqlite3_busy_timeout(db, 50);122 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);123 124 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);125 TEST_ASSERT_NOT_EQUAL((void*)custom_busy_handler, (void*)db->busyHandler.xBusyHandler);126 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);127 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);128 TEST_ASSERT_EQUAL_INT(50, db->busyTimeout);129#ifdef SQLITE_ENABLE_SETLK_TIMEOUT130 TEST_ASSERT_EQUAL_INT(50, db->setlkTimeout);131#endif132 133 close_db(db);134}135 136/* Test: Updating timeout updates busyTimeout and keeps a valid handler */137void test_sqlite3_busy_timeout_update_value(void){138 sqlite3 *db = open_memory_db();139 140 int rc = sqlite3_busy_timeout(db, 100);141 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);142 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);143 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);144 TEST_ASSERT_EQUAL_INT(100, db->busyTimeout);145 146 rc = sqlite3_busy_timeout(db, 200);147 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);148 TEST_ASSERT_NOT_NULL(db->busyHandler.xBusyHandler);149 TEST_ASSERT_EQUAL_PTR(db, db->busyHandler.pBusyArg);150 TEST_ASSERT_EQUAL_INT(200, db->busyTimeout);151#ifdef SQLITE_ENABLE_SETLK_TIMEOUT152 TEST_ASSERT_EQUAL_INT(200, db->setlkTimeout);153#endif154 155 close_db(db);156}157 158/* Test: With API armor, passing NULL returns SQLITE_MISUSE_BKPT (and should not crash) */159void test_sqlite3_busy_timeout_null_db_with_api_armor(void){160#ifdef SQLITE_ENABLE_API_ARMOR161 int rc = sqlite3_busy_timeout(NULL, 1000);162 TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE_BKPT, rc);163#else164 TEST_IGNORE_MESSAGE("SQLITE_ENABLE_API_ARMOR not enabled; skipping NULL db test.");165#endif166}167 168int main(void) {169 UNITY_BEGIN();170 171 RUN_TEST(test_sqlite3_busy_timeout_set_positive_ms);172 RUN_TEST(test_sqlite3_busy_timeout_clear_with_zero);173 RUN_TEST(test_sqlite3_busy_timeout_clear_with_negative);174 RUN_TEST(test_sqlite3_busy_timeout_overwrites_custom_handler);175 RUN_TEST(test_sqlite3_busy_timeout_update_value);176 RUN_TEST(test_sqlite3_busy_timeout_null_db_with_api_armor);177 178 return UNITY_END();179}