Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_main_sqlite3_snapshot_get.c257 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <stdlib.h>6#include <string.h>7#include <time.h>8 9static int g_counter = 0;10 11/* Unity hooks */12void setUp(void) {13  /* Optional setup */14}15void tearDown(void) {16  /* Optional teardown */17}18 19/* Helper: generate a unique filename for a database file */20static void make_filename(char *buf, size_t n, const char *tag){21  ++g_counter;22  snprintf(buf, n, "test_snapshot_get_%s_%ld_%d.db",23           tag ? tag : "db", (long)time(NULL), g_counter);24}25 26/* Helper: remove db and its associated -wal and -shm files */27static void cleanup_db_files(const char *dbfile){28  if( dbfile && dbfile[0] ){29    char wal[1024], shm[1024];30    snprintf(wal, sizeof(wal), "%s-wal", dbfile);31    snprintf(shm, sizeof(shm), "%s-shm", dbfile);32    remove(wal);33    remove(shm);34    remove(dbfile);35  }36}37 38/* Helper: exec SQL and assert success */39static void exec_or_fail(sqlite3 *db, const char *sql){40  char *errmsg = NULL;41  int rc = sqlite3_exec(db, sql, 0, 0, &errmsg);42  if( rc!=SQLITE_OK ){43    const char *msg = errmsg ? errmsg : "sqlite3_exec failed";44    TEST_FAIL_MESSAGE(msg);45  }46  sqlite3_free(errmsg);47}48 49/* Helper: set journal mode to WAL for a given database schema (NULL->main).50   Returns 1 if journal_mode is "wal", 0 otherwise. */51static int ensure_wal(sqlite3 *db, const char *zDb){52  int rc;53  sqlite3_stmt *pStmt = NULL;54  char sql[256];55  if( zDb==NULL || zDb[0]==0 ){56    snprintf(sql, sizeof(sql), "PRAGMA journal_mode=WAL;");57  }else{58    snprintf(sql, sizeof(sql), "PRAGMA %s.journal_mode=WAL;", zDb);59  }60  rc = sqlite3_prepare_v2(db, sql, -1, &pStmt, 0);61  if( rc!=SQLITE_OK ) return 0;62  rc = sqlite3_step(pStmt);63  if( rc!=SQLITE_ROW ){64    sqlite3_finalize(pStmt);65    return 0;66  }67  const unsigned char *z = sqlite3_column_text(pStmt, 0);68  int isWal = (z && sqlite3_stricmp((const char*)z, "wal")==0);69  sqlite3_finalize(pStmt);70  return isWal;71}72 73/* Test: calling without an explicit transaction should return SQLITE_ERROR */74void test_sqlite3_snapshot_get_not_in_txn(void){75  sqlite3 *db = NULL;76  char dbfile[512];77  make_filename(dbfile, sizeof(dbfile), "notx");78  int rc = sqlite3_open(dbfile, &db);79  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);80 81  sqlite3_snapshot *pSnap = NULL;82  rc = sqlite3_snapshot_get(db, "main", &pSnap);83  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);84 85  sqlite3_close(db);86  cleanup_db_files(dbfile);87}88 89/* Test: successful snapshot retrieval on main in read transaction with WAL */90void test_sqlite3_snapshot_get_read_txn_main_wal(void){91  sqlite3 *db = NULL;92  char dbfile[512];93  make_filename(dbfile, sizeof(dbfile), "mainwal");94  int rc = sqlite3_open(dbfile, &db);95  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);96 97  if( !ensure_wal(db, NULL) ){98    sqlite3_close(db);99    cleanup_db_files(dbfile);100    TEST_IGNORE_MESSAGE("WAL not supported on this build or VFS. Skipping.");101  }102 103  exec_or_fail(db, "CREATE TABLE t(x);");104  exec_or_fail(db, "INSERT INTO t VALUES(1);");105  exec_or_fail(db, "INSERT INTO t VALUES(2);");106  exec_or_fail(db, "COMMIT;"); /* ensure there's a commit point */107  exec_or_fail(db, "BEGIN;");  /* start explicit transaction to satisfy autoCommit==0 */108 109  sqlite3_snapshot *pSnap = NULL;110  rc = sqlite3_snapshot_get(db, "main", &pSnap);111  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);112  TEST_ASSERT_NOT_NULL(pSnap);113 114  sqlite3_snapshot_free(pSnap);115  exec_or_fail(db, "COMMIT;");116 117  sqlite3_close(db);118  cleanup_db_files(dbfile);119}120 121/* Test: snapshot_get on temp schema should return SQLITE_ERROR */122void test_sqlite3_snapshot_get_temp_schema_error(void){123  sqlite3 *db = NULL;124  char dbfile[512];125  make_filename(dbfile, sizeof(dbfile), "temp");126  int rc = sqlite3_open(dbfile, &db);127  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);128 129  if( !ensure_wal(db, NULL) ){130    sqlite3_close(db);131    cleanup_db_files(dbfile);132    TEST_IGNORE_MESSAGE("WAL not supported on this build or VFS. Skipping.");133  }134 135  exec_or_fail(db, "BEGIN;");136  sqlite3_snapshot *pSnap = NULL;137  rc = sqlite3_snapshot_get(db, "temp", &pSnap);138  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);139  exec_or_fail(db, "COMMIT;");140 141  sqlite3_close(db);142  cleanup_db_files(dbfile);143}144 145/* Test: snapshot_get during a write transaction should return SQLITE_ERROR */146void test_sqlite3_snapshot_get_write_txn_error(void){147  sqlite3 *db = NULL;148  char dbfile[512];149  make_filename(dbfile, sizeof(dbfile), "writetx");150  int rc = sqlite3_open(dbfile, &db);151  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);152 153  if( !ensure_wal(db, NULL) ){154    sqlite3_close(db);155    cleanup_db_files(dbfile);156    TEST_IGNORE_MESSAGE("WAL not supported on this build or VFS. Skipping.");157  }158 159  exec_or_fail(db, "CREATE TABLE t(x);");160  exec_or_fail(db, "INSERT INTO t VALUES(1);");161  exec_or_fail(db, "COMMIT;");162  exec_or_fail(db, "BEGIN IMMEDIATE;"); /* enter write transaction */163 164  sqlite3_snapshot *pSnap = NULL;165  rc = sqlite3_snapshot_get(db, "main", &pSnap);166  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);167 168  exec_or_fail(db, "ROLLBACK;");169 170  sqlite3_close(db);171  cleanup_db_files(dbfile);172}173 174/* Test: snapshot_get with an unknown schema name should return SQLITE_ERROR */175void test_sqlite3_snapshot_get_unknown_schema_error(void){176  sqlite3 *db = NULL;177  char dbfile[512];178  make_filename(dbfile, sizeof(dbfile), "unknown");179  int rc = sqlite3_open(dbfile, &db);180  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);181 182  if( !ensure_wal(db, NULL) ){183    sqlite3_close(db);184    cleanup_db_files(dbfile);185    TEST_IGNORE_MESSAGE("WAL not supported on this build or VFS. Skipping.");186  }187 188  exec_or_fail(db, "BEGIN;");189  sqlite3_snapshot *pSnap = NULL;190  rc = sqlite3_snapshot_get(db, "nosuchdb", &pSnap);191  TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);192  exec_or_fail(db, "COMMIT;");193 194  sqlite3_close(db);195  cleanup_db_files(dbfile);196}197 198/* Test: successful snapshot retrieval on an attached database in WAL mode */199void test_sqlite3_snapshot_get_attached_db_wal(void){200  sqlite3 *db = NULL;201  char mainfile[512], auxfile[512];202  make_filename(mainfile, sizeof(mainfile), "main_attach");203  make_filename(auxfile, sizeof(auxfile), "aux");204 205  int rc = sqlite3_open(mainfile, &db);206  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);207 208  if( !ensure_wal(db, NULL) ){209    sqlite3_close(db);210    cleanup_db_files(mainfile);211    cleanup_db_files(auxfile);212    TEST_IGNORE_MESSAGE("WAL not supported on this build or VFS. Skipping.");213  }214 215  /* Attach auxiliary database */216  char attachsql[1024];217  snprintf(attachsql, sizeof(attachsql), "ATTACH '%s' AS aux;", auxfile);218  exec_or_fail(db, attachsql);219 220  /* Ensure WAL for attached database */221  if( !ensure_wal(db, "aux") ){222    exec_or_fail(db, "DETACH aux;");223    sqlite3_close(db);224    cleanup_db_files(mainfile);225    cleanup_db_files(auxfile);226    TEST_IGNORE_MESSAGE("WAL not supported for attached database. Skipping.");227  }228 229  exec_or_fail(db, "CREATE TABLE aux.t2(y);");230  exec_or_fail(db, "INSERT INTO aux.t2 VALUES(10);");231  exec_or_fail(db, "COMMIT;");232  exec_or_fail(db, "BEGIN;");233 234  sqlite3_snapshot *pSnap = NULL;235  rc = sqlite3_snapshot_get(db, "aux", &pSnap);236  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);237  TEST_ASSERT_NOT_NULL(pSnap);238  sqlite3_snapshot_free(pSnap);239 240  exec_or_fail(db, "COMMIT;");241  exec_or_fail(db, "DETACH aux;");242 243  sqlite3_close(db);244  cleanup_db_files(mainfile);245  cleanup_db_files(auxfile);246}247 248int main(void){249  UNITY_BEGIN();250  RUN_TEST(test_sqlite3_snapshot_get_not_in_txn);251  RUN_TEST(test_sqlite3_snapshot_get_read_txn_main_wal);252  RUN_TEST(test_sqlite3_snapshot_get_temp_schema_error);253  RUN_TEST(test_sqlite3_snapshot_get_write_txn_error);254  RUN_TEST(test_sqlite3_snapshot_get_unknown_schema_error);255  RUN_TEST(test_sqlite3_snapshot_get_attached_db_wal);256  return UNITY_END();257}