Enhance fuzzershell to accept multiple input files. Add the test/fuzzdata2.txt
fuzz test content. FossilOrigin-Name: ab5523aafe4817232388d28ea99be0953e7dccf3
This commit is contained in:
+1
-1
@@ -964,7 +964,7 @@ fulltestonly: testfixture$(TEXE) sqlite3$(TEXE)
|
||||
|
||||
# Fuzz testing
|
||||
fuzztest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
./fuzzershell$(TEXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(TEXE)
|
||||
./fuzzershell$(TEXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
+1
-1
@@ -1644,7 +1644,7 @@ queryplantest: testfixture.exe sqlite3.exe
|
||||
.\testfixture.exe $(TOP)\test\permutations.test queryplanner
|
||||
|
||||
fuzztest: fuzzershell.exe
|
||||
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt
|
||||
.\fuzzershell.exe $(TOP)\test\fuzzdata1.txt $(TOP)\test\fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell.exe
|
||||
.\fuzzershell.exe -f $(TOP)\test\fuzzdata1.txt --oom
|
||||
|
||||
@@ -646,7 +646,7 @@ queryplantest: testfixture$(EXE) sqlite3$(EXE)
|
||||
./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner
|
||||
|
||||
fuzztest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt
|
||||
./fuzzershell$(EXE) $(TOP)/test/fuzzdata1.txt $(TOP)/test/fuzzdata2.txt
|
||||
|
||||
fuzzoomtest: fuzzershell$(EXE)
|
||||
./fuzzershell$(EXE) -f $(TOP)/test/fuzzdata1.txt --oom
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
C Fix\san\sassert\sin\sRTREE\sthat\swould\sfire\sif\sthe\srtree\stable\sis\smisdeclared.
|
||||
D 2015-05-01T18:00:37.511
|
||||
C Enhance\sfuzzershell\sto\saccept\smultiple\sinput\sfiles.\s\sAdd\sthe\stest/fuzzdata2.txt\nfuzz\stest\scontent.
|
||||
D 2015-05-01T19:21:12.995
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in e3268d234210842b4be0a6e2e1c5990999f1d9f4
|
||||
F Makefile.in e628c50e237251fc7e768bef14ee7e822ad69e69
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
F Makefile.msc d80278757ef0b02d797d6ab98e07baf9c608b1a2
|
||||
F Makefile.msc 4c7e6fc40c5b65134b789b18b83743abac907504
|
||||
F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858
|
||||
F README.md d58e3bebc0a4145e0f2a87994015fdb575a8e866
|
||||
F VERSION 2e244662b71e6e68a5c29b014ebc5b7564f4cc5a
|
||||
@@ -152,7 +152,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
F main.mk c0c7503b9749c1532c1e0e9501331abc1afc299d
|
||||
F main.mk 1225d45e1883000a3ed6f028893a11c04522ea6a
|
||||
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
|
||||
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
|
||||
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
|
||||
@@ -632,6 +632,7 @@ F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3
|
||||
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
|
||||
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
|
||||
F test/fuzzdata1.txt 9fceb50868e0b798160e83742bd7e44e457176a0
|
||||
F test/fuzzdata2.txt ba9b4467d7ec46cc85d32c0d031540cd727ae6ad
|
||||
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
|
||||
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
|
||||
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
|
||||
@@ -1207,7 +1208,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
|
||||
F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
|
||||
F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
|
||||
F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
|
||||
F tool/fuzzershell.c 2799d1e74c48a7fbbfc4889601005d42d1e237a5
|
||||
F tool/fuzzershell.c 32816d2c54e7243504ab8af6d9b4323ed1206342
|
||||
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
|
||||
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
|
||||
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
|
||||
@@ -1255,7 +1256,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 40db3e40126db1035fcc12989026915744dc5651
|
||||
R d52749e43e60b570f31909140ed0a510
|
||||
P 9a45409cc4078f2b6e68aa777f6ab86a14309833
|
||||
R 3a133cb00e1f62fffce773de23d1e308
|
||||
U drh
|
||||
Z 292f5446ecb0ed9f640d81ad4e3c067d
|
||||
Z 8894bd22b6f91dc8094aac398d313abb
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
9a45409cc4078f2b6e68aa777f6ab86a14309833
|
||||
ab5523aafe4817232388d28ea99be0953e7dccf3
|
||||
Binary file not shown.
+244
-230
@@ -315,15 +315,14 @@ static void sqlEvalFunc(
|
||||
** Print sketchy documentation for this utility program
|
||||
*/
|
||||
static void showHelp(void){
|
||||
printf("Usage: %s [options]\n", g.zArgv0);
|
||||
printf("Usage: %s [options] ?FILE...?\n", g.zArgv0);
|
||||
printf(
|
||||
"Read SQL text from standard input and evaluate it.\n"
|
||||
"Read SQL text from FILE... (or from standard input if FILE... is omitted)\n"
|
||||
"and then evaluate each block of SQL contained therein.\n"
|
||||
"Options:\n"
|
||||
" --autovacuum Enable AUTOVACUUM mode\n"
|
||||
" -f FILE Read SQL text from FILE instead of standard input\n"
|
||||
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
|
||||
" --help Show this help text\n"
|
||||
" --initdb DBFILE Initialize the in-memory database using template DBFILE\n"
|
||||
" --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
|
||||
" --oom Run each test multiple times in a simulated OOM loop\n"
|
||||
" --pagesize N Set the page size to N\n"
|
||||
@@ -397,28 +396,17 @@ static int integerValue(const char *zArg){
|
||||
return (int)(isNeg? -v : v);
|
||||
}
|
||||
|
||||
/*
|
||||
** Various operating modes
|
||||
*/
|
||||
#define FZMODE_Generic 1
|
||||
#define FZMODE_Strftime 2
|
||||
#define FZMODE_Printf 3
|
||||
#define FZMODE_Glob 4
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
char *zIn = 0; /* Input text */
|
||||
int nAlloc = 0; /* Number of bytes allocated for zIn[] */
|
||||
int nIn = 0; /* Number of bytes of zIn[] used */
|
||||
size_t got; /* Bytes read from input */
|
||||
FILE *in = stdin; /* Where to read SQL text from */
|
||||
int rc = SQLITE_OK; /* Result codes from API functions */
|
||||
int i; /* Loop counter */
|
||||
int iNext; /* Next block of SQL */
|
||||
sqlite3 *db; /* Open database */
|
||||
sqlite3 *dbInit = 0; /* On-disk database used to initialize the in-memory db */
|
||||
const char *zInitDb = 0;/* Name of the initialization database file */
|
||||
char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */
|
||||
char *zIn = 0; /* Input text */
|
||||
int nAlloc = 0; /* Number of bytes allocated for zIn[] */
|
||||
int nIn = 0; /* Number of bytes of zIn[] used */
|
||||
size_t got; /* Bytes read from input */
|
||||
int rc = SQLITE_OK; /* Result codes from API functions */
|
||||
int i; /* Loop counter */
|
||||
int iNext; /* Next block of SQL */
|
||||
sqlite3 *db; /* Open database */
|
||||
char *zErrMsg = 0; /* Error message returned from sqlite3_exec() */
|
||||
const char *zEncoding = 0; /* --utf16be or --utf16le */
|
||||
int nHeap = 0, mnHeap = 0; /* Heap size from --heap */
|
||||
int nLook = 0, szLook = 0; /* --lookaside configuration */
|
||||
@@ -432,7 +420,6 @@ int main(int argc, char **argv){
|
||||
int doAutovac = 0; /* True for --autovacuum */
|
||||
char *zSql; /* SQL to run */
|
||||
char *zToFree = 0; /* Call sqlite3_free() on this afte running zSql */
|
||||
int iMode = FZMODE_Generic; /* Operating mode */
|
||||
const char *zCkGlob = 0; /* Inputs must match this glob */
|
||||
int verboseFlag = 0; /* --verbose or -v flag */
|
||||
int quietFlag = 0; /* --quiet or -q flag */
|
||||
@@ -447,10 +434,15 @@ int main(int argc, char **argv){
|
||||
int oomCnt = 0; /* Counter for the OOM loop */
|
||||
char zErrBuf[200]; /* Space for the error message */
|
||||
const char *zFailCode; /* Value of the TEST_FAILURE environment var */
|
||||
const char *zPrompt; /* Initial prompt when large-file fuzzing */
|
||||
int nInFile = 0; /* Number of input files to read */
|
||||
char **azInFile = 0; /* Array of input file names */
|
||||
int jj; /* Loop counter for azInFile[] */
|
||||
|
||||
|
||||
zFailCode = getenv("TEST_FAILURE");
|
||||
g.zArgv0 = argv[0];
|
||||
zPrompt = "<stdin>";
|
||||
for(i=1; i<argc; i++){
|
||||
const char *z = argv[i];
|
||||
if( z[0]=='-' ){
|
||||
@@ -460,9 +452,8 @@ int main(int argc, char **argv){
|
||||
doAutovac = 1;
|
||||
}else
|
||||
if( strcmp(z, "f")==0 && i+1<argc ){
|
||||
if( in!=stdin ) abendError("only one -f allowed");
|
||||
in = fopen(argv[++i],"rb");
|
||||
if( in==0 ) abendError("cannot open input file \"%s\"", argv[i]);
|
||||
i++;
|
||||
goto addNewInFile;
|
||||
}else
|
||||
if( strcmp(z,"heap")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s\n", argv[i]);
|
||||
@@ -474,35 +465,12 @@ int main(int argc, char **argv){
|
||||
showHelp();
|
||||
return 0;
|
||||
}else
|
||||
if( strcmp(z, "initdb")==0 && i+1<argc ){
|
||||
if( zInitDb!=0 ) abendError("only one --initdb allowed");
|
||||
zInitDb = argv[++i];
|
||||
}else
|
||||
if( strcmp(z,"lookaside")==0 ){
|
||||
if( i>=argc-2 ) abendError("missing arguments on %s", argv[i]);
|
||||
nLook = integerValue(argv[i+1]);
|
||||
szLook = integerValue(argv[i+2]);
|
||||
i += 2;
|
||||
}else
|
||||
if( strcmp(z,"mode")==0 ){
|
||||
if( i>=argc-1 ) abendError("missing argument on %s", argv[i]);
|
||||
z = argv[++i];
|
||||
if( strcmp(z,"generic")==0 ){
|
||||
iMode = FZMODE_Printf;
|
||||
zCkGlob = 0;
|
||||
}else if( strcmp(z, "glob")==0 ){
|
||||
iMode = FZMODE_Glob;
|
||||
zCkGlob = "'*','*'";
|
||||
}else if( strcmp(z, "printf")==0 ){
|
||||
iMode = FZMODE_Printf;
|
||||
zCkGlob = "'*',*";
|
||||
}else if( strcmp(z, "strftime")==0 ){
|
||||
iMode = FZMODE_Strftime;
|
||||
zCkGlob = "'*',*";
|
||||
}else{
|
||||
abendError("unknown --mode: %s", z);
|
||||
}
|
||||
}else
|
||||
if( strcmp(z,"oom")==0 ){
|
||||
oomFlag = 1;
|
||||
}else
|
||||
@@ -545,9 +513,15 @@ int main(int argc, char **argv){
|
||||
abendError("unknown option: %s", argv[i]);
|
||||
}
|
||||
}else{
|
||||
abendError("unknown argument: %s", argv[i]);
|
||||
addNewInFile:
|
||||
nInFile++;
|
||||
azInFile = realloc(azInFile, sizeof(azInFile[0])*nInFile);
|
||||
if( azInFile==0 ) abendError("out of memory");
|
||||
azInFile[nInFile-1] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Do global SQLite initialization */
|
||||
sqlite3_config(SQLITE_CONFIG_LOG, verboseFlag ? shellLog : shellLogNoop, 0);
|
||||
if( nHeap>0 ){
|
||||
pHeap = malloc( nHeap );
|
||||
@@ -583,209 +557,245 @@ int main(int argc, char **argv){
|
||||
rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
|
||||
if( rc ) abendError("pcache configuration failed: %d", rc);
|
||||
}
|
||||
while( !feof(in) ){
|
||||
nAlloc += nAlloc+1000;
|
||||
zIn = realloc(zIn, nAlloc);
|
||||
if( zIn==0 ) fatalError("out of memory");
|
||||
got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
|
||||
nIn += (int)got;
|
||||
zIn[nIn] = 0;
|
||||
if( got==0 ) break;
|
||||
}
|
||||
if( in!=stdin ) fclose(in);
|
||||
|
||||
/* If the --unique-cases option was supplied, open the database that will
|
||||
** be used to gather unique test cases.
|
||||
*/
|
||||
if( zDataOut ){
|
||||
rc = sqlite3_open(":memory:", &dataDb);
|
||||
if( rc ) abendError("cannot open :memory: database");
|
||||
rc = sqlite3_exec(dataDb,
|
||||
"CREATE TABLE testcase(sql BLOB PRIMARY KEY) WITHOUT ROWID;",0,0,0);
|
||||
if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
rc = sqlite3_prepare_v2(dataDb, "INSERT OR IGNORE INTO testcase(sql)VALUES(?1)",
|
||||
-1, &pStmt, 0);
|
||||
rc = sqlite3_prepare_v2(dataDb,
|
||||
"INSERT OR IGNORE INTO testcase(sql)VALUES(?1)",
|
||||
-1, &pStmt, 0);
|
||||
if( rc ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
}
|
||||
if( zInitDb ){
|
||||
rc = sqlite3_open_v2(zInitDb, &dbInit, SQLITE_OPEN_READONLY, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
abendError("unable to open initialization database \"%s\"", zInitDb);
|
||||
}
|
||||
}
|
||||
for(i=0; i<nIn; i=iNext+1){ /* Skip initial lines beginning with '#' */
|
||||
if( zIn[i]!='#' ) break;
|
||||
for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){}
|
||||
}
|
||||
nHeader = i;
|
||||
for(nTest=0; i<nIn; i=iNext, nTest++, g.zTestName[0]=0){
|
||||
char cSaved;
|
||||
if( strncmp(&zIn[i], "/****<",6)==0 ){
|
||||
char *z = strstr(&zIn[i], ">****/");
|
||||
if( z ){
|
||||
z += 6;
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s",
|
||||
(int)(z-&zIn[i]) - 12, &zIn[i+6]);
|
||||
if( verboseFlag ){
|
||||
printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
i += (int)(z-&zIn[i]);
|
||||
multiTest = 1;
|
||||
}
|
||||
}
|
||||
for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
|
||||
if( zDataOut ){
|
||||
sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC);
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
sqlite3_reset(pStmt);
|
||||
continue;
|
||||
}
|
||||
cSaved = zIn[iNext];
|
||||
zIn[iNext] = 0;
|
||||
if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
|
||||
zIn[iNext] = cSaved;
|
||||
continue;
|
||||
}
|
||||
zSql = &zIn[i];
|
||||
if( verboseFlag ){
|
||||
printf("INPUT (offset: %d, size: %d): [%s]\n",
|
||||
i, (int)strlen(&zIn[i]), &zIn[i]);
|
||||
}else if( multiTest && !quietFlag ){
|
||||
if( oomFlag ){
|
||||
printf("%s\n", g.zTestName);
|
||||
}else{
|
||||
int pct = (10*iNext)/nIn;
|
||||
if( pct!=lastPct ){
|
||||
if( lastPct<0 ) printf("fuzz test:");
|
||||
printf(" %d%%", pct*10);
|
||||
lastPct = pct;
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
switch( iMode ){
|
||||
case FZMODE_Glob:
|
||||
zSql = zToFree = sqlite3_mprintf("SELECT glob(%s);", zSql);
|
||||
break;
|
||||
case FZMODE_Printf:
|
||||
zSql = zToFree = sqlite3_mprintf("SELECT printf(%s);", zSql);
|
||||
break;
|
||||
case FZMODE_Strftime:
|
||||
zSql = zToFree = sqlite3_mprintf("SELECT strftime(%s);", zSql);
|
||||
break;
|
||||
}
|
||||
if( oomFlag ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.nOomFault = 0;
|
||||
g.bOomOnce = 1;
|
||||
if( verboseFlag ){
|
||||
printf("Once.%d\n", oomCnt);
|
||||
fflush(stdout);
|
||||
|
||||
/* Initialize the input buffer used to hold SQL text */
|
||||
if( nInFile==0 ) nInFile = 1;
|
||||
nAlloc = 1000;
|
||||
zIn = malloc(nAlloc);
|
||||
if( zIn==0 ) fatalError("out of memory");
|
||||
|
||||
/* Loop over all input files */
|
||||
for(jj=0; jj<nInFile; jj++){
|
||||
|
||||
/* Read the complete content of the next input file into zIn[] */
|
||||
FILE *in;
|
||||
if( azInFile ){
|
||||
int j, k;
|
||||
in = fopen(azInFile[jj],"rb");
|
||||
if( in==0 ){
|
||||
abendError("cannot open %s for reading", azInFile[jj]);
|
||||
}
|
||||
zPrompt = azInFile[jj];
|
||||
for(j=k=0; zPrompt[j]; j++) if( zPrompt[j]=='/' ) k = j+1;
|
||||
zPrompt += k;
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
in = stdin;
|
||||
zPrompt = "<stdin>";
|
||||
}
|
||||
do{
|
||||
rc = sqlite3_open_v2(
|
||||
"main.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
|
||||
0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
abendError("Unable to open the in-memory database");
|
||||
}
|
||||
if( pLook ){
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook);
|
||||
if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
|
||||
}
|
||||
if( zInitDb ){
|
||||
sqlite3_backup *pBackup;
|
||||
pBackup = sqlite3_backup_init(db, "main", dbInit, "main");
|
||||
rc = sqlite3_backup_step(pBackup, -1);
|
||||
if( rc!=SQLITE_DONE ){
|
||||
abendError("attempt to initialize the in-memory database failed (rc=%d)",
|
||||
rc);
|
||||
}
|
||||
sqlite3_backup_finish(pBackup);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0);
|
||||
#endif
|
||||
sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
|
||||
if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
|
||||
if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
|
||||
if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
|
||||
g.bOomEnable = 1;
|
||||
if( verboseFlag ){
|
||||
zErrMsg = 0;
|
||||
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
sqlite3_snprintf(sizeof(zErrBuf),zErrBuf,"%z", zErrMsg);
|
||||
zErrMsg = 0;
|
||||
}
|
||||
}else {
|
||||
rc = sqlite3_exec(db, zSql, execNoop, 0, 0);
|
||||
}
|
||||
g.bOomEnable = 0;
|
||||
rc = sqlite3_close(db);
|
||||
if( rc ){
|
||||
abendError("sqlite3_close() failed with rc=%d", rc);
|
||||
}
|
||||
if( sqlite3_memory_used()>0 ){
|
||||
abendError("memory in use after close: %lld bytes", sqlite3_memory_used());
|
||||
}
|
||||
if( oomFlag ){
|
||||
/* Limit the number of iterations of the OOM loop to OOM_MAX. If the
|
||||
** first pass (single failure) exceeds 2/3rds of OOM_MAX this skip the
|
||||
** second pass (continuous failure after first) completely. */
|
||||
if( g.nOomFault==0 || oomCnt>OOM_MAX ){
|
||||
if( g.bOomOnce && oomCnt<=(OOM_MAX*2/3) ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.bOomOnce = 0;
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
}
|
||||
}else{
|
||||
g.iOomCntdown = ++oomCnt;
|
||||
g.nOomFault = 0;
|
||||
}
|
||||
if( oomCnt ){
|
||||
while( !feof(in) ){
|
||||
zIn = realloc(zIn, nAlloc);
|
||||
if( zIn==0 ) fatalError("out of memory");
|
||||
got = fread(zIn+nIn, 1, nAlloc-nIn-1, in);
|
||||
nIn += (int)got;
|
||||
zIn[nIn] = 0;
|
||||
if( got==0 ) break;
|
||||
nAlloc += nAlloc+1000;
|
||||
}
|
||||
if( in!=stdin ) fclose(in);
|
||||
lastPct = -1;
|
||||
|
||||
/* Skip initial lines of the input file that begin with "#" */
|
||||
for(i=0; i<nIn; i=iNext+1){
|
||||
if( zIn[i]!='#' ) break;
|
||||
for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){}
|
||||
}
|
||||
nHeader = i;
|
||||
|
||||
/* Process all test cases contained within the input file.
|
||||
*/
|
||||
for(; i<nIn; i=iNext, nTest++, g.zTestName[0]=0){
|
||||
char cSaved;
|
||||
if( strncmp(&zIn[i], "/****<",6)==0 ){
|
||||
char *z = strstr(&zIn[i], ">****/");
|
||||
if( z ){
|
||||
z += 6;
|
||||
sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s",
|
||||
(int)(z-&zIn[i]) - 12, &zIn[i+6]);
|
||||
if( verboseFlag ){
|
||||
printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt);
|
||||
printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
nTest++;
|
||||
i += (int)(z-&zIn[i]);
|
||||
multiTest = 1;
|
||||
}
|
||||
}
|
||||
}while( oomCnt>0 );
|
||||
if( zToFree ){
|
||||
sqlite3_free(zToFree);
|
||||
zToFree = 0;
|
||||
}
|
||||
zIn[iNext] = cSaved;
|
||||
if( verboseFlag ){
|
||||
printf("RESULT-CODE: %d\n", rc);
|
||||
if( zErrMsg ){
|
||||
printf("ERROR-MSG: [%s]\n", zErrBuf);
|
||||
for(iNext=i; iNext<nIn && strncmp(&zIn[iNext],"/****<",6)!=0; iNext++){}
|
||||
|
||||
/* Store unique test cases in the in the dataDb database if the
|
||||
** --unique-cases flag is present
|
||||
*/
|
||||
if( zDataOut ){
|
||||
sqlite3_bind_blob(pStmt, 1, &zIn[i], iNext-i, SQLITE_STATIC);
|
||||
rc = sqlite3_step(pStmt);
|
||||
if( rc!=SQLITE_DONE ) abendError("%s", sqlite3_errmsg(dataDb));
|
||||
sqlite3_reset(pStmt);
|
||||
continue;
|
||||
}
|
||||
cSaved = zIn[iNext];
|
||||
zIn[iNext] = 0;
|
||||
if( zCkGlob && sqlite3_strglob(zCkGlob,&zIn[i])!=0 ){
|
||||
zIn[iNext] = cSaved;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Print out the SQL of the next test case is --verbose is enabled
|
||||
*/
|
||||
zSql = &zIn[i];
|
||||
if( verboseFlag ){
|
||||
printf("INPUT (offset: %d, size: %d): [%s]\n",
|
||||
i, (int)strlen(&zIn[i]), &zIn[i]);
|
||||
}else if( multiTest && !quietFlag ){
|
||||
if( oomFlag ){
|
||||
printf("%s\n", g.zTestName);
|
||||
}else{
|
||||
int pct = (10*iNext)/nIn;
|
||||
if( pct!=lastPct ){
|
||||
if( lastPct<0 ) printf("%s:", zPrompt);
|
||||
printf(" %d%%", pct*10);
|
||||
lastPct = pct;
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
/* Simulate an error if the TEST_FAILURE environment variable is "5" */
|
||||
if( zFailCode ){
|
||||
if( zFailCode[0]=='5' && zFailCode[1]==0 ){
|
||||
abendError("simulated failure");
|
||||
}else if( zFailCode[0]!=0 ){
|
||||
/* If TEST_FAILURE is something other than 5, just exit the test
|
||||
** early */
|
||||
printf("\nExit early due to TEST_FAILURE being set");
|
||||
break;
|
||||
|
||||
/* Run the next test case. Run it multiple times in --oom mode
|
||||
*/
|
||||
if( oomFlag ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.nOomFault = 0;
|
||||
g.bOomOnce = 1;
|
||||
if( verboseFlag ){
|
||||
printf("Once.%d\n", oomCnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
}
|
||||
do{
|
||||
rc = sqlite3_open_v2(
|
||||
"main.db", &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY,
|
||||
0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
abendError("Unable to open the in-memory database");
|
||||
}
|
||||
if( pLook ){
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE,pLook,szLook,nLook);
|
||||
if( rc!=SQLITE_OK ) abendError("lookaside configuration filed: %d", rc);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
sqlite3_trace(db, verboseFlag ? traceCallback : traceNoop, 0);
|
||||
#endif
|
||||
sqlite3_create_function(db, "eval", 1, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_create_function(db, "eval", 2, SQLITE_UTF8, 0, sqlEvalFunc, 0, 0);
|
||||
sqlite3_limit(db, SQLITE_LIMIT_LENGTH, 1000000);
|
||||
if( zEncoding ) sqlexec(db, "PRAGMA encoding=%s", zEncoding);
|
||||
if( pageSize ) sqlexec(db, "PRAGMA pagesize=%d", pageSize);
|
||||
if( doAutovac ) sqlexec(db, "PRAGMA auto_vacuum=FULL");
|
||||
g.bOomEnable = 1;
|
||||
if( verboseFlag ){
|
||||
zErrMsg = 0;
|
||||
rc = sqlite3_exec(db, zSql, execCallback, 0, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
sqlite3_snprintf(sizeof(zErrBuf),zErrBuf,"%z", zErrMsg);
|
||||
zErrMsg = 0;
|
||||
}
|
||||
}else {
|
||||
rc = sqlite3_exec(db, zSql, execNoop, 0, 0);
|
||||
}
|
||||
g.bOomEnable = 0;
|
||||
rc = sqlite3_close(db);
|
||||
if( rc ){
|
||||
abendError("sqlite3_close() failed with rc=%d", rc);
|
||||
}
|
||||
if( sqlite3_memory_used()>0 ){
|
||||
abendError("memory in use after close: %lld bytes",sqlite3_memory_used());
|
||||
}
|
||||
if( oomFlag ){
|
||||
/* Limit the number of iterations of the OOM loop to OOM_MAX. If the
|
||||
** first pass (single failure) exceeds 2/3rds of OOM_MAX this skip the
|
||||
** second pass (continuous failure after first) completely. */
|
||||
if( g.nOomFault==0 || oomCnt>OOM_MAX ){
|
||||
if( g.bOomOnce && oomCnt<=(OOM_MAX*2/3) ){
|
||||
oomCnt = g.iOomCntdown = 1;
|
||||
g.bOomOnce = 0;
|
||||
}else{
|
||||
oomCnt = 0;
|
||||
}
|
||||
}else{
|
||||
g.iOomCntdown = ++oomCnt;
|
||||
g.nOomFault = 0;
|
||||
}
|
||||
if( oomCnt ){
|
||||
if( verboseFlag ){
|
||||
printf("%s.%d\n", g.bOomOnce ? "Once" : "Multi", oomCnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
nTest++;
|
||||
}
|
||||
}
|
||||
}while( oomCnt>0 );
|
||||
|
||||
/* Free the SQL from the current test case
|
||||
*/
|
||||
if( zToFree ){
|
||||
sqlite3_free(zToFree);
|
||||
zToFree = 0;
|
||||
}
|
||||
zIn[iNext] = cSaved;
|
||||
|
||||
/* Show test-case results in --verbose mode
|
||||
*/
|
||||
if( verboseFlag ){
|
||||
printf("RESULT-CODE: %d\n", rc);
|
||||
if( zErrMsg ){
|
||||
printf("ERROR-MSG: [%s]\n", zErrBuf);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Simulate an error if the TEST_FAILURE environment variable is "5".
|
||||
** This is used to verify that automated test script really do spot
|
||||
** errors that occur in this test program.
|
||||
*/
|
||||
if( zFailCode ){
|
||||
if( zFailCode[0]=='5' && zFailCode[1]==0 ){
|
||||
abendError("simulated failure");
|
||||
}else if( zFailCode[0]!=0 ){
|
||||
/* If TEST_FAILURE is something other than 5, just exit the test
|
||||
** early */
|
||||
printf("\nExit early due to TEST_FAILURE being set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !verboseFlag && multiTest && !quietFlag && !oomFlag ) printf("\n");
|
||||
}
|
||||
if( !verboseFlag && multiTest && !quietFlag && !oomFlag ) printf("\n");
|
||||
|
||||
/* Report total number of tests run
|
||||
*/
|
||||
if( nTest>1 && !quietFlag ){
|
||||
printf("%s: 0 errors out of %d tests\nSQLite %s %s\n",
|
||||
g.zArgv0, nTest, sqlite3_libversion(), sqlite3_sourceid());
|
||||
}
|
||||
|
||||
/* Write the unique test cases if the --unique-cases flag was used
|
||||
*/
|
||||
if( zDataOut ){
|
||||
int n = 0;
|
||||
FILE *out = fopen(zDataOut, "wb");
|
||||
@@ -802,6 +812,10 @@ int main(int argc, char **argv){
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_close(dataDb);
|
||||
}
|
||||
|
||||
/* Clean up and exit.
|
||||
*/
|
||||
free(azInFile);
|
||||
free(zIn);
|
||||
free(pHeap);
|
||||
free(pLook);
|
||||
|
||||
Reference in New Issue
Block a user