-C In\sthe\sRTREE\sextension,\sallow\sthe\sxBeginTransaction()\sentry\spoint\sto\sbe\ninvoked\smultiple\stimes\swithout\sintervening\scalls\sto\sxEndTransaction().
-D 2024-02-11T22:56:12.780
+C Add\ssupport\sfor\sthe\s".testctrl\sfault_install"\sdot-command\sin\sthe\sCLI\swhen\nlaunched\swith\sthe\s--unsafe-testing\soption.
+D 2024-02-12T13:28:10.404
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/resolve.c d77c6160bc8f249c2196fdd3e75f66a1dd70e37aa25c39aedc7b1f93c42b7c6d
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 43fabfc01bf87addd15e39f112f1e2ade15b19594835ab8a9e5bd50839d4e1b1
-F src/shell.c.in c6cb773b7703d76677529de19d1c40584520701966422c33da3e9334498a7099
+F src/shell.c.in 2382dc2327e47af76b37a7a468152a509dc0a8e72dad887fb868102ecbd94fe8
F src/sqlite.h.in 020d7b7307dda51420dc48b47e5334eaface77baba6bd9818375d392eb3ab5b5
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d4ec2a5d2297cd9ead0a8768dcf003ea76c74d8d68d88c40f62363f484a4a4d3
-R ee61d12c62e00e1e12755723a284535a
+P f023cb541b5dd72c996f0574210344179217666a2229bc8d3fe057fdbc5c2245
+R c8236513dfcf0ef943c428e779c4a525
U drh
-Z 02dccfc637ae0768eeec52f6adfd1264
+Z 58d2be401311d1f16e9ad87e4e189606
# Remove this line to create a well-formed Fossil manifest.
return rc;
}
+/*
+** Fault-Simulator state and logic.
+*/
+static struct {
+ int iId; /* ID that triggers a simulated fault. -1 means "any" */
+ int iErr; /* The error code to return on a fault */
+ int iCnt; /* Trigger the fault only if iCnt is already zero */
+ int iInterval; /* Reset iCnt to this value after each fault */
+ int eVerbose; /* When to print output */
+} faultsim_state = {-1, 0, 0, 0, 0};
+
+/*
+** This is the fault-sim callback
+*/
+static int faultsim_callback(int iArg){
+ if( faultsim_state.iId>0 && faultsim_state.iId!=iArg ){
+ return SQLITE_OK;
+ }
+ if( faultsim_state.iCnt>0 ){
+ faultsim_state.iCnt--;
+ if( faultsim_state.eVerbose>=2 ){
+ oputf("FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt);
+ }
+ return SQLITE_OK;
+ }
+ if( faultsim_state.eVerbose>=1 ){
+ oputf("FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr);
+ }
+ faultsim_state.iCnt = faultsim_state.iInterval;
+ return faultsim_state.iErr;
+}
+
/*
** If an input line begins with "." then invoke this routine to
** process that line.
/*{"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/
{"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
{"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
- /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
+ {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." },
{"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
{"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
{"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
}
sqlite3_test_control(testctrl, &rc2);
break;
+ case SQLITE_TESTCTRL_FAULT_INSTALL: {
+ int kk;
+ int bShowHelp = nArg<=2;
+ isOk = 3;
+ for(kk=2; kk<nArg; kk++){
+ const char *z = azArg[kk];
+ if( z[0]=='-' && z[1]=='-' ) z++;
+ if( cli_strcmp(z,"off")==0 ){
+ sqlite3_test_control(testctrl, 0);
+ }else if( cli_strcmp(z,"on")==0 ){
+ faultsim_state.iCnt = faultsim_state.iInterval;
+ if( faultsim_state.iErr==0 ) faultsim_state.iErr = 1;
+ sqlite3_test_control(testctrl, faultsim_callback);
+ }else if( cli_strcmp(z,"reset")==0 ){
+ faultsim_state.iCnt = faultsim_state.iInterval;
+ }else if( cli_strcmp(z,"status")==0 ){
+ oputf("faultsim.iId: %d\n", faultsim_state.iId);
+ oputf("faultsim.iErr: %d\n", faultsim_state.iErr);
+ oputf("faultsim.iCnt: %d\n", faultsim_state.iCnt);
+ oputf("faultsim.iInterval: %d\n", faultsim_state.iInterval);
+ oputf("faultsim.eVerbose: %d\n", faultsim_state.eVerbose);
+ }else if( cli_strcmp(z,"-v")==0 ){
+ if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++;
+ }else if( cli_strcmp(z,"-q")==0 ){
+ if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--;
+ }else if( cli_strcmp(z,"-id")==0 && kk+1<nArg ){
+ faultsim_state.iId = atoi(azArg[++kk]);
+ }else if( cli_strcmp(z,"-errcode")==0 && kk+1<nArg ){
+ faultsim_state.iErr = atoi(azArg[++kk]);
+ }else if( cli_strcmp(z,"-interval")==0 && kk+1<nArg ){
+ faultsim_state.iInterval = atoi(azArg[++kk]);
+ }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){
+ bShowHelp = 1;
+ }else{
+ eputf("Unrecognized fault_install argument: \"%s\"\n",
+ azArg[kk]);
+ rc = 1;
+ bShowHelp = 1;
+ break;
+ }
+ }
+ if( bShowHelp ){
+ oputf(
+ "Usage: .testctrl fault_install ARGS\n"
+ "Possible arguments:\n"
+ " off Disable faultsim\n"
+ " on Activate faultsim\n"
+ " reset Reset the trigger counter\n"
+ " status Show current status\n"
+ " -v Increase verbosity\n"
+ " -q Decrease verbosity\n"
+ " --errcode N When triggered, return N as error code\n"
+ " --id ID Trigger only for the ID specified\n"
+ " --interval N Trigger only after every N-th call\n"
+ );
+ }
+ break;
+ }
}
}
if( isOk==0 && iCtrl>=0 ){