AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <string.h>4#include <stdlib.h>5 6static void assert_flag_state(sqlite3 *db, u64 mask, int expectedOn){7 if( expectedOn ){8 TEST_ASSERT_TRUE( (db->flags & mask) != 0 );9 }else{10 TEST_ASSERT_TRUE( (db->flags & mask) == 0 );11 }12}13 14void setUp(void) {15 /* No global setup required */16}17 18void tearDown(void) {19 /* No global teardown required */20}21 22static sqlite3* open_memory_db(void){23 sqlite3 *db = 0;24 int rc = sqlite3_open(":memory:", &db);25 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);26 TEST_ASSERT_NOT_NULL(db);27 return db;28}29 30static void close_db(sqlite3 *db){31 int rc = sqlite3_close(db);32 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);33}34 35void test_sqlite3_db_config_maindbname_sets_pointer(void){36 sqlite3 *db = open_memory_db();37 38 /* Use a stable, writable string so we can compare pointer identity */39 static char name[] = "custom_main_name";40 int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, name);41 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);42 TEST_ASSERT_EQUAL_PTR(name, db->aDb[0].zDbSName);43 44 close_db(db);45}46 47void test_sqlite3_db_config_toggle_enable_fkey(void){48 sqlite3 *db = open_memory_db();49 50 int res = -1;51 u64 mask = SQLITE_ForeignKeys;52 int rc;53 54 /* Clear the flag */55 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 0, &res);56 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);57 TEST_ASSERT_EQUAL_INT(0, res);58 assert_flag_state(db, mask, 0);59 60 /* Query only (onoff < 0) - should remain cleared */61 res = -1;62 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, -1, &res);63 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);64 TEST_ASSERT_EQUAL_INT(0, res);65 assert_flag_state(db, mask, 0);66 67 /* Set the flag */68 res = -1;69 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 1, &res);70 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);71 TEST_ASSERT_EQUAL_INT(1, res);72 assert_flag_state(db, mask, 1);73 74 /* Query only (onoff < 0) - should remain set */75 res = -1;76 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, -1, &res);77 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);78 TEST_ASSERT_EQUAL_INT(1, res);79 assert_flag_state(db, mask, 1);80 81 /* Clear again */82 res = -1;83 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_FKEY, 0, &res);84 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);85 TEST_ASSERT_EQUAL_INT(0, res);86 assert_flag_state(db, mask, 0);87 88 close_db(db);89}90 91void test_sqlite3_db_config_toggle_writable_schema_combo_bits(void){92 sqlite3 *db = open_memory_db();93 94 int res = -1;95 u64 mask = (SQLITE_WriteSchema | SQLITE_NoSchemaError);96 int rc;97 98 /* Clear both bits */99 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 0, &res);100 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);101 TEST_ASSERT_EQUAL_INT(0, res);102 assert_flag_state(db, mask, 0);103 104 /* Set both bits */105 res = -1;106 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, &res);107 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);108 TEST_ASSERT_EQUAL_INT(1, res);109 assert_flag_state(db, mask, 1);110 111 /* Query only - should remain set */112 res = -1;113 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &res);114 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);115 TEST_ASSERT_EQUAL_INT(1, res);116 assert_flag_state(db, mask, 1);117 118 /* Clear again */119 res = -1;120 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 0, &res);121 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);122 TEST_ASSERT_EQUAL_INT(0, res);123 assert_flag_state(db, mask, 0);124 125 close_db(db);126}127 128void test_sqlite3_db_config_unknown_op_returns_error(void){129 sqlite3 *db = open_memory_db();130 131 /* Use an opcode that is not recognized */132 int rc = sqlite3_db_config(db, 0x7FFFFFF0);133 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);134 135 close_db(db);136}137 138#ifndef SQLITE_OMIT_LOOKASIDE139void test_sqlite3_db_config_lookaside_with_external_buffer(void){140 sqlite3 *db = open_memory_db();141 142 int sz = 128;143 int cnt = 8;144 sqlite3_int64 total = (sqlite3_int64)sz * (sqlite3_int64)cnt;145 void *buf = sqlite3_malloc(total);146 TEST_ASSERT_NOT_NULL(buf);147 148 int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, buf, sz, cnt);149 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);150 151 /* Verify core invariants */152 int expectedSz = (sz & ~7); /* ROUNDDOWN8 */153 TEST_ASSERT_EQUAL_INT(expectedSz, db->lookaside.szTrue);154 TEST_ASSERT_EQUAL_INT(expectedSz, db->lookaside.sz);155 TEST_ASSERT_EQUAL_PTR(buf, db->lookaside.pStart);156 TEST_ASSERT_EQUAL_INT(0, db->lookaside.bMalloced);157 TEST_ASSERT_EQUAL_INT(0, db->lookaside.bDisable);158 TEST_ASSERT_TRUE(db->lookaside.nSlot >= 0); /* should be >=0; normally >0 if szAlloc>0 */159 TEST_ASSERT_NOT_NULL(db->lookaside.pTrueEnd);160 161 /* Disable lookaside so we can free our external buffer safely */162 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0);163 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);164 TEST_ASSERT_EQUAL_INT(1, db->lookaside.bDisable);165 TEST_ASSERT_EQUAL_INT(0, db->lookaside.sz);166 TEST_ASSERT_EQUAL_INT(0, db->lookaside.nSlot);167 168 sqlite3_free(buf);169 close_db(db);170}171 172void test_sqlite3_db_config_lookaside_malloc_and_busy_when_in_use(void){173 sqlite3 *db = open_memory_db();174 175 /* Configure lookaside using SQLite's allocator */176 int sz = 64;177 int cnt = 4;178 int rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, NULL, sz, cnt);179 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);180 181 TEST_ASSERT_EQUAL_INT(1, db->lookaside.bMalloced);182 TEST_ASSERT_NOT_NULL(db->lookaside.pStart);183 TEST_ASSERT_TRUE(db->lookaside.nSlot >= 0);184 185 /* Allocate a small block to consume one lookaside slot */186 void *p = sqlite3DbMallocZero(db, 32);187 TEST_ASSERT_NOT_NULL(p);188 189 /* Reconfiguring while a slot is in use should return SQLITE_BUSY */190 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, NULL, sz, cnt);191 TEST_ASSERT_EQUAL_INT(SQLITE_BUSY, rc);192 193 /* Free the lookaside allocation and reconfigure to disable */194 sqlite3DbFree(db, p);195 rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, NULL, 0, 0);196 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);197 TEST_ASSERT_EQUAL_INT(1, db->lookaside.bDisable);198 TEST_ASSERT_EQUAL_INT(0, db->lookaside.sz);199 TEST_ASSERT_EQUAL_INT(0, db->lookaside.nSlot);200 201 close_db(db);202}203#endif /* SQLITE_OMIT_LOOKASIDE */204 205int main(void) {206 UNITY_BEGIN();207 208 RUN_TEST(test_sqlite3_db_config_maindbname_sets_pointer);209 RUN_TEST(test_sqlite3_db_config_toggle_enable_fkey);210 RUN_TEST(test_sqlite3_db_config_toggle_writable_schema_combo_bits);211 RUN_TEST(test_sqlite3_db_config_unknown_op_returns_error);212#ifndef SQLITE_OMIT_LOOKASIDE213 RUN_TEST(test_sqlite3_db_config_lookaside_with_external_buffer);214 RUN_TEST(test_sqlite3_db_config_lookaside_malloc_and_busy_when_in_use);215#endif216 217 return UNITY_END();218}