Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_btree_sqlite3BtreeBeginTrans.c187 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdio.h>5 6/* Helper macros for portability */7#ifndef UNUSED_PARAMETER8#define UNUSED_PARAMETER(x) (void)(x)9#endif10 11/* Forward declarations for helpers */12static sqlite3* helper_open_memory_db(void);13static void helper_close_db(sqlite3 *db);14static void helper_commit_if_needed(Btree *p);15 16/* Unity hooks */17void setUp(void) {18  /* nothing */19}20void tearDown(void) {21  /* nothing */22}23 24/* Helpers */25 26static sqlite3* helper_open_memory_db(void){27  sqlite3 *db = NULL;28  int rc = sqlite3_open(":memory:", &db);29  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);30  TEST_ASSERT_NOT_NULL(db);31  return db;32}33 34static void helper_close_db(sqlite3 *db){35  if( db ){36    int rc = sqlite3_close(db);37    TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);38  }39}40 41static void helper_commit_if_needed(Btree *p){42  if( p ){43    if( p->inTrans!=TRANS_NONE ){44      int rc = sqlite3BtreeCommit(p);45      TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);46      TEST_ASSERT_EQUAL_INT(TRANS_NONE, p->inTrans);47    }48  }49}50 51/* Tests */52 53void test_sqlite3BtreeBeginTrans_read_ok_and_schema_version(void){54  sqlite3 *db = helper_open_memory_db();55 56  /* Get main database Btree */57  TEST_ASSERT_NOT_NULL(db);58  TEST_ASSERT_TRUE(db->nDb>0);59  Btree *p = db->aDb[0].pBt;60  TEST_ASSERT_NOT_NULL(p);61 62  int schemaVer = -1;63  int rc = sqlite3BtreeBeginTrans(p, 0, &schemaVer);64  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);65  TEST_ASSERT_EQUAL_INT(TRANS_READ, p->inTrans);66 67  /* Expect schema version read from page1 offset 40 (cookie) which should be 0 on fresh db */68  u32 expectVer = get4byte(&p->pBt->pPage1->aData[40]);69  TEST_ASSERT_EQUAL_INT(expectVer, (u32)schemaVer);70 71  helper_commit_if_needed(p);72  helper_close_db(db);73}74 75void test_sqlite3BtreeBeginTrans_read_idempotent(void){76  sqlite3 *db = helper_open_memory_db();77  Btree *p = db->aDb[0].pBt;78  TEST_ASSERT_NOT_NULL(p);79 80  int sv1 = -1;81  int rc1 = sqlite3BtreeBeginTrans(p, 0, &sv1);82  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc1);83  TEST_ASSERT_EQUAL_INT(TRANS_READ, p->inTrans);84 85  /* Second read begin should be a no-op that still returns OK */86  int sv2 = -1;87  int rc2 = sqlite3BtreeBeginTrans(p, 0, &sv2);88  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc2);89  TEST_ASSERT_EQUAL_INT(TRANS_READ, p->inTrans);90 91  /* Both schema versions should match the current cookie */92  u32 expectVer = get4byte(&p->pBt->pPage1->aData[40]);93  TEST_ASSERT_EQUAL_INT(expectVer, (u32)sv1);94  TEST_ASSERT_EQUAL_INT(expectVer, (u32)sv2);95 96  helper_commit_if_needed(p);97  helper_close_db(db);98}99 100void test_sqlite3BtreeBeginTrans_write_ok_state_flags(void){101  sqlite3 *db = helper_open_memory_db();102  Btree *p = db->aDb[0].pBt;103  TEST_ASSERT_NOT_NULL(p);104 105  int schemaVer = -1;106  int rc = sqlite3BtreeBeginTrans(p, 1, &schemaVer);107  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 109  /* Verify Btree and BtShared state indicate write transaction */110  TEST_ASSERT_EQUAL_INT(TRANS_WRITE, p->inTrans);111  TEST_ASSERT_EQUAL_INT(TRANS_WRITE, p->pBt->inTransaction);112 113  helper_commit_if_needed(p);114  helper_close_db(db);115}116 117void test_sqlite3BtreeBeginTrans_schema_version_matches_cookie(void){118  sqlite3 *db = helper_open_memory_db();119  /* Change schema_version via PRAGMA and verify the output from sqlite3BtreeBeginTrans */120  int rc = sqlite3_exec(db, "PRAGMA schema_version=12345;", 0, 0, 0);121  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);122 123  Btree *p = db->aDb[0].pBt;124  TEST_ASSERT_NOT_NULL(p);125 126  int outVer = -1;127  rc = sqlite3BtreeBeginTrans(p, 0, &outVer);128  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);129  /* Now the schema cookie should be 12345 */130  u32 expectVer = get4byte(&p->pBt->pPage1->aData[40]);131  TEST_ASSERT_EQUAL_UINT32((u32)12345, expectVer);132  TEST_ASSERT_EQUAL_UINT32(expectVer, (u32)outVer);133 134  helper_commit_if_needed(p);135  helper_close_db(db);136}137 138void test_sqlite3BtreeBeginTrans_readonly_write_fails(void){139  /* Create a disk DB, then reopen read-only and try to begin a write tx */140  const char *fname = "test_ro_btree.db";141  sqlite3 *dbw = NULL;142  int rc = sqlite3_open(fname, &dbw);143  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);144  /* Create some content to ensure the file exists with a valid header */145  rc = sqlite3_exec(dbw, "CREATE TABLE t(x);", 0, 0, 0);146  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);147  rc = sqlite3_close(dbw);148  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);149 150  sqlite3 *dbr = NULL;151  rc = sqlite3_open_v2(152    "file:test_ro_btree.db?mode=ro&cache=private",153    &dbr,154    SQLITE_OPEN_READONLY | SQLITE_OPEN_URI,155    NULL156  );157  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);158 159  /* Obtain Btree and attempt write transaction */160  Btree *p = dbr->aDb[0].pBt;161  TEST_ASSERT_NOT_NULL(p);162  int sv = -1;163  rc = sqlite3BtreeBeginTrans(p, 1, &sv);164  TEST_ASSERT_EQUAL_INT(SQLITE_READONLY, rc);165 166  /* Should not be in a write transaction */167  TEST_ASSERT_NOT_EQUAL(TRANS_WRITE, p->inTrans);168 169  helper_commit_if_needed(p);170  helper_close_db(dbr);171 172  /* Cleanup the file (best-effort) */173  sqlite3_vfs *pVfs = sqlite3_vfs_find(NULL);174  if( pVfs && pVfs->xDelete ){175    pVfs->xDelete(pVfs, fname, 0);176  }177}178 179int main(void){180  UNITY_BEGIN();181  RUN_TEST(test_sqlite3BtreeBeginTrans_read_ok_and_schema_version);182  RUN_TEST(test_sqlite3BtreeBeginTrans_read_idempotent);183  RUN_TEST(test_sqlite3BtreeBeginTrans_write_ok_state_flags);184  RUN_TEST(test_sqlite3BtreeBeginTrans_schema_version_matches_cookie);185  RUN_TEST(test_sqlite3BtreeBeginTrans_readonly_write_fails);186  return UNITY_END();187}