Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_sqlite3PagerSavepoint.c183 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5 6/* Unity setup/teardown */7void setUp(void) {8  /* Nothing to set up globally */9}10void tearDown(void) {11  /* Nothing to clean up globally */12}13 14/* Helper: allocate a zeroed Pager with minimal initialization suitable for15** exercising sqlite3PagerSavepoint without triggering I/O or WAL playback.16*/17static Pager* allocMinimalPager(void){18  Pager *p = (Pager*)sqlite3MallocZero(sizeof(*p));19  TEST_ASSERT_NOT_NULL(p);20  /* Ensure we are not in an error state */21  p->errCode = SQLITE_OK;22 23  /* Avoid entering pagerPlaybackSavepoint path:24  ** - No WAL25  ** - No open journal files26  */27  p->pWal = 0;28  /* jfd/sjfd will remain NULL/0 (isOpen() should evaluate false) */29 30  /* Some reasonable default pageSize for any arithmetic, though we avoid using it */31  p->pageSize = 4096;32 33  /* Initialize other fields used indirectly in surrounding code to benign values */34  p->nSavepoint = 0;35  p->aSavepoint = 0;36  p->nSubRec = 0;37 38  return p;39}40 41/* Helper: allocate array of PagerSavepoint with given count and attach to pPager. */42static void pagerInitSavepoints(Pager *pPager, int nSavepoint){43  PagerSavepoint *a = 0;44  if( nSavepoint>0 ){45    a = (PagerSavepoint*)sqlite3MallocZero(sizeof(PagerSavepoint) * (size_t)nSavepoint);46    TEST_ASSERT_NOT_NULL(a);47  }48  pPager->aSavepoint = a;49  pPager->nSavepoint = nSavepoint;50}51 52/* Test: No-op when iSavepoint >= nSavepoint (release) */53static void test_sqlite3PagerSavepoint_noop_when_index_out_of_range_release(void){54  Pager *p = allocMinimalPager();55  pagerInitSavepoints(p, 2);56 57  /* Ensure pInSavepoint are NULL to avoid any accidental frees */58  /* iSavepoint >= nSavepoint -> no-op */59  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_RELEASE, 2); /* iSavepoint == nSavepoint */60  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);61  TEST_ASSERT_EQUAL_INT(2, p->nSavepoint);62 63  rc = sqlite3PagerSavepoint(p, SAVEPOINT_RELEASE, 5); /* clearly out of range */64  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);65  TEST_ASSERT_EQUAL_INT(2, p->nSavepoint);66 67  sqlite3_free(p->aSavepoint);68  sqlite3_free(p);69}70 71/* Test: No-op when iSavepoint >= nSavepoint (rollback) */72static void test_sqlite3PagerSavepoint_noop_when_index_out_of_range_rollback(void){73  Pager *p = allocMinimalPager();74  pagerInitSavepoints(p, 1);75 76  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_ROLLBACK, 1); /* iSavepoint == nSavepoint */77  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78  TEST_ASSERT_EQUAL_INT(1, p->nSavepoint);79 80  rc = sqlite3PagerSavepoint(p, SAVEPOINT_ROLLBACK, 99);81  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);82  TEST_ASSERT_EQUAL_INT(1, p->nSavepoint);83 84  sqlite3_free(p->aSavepoint);85  sqlite3_free(p);86}87 88/* Test: SAVEPOINT_RELEASE reduces nSavepoint to iSavepoint, and destroys affected bitvecs.89   Setup nSavepoint=3, release savepoint 1 => remaining nSavepoint=1, elements 1 and 2 destroyed. */90static void test_sqlite3PagerSavepoint_release_shrinks_and_destroys(void){91  Pager *p = allocMinimalPager();92  pagerInitSavepoints(p, 3);93 94  /* Prepare bitvecs that should be destroyed by the operation (indices 1 and 2) */95  p->aSavepoint[0].pInSavepoint = 0; /* remains, do not allocate to avoid freeing it */96  p->aSavepoint[1].pInSavepoint = sqlite3BitvecCreate(32);97  p->aSavepoint[2].pInSavepoint = sqlite3BitvecCreate(64);98 99  /* Mark truncate flag true but sjfd is closed, so truncation path is skipped safely */100  p->aSavepoint[1].bTruncateOnRelease = 1;101  p->aSavepoint[1].iSubRec = 7;102  p->aSavepoint[2].bTruncateOnRelease = 1;103  p->aSavepoint[2].iSubRec = 9;104 105  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_RELEASE, 1);106  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);107  TEST_ASSERT_EQUAL_INT(1, p->nSavepoint);108 109  /* We cannot directly verify that Bitvecs were freed without risking double-free,110     but reaching here without crash and correct nSavepoint indicates expected behavior. */111 112  /* Clean up: the remaining savepoint [0] has NULL Bitvec, safe to free array */113  sqlite3_free(p->aSavepoint);114  sqlite3_free(p);115}116 117/* Test: SAVEPOINT_ROLLBACK reduces nSavepoint to iSavepoint+1, and destroys later bitvecs.118   Setup nSavepoint=3, rollback to 1 => remaining nSavepoint=2, element 2 destroyed. */119static void test_sqlite3PagerSavepoint_rollback_shrinks_and_destroys(void){120  Pager *p = allocMinimalPager();121  pagerInitSavepoints(p, 3);122 123  /* Only index 2 will be destroyed; leave others NULL. */124  p->aSavepoint[2].pInSavepoint = sqlite3BitvecCreate(16);125 126  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_ROLLBACK, 1);127  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);128  TEST_ASSERT_EQUAL_INT(2, p->nSavepoint);129 130  sqlite3_free(p->aSavepoint);131  sqlite3_free(p);132}133 134/* Test: SAVEPOINT_ROLLBACK with negative iSavepoint "rolls back transaction":135   For iSavepoint=-1 and nSavepoint=2 => remaining nSavepoint=0; both are destroyed. */136static void test_sqlite3PagerSavepoint_rollback_negative_rolls_all(void){137  Pager *p = allocMinimalPager();138  pagerInitSavepoints(p, 2);139 140  /* Both entries expected to be destroyed */141  p->aSavepoint[0].pInSavepoint = sqlite3BitvecCreate(8);142  p->aSavepoint[1].pInSavepoint = sqlite3BitvecCreate(8);143 144  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_ROLLBACK, -1);145  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);146  TEST_ASSERT_EQUAL_INT(0, p->nSavepoint);147 148  sqlite3_free(p->aSavepoint);149  sqlite3_free(p);150}151 152/* Test: Error propagation if pPager->errCode is non-OK */153static void test_sqlite3PagerSavepoint_propagates_errcode(void){154  Pager *p = allocMinimalPager();155  pagerInitSavepoints(p, 3);156 157  /* Set a non-OK error state; function should return this and do nothing. */158  p->errCode = SQLITE_IOERR;159 160  int rc = sqlite3PagerSavepoint(p, SAVEPOINT_ROLLBACK, 1);161  TEST_ASSERT_EQUAL_INT(SQLITE_IOERR, rc);162  TEST_ASSERT_EQUAL_INT(3, p->nSavepoint);163 164  rc = sqlite3PagerSavepoint(p, SAVEPOINT_RELEASE, 0);165  TEST_ASSERT_EQUAL_INT(SQLITE_IOERR, rc);166  TEST_ASSERT_EQUAL_INT(3, p->nSavepoint);167 168  sqlite3_free(p->aSavepoint);169  sqlite3_free(p);170}171 172int main(void){173  UNITY_BEGIN();174 175  RUN_TEST(test_sqlite3PagerSavepoint_noop_when_index_out_of_range_release);176  RUN_TEST(test_sqlite3PagerSavepoint_noop_when_index_out_of_range_rollback);177  RUN_TEST(test_sqlite3PagerSavepoint_release_shrinks_and_destroys);178  RUN_TEST(test_sqlite3PagerSavepoint_rollback_shrinks_and_destroys);179  RUN_TEST(test_sqlite3PagerSavepoint_rollback_negative_rolls_all);180  RUN_TEST(test_sqlite3PagerSavepoint_propagates_errcode);181 182  return UNITY_END();183}