Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_mem1_sqlite3MemSetDefault.c230 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6 7/* ----------------- Custom allocator used for testing ----------------- */8 9static volatile unsigned gMallocCount = 0;10static volatile unsigned gFreeCount = 0;11static volatile unsigned gReallocCount = 0;12static volatile unsigned gInitCount = 0;13static volatile unsigned gShutdownCount = 0;14 15/* Store size in a header just before the returned pointer. */16typedef struct CustomHdr {17  int n;18} CustomHdr;19 20static void *custom_xMalloc(int n){21  if( n<=0 ) n = 1;22  gMallocCount++;23  CustomHdr *h = (CustomHdr*)malloc(sizeof(CustomHdr) + (size_t)n);24  if( !h ) return NULL;25  h->n = n;26  return (void*)((unsigned char*)h + sizeof(CustomHdr));27}28 29static void custom_xFree(void *p){30  if( !p ) return;31  gFreeCount++;32  unsigned char *base = (unsigned char*)p - sizeof(CustomHdr);33  free(base);34}35 36static void *custom_xRealloc(void *p, int n){37  if( !p ){38    return custom_xMalloc(n);39  }40  if( n<=0 ){41    custom_xFree(p);42    return NULL;43  }44  gReallocCount++;45  unsigned char *base = (unsigned char*)p - sizeof(CustomHdr);46  CustomHdr *oldh = (CustomHdr*)base;47  size_t newSize = sizeof(CustomHdr) + (size_t)n;48  CustomHdr *newh = (CustomHdr*)realloc(oldh, newSize);49  if( !newh ) return NULL;50  newh->n = n;51  return (void*)((unsigned char*)newh + sizeof(CustomHdr));52}53 54static int custom_xSize(void *p){55  if( !p ) return 0;56  CustomHdr *h = (CustomHdr*)((unsigned char*)p - sizeof(CustomHdr));57  return h->n;58}59 60static int custom_xRoundup(int n){61  if( n<=0 ) return 0;62  return (n + 7) & ~7;63}64 65static int custom_xInit(void *NotUsed){66  (void)NotUsed;67  gInitCount++;68  return SQLITE_OK;69}70 71static void custom_xShutdown(void *NotUsed){72  (void)NotUsed;73  gShutdownCount++;74}75 76/* Global instance describing the custom allocator */77static sqlite3_mem_methods gCustomMethods = {78  custom_xMalloc,79  custom_xFree,80  custom_xRealloc,81  custom_xSize,82  custom_xRoundup,83  custom_xInit,84  custom_xShutdown,85  086};87 88/* Helper to zero counters */89static void reset_counters(void){90  gMallocCount = 0;91  gFreeCount = 0;92  gReallocCount = 0;93  gInitCount = 0;94  gShutdownCount = 0;95}96 97/* Helper to install the custom allocator (must be called while shut down) */98static void install_custom_allocator(void){99  int rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &gCustomMethods);100  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101}102 103/* Helper to fetch current allocator into out parameter */104static void get_current_allocator(sqlite3_mem_methods *pOut){105  memset(pOut, 0, sizeof(*pOut));106  int rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, pOut);107  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108}109 110/* ----------------- Unity fixtures ----------------- */111 112void setUp(void) {113  /* Ensure a clean state for each test */114  sqlite3_shutdown();115  reset_counters();116  /* Start each test with default allocator unless the test changes it */117  sqlite3MemSetDefault();118}119 120void tearDown(void) {121  /* Reset to default allocator to avoid cross-test contamination */122  sqlite3_shutdown();123  sqlite3MemSetDefault();124}125 126/* ----------------- Tests ----------------- */127 128/* Test that sqlite3MemSetDefault replaces a custom allocator when allowed */129void test_sqlite3MemSetDefault_replaces_custom_allocator_after_shutdown(void){130  sqlite3_shutdown();131  reset_counters();132 133  /* Install custom allocator and verify it's active */134  install_custom_allocator();135  sqlite3_mem_methods before = {0};136  get_current_allocator(&before);137  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xMalloc, before.xMalloc);138  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xFree, before.xFree);139  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xRealloc, before.xRealloc);140  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xRoundup, before.xRoundup);141 142  /* Now set default allocator and verify it's no longer the custom one */143  sqlite3MemSetDefault();144  sqlite3_mem_methods after = {0};145  get_current_allocator(&after);146  TEST_ASSERT_NOT_EQUAL(gCustomMethods.xMalloc, after.xMalloc);147  TEST_ASSERT_NOT_EQUAL(gCustomMethods.xFree, after.xFree);148  TEST_ASSERT_NOT_EQUAL(gCustomMethods.xRealloc, after.xRealloc);149  TEST_ASSERT_NOT_EQUAL(gCustomMethods.xRoundup, after.xRoundup);150 151  /* Alloc/free something; counters should not increment (custom not in use) */152  unsigned beforeMallocs = gMallocCount;153  unsigned beforeFrees = gFreeCount;154  void *p = sqlite3_malloc(37);155  TEST_ASSERT_NOT_NULL(p);156  sqlite3_free(p);157  TEST_ASSERT_EQUAL_UINT(beforeMallocs, gMallocCount);158  TEST_ASSERT_EQUAL_UINT(beforeFrees, gFreeCount);159 160  /* Sanity-check xRoundup behavior matches ROUND8 macro after default */161  TEST_ASSERT_EQUAL_INT(ROUND8(1), after.xRoundup(1));162  TEST_ASSERT_EQUAL_INT(ROUND8(7), after.xRoundup(7));163  TEST_ASSERT_EQUAL_INT(ROUND8(8), after.xRoundup(8));164  TEST_ASSERT_EQUAL_INT(ROUND8(15), after.xRoundup(15));165}166 167/* Test that calling sqlite3MemSetDefault multiple times is idempotent */168void test_sqlite3MemSetDefault_idempotent_multiple_calls(void){169  sqlite3_shutdown();170 171  sqlite3MemSetDefault();172  sqlite3_mem_methods m1 = {0};173  get_current_allocator(&m1);174 175  sqlite3MemSetDefault();176  sqlite3_mem_methods m2 = {0};177  get_current_allocator(&m2);178 179  TEST_ASSERT_EQUAL_PTR(m1.xMalloc, m2.xMalloc);180  TEST_ASSERT_EQUAL_PTR(m1.xFree, m2.xFree);181  TEST_ASSERT_EQUAL_PTR(m1.xRealloc, m2.xRealloc);182  TEST_ASSERT_EQUAL_PTR(m1.xSize, m2.xSize);183  TEST_ASSERT_EQUAL_PTR(m1.xRoundup, m2.xRoundup);184  TEST_ASSERT_EQUAL_PTR(m1.xInit, m2.xInit);185  TEST_ASSERT_EQUAL_PTR(m1.xShutdown, m2.xShutdown);186}187 188/* Test that calling sqlite3MemSetDefault while initialized does not switch allocator */189void test_sqlite3MemSetDefault_during_initialized_state_no_effect(void){190  sqlite3_shutdown();191  reset_counters();192 193  install_custom_allocator();194 195  /* Initialize SQLite implicitly via allocation */196  void *p1 = sqlite3_malloc(24);197  TEST_ASSERT_NOT_NULL(p1);198  sqlite3_free(p1);199  unsigned baseMallocs = gMallocCount;200  unsigned baseFrees = gFreeCount;201 202  /* Attempt to switch to default while initialized */203  sqlite3MemSetDefault();204 205  /* Another allocation; it should still use the custom allocator */206  void *p2 = sqlite3_malloc(64);207  TEST_ASSERT_NOT_NULL(p2);208  sqlite3_free(p2);209 210  TEST_ASSERT_TRUE(gMallocCount > baseMallocs);211  TEST_ASSERT_TRUE(gFreeCount > baseFrees);212 213  /* Additionally, GETMALLOC should still report the custom allocator */214  sqlite3_mem_methods cur = {0};215  get_current_allocator(&cur);216  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xMalloc, cur.xMalloc);217  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xFree, cur.xFree);218  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xRealloc, cur.xRealloc);219  TEST_ASSERT_EQUAL_PTR(gCustomMethods.xRoundup, cur.xRoundup);220}221 222/* ----------------- Unity main ----------------- */223 224int main(void) {225  UNITY_BEGIN();226  RUN_TEST(test_sqlite3MemSetDefault_replaces_custom_allocator_after_shutdown);227  RUN_TEST(test_sqlite3MemSetDefault_idempotent_multiple_calls);228  RUN_TEST(test_sqlite3MemSetDefault_during_initialized_state_no_effect);229  return UNITY_END();230}