Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_mem2_sqlite3MemSetDefault.c213 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <stdlib.h>5#include <string.h>6#include <unistd.h>7 8/* Target under test */9void sqlite3MemSetDefault(void);10 11/* Exported memdebug helpers from mem2.c */12void sqlite3MemdebugSetType(void *p, u8 eType);13int sqlite3MemdebugHasType(const void *p, u8 eType);14int sqlite3MemdebugNoType(const void *p, u8 eType);15void sqlite3MemdebugBacktrace(int depth);16void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **));17void sqlite3MemdebugSettitle(const char *zTitle);18void sqlite3MemdebugDump(const char *zFilename);19int sqlite3MemdebugMallocCount(void);20void sqlite3MemdebugSync(void);21 22static volatile int g_btCalled = 0;23static volatile int g_btLastSize = -1;24static volatile int g_btLastDepth = -999;25 26/* Backtrace callback to observe allocator behavior */27static void test_backtrace_cb(int nByte, int nDepth, void **ppFrames){28  (void)ppFrames;29  g_btCalled++;30  g_btLastSize = nByte;31  g_btLastDepth = nDepth;32}33 34void setUp(void) {35  /* Ensure SQLite is shut down so sqlite3_config in sqlite3MemSetDefault is valid */36  sqlite3_shutdown();37  /* Reset backtrace callback state */38  sqlite3MemdebugBacktraceCallback(NULL);39  g_btCalled = 0;40  g_btLastSize = -1;41  g_btLastDepth = -999;42}43 44void tearDown(void) {45  /* Best-effort shutdown of the configured memory subsystem */46  if( sqlite3GlobalConfig.m.xShutdown ){47    sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);48  }49  sqlite3MemdebugBacktraceCallback(NULL);50}51 52/* Helper to initialize the mem subsystem after configuration */53static void init_mem(void){54  if( sqlite3GlobalConfig.m.xInit ){55    int rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);56    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);57  }58}59 60void test_sqlite3MemSetDefault_sets_methods_nonnull(void) {61  sqlite3MemSetDefault();62  init_mem();63 64  const sqlite3_mem_methods *m = &sqlite3GlobalConfig.m;65 66  TEST_ASSERT_NOT_NULL(m->xMalloc);67  TEST_ASSERT_NOT_NULL(m->xFree);68  TEST_ASSERT_NOT_NULL(m->xRealloc);69  TEST_ASSERT_NOT_NULL(m->xSize);70  TEST_ASSERT_NOT_NULL(m->xRoundup);71  TEST_ASSERT_NOT_NULL(m->xInit);72  TEST_ASSERT_NOT_NULL(m->xShutdown);73 74  /* Roundup behavior */75  TEST_ASSERT_EQUAL_INT(0, m->xRoundup(0));76  TEST_ASSERT_EQUAL_INT(8, m->xRoundup(1));77  TEST_ASSERT_EQUAL_INT(8, m->xRoundup(7));78  TEST_ASSERT_EQUAL_INT(8, m->xRoundup(8));79  TEST_ASSERT_EQUAL_INT(16, m->xRoundup(9));80  TEST_ASSERT_EQUAL_INT(16, m->xRoundup(16));81  TEST_ASSERT_EQUAL_INT(1000 + (8 - (1000 % 8)), m->xRoundup(1000));82}83 84void test_sqlite3MemSetDefault_allocator_basic_alloc_realloc_free_and_size_roundup(void) {85  sqlite3MemSetDefault();86  init_mem();87 88  const sqlite3_mem_methods *m = &sqlite3GlobalConfig.m;89 90  /* Track allocation count difference */91  int n0 = sqlite3MemdebugMallocCount();92 93  /* Allocate 13 bytes, test size reporting */94  unsigned char *p = (unsigned char*)m->xMalloc(13);95  TEST_ASSERT_NOT_NULL(p);96  TEST_ASSERT_EQUAL_INT(13, m->xSize(p));97 98  /* Fill and then realloc to a larger 8-byte aligned size (24) */99  for(int i=0;i<13;i++) p[i] = (unsigned char)i;100  unsigned char *p2 = (unsigned char*)m->xRealloc(p, 24);101  TEST_ASSERT_NOT_NULL(p2);102  /* Old pointer should not be used anymore; content must be preserved */103  for(int i=0;i<13;i++){104    TEST_ASSERT_EQUAL_UINT8((unsigned char)i, p2[i]);105  }106  TEST_ASSERT_EQUAL_INT(24, m->xSize(p2));107 108  m->xFree(p2);109 110  int n1 = sqlite3MemdebugMallocCount();111  TEST_ASSERT_TRUE(n1 >= n0 + 2); /* one for initial alloc and one for realloc's new alloc */112}113 114void test_sqlite3MemSetDefault_memdebug_type_tagging_works(void) {115  sqlite3MemSetDefault();116  init_mem();117 118  const sqlite3_mem_methods *m = &sqlite3GlobalConfig.m;119 120  void *p = m->xMalloc(32);121  TEST_ASSERT_NOT_NULL(p);122 123  /* Initially the mem2 allocator tags allocations as MEMTYPE_HEAP */124  TEST_ASSERT_TRUE(sqlite3MemdebugHasType(p, MEMTYPE_HEAP));125 126  /* Change type to 0, verify it is no longer reported as HEAP */127  sqlite3MemdebugSetType(p, 0);128  TEST_ASSERT_FALSE(sqlite3MemdebugHasType(p, MEMTYPE_HEAP));129 130  /* Set to LOOKASIDE and validate Has/NoType logic */131  sqlite3MemdebugSetType(p, MEMTYPE_LOOKASIDE);132  TEST_ASSERT_TRUE(sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE));133  TEST_ASSERT_TRUE(sqlite3MemdebugNoType(p, MEMTYPE_HEAP));134 135  m->xFree(p);136}137 138void test_sqlite3MemSetDefault_backtrace_callback_invoked(void) {139  sqlite3MemSetDefault();140  init_mem();141 142  const sqlite3_mem_methods *m = &sqlite3GlobalConfig.m;143 144  sqlite3MemdebugBacktrace(3); /* rounded up to 4 by implementation */145  sqlite3MemdebugBacktraceCallback(test_backtrace_cb);146 147  void *p = m->xMalloc(40);148  TEST_ASSERT_NOT_NULL(p);149 150  /* Expect callback called at least once on allocation */151  TEST_ASSERT_TRUE(g_btCalled >= 1);152  TEST_ASSERT_EQUAL_INT(40, g_btLastSize);153  /* Depth is implementation-defined; just ensure it's not some sentinel */154  TEST_ASSERT_NOT_EQUAL_INT(-999, g_btLastDepth);155 156  /* Sync should invoke callback for outstanding allocations */157  int calledBefore = g_btCalled;158  sqlite3MemdebugSync();159  TEST_ASSERT_TRUE(g_btCalled >= calledBefore + 1);160 161  m->xFree(p);162 163  /* Reset callback */164  sqlite3MemdebugBacktraceCallback(NULL);165}166 167static void read_file_into_buffer(const char *zFile, char *buf, size_t bufSize){168  FILE *f = fopen(zFile, "rb");169  TEST_ASSERT_NOT_NULL(f);170  size_t n = fread(buf, 1, bufSize-1, f);171  buf[n] = '\0';172  fclose(f);173}174 175void test_sqlite3MemSetDefault_settitle_reflected_in_dump(void) {176  sqlite3MemSetDefault();177  init_mem();178 179  const sqlite3_mem_methods *m = &sqlite3GlobalConfig.m;180 181  const char *title = "UNIT-TEST-TITLE-XYZ";182  sqlite3MemdebugSettitle(title);183 184  void *p = m->xMalloc(64);185  TEST_ASSERT_NOT_NULL(p);186 187  /* Create a temporary filename for dump */188  char tmpl[] = "/tmp/sqlite_mem2_dump_XXXXXX";189  int fd = mkstemp(tmpl);190  TEST_ASSERT_TRUE(fd >= 0);191  close(fd); /* we will reopen with stdio APIs */192 193  sqlite3MemdebugDump(tmpl);194 195  char buf[8192];196  read_file_into_buffer(tmpl, buf, sizeof(buf));197  /* Our title should appear in the dump */198  TEST_ASSERT_NOT_NULL(strstr(buf, title));199 200  /* Cleanup */201  unlink(tmpl);202  m->xFree(p);203}204 205int main(void) {206  UNITY_BEGIN();207  RUN_TEST(test_sqlite3MemSetDefault_sets_methods_nonnull);208  RUN_TEST(test_sqlite3MemSetDefault_allocator_basic_alloc_realloc_free_and_size_roundup);209  RUN_TEST(test_sqlite3MemSetDefault_memdebug_type_tagging_works);210  RUN_TEST(test_sqlite3MemSetDefault_backtrace_callback_invoked);211  RUN_TEST(test_sqlite3MemSetDefault_settitle_reflected_in_dump);212  return UNITY_END();213}