From d7e185ce5d6699e94db1f8431b38c809ac204a6c Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 10 Feb 2022 21:26:53 +0000 Subject: [PATCH] Enhance SQLITE_TESTCTRL_LOCALTIME_FAULT so that is able to install an alternative localtime() interface so that the localtime logic an be better tested. FossilOrigin-Name: 6e25cb0890e8cdc63c9a21e841844d066267fc32ad143527843f7c8d05612b53 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/date.c | 22 ++++++++++++++++++---- src/global.c | 1 + src/main.c | 20 +++++++++++++++++--- src/sqliteInt.h | 1 + src/test1.c | 2 +- 7 files changed, 49 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 36eecc3606..2843e573ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprove\sto\sthe\s'localtime'\sand\s'utc'\smodifiers\sfor\sdate/time\nfunctions. -D 2022-02-10T15:40:40.522 +C Enhance\sSQLITE_TESTCTRL_LOCALTIME_FAULT\sso\sthat\sis\sable\sto\sinstall\san\nalternative\slocaltime()\sinterface\sso\sthat\sthe\slocaltime\slogic\san\sbe\sbetter\ntested. +D 2022-02-10T21:26:53.735 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -499,7 +499,7 @@ F src/build.c b59ff41525c10b429adc277d3bca6e433b09d055b0df8c1529385763cea8bb04 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 -F src/date.c 9d865dac4a796035a8cfb027c7c8450bc7ec54f8b51ebedbc5b8369e032e1cb9 +F src/date.c 4088c042680ecc5ea1b7d5bfa67b91e7d0f48e91de2d2c5244852250ae86a2cb F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d @@ -507,7 +507,7 @@ F src/expr.c b90a029105a93a93a0ed5e5f8c5eaed8f19043a3b62e4c4d235a4611d9ada178 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 06e4ac33031b02dde7130c12e79cddf4dc5cfa72b23d8e63a3c26878fc9c1d3c F src/func.c 5a0379450bd19ca5cb2d65327b0df6466a14fa0f06f9355329c3e0eec483519a -F src/global.c 1f56aead86e8a18c4415638f5e6c4d0a0550427f4b3f5d065ba5164cc09c22e8 +F src/global.c a3daa18a1696aadd94f18d37cbbdebf0bbdb827b8397a534f021cd56c15cd0f9 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 @@ -516,7 +516,7 @@ F src/insert.c 1eea44389de3768ac98588c1410171cd53e7c6ad1af74049983dcbac82093de0 F src/json.c 225b00422112ecd7094a555f3ace16b25d7d5894062b823269ed03899907c2a2 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c aa919a6a7884f8b34d7b791841b24d14b1b0ab43f45b3940f4851043b2855c0c -F src/main.c 2b6b0dbfeb14d4bb57e368604b0736b2aa42b51b00339d399b01d6b1fc9b4960 +F src/main.c 911a4d673782df8f53838f779291de9059f1d00adb506a3c2c758bbd6231a5d3 F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -557,12 +557,12 @@ F src/shell.c.in b800bf8e02d9b4fd97078b68ca4371048f7196fc63accaa99c3c5943f72c80a F src/sqlite.h.in 7047c4b60fa550264d6363bb1d983540e7828fb19d2d1e5aa43b52ca13144807 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 -F src/sqliteInt.h b6619030ed13b2a8d49c0b5cb0525db1f727966b65ab1ec40b5f11102af7254d +F src/sqliteInt.h f8814239fb1f95056555e2d7fa475750e64681cac4221fb03610d1fde0b79d53 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 48f291e1a7e672a7204884d4c164a8ed3a522ff087c361ada2991f5d54e987f6 -F src/test1.c ce2a866f6977d4016e5801ab58b21dc06459a4c304d95961a662645e7364361f +F src/test1.c a5d93408dfc5d91f35af12a9c6e90562cc1713f435a8642c9dbd3ffdb4d39ad2 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@ -1944,8 +1944,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fa1b393bdb66b985f6552190a8242ed878f91d653a03352f65aa8d750de3cec4 -R 67dc667c505ca83a0a8211aab2594ab6 +P 85cb6014751a0572d28ebd839331d5d7a78de45c9e522adcd834a8a85746f32e +R 223a6ad4591810b91660311766f1accb U drh -Z f3fee6ce5a9f7a29390c33b813554b1e +Z aed68e242e6b8ba2c978ed50de469779 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6a69ddd7b7..2560a392e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85cb6014751a0572d28ebd839331d5d7a78de45c9e522adcd834a8a85746f32e \ No newline at end of file +6e25cb0890e8cdc63c9a21e841844d066267fc32ad143527843f7c8d05612b53 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 3225a5528d..1306847f89 100644 --- a/src/date.c +++ b/src/date.c @@ -503,8 +503,10 @@ static void clearYMD_HMS_TZ(DateTime *p){ ** is available. This routine returns 0 on success and ** non-zero on any kind of error. ** -** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this -** routine will always fail. +** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this +** routine will always fail. If bLocaltimeFault is nonzero and +** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is +** invoked in place of the OS-defined localtime() function. ** ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C ** library function localtime_r() is used to assist in the calculation of @@ -520,7 +522,13 @@ static int osLocaltime(time_t *t, struct tm *pTm){ sqlite3_mutex_enter(mutex); pX = localtime(t); #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 ){ + return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm); + }else{ + pX = 0; + } + } #endif if( pX ) *pTm = *pX; #if SQLITE_THREADSAFE>0 @@ -529,7 +537,13 @@ static int osLocaltime(time_t *t, struct tm *pTm){ rc = pX==0; #else #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 ){ + return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm); + }else{ + return 1; + } + } #endif #if HAVE_LOCALTIME_R rc = localtime_r(t, pTm)==0; diff --git a/src/global.c b/src/global.c index 34b7d9583b..6ad3bb4654 100644 --- a/src/global.c +++ b/src/global.c @@ -286,6 +286,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ diff --git a/src/main.c b/src/main.c index e8b775a219..f34e981d51 100644 --- a/src/main.c +++ b/src/main.c @@ -4161,13 +4161,27 @@ int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** - ** If parameter onoff is non-zero, subsequent calls to localtime() - ** and its variants fail. If onoff is zero, undo this setting. + ** If parameter onoff is 1, subsequent calls to localtime() fail. + ** If 2, then invoke xAlt() instead of localtime(). If 0, normal + ** processing. + ** + ** xAlt arguments are void pointers, but they really want to be: + ** + ** int xAlt(const time_t*, struct tm*); + ** + ** xAlt should write results in to struct tm object of its 2nd argument + ** and return zero on success, or return non-zero on failure. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + if( sqlite3GlobalConfig.bLocaltimeFault==2 ){ + sqlite3GlobalConfig.xAltLocaltime = + va_arg(ap, int(*)(const void*,void*)); + }else{ + sqlite3GlobalConfig.xAltLocaltime = 0; + } break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1ed600f4dd..c8dbec2f15 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3936,6 +3936,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ diff --git a/src/test1.c b/src/test1.c index 05aa97539a..3eba084497 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7258,7 +7258,7 @@ static int SQLITE_TCLAPI test_test_control( return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; - sqlite3_test_control(iFlag, val); + sqlite3_test_control(iFlag, val!=0); break; }