Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_build_sqlite3OpenTempDatabase.c146 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <string.h>5#include <stdlib.h>6 7/* Unity setup/teardown */8void setUp(void) {9  /* No global setup needed */10}11 12void tearDown(void) {13  /* No global teardown needed */14}15 16/* Helper: Open an in-memory database and assert success */17static sqlite3* open_db(void){18  sqlite3 *db = 0;19  int rc = sqlite3_open(":memory:", &db);20  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open failed");21  TEST_ASSERT_NOT_NULL_MESSAGE(db, "sqlite3_open returned NULL db");22  return db;23}24 25/* Helper: Initialize a Parse object for a given db */26static void init_parse(Parse *pParse, sqlite3 *db){27  memset(pParse, 0, sizeof(*pParse));28  pParse->db = db;29  /* pParse->rc defaults to SQLITE_OK (0) */30}31 32/* A VFS xOpen that always fails to simulate I/O errors on open */33static int failvfs_xOpen(sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile,34                         int flags, int *pOutFlags){35  UNUSED_PARAMETER(pVfs);36  UNUSED_PARAMETER(zName);37  UNUSED_PARAMETER(pFile);38  UNUSED_PARAMETER(flags);39  if( pOutFlags ) *pOutFlags = 0;40  return SQLITE_IOERR;41}42 43/* Test: Successful open should create a temp btree and return 0 */44static void test_sqlite3OpenTempDatabase_success_opens_temp_btree(void){45  sqlite3 *db = open_db();46  Parse parse;47  init_parse(&parse, db);48 49  /* Precondition: TEMP btree not yet open */50  TEST_ASSERT_NULL(db->aDb[1].pBt);51 52  int rc = sqlite3OpenTempDatabase(&parse);53  TEST_ASSERT_EQUAL_INT(0, rc);54  TEST_ASSERT_NOT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP btree was not opened");55  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, parse.rc, "parse.rc should remain SQLITE_OK");56 57  sqlite3_close(db);58}59 60/* Test: When explain flag is set, function should do nothing and return 0 */61static void test_sqlite3OpenTempDatabase_noop_when_explain(void){62  sqlite3 *db = open_db();63  Parse parse;64  init_parse(&parse, db);65 66  /* Precondition: TEMP btree not yet open */67  TEST_ASSERT_NULL(db->aDb[1].pBt);68 69  parse.explain = 1; /* Force explain mode */70  int rc = sqlite3OpenTempDatabase(&parse);71  TEST_ASSERT_EQUAL_INT(0, rc);72  TEST_ASSERT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP btree should not be opened in EXPLAIN mode");73  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, parse.rc, "parse.rc should remain SQLITE_OK in EXPLAIN mode");74 75  sqlite3_close(db);76}77 78/* Test: Calling when btree already open should be a no-op */79static void test_sqlite3OpenTempDatabase_noop_if_already_open(void){80  sqlite3 *db = open_db();81  Parse parse;82  init_parse(&parse, db);83 84  /* First call opens the TEMP database */85  int rc1 = sqlite3OpenTempDatabase(&parse);86  TEST_ASSERT_EQUAL_INT(0, rc1);87  TEST_ASSERT_NOT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP btree was not opened on first call");88  Btree *pBtFirst = db->aDb[1].pBt;89 90  /* Second call should not change anything */91  int rc2 = sqlite3OpenTempDatabase(&parse);92  TEST_ASSERT_EQUAL_INT(0, rc2);93  TEST_ASSERT_EQUAL_PTR_MESSAGE(pBtFirst, db->aDb[1].pBt, "TEMP btree pointer should remain unchanged");94  TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, parse.rc, "parse.rc should remain SQLITE_OK");95 96  sqlite3_close(db);97}98 99/* Test: Force sqlite3BtreeOpen() to fail via a VFS whose xOpen always fails */100static void test_sqlite3OpenTempDatabase_btree_open_failure_sets_error_and_rc(void){101  sqlite3 *db = open_db();102  Parse parse;103  init_parse(&parse, db);104 105  /* Ensure starting state has no TEMP btree */106  TEST_ASSERT_NULL(db->aDb[1].pBt);107 108  /* Build a failing VFS based on the default, overriding only xOpen */109  sqlite3_vfs *orig = db->pVfs;110  TEST_ASSERT_NOT_NULL_MESSAGE(orig, "db->pVfs is NULL");111 112  sqlite3_vfs failvfs = *orig; /* Shallow copy is sufficient for our purpose */113  failvfs.zName = "failvfs";114  failvfs.xOpen = failvfs_xOpen;115 116  /* Swap the connection's VFS to the failing one */117  db->pVfs = &failvfs;118 119  int rc = sqlite3OpenTempDatabase(&parse);120 121  /* Restore original VFS immediately after call */122  db->pVfs = orig;123 124  TEST_ASSERT_EQUAL_INT_MESSAGE(1, rc, "Function should return 1 on btree open failure");125  TEST_ASSERT_NULL_MESSAGE(db->aDb[1].pBt, "TEMP btree should not be set on failure");126  TEST_ASSERT_NOT_EQUAL_MESSAGE(SQLITE_OK, parse.rc, "parse.rc should be set to an error code");127  TEST_ASSERT_NOT_NULL_MESSAGE(parse.zErrMsg, "Error message should be set on failure");128  if( parse.zErrMsg ){129    /* Check error message contains expected text */130    TEST_ASSERT_NOT_NULL_MESSAGE(strstr(parse.zErrMsg, "unable to open a temporary database"),131                                 "Error message does not contain expected text");132    sqlite3DbFree(db, parse.zErrMsg);133    parse.zErrMsg = 0;134  }135 136  sqlite3_close(db);137}138 139int main(void){140  UNITY_BEGIN();141  RUN_TEST(test_sqlite3OpenTempDatabase_success_opens_temp_btree);142  RUN_TEST(test_sqlite3OpenTempDatabase_noop_when_explain);143  RUN_TEST(test_sqlite3OpenTempDatabase_noop_if_already_open);144  RUN_TEST(test_sqlite3OpenTempDatabase_btree_open_failure_sets_error_and_rc);145  return UNITY_END();146}