AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Wrapper for the static function under test (provided in module) */7extern void test_setGetterMethod(Pager *pPager);8 9static Pager* alloc_zeroed_pager(void){10 Pager *p = (Pager*)sqlite3_malloc(sizeof(Pager));11 TEST_ASSERT_NOT_NULL_MESSAGE(p, "Failed to allocate Pager");12 memset(p, 0, sizeof(Pager));13 return p;14}15 16static void attach_fd_with_methods(Pager *pPager, int iVersion){17 /* Allocate a minimal sqlite3_file and sqlite3_io_methods */18 sqlite3_file *pFd = (sqlite3_file*)sqlite3_malloc(sizeof(*pFd));19 TEST_ASSERT_NOT_NULL_MESSAGE(pFd, "Failed to allocate sqlite3_file");20 memset(pFd, 0, sizeof(*pFd));21 22 sqlite3_io_methods *pMethods = (sqlite3_io_methods*)sqlite3_malloc(sizeof(*pMethods));23 TEST_ASSERT_NOT_NULL_MESSAGE(pMethods, "Failed to allocate sqlite3_io_methods");24 memset(pMethods, 0, sizeof(*pMethods));25 pMethods->iVersion = iVersion;26 27 pFd->pMethods = pMethods;28 pPager->fd = pFd;29}30 31static void free_fd_with_methods(Pager *pPager){32 if( pPager && pPager->fd ){33 sqlite3_io_methods *pMethods = (sqlite3_io_methods*)pPager->fd->pMethods;34 if( pMethods ) sqlite3_free(pMethods);35 sqlite3_free(pPager->fd);36 pPager->fd = 0;37 }38}39 40void setUp(void) {41 /* no-op */42}43 44void tearDown(void) {45 /* no-op */46}47 48/* Test: Non-zero errCode should select the "error" getter (non-NULL and stable) */49void test_setGetterMethod_errcode_selects_error(void){50 Pager *pPager = alloc_zeroed_pager();51 52 pPager->errCode = SQLITE_IOERR; /* any non-zero error */53 /* Initially NULL xGet; after call it should be non-NULL. */54 TEST_ASSERT_NULL(pPager->xGet);55 test_setGetterMethod(pPager);56 TEST_ASSERT_NOT_NULL(pPager->xGet);57 void *errPtr = (void*)pPager->xGet;58 59 /* Calling again without changing state should not change the getter */60 test_setGetterMethod(pPager);61 TEST_ASSERT_EQUAL_PTR(errPtr, (void*)pPager->xGet);62 63 sqlite3_free(pPager);64}65 66/* Test: With errCode==0 and USEFETCH disabled, select the "normal" getter.67 Switching errCode to non-zero should select a different "error" getter,68 and clearing errCode should revert to the original normal getter. */69void test_setGetterMethod_normal_selects_normal(void){70 Pager *pPager = alloc_zeroed_pager();71 72 /* Prepare a safe environment even if USEFETCH macro inspects fd/pMethods. */73 attach_fd_with_methods(pPager, 1); /* iVersion < 3 ensures USEFETCH may be false if it uses iVersion>=3 */74 75 pPager->errCode = 0;76#if SQLITE_MAX_MMAP_SIZE>077 pPager->bUseFetch = 0; /* explicitly disable fetching */78#endif79 80 /* First call sets normal getter */81 test_setGetterMethod(pPager);82 TEST_ASSERT_NOT_NULL(pPager->xGet);83 void *normalPtr = (void*)pPager->xGet;84 85 /* Idempotent under same conditions */86 test_setGetterMethod(pPager);87 TEST_ASSERT_EQUAL_PTR(normalPtr, (void*)pPager->xGet);88 89 /* Now force error path */90 pPager->errCode = SQLITE_FULL;91 test_setGetterMethod(pPager);92 TEST_ASSERT_NOT_NULL(pPager->xGet);93 void *errorPtr = (void*)pPager->xGet;94 TEST_ASSERT_NOT_EQUAL_PTR(normalPtr, errorPtr);95 96 /* Clear error, should revert to normal getter */97 pPager->errCode = 0;98 test_setGetterMethod(pPager);99 TEST_ASSERT_EQUAL_PTR(normalPtr, (void*)pPager->xGet);100 101 free_fd_with_methods(pPager);102 sqlite3_free(pPager);103}104 105#if SQLITE_MAX_MMAP_SIZE>0106/* Test: With USEFETCH enabled (bUseFetch=1 and iVersion>=3), select "mmap" getter.107 Toggling USEFETCH off selects normal getter. Any non-zero errCode selects108 the error getter, and clearing the error restores mmap getter. */109void test_setGetterMethod_usefetch_selects_mmap(void){110 Pager *pPager = alloc_zeroed_pager();111 112 /* Prepare fd with iVersion>=3 so USEFETCH can be true */113 attach_fd_with_methods(pPager, 3);114 115 /* Enable memory-mapped fetch */116 pPager->errCode = 0;117 pPager->bUseFetch = 1;118 119 test_setGetterMethod(pPager);120 TEST_ASSERT_NOT_NULL(pPager->xGet);121 void *mmapPtr = (void*)pPager->xGet;122 123 /* Turning USEFETCH off should select a different (normal) getter */124 pPager->bUseFetch = 0;125 test_setGetterMethod(pPager);126 TEST_ASSERT_NOT_NULL(pPager->xGet);127 void *normalPtr = (void*)pPager->xGet;128 TEST_ASSERT_NOT_EQUAL_PTR(mmapPtr, normalPtr);129 130 /* Error overrides everything and should select a distinct error getter */131 pPager->bUseFetch = 1; /* enable again */132 pPager->errCode = SQLITE_CORRUPT;133 test_setGetterMethod(pPager);134 TEST_ASSERT_NOT_NULL(pPager->xGet);135 void *errorPtr = (void*)pPager->xGet;136 TEST_ASSERT_NOT_EQUAL_PTR(errorPtr, normalPtr);137 TEST_ASSERT_NOT_EQUAL_PTR(errorPtr, mmapPtr);138 139 /* Clear error; with USEFETCH still enabled, should revert to mmap getter */140 pPager->errCode = 0;141 test_setGetterMethod(pPager);142 TEST_ASSERT_EQUAL_PTR(mmapPtr, (void*)pPager->xGet);143 144 free_fd_with_methods(pPager);145 sqlite3_free(pPager);146}147#endif148 149int main(void){150 UNITY_BEGIN();151 RUN_TEST(test_setGetterMethod_errcode_selects_error);152 RUN_TEST(test_setGetterMethod_normal_selects_normal);153#if SQLITE_MAX_MMAP_SIZE>0154 RUN_TEST(test_setGetterMethod_usefetch_selects_mmap);155#endif156 return UNITY_END();157}