AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6/* Prototypes for the target and helper from memdb.c */7extern int sqlite3MemdbInit(void);8extern int sqlite3IsMemdb(const sqlite3_vfs *pVfs);9 10/* Helper: unregister all instances of the memdb VFS provided by this module */11static void unregister_all_memdb(void){12 /* If multiple memdb VFS objects are registered (due to multiple init calls),13 they appear at the head of the VFS list in reverse order of registration.14 Unregister until none of our memdb VFS remain. */15 for(;;){16 sqlite3_vfs *v = sqlite3_vfs_find("memdb");17 if( v==NULL ) break;18 if( !sqlite3IsMemdb(v) ){19 /* A different VFS named "memdb" that is not our target; leave it alone. */20 break;21 }22 sqlite3_vfs_unregister(v);23 }24}25 26void setUp(void) {27 /* Ensure SQLite is initialized and any previous memdb registrations28 from this module are unregistered for a clean slate. */29 sqlite3_initialize();30 unregister_all_memdb();31}32 33void tearDown(void) {34 /* Clean up any memdb registrations that may remain after a test. */35 unregister_all_memdb();36}37 38/* Test that sqlite3MemdbInit registers a "memdb" VFS with expected properties. */39void test_sqlite3MemdbInit_registers_vfs_basic_properties(void){40 /* Precondition: no memdb VFS from this module is registered */41 sqlite3_vfs *pre = sqlite3_vfs_find("memdb");42 if( pre ){43 /* It must not be ours, as setUp unregistered ours. */44 TEST_ASSERT_FALSE_MESSAGE(sqlite3IsMemdb(pre), "Unexpected pre-existing memdb VFS from this module");45 }46 47 sqlite3_vfs *lower = sqlite3_vfs_find(0);48 TEST_ASSERT_NOT_NULL_MESSAGE(lower, "Default VFS not found");49 50 int rc = sqlite3MemdbInit();51 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3MemdbInit should return SQLITE_OK");52 53 sqlite3_vfs *memvfs = sqlite3_vfs_find("memdb");54 TEST_ASSERT_NOT_NULL_MESSAGE(memvfs, "memdb VFS should be registered");55 TEST_ASSERT_TRUE_MESSAGE(sqlite3IsMemdb(memvfs), "Registered VFS should be recognized by sqlite3IsMemdb");56 TEST_ASSERT_NOT_NULL_MESSAGE(memvfs->zName, "VFS name must not be NULL");57 TEST_ASSERT_EQUAL_STRING("memdb", memvfs->zName);58 59 /* Should not become the default VFS */60 TEST_ASSERT_EQUAL_PTR_MESSAGE(lower, sqlite3_vfs_find(0), "Default VFS should remain unchanged");61 62 /* pAppData should hold the lower/default VFS pointer */63 TEST_ASSERT_NOT_NULL_MESSAGE(memvfs->pAppData, "memdb VFS pAppData should point to lower VFS");64 TEST_ASSERT_EQUAL_PTR_MESSAGE(lower, memvfs->pAppData, "memdb VFS pAppData should equal default VFS");65 66 /* szOsFile should be at least the lower VFS szOsFile */67 TEST_ASSERT_TRUE_MESSAGE(memvfs->szOsFile >= lower->szOsFile,68 "memdb VFS szOsFile should be >= lower VFS szOsFile");69 70 /* Cleanup */71 sqlite3_vfs_unregister(memvfs);72}73 74/* Test that calling sqlite3MemdbInit multiple times succeeds and leaves valid VFS */75void test_sqlite3MemdbInit_is_idempotent_registration(void){76 int rc1 = sqlite3MemdbInit();77 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc1);78 sqlite3_vfs *v1 = sqlite3_vfs_find("memdb");79 TEST_ASSERT_NOT_NULL(v1);80 TEST_ASSERT_TRUE(sqlite3IsMemdb(v1));81 82 int rc2 = sqlite3MemdbInit();83 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc2);84 sqlite3_vfs *v2 = sqlite3_vfs_find("memdb");85 TEST_ASSERT_NOT_NULL(v2);86 TEST_ASSERT_TRUE(sqlite3IsMemdb(v2));87 88 /* Unregister the most recent memdb VFS, then ensure an earlier one (if any) is present and valid. */89 sqlite3_vfs_unregister(v2);90 sqlite3_vfs *v3 = sqlite3_vfs_find("memdb");91 if( v3 ){92 TEST_ASSERT_TRUE(sqlite3IsMemdb(v3));93 sqlite3_vfs_unregister(v3);94 }95 96 /* After unregistering all of ours, there should be no memdb VFS from this module. */97 sqlite3_vfs *v_final = sqlite3_vfs_find("memdb");98 if( v_final ){99 TEST_ASSERT_FALSE_MESSAGE(sqlite3IsMemdb(v_final),100 "All memdb VFS instances from this module should be unregistered");101 }102}103 104/* Test that the registered memdb VFS can be used to open and operate on a database. */105void test_sqlite3MemdbInit_can_open_db_with_memdb_vfs(void){106 int rc = sqlite3MemdbInit();107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 sqlite3_vfs *memvfs = sqlite3_vfs_find("memdb");109 TEST_ASSERT_NOT_NULL(memvfs);110 TEST_ASSERT_TRUE(sqlite3IsMemdb(memvfs));111 112 sqlite3 *db = NULL;113 rc = sqlite3_open_v2("unit_memdb_test",114 &db,115 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,116 "memdb");117 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3_open_v2 with memdb VFS should succeed");118 TEST_ASSERT_NOT_NULL(db);119 120 char *err = NULL;121 rc = sqlite3_exec(db, "CREATE TABLE t(x); INSERT INTO t VALUES(1);", 0, 0, &err);122 if( rc!=SQLITE_OK ){123 if( err ){124 /* Ensure any error message is freed to avoid leaks in test */125 sqlite3_free(err);126 }127 }128 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "DDL/INSERT using memdb VFS should succeed");129 130 sqlite3_stmt *stmt = NULL;131 rc = sqlite3_prepare_v2(db, "SELECT count(*) FROM t;", -1, &stmt, NULL);132 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);133 rc = sqlite3_step(stmt);134 TEST_ASSERT_EQUAL_INT(SQLITE_ROW, rc);135 int cnt = sqlite3_column_int(stmt, 0);136 TEST_ASSERT_EQUAL_INT(1, cnt);137 rc = sqlite3_finalize(stmt);138 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);139 140 rc = sqlite3_close(db);141 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);142 143 sqlite3_vfs_unregister(memvfs);144}145 146int main(void) {147 UNITY_BEGIN();148 RUN_TEST(test_sqlite3MemdbInit_registers_vfs_basic_properties);149 RUN_TEST(test_sqlite3MemdbInit_is_idempotent_registration);150 RUN_TEST(test_sqlite3MemdbInit_can_open_db_with_memdb_vfs);151 return UNITY_END();152}