Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_malloc_sqlite3DbFreeNN.c158 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdint.h>6 7/* Globals for each test */8static sqlite3 *gDb = NULL;9#ifndef SQLITE_OMIT_LOOKASIDE10static void *gLookBuf = NULL;11static const int gLookSlotSize = 128;   /* reasonable default slot size */12static const int gLookSlotCount = 32;   /* number of slots in lookaside */13#endif14 15void setUp(void) {16  int rc = sqlite3_open(":memory:", &gDb);17  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);18 19#ifndef SQLITE_OMIT_LOOKASIDE20  /* Provide our own lookaside buffer so we control size/count deterministically */21  gLookBuf = sqlite3_malloc(gLookSlotSize * gLookSlotCount);22  TEST_ASSERT_NOT_NULL(gLookBuf);23  rc = sqlite3_db_config(gDb, SQLITE_DBCONFIG_LOOKASIDE,24                         gLookBuf, gLookSlotSize, gLookSlotCount);25  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);26#endif27}28 29void tearDown(void) {30#ifndef SQLITE_OMIT_LOOKASIDE31  if( gLookBuf ){32    sqlite3_free(gLookBuf);33    gLookBuf = NULL;34  }35#endif36  if( gDb ){37    int rc = sqlite3_close(gDb);38    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);39    gDb = NULL;40  }41}42 43#ifndef SQLITE_OMIT_LOOKASIDE44static int hold_db_mutex(sqlite3 *db){45  if( db && db->mutex ) sqlite3_mutex_enter(db->mutex);46  return 1;47}48static void release_db_mutex(sqlite3 *db){49  if( db && db->mutex ) sqlite3_mutex_leave(db->mutex);50}51#endif52 53/* Test 1: Freeing a lookaside allocation returns it to the freelist (LIFO) */54#ifndef SQLITE_OMIT_LOOKASIDE55void test_sqlite3DbFreeNN_lookaside_roundtrip(void){56  TEST_ASSERT_NOT_NULL(gDb);57  /* Ensure lookaside is enabled and sized */58  TEST_ASSERT_TRUE(gDb->lookaside.sz > 0);59  TEST_ASSERT_TRUE(gDb->lookaside.bDisable == 0);60 61  hold_db_mutex(gDb);62 63  /* Pick a size that will definitely use lookaside: n <= db->lookaside.sz */64  int n = gDb->lookaside.sz;65  if( n <= 0 ) n = 1;66  if( n > 8 ) n = n/2 + 1; /* a valid, non-trivial size within lookaside */67 68  void *pA = sqlite3DbMallocRawNN(gDb, (u64)n);69  TEST_ASSERT_NOT_NULL(pA);70  void *pB = sqlite3DbMallocRawNN(gDb, (u64)n);71  TEST_ASSERT_NOT_NULL(pB);72 73  /* Free the most recent allocation and expect LIFO reuse on the next alloc */74  sqlite3DbFreeNN(gDb, pB);75  void *q = sqlite3DbMallocRawNN(gDb, (u64)n);76  TEST_ASSERT_EQUAL_PTR(pB, q);77 78  /* Free the remaining lookaside allocations */79  sqlite3DbFreeNN(gDb, pA);80  sqlite3DbFreeNN(gDb, q);81 82  /* Verify that pnBytesFreed does NOT change when freeing lookaside */83  size_t counter = 0;84  gDb->pnBytesFreed = &counter;85  void *pC = sqlite3DbMallocRawNN(gDb, (u64)n);86  TEST_ASSERT_NOT_NULL(pC);87  sqlite3DbFreeNN(gDb, pC); /* lookaside free should not increment counter */88  TEST_ASSERT_EQUAL_UINT64(0, (sqlite3_uint64)counter);89  gDb->pnBytesFreed = 0; /* reset to satisfy future allocations' assert */90 91  release_db_mutex(gDb);92}93#endif94 95/* Test 2: Heap pointer path increments pnBytesFreed and does not free */96void test_sqlite3DbFreeNN_heap_measures_and_late_free(void){97  TEST_ASSERT_NOT_NULL(gDb);98 99  /* Choose a size that forces heap allocation (n > lookaside.sz),100  ** or a reasonable size if lookaside is omitted/disabled. */101  int nHeap = 256;102#ifndef SQLITE_OMIT_LOOKASIDE103  if( gDb->lookaside.sz > 0 ) nHeap = gDb->lookaside.sz + 64;104#endif105 106  if( gDb->mutex ) sqlite3_mutex_enter(gDb->mutex);107 108  /* Allocate from heap via sqlite3DbMallocRawNN */109  void *p = sqlite3DbMallocRawNN(gDb, (u64)nHeap);110  TEST_ASSERT_NOT_NULL(p);111 112  /* Determine the size as sqlite3DbFreeNN would measure it */113  int sz = sqlite3DbMallocSize(gDb, p);114  TEST_ASSERT_TRUE(sz > 0);115 116  /* Set pnBytesFreed and call sqlite3DbFreeNN: should only count, not free */117  size_t counter = 0;118  gDb->pnBytesFreed = &counter;119  sqlite3DbFreeNN(gDb, p);120  TEST_ASSERT_EQUAL_UINT64((sqlite3_uint64)sz, (sqlite3_uint64)counter);121 122  /* Now actually free it by clearing pnBytesFreed and calling again */123  gDb->pnBytesFreed = 0;124  sqlite3DbFreeNN(gDb, p);125 126  if( gDb->mutex ) sqlite3_mutex_leave(gDb->mutex);127}128 129/* Test 3: Heap pointer freed normally when pnBytesFreed is NULL */130void test_sqlite3DbFreeNN_heap_plain_free(void){131  TEST_ASSERT_NOT_NULL(gDb);132 133  int nHeap = 512;134#ifndef SQLITE_OMIT_LOOKASIDE135  if( gDb->lookaside.sz > 0 ) nHeap = gDb->lookaside.sz + 128;136#endif137 138  if( gDb->mutex ) sqlite3_mutex_enter(gDb->mutex);139 140  void *p = sqlite3DbMallocRawNN(gDb, (u64)nHeap);141  TEST_ASSERT_NOT_NULL(p);142 143  /* Ensure pnBytesFreed is not set (normal free) */144  gDb->pnBytesFreed = 0;145  sqlite3DbFreeNN(gDb, p);146 147  if( gDb->mutex ) sqlite3_mutex_leave(gDb->mutex);148}149 150int main(void) {151  UNITY_BEGIN();152#ifndef SQLITE_OMIT_LOOKASIDE153  RUN_TEST(test_sqlite3DbFreeNN_lookaside_roundtrip);154#endif155  RUN_TEST(test_sqlite3DbFreeNN_heap_measures_and_late_free);156  RUN_TEST(test_sqlite3DbFreeNN_heap_plain_free);157  return UNITY_END();158}