AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "sqlite3.h"3#include "unity.h"4#include <stdlib.h>5#include <string.h>6 7/* Helper: get current SQLite memory usage (in bytes) */8static sqlite3_int64 get_mem_used(void){9 sqlite3_int64 cur = 0, hi = 0;10 int rc = sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &cur, &hi, 0);11 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_status64 failed");12 return cur;13}14 15void setUp(void) {16 /* Ensure we can enable memory status tracking */17 sqlite3_shutdown(); /* Make sure SQLite is not initialized yet */18 int rc = sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 1);19 TEST_ASSERT_TRUE_MESSAGE(rc == SQLITE_OK || rc == SQLITE_MISUSE, "sqlite3_config failed");20 /* Initialize SQLite for each test */21 rc = sqlite3_initialize();22 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_initialize failed");23}24 25void tearDown(void) {26 sqlite3_shutdown();27}28 29/* Test: Destroying a NULL pointer should be a no-op and not change memory usage */30void test_sqlite3BitvecDestroy_null_noop(void){31 sqlite3_int64 m0 = get_mem_used();32 sqlite3BitvecDestroy(NULL);33 sqlite3_int64 m1 = get_mem_used();34 TEST_ASSERT_EQUAL_INT64(m0, m1);35}36 37/* Test: Create a small (bitmap) bitvec, set some bits, destroy, memory should return to baseline */38void test_sqlite3BitvecDestroy_small_bitmap(void){39 sqlite3_int64 m0 = get_mem_used();40 41 Bitvec *p = sqlite3BitvecCreate(100); /* small -> bitmap representation */42 TEST_ASSERT_NOT_NULL(p);43 44 /* Exercise the bitvec a little */45 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3BitvecSet(p, 1));46 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3BitvecSet(p, 50));47 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3BitvecSet(p, 100));48 49 sqlite3_int64 m_after_alloc = get_mem_used();50 TEST_ASSERT_TRUE(m_after_alloc >= m0); /* memory should be >= baseline */51 52 sqlite3BitvecDestroy(p);53 p = NULL;54 55 sqlite3_int64 m1 = get_mem_used();56 TEST_ASSERT_EQUAL_INT64(m0, m1);57}58 59/* Test: Create a large (hash) bitvec but do not force subdivision. Destroy and check memory returns. */60void test_sqlite3BitvecDestroy_large_hash_nosub(void){61 sqlite3_int64 m0 = get_mem_used();62 63 Bitvec *p = sqlite3BitvecCreate(100000); /* large enough for hash representation */64 TEST_ASSERT_NOT_NULL(p);65 66 /* Optionally set a few bits (far fewer than the hash threshold) */67 for(int i = 1; i <= 10; i++){68 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3BitvecSet(p, (u32)(i * 7)));69 }70 71 sqlite3_int64 m_after_alloc = get_mem_used();72 TEST_ASSERT_TRUE(m_after_alloc >= m0);73 74 sqlite3BitvecDestroy(p);75 p = NULL;76 77 sqlite3_int64 m1 = get_mem_used();78 TEST_ASSERT_EQUAL_INT64(m0, m1);79}80 81/* Test: Force rehash and creation of sub-bitmaps (recursive representation). Destroy and verify memory returns. */82void test_sqlite3BitvecDestroy_recursive_subbitmaps(void){83 sqlite3_int64 m0 = get_mem_used();84 85 /* Very large size to ensure that after rehash, iDivisor is large and sub-bitmaps are used */86 Bitvec *p = sqlite3BitvecCreate(1000000);87 TEST_ASSERT_NOT_NULL(p);88 89 /* Set many distinct bits to trigger hash-table growth and rehashing into sub-bitmaps.90 Using sequential values ensures collisions occur and threshold is exceeded. */91 for(int i = 1; i <= 2000; i++){92 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3BitvecSet(p, (u32)i));93 }94 95 sqlite3_int64 m_after_alloc = get_mem_used();96 TEST_ASSERT_TRUE(m_after_alloc > m0); /* should have allocated multiple sub-bitmaps */97 98 sqlite3BitvecDestroy(p);99 p = NULL;100 101 sqlite3_int64 m1 = get_mem_used();102 TEST_ASSERT_EQUAL_INT64(m0, m1);103}104 105int main(void) {106 UNITY_BEGIN();107 108 RUN_TEST(test_sqlite3BitvecDestroy_null_noop);109 RUN_TEST(test_sqlite3BitvecDestroy_small_bitmap);110 RUN_TEST(test_sqlite3BitvecDestroy_large_hash_nosub);111 RUN_TEST(test_sqlite3BitvecDestroy_recursive_subbitmaps);112 113 return UNITY_END();114}