Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3CodeVerifySchemaAtToplevel.c185 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Wrapper provided in the source for calling the static function under test */7void test_sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb);8 9static void enterDbMutex(sqlite3 *db){10  if( db && db->mutex ){11    sqlite3_mutex_enter(db->mutex);12  }else{13    /* In some builds, db->mutex may be NULL; sqlite3_mutex_enter(NULL) is a no-op anyway */14    sqlite3_mutex_enter(db ? db->mutex : 0);15  }16}17static void leaveDbMutex(sqlite3 *db){18  if( db && db->mutex ){19    sqlite3_mutex_leave(db->mutex);20  }else{21    sqlite3_mutex_leave(db ? db->mutex : 0);22  }23}24 25void setUp(void) {26  /* No global setup needed */27}28void tearDown(void) {29  /* No global teardown needed */30}31 32/* Helper: create a fresh in-memory db connection */33static sqlite3* open_memory_db(void){34  sqlite3 *db = 0;35  int rc = sqlite3_open(":memory:", &db);36  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "Failed to open in-memory database");37  TEST_ASSERT_NOT_NULL(db);38  return db;39}40 41/* Ensure main database B-Tree (aDb[0].pBt) is opened by creating a table */42static void ensure_main_btree_open(sqlite3 *db){43  char *errmsg = 0;44  int rc = sqlite3_exec(db, "CREATE TABLE t(x)", 0, 0, &errmsg);45  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, errmsg ? errmsg : "sqlite3_exec failed");46  if( errmsg ) sqlite3_free(errmsg);47  TEST_ASSERT_NOT_NULL_MESSAGE(db->aDb[0].pBt, "Main DB pBt should be non-NULL after creating a table");48}49 50/* Test: For iDb==1 (TEMP), when cookie bit is unset and explain==0,51         the bit is set and TEMP database is opened (pBt becomes non-NULL). */52void test_sqlite3CodeVerifySchemaAtToplevel_sets_mask_and_opens_temp_db(void){53  sqlite3 *db = open_memory_db();54  Parse p;55  memset(&p, 0, sizeof(p));56  p.db = db;57  p.explain = 0;58  DbMaskZero(p.cookieMask);59 60  TEST_ASSERT_NULL(db->aDb[1].pBt);61 62  enterDbMutex(db);63  test_sqlite3CodeVerifySchemaAtToplevel(&p, 1);64  leaveDbMutex(db);65 66  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 1));67  TEST_ASSERT_NOT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP DB pBt should be opened");68 69  sqlite3_close(db);70}71 72/* Test: For iDb==1 (TEMP), when cookie bit is already set,73         the function does not attempt to open TEMP (pBt remains NULL). */74void test_sqlite3CodeVerifySchemaAtToplevel_no_open_when_bit_already_set_for_temp(void){75  sqlite3 *db = open_memory_db();76  Parse p;77  memset(&p, 0, sizeof(p));78  p.db = db;79  p.explain = 0;80  DbMaskZero(p.cookieMask);81  DbMaskSet(p.cookieMask, 1);82 83  TEST_ASSERT_NULL(db->aDb[1].pBt);84 85  enterDbMutex(db);86  test_sqlite3CodeVerifySchemaAtToplevel(&p, 1);87  leaveDbMutex(db);88 89  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 1));90  TEST_ASSERT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP DB pBt should remain NULL when bit already set");91 92  sqlite3_close(db);93}94 95/* Test: For iDb==0 (main DB), when cookie bit is unset,96         the bit is set and TEMP DB is not opened/touched. */97void test_sqlite3CodeVerifySchemaAtToplevel_sets_mask_for_main_db_only(void){98  sqlite3 *db = open_memory_db();99 100  /* Ensure main database B-Tree exists to satisfy assert */101  ensure_main_btree_open(db);102 103  Parse p;104  memset(&p, 0, sizeof(p));105  p.db = db;106  p.explain = 0;107  DbMaskZero(p.cookieMask);108 109  void *initialTempBt = db->aDb[1].pBt; /* likely NULL */110 111  enterDbMutex(db);112  test_sqlite3CodeVerifySchemaAtToplevel(&p, 0);113  leaveDbMutex(db);114 115  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 0));116  TEST_ASSERT_EQUAL_PTR_MESSAGE(initialTempBt, db->aDb[1].pBt, "TEMP DB pBt should be unchanged for iDb=0");117 118  sqlite3_close(db);119}120 121/* Test: For iDb==1 (TEMP), when cookie bit is unset but Parse.explain is true,122         the bit is set but TEMP DB is not opened (pBt stays NULL). */123void test_sqlite3CodeVerifySchemaAtToplevel_with_explain_does_not_open_temp(void){124  sqlite3 *db = open_memory_db();125 126  Parse p;127  memset(&p, 0, sizeof(p));128  p.db = db;129  p.explain = 1; /* explain mode prevents temp DB open inside sqlite3OpenTempDatabase */130  DbMaskZero(p.cookieMask);131 132  TEST_ASSERT_NULL(db->aDb[1].pBt);133 134  enterDbMutex(db);135  test_sqlite3CodeVerifySchemaAtToplevel(&p, 1);136  leaveDbMutex(db);137 138  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 1));139  TEST_ASSERT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP DB pBt should remain NULL when in explain mode");140 141  sqlite3_close(db);142}143 144/* Test: Idempotency for TEMP DB: first call opens TEMP and sets bit,145         second call should not change pBt or cookieMask. */146void test_sqlite3CodeVerifySchemaAtToplevel_idempotent_for_temp_db(void){147  sqlite3 *db = open_memory_db();148 149  Parse p;150  memset(&p, 0, sizeof(p));151  p.db = db;152  p.explain = 0;153  DbMaskZero(p.cookieMask);154 155  /* First call: set bit and open temp DB */156  enterDbMutex(db);157  test_sqlite3CodeVerifySchemaAtToplevel(&p, 1);158  leaveDbMutex(db);159 160  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 1));161  TEST_ASSERT_NOT_NULL(db->aDb[1].pBt);162  void *tempBtFirst = db->aDb[1].pBt;163 164  /* Second call: no-op regarding opening, pBt should remain the same */165  enterDbMutex(db);166  test_sqlite3CodeVerifySchemaAtToplevel(&p, 1);167  leaveDbMutex(db);168 169  TEST_ASSERT_TRUE(DbMaskTest(p.cookieMask, 1));170  TEST_ASSERT_EQUAL_PTR_MESSAGE(tempBtFirst, db->aDb[1].pBt, "TEMP DB pBt should not change on second call");171 172  sqlite3_close(db);173}174 175int main(void) {176  UNITY_BEGIN();177 178  RUN_TEST(test_sqlite3CodeVerifySchemaAtToplevel_sets_mask_and_opens_temp_db);179  RUN_TEST(test_sqlite3CodeVerifySchemaAtToplevel_no_open_when_bit_already_set_for_temp);180  RUN_TEST(test_sqlite3CodeVerifySchemaAtToplevel_sets_mask_for_main_db_only);181  RUN_TEST(test_sqlite3CodeVerifySchemaAtToplevel_with_explain_does_not_open_temp);182  RUN_TEST(test_sqlite3CodeVerifySchemaAtToplevel_idempotent_for_temp_db);183 184  return UNITY_END();185}