diff options
author | drh <> | 2022-02-10 21:26:53 +0000 |
---|---|---|
committer | drh <> | 2022-02-10 21:26:53 +0000 |
commit | d7e185ce5d6699e94db1f8431b38c809ac204a6c (patch) | |
tree | bd172263c5497b6012a0c7095ac4933037f74361 /src | |
parent | eadccaa9269560e567b4ae0440de6e24745e6142 (diff) | |
download | sqlite-d7e185ce5d6699e94db1f8431b38c809ac204a6c.tar.gz sqlite-d7e185ce5d6699e94db1f8431b38c809ac204a6c.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/date.c | 22 | ||||
-rw-r--r-- | src/global.c | 1 | ||||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/test1.c | 2 |
5 files changed, 38 insertions, 8 deletions
diff --git a/src/date.c b/src/date.c index 3225a5528..1306847f8 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 34b7d9583..6ad3bb465 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 e8b775a21..f34e981d5 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 1ed600f4d..c8dbec2f1 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 05aa97539..3eba08449 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; } |