AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdint.h>6 7/* External test wrapper for the static function mallocWithAlarm */8extern void test_mallocWithAlarm(int n, void **pp);9 10static void call_mallocWithAlarm_locked(int n, void **pp){11 sqlite3_mutex *m = sqlite3MallocMutex();12 TEST_ASSERT_NOT_NULL_MESSAGE(m, "sqlite3MallocMutex returned NULL");13 sqlite3_mutex_enter(m);14 test_mallocWithAlarm(n, pp);15 sqlite3_mutex_leave(m);16}17 18void setUp(void) {19 int rc = sqlite3_initialize();20 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_initialize failed");21 /* Reset limits to ensure a clean starting state */22 (void)sqlite3_hard_heap_limit64(0);23 (void)sqlite3_soft_heap_limit64(0);24}25 26void tearDown(void) {27 /* Reset limits after each test */28 (void)sqlite3_hard_heap_limit64(0);29 (void)sqlite3_soft_heap_limit64(0);30}31 32/* Basic allocation should succeed when no limits are set */33void test_mallocWithAlarm_basic_allocation(void){34 const int n = 128;35 int nFull = sqlite3GlobalConfig.m.xRoundup(n);36 37 void *p = NULL;38 call_mallocWithAlarm_locked(n, &p);39 40 TEST_ASSERT_NOT_NULL(p);41 /* Verify the allocated size is at least the request and at least xRoundup(n) */42 sqlite3_uint64 msz = sqlite3_msize(p);43 TEST_ASSERT_TRUE(msz >= (sqlite3_uint64)n);44 TEST_ASSERT_TRUE(msz >= (sqlite3_uint64)nFull);45 46 sqlite3_free(p);47}48 49/* Soft heap limit near should trigger alarm path and set nearlyFull=1, but still allocate */50void test_mallocWithAlarm_triggers_alarm_and_sets_nearlyFull(void){51 const int n = 256;52 int nFull = sqlite3GlobalConfig.m.xRoundup(n);53 54 sqlite3_int64 used = sqlite3_memory_used();55 sqlite3_int64 softLimit = used + nFull - 1; /* ensure nUsed >= soft - nFull */56 57 (void)sqlite3_soft_heap_limit64(softLimit);58 (void)sqlite3_hard_heap_limit64(0); /* no hard limit to block allocation */59 60 void *p = NULL;61 call_mallocWithAlarm_locked(n, &p);62 63 TEST_ASSERT_NOT_NULL(p);64 TEST_ASSERT_EQUAL_INT(1, sqlite3HeapNearlyFull());65 66 sqlite3_free(p);67 68 /* Clear soft limit and verify nearlyFull can be cleared by setting limit to 0 */69 (void)sqlite3_soft_heap_limit64(0);70 TEST_ASSERT_EQUAL_INT(0, sqlite3HeapNearlyFull());71}72 73/* Soft heap limit set but not near should set nearlyFull=0 and allocate */74void test_mallocWithAlarm_soft_limit_not_near_does_not_set_nearlyFull(void){75 const int n = 200;76 int nFull = sqlite3GlobalConfig.m.xRoundup(n);77 78 sqlite3_int64 used = sqlite3_memory_used();79 sqlite3_int64 softLimit = used + nFull + 1024; /* comfortably above threshold */80 81 (void)sqlite3_soft_heap_limit64(softLimit);82 (void)sqlite3_hard_heap_limit64(0);83 84 void *p = NULL;85 call_mallocWithAlarm_locked(n, &p);86 87 TEST_ASSERT_NOT_NULL(p);88 TEST_ASSERT_EQUAL_INT(0, sqlite3HeapNearlyFull());89 90 sqlite3_free(p);91}92 93/* Hard heap limit should prevent allocation and set *pp to NULL */94void test_mallocWithAlarm_hard_limit_blocks_allocation(void){95 const int n = 300;96 int nFull = sqlite3GlobalConfig.m.xRoundup(n);97 98 sqlite3_int64 used = sqlite3_memory_used();99 /* Set hard limit so that nUsed >= hardLimit - nFull is true */100 sqlite3_int64 hardLimit = used + nFull - 1;101 102 (void)sqlite3_hard_heap_limit64(hardLimit);103 /* hard limit call also constrains soft limit accordingly */104 105 void *p = (void*)0x1; /* sentinel to ensure function writes NULL */106 call_mallocWithAlarm_locked(n, &p);107 108 TEST_ASSERT_NULL(p);109 TEST_ASSERT_EQUAL_INT(1, sqlite3HeapNearlyFull());110 111 /* Reset limits so future tests are unaffected */112 (void)sqlite3_hard_heap_limit64(0);113 (void)sqlite3_soft_heap_limit64(0);114}115 116/* Unity main */117int main(void){118 UNITY_BEGIN();119 RUN_TEST(test_mallocWithAlarm_basic_allocation);120 RUN_TEST(test_mallocWithAlarm_triggers_alarm_and_sets_nearlyFull);121 RUN_TEST(test_mallocWithAlarm_soft_limit_not_near_does_not_set_nearlyFull);122 RUN_TEST(test_mallocWithAlarm_hard_limit_blocks_allocation);123 return UNITY_END();124}