Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_pager_releaseAllSavepoints.c164 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper provided in the module for static function */7extern void test_releaseAllSavepoints(Pager *pPager);8 9/* Global flag to observe if xClose was called by sqlite3OsClose */10static int g_closeCalled = 0;11 12/* Minimal xClose implementation to observe closing behavior */13static int test_xClose(sqlite3_file *pFile){14  g_closeCalled++;15  if( pFile ){16    pFile->pMethods = 0; /* normal sqlite3OsClose will also clear this */17  }18  return SQLITE_OK;19}20 21/* sqlite3_io_methods used for our test sqlite3_file objects */22static sqlite3_io_methods g_TestIoMethods;23 24/* Helper: allocate an sqlite3_file and optionally attach our io_methods */25static sqlite3_file* makeTestFileWithMethods(int attachMethods){26  sqlite3_file *p = (sqlite3_file*)sqlite3_malloc(sizeof(sqlite3_file));27  TEST_ASSERT_NOT_NULL(p);28  memset(p, 0, sizeof(*p));29  if( attachMethods ){30    memset(&g_TestIoMethods, 0, sizeof(g_TestIoMethods));31    g_TestIoMethods.iVersion = 1;32    g_TestIoMethods.xClose = test_xClose;33    p->pMethods = &g_TestIoMethods;34  }else{35    p->pMethods = 0; /* Simulate in-memory journal or already-closed file */36  }37  return p;38}39 40/* Helper: initialize a Pager with nSave savepoints and valid Bitvecs */41static void initPagerWithSavepoints(Pager *pPager, int nSave){42  memset(pPager, 0, sizeof(*pPager));43  if( nSave>0 ){44    pPager->aSavepoint = (PagerSavepoint*)sqlite3_malloc(sizeof(PagerSavepoint)*nSave);45    TEST_ASSERT_NOT_NULL(pPager->aSavepoint);46    memset(pPager->aSavepoint, 0, sizeof(PagerSavepoint)*nSave);47    pPager->nSavepoint = nSave;48    for(int i=0; i<nSave; i++){49      pPager->aSavepoint[i].pInSavepoint = sqlite3BitvecCreate(128);50      TEST_ASSERT_NOT_NULL(pPager->aSavepoint[i].pInSavepoint);51    }52  }53  pPager->nSubRec = 123; /* some non-zero value to verify reset */54}55 56/* Unity required hooks */57void setUp(void) {58  g_closeCalled = 0;59}60void tearDown(void) {61  /* Nothing to teardown globally */62}63 64/* Test: Non-exclusive mode should close non-mem journal and reset all fields */65void test_releaseAllSavepoints_closes_nonmem_in_nonexclusive_and_resets(void){66  Pager p;67  initPagerWithSavepoints(&p, 3);68  p.exclusiveMode = 0; /* non-exclusive -> must close */69  p.sjfd = makeTestFileWithMethods(1); /* non-mem (custom methods) */70 71  test_releaseAllSavepoints(&p);72 73  /* Verify savepoints freed and counters reset */74  TEST_ASSERT_EQUAL_INT(0, p.nSavepoint);75  TEST_ASSERT_NULL(p.aSavepoint);76  TEST_ASSERT_EQUAL_INT(0, p.nSubRec);77 78  /* Verify the sub-journal was closed */79  TEST_ASSERT_EQUAL_INT(1, g_closeCalled);80  TEST_ASSERT_NOT_NULL(p.sjfd);81  TEST_ASSERT_NULL(p.sjfd->pMethods);82 83  /* Cleanup our allocated sqlite3_file container */84  sqlite3_free(p.sjfd);85}86 87/* Test: Exclusive mode should NOT close non-mem journal; still resets fields */88void test_releaseAllSavepoints_does_not_close_in_exclusive_with_nonmem(void){89  Pager p;90  initPagerWithSavepoints(&p, 2);91  p.exclusiveMode = 1; /* exclusive -> do not close unless in-memory */92  p.sjfd = makeTestFileWithMethods(1); /* non-mem (custom methods) */93 94  test_releaseAllSavepoints(&p);95 96  /* Verify savepoints freed and counters reset */97  TEST_ASSERT_EQUAL_INT(0, p.nSavepoint);98  TEST_ASSERT_NULL(p.aSavepoint);99  TEST_ASSERT_EQUAL_INT(0, p.nSubRec);100 101  /* Verify not closed */102  TEST_ASSERT_EQUAL_INT(0, g_closeCalled);103  TEST_ASSERT_NOT_NULL(p.sjfd);104  TEST_ASSERT_EQUAL_PTR(&g_TestIoMethods, p.sjfd->pMethods);105 106  /* Close and free our test file to clean up */107  sqlite3OsClose(p.sjfd); /* invokes our xClose */108  sqlite3_free(p.sjfd);109}110 111/* Test: Exclusive mode but in-memory journal -> function should attempt close; fields reset */112void test_releaseAllSavepoints_in_exclusive_with_inmemory_resets_and_safe_close(void){113  Pager p;114  initPagerWithSavepoints(&p, 1);115  p.exclusiveMode = 1; /* exclusive */116  p.sjfd = makeTestFileWithMethods(0); /* simulate in-memory/closed (pMethods==NULL) */117 118  test_releaseAllSavepoints(&p);119 120  /* Verify savepoints freed and counters reset */121  TEST_ASSERT_EQUAL_INT(0, p.nSavepoint);122  TEST_ASSERT_NULL(p.aSavepoint);123  TEST_ASSERT_EQUAL_INT(0, p.nSubRec);124 125  /* pMethods was NULL; sqlite3OsClose is a no-op in this case */126  TEST_ASSERT_EQUAL_INT(0, g_closeCalled);127  TEST_ASSERT_NOT_NULL(p.sjfd);128  TEST_ASSERT_NULL(p.sjfd->pMethods);129 130  sqlite3_free(p.sjfd);131}132 133/* Test: nSavepoint==0 but aSavepoint non-NULL is cleaned up and journal closed when allowed */134void test_releaseAllSavepoints_handles_zero_count_and_frees_array(void){135  Pager p;136  memset(&p, 0, sizeof(p));137  /* Create an array but set count to 0 */138  p.aSavepoint = (PagerSavepoint*)sqlite3_malloc(sizeof(PagerSavepoint));139  TEST_ASSERT_NOT_NULL(p.aSavepoint);140  memset(p.aSavepoint, 0, sizeof(PagerSavepoint));141  p.nSavepoint = 0;142  p.nSubRec = 7;143  p.exclusiveMode = 0; /* non-exclusive -> should close */144  p.sjfd = makeTestFileWithMethods(1);145 146  test_releaseAllSavepoints(&p);147 148  TEST_ASSERT_EQUAL_INT(0, p.nSavepoint);149  TEST_ASSERT_NULL(p.aSavepoint);150  TEST_ASSERT_EQUAL_INT(0, p.nSubRec);151  TEST_ASSERT_EQUAL_INT(1, g_closeCalled);152  TEST_ASSERT_NULL(p.sjfd->pMethods);153 154  sqlite3_free(p.sjfd);155}156 157int main(void) {158  UNITY_BEGIN();159  RUN_TEST(test_releaseAllSavepoints_closes_nonmem_in_nonexclusive_and_resets);160  RUN_TEST(test_releaseAllSavepoints_does_not_close_in_exclusive_with_nonmem);161  RUN_TEST(test_releaseAllSavepoints_in_exclusive_with_inmemory_resets_and_safe_close);162  RUN_TEST(test_releaseAllSavepoints_handles_zero_count_and_frees_array);163  return UNITY_END();164}