AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <stdlib.h>6#include <string.h>7 8/* Some compilers warn on tmpnam; for unit tests it's acceptable. */9static void makeFileWithData(const char *path, const unsigned char *data, int len){10 FILE *f = fopen(path, "wb");11 TEST_ASSERT_NOT_NULL_MESSAGE(f, "Failed to open temp file for writing");12 if( len>0 && data!=NULL ){13 size_t nw = fwrite(data, 1, (size_t)len, f);14 TEST_ASSERT_EQUAL_size_t((size_t)len, nw);15 }16 fclose(f);17}18 19static void deleteFileIfExists(const char *path){20 if( path && path[0] ){21 remove(path); /* ignore errors */22 }23}24 25/* Create a unique temporary filename in the current directory. */26static void makeTempFilename(char *zOut, size_t nOut){27 TEST_ASSERT_TRUE(nOut > 0);28 /* Use tmpnam to generate a name, then ensure it ends with .db for clarity. */29 char tmpbuf[L_tmpnam];30 char *z = tmpnam(tmpbuf);31 TEST_ASSERT_NOT_NULL_MESSAGE(z, "tmpnam failed");32 /* Copy to output buffer */33 snprintf(zOut, nOut, "%s.db", z);34}35 36static Pager* openPagerOnFile(const char *zFilename){37 sqlite3_vfs *pVfs = sqlite3_vfs_find(0);38 TEST_ASSERT_NOT_NULL_MESSAGE(pVfs, "sqlite3_vfs_find returned NULL");39 Pager *pPager = 0;40 int rc = sqlite3PagerOpen(41 pVfs,42 &pPager,43 zFilename,44 0, /* nExtra */45 0, /* pager flags */46 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,47 0 /* xReinit */48 );49 TEST_ASSERT_EQUAL_INT_MESSAGE(SQLITE_OK, rc, "sqlite3PagerOpen failed");50 TEST_ASSERT_NOT_NULL(pPager);51 return pPager;52}53 54static void closePagerAndCleanup(Pager *pPager, const char *zFilename){55 if( pPager ){56 /* Close pager; ignore return code for cleanup in tests. */57 (void)sqlite3PagerClose(pPager);58 }59 deleteFileIfExists(zFilename);60}61 62void setUp(void) {63 /* Ensure SQLite is initialized (usually already is). */64 sqlite3_initialize();65}66 67void tearDown(void) {68 /* No-op */69}70 71/* Test 1: Empty file => header buffer remains zero, rc==SQLITE_OK */72void test_sqlite3PagerReadFileheader_empty_file_zeroed_buffer(void){73 char zFile[512];74 makeTempFilename(zFile, sizeof(zFile));75 makeFileWithData(zFile, NULL, 0);76 77 Pager *pPager = openPagerOnFile(zFile);78 79 const int N = 128;80 unsigned char buf[128];81 memset(buf, 0xAB, sizeof(buf)); /* Pre-fill with non-zero to detect zeroing */82 83 int rc = sqlite3PagerReadFileheader(pPager, N, buf);84 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);85 86 /* Expect entire buffer zeroed */87 for(int i=0; i<N; i++){88 TEST_ASSERT_EQUAL_UINT8(0x00, buf[i]);89 }90 91 closePagerAndCleanup(pPager, zFile);92}93 94/* Test 2: File smaller than N bytes => prefix read, remainder zero-filled, rc==SQLITE_OK */95void test_sqlite3PagerReadFileheader_short_read_prefix_and_zeros(void){96 char zFile[512];97 makeTempFilename(zFile, sizeof(zFile));98 99 unsigned char content[16];100 for(int i=0; i<(int)sizeof(content); i++) content[i] = (unsigned char)(i + 1);101 makeFileWithData(zFile, content, (int)sizeof(content));102 103 Pager *pPager = openPagerOnFile(zFile);104 105 const int N = 64;106 unsigned char buf[64];107 memset(buf, 0xCD, sizeof(buf)); /* sentinel */108 109 int rc = sqlite3PagerReadFileheader(pPager, N, buf);110 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);111 112 /* First len bytes should match file content */113 for(int i=0; i<(int)sizeof(content); i++){114 TEST_ASSERT_EQUAL_UINT8(content[i], buf[i]);115 }116 /* Remaining bytes should be zero due to initial memset and short read */117 for(int i=(int)sizeof(content); i<N; i++){118 TEST_ASSERT_EQUAL_UINT8(0x00, buf[i]);119 }120 121 closePagerAndCleanup(pPager, zFile);122}123 124/* Test 3: File size >= N => exact N bytes read into buffer, rc==SQLITE_OK */125void test_sqlite3PagerReadFileheader_full_read_exact_bytes(void){126 char zFile[512];127 makeTempFilename(zFile, sizeof(zFile));128 129 const int N = 64;130 unsigned char content[96];131 for(int i=0; i<(int)sizeof(content); i++) content[i] = (unsigned char)(0xF0 ^ i);132 makeFileWithData(zFile, content, (int)sizeof(content)); /* larger than N */133 134 Pager *pPager = openPagerOnFile(zFile);135 136 unsigned char buf[64];137 memset(buf, 0xEE, sizeof(buf));138 139 int rc = sqlite3PagerReadFileheader(pPager, N, buf);140 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);141 142 /* Expect first N bytes from file */143 TEST_ASSERT_EQUAL_INT(0, memcmp(buf, content, N));144 145 closePagerAndCleanup(pPager, zFile);146}147 148/* Test 4: N == 0 edge case => buffer unchanged, rc==SQLITE_OK */149void test_sqlite3PagerReadFileheader_zero_bytes_requested_no_change(void){150 char zFile[512];151 makeTempFilename(zFile, sizeof(zFile));152 153 unsigned char content[32];154 for(int i=0; i<(int)sizeof(content); i++) content[i] = (unsigned char)(0x80 + i);155 makeFileWithData(zFile, content, (int)sizeof(content));156 157 Pager *pPager = openPagerOnFile(zFile);158 159 unsigned char buf[16];160 for(int i=0; i<(int)sizeof(buf); i++) buf[i] = 0xAA;161 162 int rc = sqlite3PagerReadFileheader(pPager, 0, buf);163 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);164 165 /* Buffer should be unchanged */166 for(int i=0; i<(int)sizeof(buf); i++){167 TEST_ASSERT_EQUAL_UINT8(0xAA, buf[i]);168 }169 170 closePagerAndCleanup(pPager, zFile);171}172 173int main(void){174 UNITY_BEGIN();175 RUN_TEST(test_sqlite3PagerReadFileheader_empty_file_zeroed_buffer);176 RUN_TEST(test_sqlite3PagerReadFileheader_short_read_prefix_and_zeros);177 RUN_TEST(test_sqlite3PagerReadFileheader_full_read_exact_bytes);178 RUN_TEST(test_sqlite3PagerReadFileheader_zero_bytes_requested_no_change);179 return UNITY_END();180}