AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdio.h>4#include <stdlib.h>5#include <string.h>6#include <time.h>7 8/* Unity hooks */9void setUp(void) {10 /* No-op */11}12void tearDown(void) {13 /* No-op */14}15 16/* Helpers */17static int testFaultCallback(int x){18 /* Return a fixed code to verify FAULT_INSTALL wiring */19 return 123;20}21 22static void testBenignBegin(void){ /* no-op */ }23static void testBenignEnd(void){ /* no-op */ }24 25static int testAltLocaltime(const void *a, void *b){26 /* Provide a valid alternative localtime function shape */27 (void)a;28 (void)b;29 return 0; /* success */30}31 32/* Tests */33 34static void test_sqlite3_test_control_ISINIT_after_initialize(void){35 int rcInit = sqlite3_initialize();36 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcInit);37 int rc = sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);38 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);39}40 41static void test_sqlite3_test_control_ISINIT_after_shutdown(void){42 int rcInit = sqlite3_initialize();43 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcInit);44 sqlite3_shutdown();45 int rc = sqlite3_test_control(SQLITE_TESTCTRL_ISINIT);46 TEST_ASSERT_EQUAL_INT(SQLITE_ERROR, rc);47 /* Restore library for subsequent tests */48 rcInit = sqlite3_initialize();49 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rcInit);50}51 52static void test_sqlite3_test_control_PRNG_SAVE_RESTORE(void){53 unsigned char a1[64];54 unsigned char a2[64];55 memset(a1, 0, sizeof(a1));56 memset(a2, 0, sizeof(a2));57 /* Save state, get bytes, restore, get bytes again -> must match */58 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE);59 sqlite3_randomness((int)sizeof(a1), a1);60 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE);61 sqlite3_randomness((int)sizeof(a2), a2);62 TEST_ASSERT_EQUAL_INT(0, memcmp(a1, a2, sizeof(a1)));63}64 65#ifndef SQLITE_OMIT_WSD66static void test_sqlite3_test_control_PRNG_SEED_constant(void){67 unsigned char a1[32];68 unsigned char a2[32];69 memset(a1, 0, sizeof(a1));70 memset(a2, 0, sizeof(a2));71 /* Seed PRNG deterministically and verify reproducible output */72 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1234, (sqlite3*)0);73 sqlite3_randomness((int)sizeof(a1), a1);74 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, 1234, (sqlite3*)0);75 sqlite3_randomness((int)sizeof(a2), a2);76 TEST_ASSERT_EQUAL_INT(0, memcmp(a1, a2, sizeof(a1)));77}78#endif79 80static void test_sqlite3_test_control_PENDING_BYTE_returns_constant(void){81 int rc = sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, (unsigned int)0);82 TEST_ASSERT_EQUAL_INT(PENDING_BYTE, rc);83}84 85static void test_sqlite3_test_control_BYTEORDER_value(void){86 int rc = sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER);87 /* Accept one of the documented encodings */88 int ok = 0;89 if( rc==1 || rc==10 || rc==432101 || rc==123410 ) ok = 1;90 TEST_ASSERT_TRUE(ok);91}92 93static void test_sqlite3_test_control_ALWAYS_behavior(void){94 int rc = sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2);95 /* Depending on build, rc is 2 (pass-through) or 1 (forced true) */96 TEST_ASSERT_TRUE(rc==2 || rc==1);97}98 99static void test_sqlite3_test_control_FK_NO_ACTION_toggle(void){100 sqlite3 *db = 0;101 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));102 TEST_ASSERT_NOT_NULL(db);103 /* Set */104 sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, db, 1);105 TEST_ASSERT_TRUE((db->flags & SQLITE_FkNoAction)!=0);106 /* Clear */107 sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, db, 0);108 TEST_ASSERT_TRUE((db->flags & SQLITE_FkNoAction)==0);109 sqlite3_close(db);110}111 112static void test_sqlite3_test_control_OPTIMIZATIONS_and_GETOPT(void){113 sqlite3 *db = 0;114 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));115 TEST_ASSERT_NOT_NULL(db);116 u32 mask = 0x5a5a5a5au;117 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);118 int got = 0;119 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, db, &got);120 TEST_ASSERT_EQUAL_INT((int)mask, got);121 /* Restore to 0 for a clean state */122 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, 0);123 sqlite3_close(db);124}125 126static void test_sqlite3_test_control_LOCALTIME_FAULT_and_alt(void){127 /* Set to alternate function */128 sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, 2, testAltLocaltime);129 TEST_ASSERT_EQUAL_INT(2, sqlite3GlobalConfig.bLocaltimeFault);130 TEST_ASSERT_NOT_NULL(sqlite3GlobalConfig.xAltLocaltime);131 /* Turn off and ensure alt cleared */132 sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, 0);133 TEST_ASSERT_EQUAL_INT(0, sqlite3GlobalConfig.bLocaltimeFault);134 TEST_ASSERT_NULL(sqlite3GlobalConfig.xAltLocaltime);135}136 137static void test_sqlite3_test_control_INTERNAL_FUNCTIONS_toggle(void){138 sqlite3 *db = 0;139 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));140 TEST_ASSERT_NOT_NULL(db);141 unsigned int before = db->mDbFlags;142 sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, db);143 TEST_ASSERT_EQUAL_UINT32(before ^ DBFLAG_InternalFunc, db->mDbFlags);144 sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, db);145 TEST_ASSERT_EQUAL_UINT32(before, db->mDbFlags);146 sqlite3_close(db);147}148 149static void test_sqlite3_test_control_NEVER_CORRUPT_toggle(void){150 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1);151 TEST_ASSERT_EQUAL_INT(1, sqlite3GlobalConfig.neverCorrupt);152 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0);153 TEST_ASSERT_EQUAL_INT(0, sqlite3GlobalConfig.neverCorrupt);154}155 156static void test_sqlite3_test_control_EXTRA_SCHEMA_CHECKS_toggle(void){157 sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, 0);158 TEST_ASSERT_EQUAL_INT(0, sqlite3GlobalConfig.bExtraSchemaChecks);159 sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, 1);160 TEST_ASSERT_EQUAL_INT(1, sqlite3GlobalConfig.bExtraSchemaChecks);161 /* restore default to on */162 sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, 1);163}164 165static void test_sqlite3_test_control_ONCE_RESET_THRESHOLD_set_restore(void){166 int oldv = sqlite3GlobalConfig.iOnceResetThreshold;167 int newv = 1000;168 sqlite3_test_control(SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD, newv);169 TEST_ASSERT_EQUAL_INT(newv, sqlite3GlobalConfig.iOnceResetThreshold);170 sqlite3_test_control(SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD, oldv);171 TEST_ASSERT_EQUAL_INT(oldv, sqlite3GlobalConfig.iOnceResetThreshold);172}173 174static void test_sqlite3_test_control_SORTER_MMAP(void){175 sqlite3 *db = 0;176 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));177 TEST_ASSERT_NOT_NULL(db);178 int v = 1<<20; /* 1MB */179 sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, v);180 TEST_ASSERT_EQUAL_INT(v, db->nMaxSorterMmap);181 sqlite3_close(db);182}183 184static void test_sqlite3_test_control_IMPOSTER_mode_and_reset(void){185 sqlite3 *db = 0;186 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));187 TEST_ASSERT_NOT_NULL(db);188 189 /* Turn on imposter on main with tnum=55 */190 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "main", 1, 55);191 TEST_ASSERT_EQUAL_INT(0, db->init.iDb); /* main is index 0 */192 TEST_ASSERT_EQUAL_INT(1, db->init.busy);193 TEST_ASSERT_EQUAL_INT(1, db->init.imposterTable);194 TEST_ASSERT_EQUAL_INT(55, db->init.newTnum);195 196 /* Turn off (busy=0) with a new tnum and ensure fields updated */197 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "main", 0, 88);198 TEST_ASSERT_EQUAL_INT(0, db->init.busy);199 TEST_ASSERT_EQUAL_INT(0, db->init.imposterTable);200 TEST_ASSERT_EQUAL_INT(88, db->init.newTnum);201 202 /* Unknown db name should not change anything */203 int prevBusy = db->init.busy;204 int prevImp = db->init.imposterTable;205 int prevTnum = db->init.newTnum;206 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, "nosuchdb", 1, 99);207 TEST_ASSERT_EQUAL_INT(prevBusy, db->init.busy);208 TEST_ASSERT_EQUAL_INT(prevImp, db->init.imposterTable);209 TEST_ASSERT_EQUAL_INT(prevTnum, db->init.newTnum);210 211 sqlite3_close(db);212}213 214static void test_sqlite3_test_control_FAULT_INSTALL_callback(void){215 /* Install callback and verify rc is callback return */216 int rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, testFaultCallback);217 TEST_ASSERT_EQUAL_INT(123, rc);218 /* Uninstall callback (NULL). Expected rc is sqlite3FaultSim(0) with no cb -> 0 */219 rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, (void*)0);220 TEST_ASSERT_EQUAL_INT(0, rc);221}222 223static void test_sqlite3_test_control_BENIGN_MALLOC_HOOKS_set_clear(void){224 /* Just ensure it can be set without crashing */225 sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, testBenignBegin, testBenignEnd);226 /* And can be set to NULLs */227 sqlite3_test_control(SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, (void(*)(void))0, (void(*)(void))0);228 TEST_ASSERT_TRUE(1);229}230 231static void test_sqlite3_test_control_LOGEST_roundtrip(void){232 double ins[] = {0.1, 0.5, 1.0, 2.0, 10.0, 1234567.0, 1e-9, 1e9};233 for(size_t i=0; i<sizeof(ins)/sizeof(ins[0]); i++){234 int i1 = 0, i2 = 0;235 u64 u = 0;236 int rc = sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, ins[i], &i1, &u, &i2);237 TEST_ASSERT_EQUAL_INT(0, rc);238 TEST_ASSERT_EQUAL_INT(i1, i2);239 /* The integer reconstructed from LogEst should be non-zero for positive inputs */240 if( ins[i] > 0.0 ){241 TEST_ASSERT_TRUE(u>0);242 }243 }244}245 246#if defined(SQLITE_DEBUG)247static void test_sqlite3_test_control_TRACEFLAGS_roundtrip(void){248 u32 v = 0, tmp = 0;249 /* Tree trace: read, set, read */250 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &v);251 tmp = 0x1u;252 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &tmp);253 tmp = 0;254 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &tmp);255 TEST_ASSERT_EQUAL_UINT32(0x1u, tmp);256 257 /* Where trace: read, set, read */258 tmp = 0;259 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &tmp);260 tmp = 0x2u;261 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &tmp);262 tmp = 0;263 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &tmp);264 TEST_ASSERT_EQUAL_UINT32(0x2u, tmp);265}266#endif267 268#if defined(SQLITE_DEBUG)269static void test_sqlite3_test_control_SEEK_COUNT_reset_behavior(void){270 sqlite3 *db = 0;271 TEST_ASSERT_EQUAL_INT(SQLITE_OK, sqlite3_open(":memory:", &db));272 TEST_ASSERT_NOT_NULL(db);273 sqlite3_uint64 a = 0, b = 0;274 sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, db, &a);275 sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, db, &b);276 TEST_ASSERT_EQUAL_UINT64((sqlite3_uint64)0, b);277 sqlite3_close(db);278}279#endif280 281#if defined(SQLITE_VDBE_COVERAGE)282static void vdbeBranchCb(void *p, unsigned int addr, unsigned char t, unsigned char n){283 (void)p; (void)addr; (void)t; (void)n; /* no-op */284}285static void test_sqlite3_test_control_VDBE_COVERAGE_set(void){286 void *ctx = (void*)0x1234;287 sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, vdbeBranchCb, ctx);288 TEST_ASSERT_NOT_NULL(sqlite3GlobalConfig.xVdbeBranch);289 TEST_ASSERT_EQUAL_PTR(ctx, sqlite3GlobalConfig.pVdbeBranchArg);290}291#endif292 293#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)294static void test_sqlite3_test_control_TUNE_set_get(void){295 int id = 1; /* assume at least 1 tuning parameter exists */296 int setv = 77, getv = 0;297 int rc = sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, &setv);298 if( rc==SQLITE_OK ){299 int qid = -id;300 rc = sqlite3_test_control(SQLITE_TESTCTRL_TUNE, qid, &getv);301 TEST_ASSERT_EQUAL_INT(SQLITE_OK, rc);302 TEST_ASSERT_EQUAL_INT(setv, getv);303 } else {304 /* If id out of range, SQLITE_NOTFOUND allowed; just skip strict check */305 TEST_ASSERT_TRUE(rc==SQLITE_NOTFOUND || rc==SQLITE_OK);306 }307}308#endif309 310#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)311static void test_sqlite3_test_control_JSON_SELFCHECK_toggle(void){312 int v = -1;313 sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &v);314 /* v now holds current setting. Toggle and read back again. */315 int newv = (v?0:1);316 sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &newv);317 int q = -1;318 sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &q);319 TEST_ASSERT_EQUAL_INT(newv, q);320 /* Restore original */321 sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &v);322}323#endif324 325int main(void){326 UNITY_BEGIN();327 328 RUN_TEST(test_sqlite3_test_control_ISINIT_after_initialize);329 RUN_TEST(test_sqlite3_test_control_ISINIT_after_shutdown);330 RUN_TEST(test_sqlite3_test_control_PRNG_SAVE_RESTORE);331#ifndef SQLITE_OMIT_WSD332 RUN_TEST(test_sqlite3_test_control_PRNG_SEED_constant);333#endif334 RUN_TEST(test_sqlite3_test_control_PENDING_BYTE_returns_constant);335 RUN_TEST(test_sqlite3_test_control_BYTEORDER_value);336 RUN_TEST(test_sqlite3_test_control_ALWAYS_behavior);337 RUN_TEST(test_sqlite3_test_control_FK_NO_ACTION_toggle);338 RUN_TEST(test_sqlite3_test_control_OPTIMIZATIONS_and_GETOPT);339 RUN_TEST(test_sqlite3_test_control_LOCALTIME_FAULT_and_alt);340 RUN_TEST(test_sqlite3_test_control_INTERNAL_FUNCTIONS_toggle);341 RUN_TEST(test_sqlite3_test_control_NEVER_CORRUPT_toggle);342 RUN_TEST(test_sqlite3_test_control_EXTRA_SCHEMA_CHECKS_toggle);343 RUN_TEST(test_sqlite3_test_control_ONCE_RESET_THRESHOLD_set_restore);344 RUN_TEST(test_sqlite3_test_control_SORTER_MMAP);345 RUN_TEST(test_sqlite3_test_control_IMPOSTER_mode_and_reset);346 RUN_TEST(test_sqlite3_test_control_FAULT_INSTALL_callback);347 RUN_TEST(test_sqlite3_test_control_BENIGN_MALLOC_HOOKS_set_clear);348 RUN_TEST(test_sqlite3_test_control_LOGEST_roundtrip);349#if defined(SQLITE_DEBUG)350 RUN_TEST(test_sqlite3_test_control_TRACEFLAGS_roundtrip);351 RUN_TEST(test_sqlite3_test_control_SEEK_COUNT_reset_behavior);352#endif353#if defined(SQLITE_VDBE_COVERAGE)354 RUN_TEST(test_sqlite3_test_control_VDBE_COVERAGE_set);355#endif356#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)357 RUN_TEST(test_sqlite3_test_control_TUNE_set_get);358 RUN_TEST(test_sqlite3_test_control_JSON_SELFCHECK_toggle);359#endif360 361 return UNITY_END();362}