Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_loadext_sqlite3AutoLoadExtensions.c233 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Test stub extension init functions and state */7static int ext1_calls = 0;8static int ext2_calls = 0;9static int ext1_should_fail = 0;10static int ext2_should_fail = 0;11static int ext1_fail_rc = SQLITE_ERROR;12static int ext2_fail_rc = SQLITE_ERROR;13static int ext1_set_errmsg = 1;14static int ext2_set_errmsg = 1;15static const sqlite3_api_routines *ext1_last_pThunk = NULL;16static const sqlite3_api_routines *ext2_last_pThunk = NULL;17static sqlite3 *ext1_last_db = NULL;18static sqlite3 *ext2_last_db = NULL;19 20/* sqlite3_loadext_entry signature */21static int test_ext1(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pThunk){22  ext1_calls++;23  ext1_last_db = db;24  ext1_last_pThunk = pThunk;25  if( ext1_should_fail ){26    if( pzErr && ext1_set_errmsg ){27      *pzErr = sqlite3_mprintf("ext1-failure");28    }29    return ext1_fail_rc;30  }31  return SQLITE_OK;32}33static int test_ext2(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pThunk){34  ext2_calls++;35  ext2_last_db = db;36  ext2_last_pThunk = pThunk;37  if( ext2_should_fail ){38    if( pzErr && ext2_set_errmsg ){39      *pzErr = sqlite3_mprintf("ext2-failure");40    }41    return ext2_fail_rc;42  }43  return SQLITE_OK;44}45 46/* Unity fixtures */47void setUp(void) {48  /* Reset global auto-extension list and our local counters/flags */49  sqlite3_reset_auto_extension();50  ext1_calls = ext2_calls = 0;51  ext1_should_fail = ext2_should_fail = 0;52  ext1_fail_rc = ext2_fail_rc = SQLITE_ERROR;53  ext1_set_errmsg = ext2_set_errmsg = 1;54  ext1_last_pThunk = ext2_last_pThunk = NULL;55  ext1_last_db = ext2_last_db = NULL;56}57void tearDown(void) {58  sqlite3_reset_auto_extension();59}60 61/* Helper: open/close an in-memory database, returning db through out param */62static sqlite3* open_memory_db(void){63  sqlite3 *db = NULL;64  int rc = sqlite3_open(":memory:", &db);65  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);66  TEST_ASSERT_NOT_NULL(db);67  return db;68}69static void close_db(sqlite3 *db){70  if( db ){71    int rc = sqlite3_close(db);72    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);73  }74}75 76/* Tests */77 78void test_sqlite3AutoLoadExtensions_no_extensions_returns_immediately(void){79  sqlite3 *db = open_memory_db();80 81  /* No auto-extensions registered */82  sqlite3AutoLoadExtensions(db);83 84  /* No error set; counters unchanged */85  TEST_ASSERT_EQUAL_INT(0, ext1_calls);86  TEST_ASSERT_EQUAL_INT(0, ext2_calls);87  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(db));88 89  close_db(db);90}91 92void test_sqlite3AutoLoadExtensions_calls_single_extension(void){93  /* Register ext1 */94  int rc = sqlite3_auto_extension((void(*)(void))test_ext1);95  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);96 97  sqlite3 *db = open_memory_db();98 99  sqlite3AutoLoadExtensions(db);100 101  TEST_ASSERT_EQUAL_INT(1, ext1_calls);102  TEST_ASSERT_EQUAL_PTR(db, ext1_last_db);103  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(db));104 105  close_db(db);106}107 108void test_sqlite3AutoLoadExtensions_calls_multiple_extensions(void){109  int rc;110  rc = sqlite3_auto_extension((void(*)(void))test_ext1);111  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);112  rc = sqlite3_auto_extension((void(*)(void))test_ext2);113  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);114 115  sqlite3 *db = open_memory_db();116 117  sqlite3AutoLoadExtensions(db);118 119  TEST_ASSERT_EQUAL_INT(1, ext1_calls);120  TEST_ASSERT_EQUAL_INT(1, ext2_calls);121  TEST_ASSERT_EQUAL_PTR(db, ext1_last_db);122  TEST_ASSERT_EQUAL_PTR(db, ext2_last_db);123  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(db));124 125  close_db(db);126}127 128void test_sqlite3AutoLoadExtensions_duplicate_registration_only_calls_once(void){129  int rc;130  rc = sqlite3_auto_extension((void(*)(void))test_ext1);131  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);132  /* Attempt to add duplicate */133  rc = sqlite3_auto_extension((void(*)(void))test_ext1);134  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);135 136  sqlite3 *db = open_memory_db();137 138  sqlite3AutoLoadExtensions(db);139 140  TEST_ASSERT_EQUAL_INT(1, ext1_calls);141  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(db));142 143  close_db(db);144}145 146void test_sqlite3AutoLoadExtensions_cancel_extension(void){147  int rc;148  rc = sqlite3_auto_extension((void(*)(void))test_ext1);149  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);150 151  /* Cancel should return 1 as it was present */152  int removed = sqlite3_cancel_auto_extension((void(*)(void))test_ext1);153  TEST_ASSERT_EQUAL_INT(1, removed);154  /* Second cancel returns 0 */155  removed = sqlite3_cancel_auto_extension((void(*)(void))test_ext1);156  TEST_ASSERT_EQUAL_INT(0, removed);157 158  sqlite3 *db = open_memory_db();159 160  sqlite3AutoLoadExtensions(db);161 162  TEST_ASSERT_EQUAL_INT(0, ext1_calls);163  TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_errcode(db));164 165  close_db(db);166}167 168void test_sqlite3AutoLoadExtensions_error_stops_and_sets_error(void){169  int rc;170  rc = sqlite3_auto_extension((void(*)(void))test_ext1);171  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);172  rc = sqlite3_auto_extension((void(*)(void))test_ext2);173  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);174 175  /* Configure ext1 to fail with an error message */176  ext1_should_fail = 1;177  ext1_fail_rc = SQLITE_ERROR;178  ext1_set_errmsg = 1;179 180  sqlite3 *db = open_memory_db();181 182  sqlite3AutoLoadExtensions(db);183 184  /* ext1 called once and failed; ext2 not called */185  TEST_ASSERT_EQUAL_INT(1, ext1_calls);186  TEST_ASSERT_EQUAL_INT(0, ext2_calls);187 188  /* Connection error set to ext1_fail_rc with message including our text */189  TEST_ASSERT_EQUAL_INT(ext1_fail_rc, sqlite3_errcode(db));190  const char *zErr = sqlite3_errmsg(db);191  TEST_ASSERT_NOT_NULL(zErr);192  TEST_ASSERT_NOT_NULL(strstr(zErr, "automatic extension loading failed"));193  TEST_ASSERT_NOT_NULL(strstr(zErr, "ext1-failure"));194 195  close_db(db);196}197 198void test_sqlite3AutoLoadExtensions_error_without_message(void){199  int rc;200  rc = sqlite3_auto_extension((void(*)(void))test_ext1);201  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);202  /* ext1 fails but does not provide an error message */203  ext1_should_fail = 1;204  ext1_fail_rc = SQLITE_ERROR;205  ext1_set_errmsg = 0;206 207  sqlite3 *db = open_memory_db();208 209  sqlite3AutoLoadExtensions(db);210 211  TEST_ASSERT_EQUAL_INT(1, ext1_calls);212  TEST_ASSERT_EQUAL_INT(ext1_fail_rc, sqlite3_errcode(db));213  const char *zErr = sqlite3_errmsg(db);214  TEST_ASSERT_NOT_NULL(zErr);215  /* Ensure the generic failure prefix is present */216  TEST_ASSERT_NOT_NULL(strstr(zErr, "automatic extension loading failed"));217 218  close_db(db);219}220 221int main(void) {222  UNITY_BEGIN();223 224  RUN_TEST(test_sqlite3AutoLoadExtensions_no_extensions_returns_immediately);225  RUN_TEST(test_sqlite3AutoLoadExtensions_calls_single_extension);226  RUN_TEST(test_sqlite3AutoLoadExtensions_calls_multiple_extensions);227  RUN_TEST(test_sqlite3AutoLoadExtensions_duplicate_registration_only_calls_once);228  RUN_TEST(test_sqlite3AutoLoadExtensions_cancel_extension);229  RUN_TEST(test_sqlite3AutoLoadExtensions_error_stops_and_sets_error);230  RUN_TEST(test_sqlite3AutoLoadExtensions_error_without_message);231 232  return UNITY_END();233}