Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_expr_addAggInfoFunc.c203 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6 7/* Call the provided wrapper for the static function */8extern int test_addAggInfoFunc(sqlite3 *db, AggInfo *pInfo);9 10/* Helpers for memory failure injection */11static sqlite3_mem_methods g_origMem;12static int g_haveOrigMem = 0;13 14static void *failMalloc(int n){ (void)n; return NULL; }15static void failFree(void *p){ (void)p; }16static void *failRealloc(void *p, int n){ (void)p; (void)n; return NULL; }17static int failSize(void *p){ (void)p; return 0; }18static int failRoundup(int n){ return n; }19static int failInit(void *p){ (void)p; return SQLITE_OK; }20static void failShutdown(void *p){ (void)p; }21 22static int installFailingAllocator(void){23  int rc;24  rc = sqlite3_shutdown();25  if( rc!=SQLITE_OK && rc!=SQLITE_MISUSE ){26    return rc;27  }28  rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &g_origMem);29  if( rc!=SQLITE_OK ) return rc;30  g_haveOrigMem = 1;31 32  sqlite3_mem_methods fail = {33    failMalloc, failFree, failRealloc, failSize, failRoundup, failInit, failShutdown, 034  };35  rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &fail);36  if( rc!=SQLITE_OK ) return rc;37  rc = sqlite3_initialize();38  return rc;39}40 41static int restoreAllocator(void){42  int rc;43  if( !g_haveOrigMem ) return SQLITE_OK;44  rc = sqlite3_shutdown();45  if( rc!=SQLITE_OK && rc!=SQLITE_MISUSE ){46    return rc;47  }48  rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &g_origMem);49  if( rc!=SQLITE_OK ) return rc;50  rc = sqlite3_initialize();51  return rc;52}53 54static int is_zero_memory(const void *p, size_t n){55  const unsigned char *b = (const unsigned char*)p;56  for(size_t i=0;i<n;i++){57    if( b[i]!=0 ) return 0;58  }59  return 1;60}61 62void setUp(void) {63  /* Ensure SQLite is initialized in default state for tests that do not override it */64  sqlite3_initialize();65}66 67void tearDown(void) {68  /* Restore allocator if a test changed it */69  if( g_haveOrigMem ){70    restoreAllocator();71    g_haveOrigMem = 0;72  }73}74 75/* Test 1: First allocation with db==NULL (global allocator) */76void test_addAggInfoFunc_first_alloc_db_null(void){77  AggInfo info;78  memset(&info, 0, sizeof(info));79 80  int idx = test_addAggInfoFunc(NULL, &info);81  TEST_ASSERT_EQUAL_INT(0, idx);82  TEST_ASSERT_EQUAL_INT(1, info.nFunc);83  TEST_ASSERT_NOT_NULL(info.aFunc);84 85  /* New slot must be zero-initialized */86  TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[0], sizeof(info.aFunc[0])));87 88  /* Cleanup */89  sqlite3_free(info.aFunc);90}91 92/* Test 2: Second allocation preserves first element and zero-initializes new */93void test_addAggInfoFunc_second_alloc_preserve_and_zero_new(void){94  AggInfo info;95  memset(&info, 0, sizeof(info));96 97  int idx0 = test_addAggInfoFunc(NULL, &info);98  TEST_ASSERT_EQUAL_INT(0, idx0);99  TEST_ASSERT_EQUAL_INT(1, info.nFunc);100  TEST_ASSERT_NOT_NULL(info.aFunc);101  TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[0], sizeof(info.aFunc[0])));102 103  /* Set a known field in the first element to a non-zero value to ensure preservation.104     Use a commonly-present integer field iMem in AggInfo_func. */105  info.aFunc[0].iMem = 12345;106 107  int idx1 = test_addAggInfoFunc(NULL, &info);108  TEST_ASSERT_EQUAL_INT(1, idx1);109  TEST_ASSERT_EQUAL_INT(2, info.nFunc);110  TEST_ASSERT_NOT_NULL(info.aFunc);111 112  /* Ensure first element preserved */113  TEST_ASSERT_EQUAL_INT(12345, info.aFunc[0].iMem);114 115  /* Ensure the newly added slot is zero-initialized */116  TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[1], sizeof(info.aFunc[1])));117 118  /* Cleanup */119  sqlite3_free(info.aFunc);120}121 122/* Test 3: Multiple appends yield consecutive indices and correct nFunc */123void test_addAggInfoFunc_multiple_appends_indexes(void){124  AggInfo info;125  memset(&info, 0, sizeof(info));126 127  const int N = 50;128  for(int k=0; k<N; k++){129    int idx = test_addAggInfoFunc(NULL, &info);130    TEST_ASSERT_EQUAL_INT(k, idx);131    TEST_ASSERT_EQUAL_INT(k+1, info.nFunc);132    TEST_ASSERT_NOT_NULL(info.aFunc);133 134    /* The most recently added slot must be zeroed */135    TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[idx], sizeof(info.aFunc[idx])));136 137    /* Optionally set a value in a previous element and ensure it persists after growth */138    if( k==0 ){139      info.aFunc[0].iMem = 777;140    }else{141      TEST_ASSERT_EQUAL_INT(777, info.aFunc[0].iMem);142    }143  }144 145  /* Cleanup */146  sqlite3_free(info.aFunc);147}148 149/* Test 4: Works with a real sqlite3* handle (db lookaside-aware allocation path) */150void test_addAggInfoFunc_with_real_db(void){151  sqlite3 *db = NULL;152  int rc = sqlite3_open(":memory:", &db);153  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);154  TEST_ASSERT_NOT_NULL(db);155 156  AggInfo info;157  memset(&info, 0, sizeof(info));158 159  int idx0 = test_addAggInfoFunc(db, &info);160  TEST_ASSERT_EQUAL_INT(0, idx0);161  TEST_ASSERT_EQUAL_INT(1, info.nFunc);162  TEST_ASSERT_NOT_NULL(info.aFunc);163  TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[0], sizeof(info.aFunc[0])));164 165  int idx1 = test_addAggInfoFunc(db, &info);166  TEST_ASSERT_EQUAL_INT(1, idx1);167  TEST_ASSERT_EQUAL_INT(2, info.nFunc);168  TEST_ASSERT_TRUE(is_zero_memory(&info.aFunc[1], sizeof(info.aFunc[1])));169 170  /* Cleanup using db-aware free */171  sqlite3DbFree(db, info.aFunc);172  sqlite3_close(db);173}174 175/* Test 5: Allocation failure returns negative and does not modify pInfo */176void test_addAggInfoFunc_allocation_failure_returns_negative(void){177  /* Install failing allocator */178  int rc = installFailingAllocator();179  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);180 181  AggInfo info;182  memset(&info, 0, sizeof(info));183 184  int idx = test_addAggInfoFunc(NULL, &info);185  TEST_ASSERT_TRUE(idx < 0);186  TEST_ASSERT_EQUAL_INT(0, info.nFunc);187  TEST_ASSERT_NULL(info.aFunc);188 189  /* Restore allocator for the rest of the tests */190  rc = restoreAllocator();191  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);192  g_haveOrigMem = 0;193}194 195int main(void){196  UNITY_BEGIN();197  RUN_TEST(test_addAggInfoFunc_first_alloc_db_null);198  RUN_TEST(test_addAggInfoFunc_second_alloc_preserve_and_zero_new);199  RUN_TEST(test_addAggInfoFunc_multiple_appends_indexes);200  RUN_TEST(test_addAggInfoFunc_with_real_db);201  RUN_TEST(test_addAggInfoFunc_allocation_failure_returns_negative);202  return UNITY_END();203}