AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5#include <stdio.h>6 7/* The wrapper added in memdb.c for the static function under test */8int test_memdbFileControl(sqlite3_file *pFile, int op, void *pArg);9 10static int g_initialized = 0;11 12static void ensure_memdb_vfs_initialized(void){13 if( !g_initialized ){14 int rc = sqlite3_initialize();15 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);16 /* Register memdb VFS */17 rc = sqlite3MemdbInit();18 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);19 /* Ensure there is enough headroom for allocations in tests */20 sqlite3GlobalConfig.mxMemdbSize = 1024*1024; /* 1MB */21 g_initialized = 1;22 }23}24 25static sqlite3_file* open_memdb_file(const char *zName){26 sqlite3_vfs *pVfs = sqlite3_vfs_find("memdb");27 TEST_ASSERT_NOT_NULL(pVfs);28 sqlite3_file *pFile = (sqlite3_file*)sqlite3_malloc64(pVfs->szOsFile);29 TEST_ASSERT_NOT_NULL(pFile);30 memset(pFile, 0, pVfs->szOsFile);31 int outFlags = 0;32 int flags = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_MEMORY;33 int rc = pVfs->xOpen(pVfs, zName, pFile, flags, &outFlags);34 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);35 TEST_ASSERT_NOT_NULL(pFile->pMethods);36 return pFile;37}38 39static void close_memdb_file(sqlite3_file *pFile){40 int rc = pFile->pMethods->xClose(pFile);41 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);42 sqlite3_free(pFile);43}44 45static sqlite3_int64 parse_size_from_vfsname(const char *z){46 /* Format: "memdb(%p,%lld)". Extract the integer after the last comma. */47 const char *comma = strrchr(z, ',');48 const char *paren = strrchr(z, ')');49 if( !comma || !paren || paren <= comma ) return -1;50 size_t n = (size_t)(paren - (comma + 1));51 char buf[64];52 if( n >= sizeof(buf) ) n = sizeof(buf) - 1;53 memcpy(buf, comma + 1, n);54 buf[n] = '\0';55 return (sqlite3_int64)strtoll(buf, NULL, 10);56}57 58void setUp(void) {59 ensure_memdb_vfs_initialized();60}61 62void tearDown(void) {63 /* No per-test teardown necessary */64}65 66void test_memdbFileControl_VFSNAME_initial(void){67 sqlite3_file *pFile = open_memdb_file("/t-vfsname-initial");68 69 char *zOut = NULL;70 int rc = test_memdbFileControl(pFile, SQLITE_FCNTL_VFSNAME, &zOut);71 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);72 TEST_ASSERT_NOT_NULL(zOut);73 TEST_ASSERT_TRUE(strncmp(zOut, "memdb(", 6) == 0);74 TEST_ASSERT_TRUE(zOut[strlen(zOut)-1] == ')');75 sqlite3_int64 sz = parse_size_from_vfsname(zOut);76 TEST_ASSERT_EQUAL_INT64(0, sz);77 sqlite3_free(zOut);78 79 close_memdb_file(pFile);80}81 82void test_memdbFileControl_VFSNAME_after_write(void){83 sqlite3_file *pFile = open_memdb_file("/t-vfsname-after-write");84 85 /* Write 1000 bytes at offset 0 to increase file size */86 int amt = 1000;87 void *buf = sqlite3_malloc(amt);88 TEST_ASSERT_NOT_NULL(buf);89 memset(buf, 0xAB, amt);90 int rcW = pFile->pMethods->xWrite(pFile, buf, amt, 0);91 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcW);92 sqlite3_free(buf);93 94 char *zOut = NULL;95 int rc = test_memdbFileControl(pFile, SQLITE_FCNTL_VFSNAME, &zOut);96 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);97 TEST_ASSERT_NOT_NULL(zOut);98 sqlite3_int64 sz = parse_size_from_vfsname(zOut);99 TEST_ASSERT_EQUAL_INT64((sqlite3_int64)amt, sz);100 sqlite3_free(zOut);101 102 close_memdb_file(pFile);103}104 105void test_memdbFileControl_SIZE_LIMIT_set_and_get(void){106 sqlite3_file *pFile = open_memdb_file("/t-szlimit-setget");107 108 /* Set limit to 4096 */109 sqlite3_int64 limit = 4096;110 int rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &limit);111 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);112 TEST_ASSERT_EQUAL_INT64(4096, limit);113 114 /* Query current limit with -1 (should return current szMax) */115 sqlite3_int64 query = -1;116 rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &query);117 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);118 TEST_ASSERT_EQUAL_INT64(4096, query);119 120 close_memdb_file(pFile);121}122 123void test_memdbFileControl_SIZE_LIMIT_lower_than_current_size_is_clamped(void){124 sqlite3_file *pFile = open_memdb_file("/t-szlimit-clamp");125 126 /* Grow file to 2000 bytes */127 int amt = 2000;128 void *buf = sqlite3_malloc(amt);129 TEST_ASSERT_NOT_NULL(buf);130 memset(buf, 0xCD, amt);131 int rcW = pFile->pMethods->xWrite(pFile, buf, amt, 0);132 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcW);133 sqlite3_free(buf);134 135 /* Attempt to set size limit to 100, which is < current size (2000). */136 sqlite3_int64 limit = 100;137 int rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &limit);138 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);139 /* Expect it to clamp to current size (2000) and return that */140 TEST_ASSERT_EQUAL_INT64(2000, limit);141 142 /* Verify current limit with -1 also reports 2000 */143 sqlite3_int64 query = -1;144 rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &query);145 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);146 TEST_ASSERT_EQUAL_INT64(2000, query);147 148 close_memdb_file(pFile);149}150 151void test_memdbFileControl_SIZE_LIMIT_query_after_update(void){152 sqlite3_file *pFile = open_memdb_file("/t-szlimit-query");153 154 /* Set to known value */155 sqlite3_int64 limit = 12345;156 int rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &limit);157 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);158 TEST_ASSERT_EQUAL_INT64(12345, limit);159 160 /* Query with -1 should return the same value */161 sqlite3_int64 query = -1;162 rc = test_memdbFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &query);163 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);164 TEST_ASSERT_EQUAL_INT64(12345, query);165 166 close_memdb_file(pFile);167}168 169void test_memdbFileControl_unknown_op_returns_notfound(void){170 sqlite3_file *pFile = open_memdb_file("/t-unknown-op");171 172 int bogusOp = 999999;173 int dummy = 0;174 int rc = test_memdbFileControl(pFile, bogusOp, &dummy);175 TEST_ASSERT_EQUAL_INT(SQLITE_NOTFOUND, rc);176 177 close_memdb_file(pFile);178}179 180int main(void){181 UNITY_BEGIN();182 RUN_TEST(test_memdbFileControl_VFSNAME_initial);183 RUN_TEST(test_memdbFileControl_VFSNAME_after_write);184 RUN_TEST(test_memdbFileControl_SIZE_LIMIT_set_and_get);185 RUN_TEST(test_memdbFileControl_SIZE_LIMIT_lower_than_current_size_is_clamped);186 RUN_TEST(test_memdbFileControl_SIZE_LIMIT_query_after_update);187 RUN_TEST(test_memdbFileControl_unknown_op_returns_notfound);188 return UNITY_END();189}