Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_memdb_memdbWrite.c195 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6extern int sqlite3MemdbInit(void);7extern int test_memdbWrite(sqlite3_file *pFile, const void *z, int iAmt, sqlite_int64 iOfst);8 9static sqlite3_file* open_memdb_file(const char *zName, void **ppBuf){10  int rc;11  sqlite3_vfs *pVfs;12  sqlite3_file *pFile = 0;13  int outFlags = 0;14 15  /* Ensure memdb VFS is registered */16  rc = sqlite3MemdbInit();17  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);18 19  pVfs = sqlite3_vfs_find("memdb");20  TEST_ASSERT_NOT_NULL(pVfs);21 22  *ppBuf = sqlite3_malloc64(pVfs->szOsFile);23  TEST_ASSERT_NOT_NULL(*ppBuf);24  memset(*ppBuf, 0, pVfs->szOsFile);25 26  pFile = (sqlite3_file*)(*ppBuf);27  rc = pVfs->xOpen(pVfs, zName, pFile,28                   SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,29                   &outFlags);30  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);31  TEST_ASSERT_NOT_NULL(pFile->pMethods);32  return pFile;33}34 35static void close_memdb_file(sqlite3_file *pFile, void *pBuf){36  int rc = pFile->pMethods->xClose(pFile);37  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);38  sqlite3_free(pBuf);39}40 41void setUp(void) {42  /* No-op */43}44void tearDown(void) {45  /* No-op */46}47 48/* Test 1: Zero-length write is a no-op and returns SQLITE_OK, size remains 0 */49void test_memdbWrite_zero_length_noop(void) {50  void *pBuf = NULL;51  sqlite3_file *pFile = open_memdb_file("/t_zero", &pBuf);52 53  int rc = test_memdbWrite(pFile, "", 0, 0);54  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);55 56  sqlite3_int64 sz = -1;57  rc = pFile->pMethods->xFileSize(pFile, &sz);58  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);59  TEST_ASSERT_EQUAL_INT64(0, sz);60 61  close_memdb_file(pFile, pBuf);62}63 64/* Test 2: Basic write and read-back */65void test_memdbWrite_basic_write_and_readback(void) {66  void *pBuf = NULL;67  sqlite3_file *pFile = open_memdb_file("/t_basic", &pBuf);68 69  const char *data = "hello";70  int len = (int)strlen(data);71 72  int rc = test_memdbWrite(pFile, data, len, 0);73  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);74 75  sqlite3_int64 sz = -1;76  rc = pFile->pMethods->xFileSize(pFile, &sz);77  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78  TEST_ASSERT_EQUAL_INT(len, (int)sz);79 80  char buf[16];81  memset(buf, 0xAA, sizeof(buf));82  rc = pFile->pMethods->xRead(pFile, buf, len, 0);83  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);84  TEST_ASSERT_EQUAL_INT(0, memcmp(buf, data, len));85 86  close_memdb_file(pFile, pBuf);87}88 89/* Test 3: Write with a gap should zero-fill the gap */90void test_memdbWrite_gap_zero_fill(void) {91  void *pBuf = NULL;92  sqlite3_file *pFile = open_memdb_file("/t_gap", &pBuf);93 94  const char *data = "abc";95  int len = (int)strlen(data);96  sqlite3_int64 ofst = 10;97 98  int rc = test_memdbWrite(pFile, data, len, ofst);99  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);100 101  sqlite3_int64 sz = -1;102  rc = pFile->pMethods->xFileSize(pFile, &sz);103  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);104  TEST_ASSERT_EQUAL_INT64(ofst + len, sz);105 106  unsigned char buf[32];107  memset(buf, 0xFF, sizeof(buf));108  rc = pFile->pMethods->xRead(pFile, buf, (int)(ofst + len), 0);109  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);110 111  /* First 'ofst' bytes should be zero */112  for (int i = 0; i < (int)ofst; i++){113    TEST_ASSERT_EQUAL_UINT8(0, buf[i]);114  }115  /* Then the data */116  TEST_ASSERT_EQUAL_INT(0, memcmp(buf + ofst, data, len));117 118  close_memdb_file(pFile, pBuf);119}120 121/* Test 4: Respect SQLITE_FCNTL_SIZE_LIMIT (writing beyond should return SQLITE_FULL) */122void test_memdbWrite_respects_size_limit(void) {123  void *pBuf = NULL;124  sqlite3_file *pFile = open_memdb_file("/t_limit", &pBuf);125 126  sqlite3_int64 limit = 8;127  int rc = pFile->pMethods->xFileControl(pFile, SQLITE_FCNTL_SIZE_LIMIT, &limit);128  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);129  TEST_ASSERT_EQUAL_INT64(8, limit);130 131  unsigned char big[32];132  for (int i = 0; i < (int)sizeof(big); i++) big[i] = (unsigned char)i;133 134  rc = test_memdbWrite(pFile, big, 16, 0);135  TEST_ASSERT_EQUAL_INT(SQLITE_FULL, rc);136 137  /* Size should remain 0 */138  sqlite3_int64 sz = -1;139  rc = pFile->pMethods->xFileSize(pFile, &sz);140  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);141  TEST_ASSERT_EQUAL_INT64(0, sz);142 143  close_memdb_file(pFile, pBuf);144}145 146/* Test 5: READONLY flag leads to SQLITE_IOERR_WRITE */147void test_memdbWrite_readonly_returns_error(void) {148  int rc;149  sqlite3 *db = NULL;150 151  /* Ensure memdb VFS is registered so we can open DB on it */152  rc = sqlite3MemdbInit();153  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);154 155  rc = sqlite3_open_v2("file:ro_test?vfs=memdb", &db,156                       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, 0);157  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);158  TEST_ASSERT_NOT_NULL(db);159 160  /* Prepare a small buffer and deserialize as READONLY */161  int sz = 16;162  unsigned char *pData = (unsigned char*)sqlite3_malloc64(sz);163  TEST_ASSERT_NOT_NULL(pData);164  for (int i = 0; i < sz; i++) pData[i] = (unsigned char)(0xA0 + i);165 166  rc = sqlite3_deserialize(db, "main", pData, sz, sz, SQLITE_DESERIALIZE_READONLY);167  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);168 169  /* Get the underlying file pointer */170  sqlite3_file *pFile = NULL;171  rc = sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &pFile);172  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);173  TEST_ASSERT_NOT_NULL(pFile);174 175  /* Attempt to write should return SQLITE_IOERR_WRITE */176  const char c = 'X';177  int wrc = test_memdbWrite(pFile, &c, 1, 0);178  TEST_ASSERT_EQUAL_INT(SQLITE_IOERR_WRITE, wrc);179 180  rc = sqlite3_close(db);181  TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);182 183  /* Since we used SQLITE_DESERIALIZE_READONLY (no FREEONCLOSE), we own the buffer */184  sqlite3_free(pData);185}186 187int main(void) {188  UNITY_BEGIN();189  RUN_TEST(test_memdbWrite_zero_length_noop);190  RUN_TEST(test_memdbWrite_basic_write_and_readback);191  RUN_TEST(test_memdbWrite_gap_zero_fill);192  RUN_TEST(test_memdbWrite_respects_size_limit);193  RUN_TEST(test_memdbWrite_readonly_returns_error);194  return UNITY_END();195}