AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <stdlib.h>5 6/* Dummy busy handlers for testing pointer assignment */7static int busy_cb_a(void *p, int cnt){8 /* Do not rely on side effects; the function under test never calls this. */9 (void)p;10 (void)cnt;11 return 0;12}13static int busy_cb_b(void *p, int cnt){14 (void)p;15 (void)cnt;16 return 0;17}18 19/* Helper to open an in-memory database and assert success */20static sqlite3* open_memdb(void){21 sqlite3 *db = NULL;22 int rc = sqlite3_open(":memory:", &db);23 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open(:memory:) failed");24 TEST_ASSERT_NOT_NULL_MESSAGE(db, "sqlite3_open returned NULL db");25 return db;26}27 28/* Helper to close database and assert success */29static void close_db(sqlite3 *db){30 int rc = sqlite3_close(db);31 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_close failed");32}33 34void setUp(void) {35 /* Setup code here, or leave empty */36}37 38void tearDown(void) {39 /* Cleanup code here, or leave empty */40}41 42/* Test that setting a busy handler populates fields and clears timeouts/counters */43void test_sqlite3_busy_handler_sets_fields_and_clears_timeouts(void){44 sqlite3 *db = open_memdb();45 46 /* Pre-set fields to non-default values to ensure they are overwritten/reset */47 db->busyHandler.xBusyHandler = busy_cb_b;48 db->busyHandler.pBusyArg = (void*)0x1;49 db->busyHandler.nBusy = 123;50 db->busyTimeout = 9999;51#ifdef SQLITE_ENABLE_SETLK_TIMEOUT52 db->setlkTimeout = 777;53#endif54 55 int dummyArg = 0xABCD;56 int rc = sqlite3_busy_handler(db, busy_cb_a, &dummyArg);57 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);58 59 TEST_ASSERT_EQUAL_PTR((void*)busy_cb_a, (void*)db->busyHandler.xBusyHandler);60 TEST_ASSERT_EQUAL_PTR((void*)&dummyArg, db->busyHandler.pBusyArg);61 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);62 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);63#ifdef SQLITE_ENABLE_SETLK_TIMEOUT64 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);65#endif66 67 close_db(db);68}69 70/* Test that passing NULL handler clears the handler and still resets counters/timeouts */71void test_sqlite3_busy_handler_clear_handler_resets_state(void){72 sqlite3 *db = open_memdb();73 74 /* First set some non-NULL handler */75 int argA = 42;76 int rc = sqlite3_busy_handler(db, busy_cb_b, &argA);77 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78 79 /* Dirty nBusy and timeouts to verify reset upon clearing */80 db->busyHandler.nBusy = 55;81 db->busyTimeout = 5000;82#ifdef SQLITE_ENABLE_SETLK_TIMEOUT83 db->setlkTimeout = 333;84#endif85 86 /* Now clear the handler */87 rc = sqlite3_busy_handler(db, NULL, NULL);88 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);89 90 TEST_ASSERT_EQUAL_PTR(NULL, db->busyHandler.xBusyHandler);91 TEST_ASSERT_EQUAL_PTR(NULL, db->busyHandler.pBusyArg);92 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);93 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);94#ifdef SQLITE_ENABLE_SETLK_TIMEOUT95 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);96#endif97 98 close_db(db);99}100 101/* Test repeated calls: handler/arg update and nBusy/timeout always reset */102void test_sqlite3_busy_handler_multiple_calls_update_and_reset(void){103 sqlite3 *db = open_memdb();104 105 int arg1 = 11;106 int arg2 = 22;107 int arg3 = 33;108 109 /* First set to A */110 int rc = sqlite3_busy_handler(db, busy_cb_a, &arg1);111 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);112 TEST_ASSERT_EQUAL_PTR((void*)busy_cb_a, (void*)db->busyHandler.xBusyHandler);113 TEST_ASSERT_EQUAL_PTR((void*)&arg1, db->busyHandler.pBusyArg);114 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);115 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);116#ifdef SQLITE_ENABLE_SETLK_TIMEOUT117 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);118#endif119 120 /* Dirty nBusy to ensure it gets reset on next call */121 db->busyHandler.nBusy = 7;122 db->busyTimeout = 1234;123#ifdef SQLITE_ENABLE_SETLK_TIMEOUT124 db->setlkTimeout = 99;125#endif126 127 /* Change to B */128 rc = sqlite3_busy_handler(db, busy_cb_b, &arg2);129 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);130 TEST_ASSERT_EQUAL_PTR((void*)busy_cb_b, (void*)db->busyHandler.xBusyHandler);131 TEST_ASSERT_EQUAL_PTR((void*)&arg2, db->busyHandler.pBusyArg);132 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);133 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);134#ifdef SQLITE_ENABLE_SETLK_TIMEOUT135 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);136#endif137 138 /* Same handler, different arg; still resets counters/timeouts */139 db->busyHandler.nBusy = 999;140 db->busyTimeout = 4321;141#ifdef SQLITE_ENABLE_SETLK_TIMEOUT142 db->setlkTimeout = 101;143#endif144 145 rc = sqlite3_busy_handler(db, busy_cb_b, &arg3);146 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);147 TEST_ASSERT_EQUAL_PTR((void*)busy_cb_b, (void*)db->busyHandler.xBusyHandler);148 TEST_ASSERT_EQUAL_PTR((void*)&arg3, db->busyHandler.pBusyArg);149 TEST_ASSERT_EQUAL_INT(0, db->busyHandler.nBusy);150 TEST_ASSERT_EQUAL_INT(0, db->busyTimeout);151#ifdef SQLITE_ENABLE_SETLK_TIMEOUT152 TEST_ASSERT_EQUAL_INT(0, db->setlkTimeout);153#endif154 155 close_db(db);156}157 158#ifdef SQLITE_ENABLE_API_ARMOR159/* Only valid when API armor is enabled; otherwise behavior is undefined */160void test_sqlite3_busy_handler_returns_misuse_on_null_db(void){161 int rc = sqlite3_busy_handler(NULL, busy_cb_a, NULL);162 TEST_ASSERT_EQUAL_INT(SQLITE_MISUSE_BKPT, rc);163}164#endif165 166int main(void){167 UNITY_BEGIN();168 169 RUN_TEST(test_sqlite3_busy_handler_sets_fields_and_clears_timeouts);170 RUN_TEST(test_sqlite3_busy_handler_clear_handler_resets_state);171 RUN_TEST(test_sqlite3_busy_handler_multiple_calls_update_and_reset);172#ifdef SQLITE_ENABLE_API_ARMOR173 RUN_TEST(test_sqlite3_busy_handler_returns_misuse_on_null_db);174#endif175 176 return UNITY_END();177}