Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_hash_sqlite3HashClear.c199 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdlib.h>5#include <string.h>6#include <stdio.h>7#include <stdint.h>8 9/* Unity setup/teardown */10void setUp(void) {11  /* Ensure SQLite subsystems (including memory allocator) are initialized */12  sqlite3_initialize();13}14void tearDown(void) {15  /* Shutdown between tests to avoid cross-test interference */16  sqlite3_shutdown();17}18 19/* Helper to populate a hash with n distinct key/value pairs.20   Keys are stored in keys[i], values are addresses of values[i]. */21static void populate_hash(Hash *pH, int n, char keys[][32], int *values){22  for(int i=0; i<n; i++){23    snprintf(keys[i], 32, "key_%03d", i);24    values[i] = i + 1000;25    void *old = sqlite3HashInsert(pH, keys[i], &values[i]);26    TEST_ASSERT_NULL(old);27  }28}29 30/* Test: Clearing an empty hash should be a no-op and maintain zeroed state. */31void test_sqlite3HashClear_on_empty_hash(void){32  Hash h;33  sqlite3HashInit(&h);34 35  /* Verify initial state */36  TEST_ASSERT_EQUAL_PTR(NULL, h.first);37  TEST_ASSERT_EQUAL_UINT(0u, h.count);38  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);39  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);40 41  /* Clear empty */42  sqlite3HashClear(&h);43 44  /* Verify remains empty */45  TEST_ASSERT_EQUAL_PTR(NULL, h.first);46  TEST_ASSERT_EQUAL_UINT(0u, h.count);47  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);48  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);49 50  /* Ensure find returns NULL */51  TEST_ASSERT_NULL(sqlite3HashFind(&h, "nonexistent"));52}53 54/* Test: Insert a single element, then clear. */55void test_sqlite3HashClear_after_single_insert(void){56  Hash h;57  sqlite3HashInit(&h);58 59  int v = 42;60  const char *key = "abc";61  void *old = sqlite3HashInsert(&h, key, &v);62  TEST_ASSERT_NULL(old);63 64  /* Pre-clear: should find value (case-insensitive) */65  TEST_ASSERT_EQUAL_PTR(&v, sqlite3HashFind(&h, "ABC"));66  TEST_ASSERT_EQUAL_UINT(1u, h.count);67  TEST_ASSERT_NOT_NULL(h.first);68 69  /* Clear */70  sqlite3HashClear(&h);71 72  /* Post-clear state */73  TEST_ASSERT_EQUAL_PTR(NULL, h.first);74  TEST_ASSERT_EQUAL_UINT(0u, h.count);75  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);76  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);77 78  /* Should not find previously inserted key */79  TEST_ASSERT_NULL(sqlite3HashFind(&h, "abc"));80  TEST_ASSERT_NULL(sqlite3HashFind(&h, "ABC"));81}82 83/* Test: Insert many elements (likely causing bucket allocation/rehash), then clear. */84void test_sqlite3HashClear_many_inserts_and_rehash(void){85  Hash h;86  sqlite3HashInit(&h);87 88  enum { N = 40 };89  char keys[N][32];90  int values[N];91 92  populate_hash(&h, N, keys, values);93 94  /* Pre-clear: Should find a couple of entries */95  TEST_ASSERT_EQUAL_UINT((unsigned)N, h.count);96  void *found0 = sqlite3HashFind(&h, "KEY_000"); /* case-insensitive */97  void *foundN1 = sqlite3HashFind(&h, "KEY_039");98  TEST_ASSERT_NOT_NULL(found0);99  TEST_ASSERT_NOT_NULL(foundN1);100 101  /* Record whether buckets were allocated (implementation detail) */102  int hadBuckets = (h.ht != NULL);103  unsigned int pre_htsize = h.htsize;104 105  /* Clear */106  sqlite3HashClear(&h);107 108  /* Post-clear invariants */109  TEST_ASSERT_EQUAL_PTR(NULL, h.first);110  TEST_ASSERT_EQUAL_UINT(0u, h.count);111  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);112  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);113 114  /* Ensure previous keys are gone */115  TEST_ASSERT_NULL(sqlite3HashFind(&h, "KEY_000"));116  TEST_ASSERT_NULL(sqlite3HashFind(&h, "KEY_039"));117 118  /* Reuse the hash after clearing */119  int v = 777;120  void *old = sqlite3HashInsert(&h, "after_clear", &v);121  TEST_ASSERT_NULL(old);122  TEST_ASSERT_EQUAL_UINT(1u, h.count);123  TEST_ASSERT_EQUAL_PTR(&v, sqlite3HashFind(&h, "AFTER_CLEAR"));124 125  /* If buckets existed before, they must have been freed and not retained */126  if( hadBuckets ){127    TEST_ASSERT_EQUAL_UINT(0u, h.htsize);128  }129 130  /* Clean up and clear again to ensure no residual state */131  sqlite3HashClear(&h);132  TEST_ASSERT_EQUAL_UINT(0u, h.count);133  TEST_ASSERT_EQUAL_PTR(NULL, sqlite3HashFind(&h, "after_clear"));134}135 136/* Test: sqlite3HashClear must not free or modify client data pointers. */137void test_sqlite3HashClear_does_not_free_client_data(void){138  Hash h;139  sqlite3HashInit(&h);140 141  int *pdata = (int*)sqlite3_malloc(sizeof(int));142  TEST_ASSERT_NOT_NULL(pdata);143  *pdata = 0x12345678;144 145  void *old = sqlite3HashInsert(&h, "data_key", pdata);146  TEST_ASSERT_NULL(old);147  TEST_ASSERT_EQUAL_PTR(pdata, sqlite3HashFind(&h, "DATA_KEY"));148 149  /* Clear the hash; user data must not be freed or modified */150  sqlite3HashClear(&h);151 152  /* Verify pdata remains valid and unchanged */153  TEST_ASSERT_EQUAL_INT(0x12345678, *pdata);154  sqlite3_free(pdata);155 156  /* Hash should be empty */157  TEST_ASSERT_EQUAL_UINT(0u, h.count);158  TEST_ASSERT_EQUAL_PTR(NULL, h.first);159  TEST_ASSERT_NULL(sqlite3HashFind(&h, "data_key"));160}161 162/* Test: Idempotency - calling sqlite3HashClear twice should be safe. */163void test_sqlite3HashClear_idempotent_twice(void){164  Hash h;165  sqlite3HashInit(&h);166 167  int a=1, b=2, c=3;168  TEST_ASSERT_NULL(sqlite3HashInsert(&h, "one", &a));169  TEST_ASSERT_NULL(sqlite3HashInsert(&h, "two", &b));170  TEST_ASSERT_NULL(sqlite3HashInsert(&h, "three", &c));171 172  TEST_ASSERT_EQUAL_UINT(3u, h.count);173 174  sqlite3HashClear(&h);175 176  TEST_ASSERT_EQUAL_UINT(0u, h.count);177  TEST_ASSERT_EQUAL_PTR(NULL, h.first);178  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);179  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);180 181  /* Second clear should be a no-op */182  sqlite3HashClear(&h);183 184  TEST_ASSERT_EQUAL_UINT(0u, h.count);185  TEST_ASSERT_EQUAL_PTR(NULL, h.first);186  TEST_ASSERT_EQUAL_UINT(0u, h.htsize);187  TEST_ASSERT_EQUAL_PTR(NULL, h.ht);188}189 190/* Main runner */191int main(void){192  UNITY_BEGIN();193  RUN_TEST(test_sqlite3HashClear_on_empty_hash);194  RUN_TEST(test_sqlite3HashClear_after_single_insert);195  RUN_TEST(test_sqlite3HashClear_many_inserts_and_rehash);196  RUN_TEST(test_sqlite3HashClear_does_not_free_client_data);197  RUN_TEST(test_sqlite3HashClear_idempotent_twice);198  return UNITY_END();199}