AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Globals to control and observe fake xOpen behavior */7static int g_xOpen_rc = SQLITE_OK;8static int g_xOpen_last_flags = 0;9static const char *g_xOpen_last_zPath = (const char*)0xFFFFFFFF;10static sqlite3_vfs *g_xOpen_last_pVfs = (sqlite3_vfs*)0xFFFFFFFF;11static int g_xOpen_last_pOutFlags_was_null = 0;12static int g_xOpen_value_for_pOutFlags = 0x12345678;13 14/* Dummy io_methods to mark a file as "opened" */15static sqlite3_io_methods g_dummyIoMethods;16 17/* Fake xOpen implementation used by our test VFS */18static int testVfs_xOpen(19 sqlite3_vfs *pVfs,20 const char *zPath,21 sqlite3_file *pFile,22 int flags,23 int *pOutFlags24){25 g_xOpen_last_pVfs = pVfs;26 g_xOpen_last_zPath = zPath;27 g_xOpen_last_flags = flags;28 g_xOpen_last_pOutFlags_was_null = (pOutFlags==0);29 30 if( pOutFlags ){31 *pOutFlags = g_xOpen_value_for_pOutFlags;32 }33 34 if( g_xOpen_rc==SQLITE_OK ){35 pFile->pMethods = &g_dummyIoMethods;36 }else{37 pFile->pMethods = 0;38 }39 return g_xOpen_rc;40}41 42/* Helper to build a minimal VFS with our test xOpen */43static void initTestVfs(sqlite3_vfs *pVfs){44 memset(pVfs, 0, sizeof(*pVfs));45 pVfs->iVersion = 3;46 pVfs->szOsFile = (int)sizeof(sqlite3_file);47 pVfs->mxPathname = 255;48 pVfs->zName = "testvfs";49 pVfs->xOpen = testVfs_xOpen;50}51 52/* Unity fixtures */53void setUp(void) {54 memset(&g_dummyIoMethods, 0, sizeof(g_dummyIoMethods));55 g_dummyIoMethods.iVersion = 1;56 57 g_xOpen_rc = SQLITE_OK;58 g_xOpen_last_flags = 0;59 g_xOpen_last_zPath = (const char*)0xFFFFFFFF;60 g_xOpen_last_pVfs = (sqlite3_vfs*)0xFFFFFFFF;61 g_xOpen_last_pOutFlags_was_null = 0;62 g_xOpen_value_for_pOutFlags = 0x12345678;63}64 65void tearDown(void) {66 /* Nothing to clean up */67}68 69/* Tests */70 71void test_sqlite3OsOpen_masks_flags_and_passes_arguments(void){72 sqlite3_vfs vfs;73 sqlite3_file fileObj;74 int rc;75 int outFlags = 0;76 const char *path = "test.db";77 78 initTestVfs(&vfs);79 memset(&fileObj, 0, sizeof(fileObj));80 81 /* Include flags that should be masked out (FULLMUTEX, SHAREDCACHE)82 and flags that should pass through (READWRITE, CREATE, MAIN_JOURNAL) */83 int originalFlags = SQLITE_OPEN_READWRITE84 | SQLITE_OPEN_CREATE85 | SQLITE_OPEN_FULLMUTEX86 | SQLITE_OPEN_SHAREDCACHE87 | SQLITE_OPEN_MAIN_JOURNAL;88 89 rc = sqlite3OsOpen(&vfs, path, &fileObj, originalFlags, &outFlags);90 91 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);92 TEST_ASSERT_EQUAL_PTR(&vfs, g_xOpen_last_pVfs);93 TEST_ASSERT_EQUAL_PTR(path, g_xOpen_last_zPath);94 95 /* Verify mask used by sqlite3OsOpen */96 int expectedMasked = (originalFlags & 0x1087f7f);97 TEST_ASSERT_EQUAL_INT(expectedMasked, g_xOpen_last_flags);98 99 /* Verify that pOutFlags data written by xOpen is visible to caller */100 TEST_ASSERT_EQUAL_INT(g_xOpen_value_for_pOutFlags, outFlags);101 102 /* On success, pMethods must be non-NULL */103 TEST_ASSERT_NOT_NULL(fileObj.pMethods);104}105 106void test_sqlite3OsOpen_error_propagates_and_pMethods_null(void){107 sqlite3_vfs vfs;108 sqlite3_file fileObj;109 int rc;110 int outFlags = 0;111 const char *path = "err.db";112 113 initTestVfs(&vfs);114 memset(&fileObj, 0, sizeof(fileObj));115 116 g_xOpen_rc = SQLITE_IOERR; /* Force error from our fake xOpen */117 118 int flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB;119 120 rc = sqlite3OsOpen(&vfs, path, &fileObj, flags, &outFlags);121 122 TEST_ASSERT_EQUAL_INT(SQLITE_IOERR, rc);123 /* On error, the assert in sqlite3OsOpen requires pMethods==NULL */124 TEST_ASSERT_NULL(fileObj.pMethods);125}126 127void test_sqlite3OsOpen_allows_null_path_with_exclusive_flag(void){128 sqlite3_vfs vfs;129 sqlite3_file fileObj;130 int rc;131 int outFlags = 0;132 133 initTestVfs(&vfs);134 memset(&fileObj, 0, sizeof(fileObj));135 136 /* zPath may be NULL if SQLITE_OPEN_EXCLUSIVE is present */137 int flags = SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_READWRITE;138 139 rc = sqlite3OsOpen(&vfs, NULL, &fileObj, flags, &outFlags);140 141 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);142 TEST_ASSERT_NULL(g_xOpen_last_zPath);143 144 int expectedMasked = (flags & 0x1087f7f);145 TEST_ASSERT_EQUAL_INT(expectedMasked, g_xOpen_last_flags);146 147 TEST_ASSERT_NOT_NULL(fileObj.pMethods);148}149 150void test_sqlite3OsOpen_with_zero_flags_masks_to_zero(void){151 sqlite3_vfs vfs;152 sqlite3_file fileObj;153 int rc;154 int outFlags = 0;155 const char *path = "zero.db";156 157 initTestVfs(&vfs);158 memset(&fileObj, 0, sizeof(fileObj));159 160 int flags = 0;161 162 rc = sqlite3OsOpen(&vfs, path, &fileObj, flags, &outFlags);163 164 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);165 TEST_ASSERT_EQUAL_INT(0, g_xOpen_last_flags);166 TEST_ASSERT_NOT_NULL(fileObj.pMethods);167}168 169void test_sqlite3OsOpen_handles_null_pFlagsOut(void){170 sqlite3_vfs vfs;171 sqlite3_file fileObj;172 int rc;173 const char *path = "noflagsout.db";174 175 initTestVfs(&vfs);176 memset(&fileObj, 0, sizeof(fileObj));177 178 g_xOpen_last_pOutFlags_was_null = 0;179 180 int flags = SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB;181 182 rc = sqlite3OsOpen(&vfs, path, &fileObj, flags, NULL);183 184 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);185 TEST_ASSERT_EQUAL_INT(1, g_xOpen_last_pOutFlags_was_null);186 TEST_ASSERT_NOT_NULL(fileObj.pMethods);187}188 189/* Unity main */190int main(void) {191 UNITY_BEGIN();192 193 RUN_TEST(test_sqlite3OsOpen_masks_flags_and_passes_arguments);194 RUN_TEST(test_sqlite3OsOpen_error_propagates_and_pMethods_null);195 RUN_TEST(test_sqlite3OsOpen_allows_null_path_with_exclusive_flag);196 RUN_TEST(test_sqlite3OsOpen_with_zero_flags_masks_to_zero);197 RUN_TEST(test_sqlite3OsOpen_handles_null_pFlagsOut);198 199 return UNITY_END();200}