From d9972ef7521ae00520061019601221aa3ac60423 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 May 2015 17:57:56 +0000 Subject: [PATCH] Enhance fuzzcheck with the ability to store descriptions in each source database and to run multiple source databases in a single invocation. FossilOrigin-Name: 193364c81c301a41c16835108d23ad2ab84d9dd7 --- manifest | 14 +-- manifest.uuid | 2 +- test/fuzzcheck.c | 279 +++++++++++++++++++++++++++-------------------- 3 files changed, 171 insertions(+), 124 deletions(-) diff --git a/manifest b/manifest index 9d02bbac65..7a107d9d01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scast\sto\sone\sside\sof\sthe\stest\sadded\sby\s[97806a78]\sin\sorder\sto\savoid\sa\ssigned/unsigned\scomparison\swarning. -D 2015-05-26T17:33:30.013 +C Enhance\sfuzzcheck\swith\sthe\sability\sto\sstore\sdescriptions\sin\seach\ssource\ndatabase\sand\sto\srun\smultiple\ssource\sdatabases\sin\sa\ssingle\sinvocation. +D 2015-05-26T17:57:56.164 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 69b596e4be75a16f4e55587f29db66497b207fad F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -651,7 +651,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 449c4e5928b1cd8da72d2e01dd271188b699342b +F test/fuzzcheck.c 69998e6430903af8f1904dfa8c7fc21c94d59ebc F test/fuzzdata1.txt 9fceb50868e0b798160e83742bd7e44e457176a0 F test/fuzzdata2.txt ba9b4467d7ec46cc85d32c0d031540cd727ae6ad F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 @@ -1279,7 +1279,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 b05cae36cedd98d59813e637f328a52eee7ef0d2 -R 71dc8a83e674b695379f248ac499faa7 -U dan -Z 9e4f492737d95c87cb31979895ac2144 +P 5b46d2a78a45de4176b666bfc89c2aaa6f083662 +R 0ae8e5db841e94a0cd60c9e4742373e1 +U drh +Z f62c751ed8a012eb7d841a949af555ac diff --git a/manifest.uuid b/manifest.uuid index eb3420695f..cf359c332f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b46d2a78a45de4176b666bfc89c2aaa6f083662 \ No newline at end of file +193364c81c301a41c16835108d23ad2ab84d9dd7 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 0af61caf2b..469bd6c987 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -602,6 +602,7 @@ static void showHelp(void){ " --quiet Reduced output\n" " --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n" " --load-db ARGS... Load template databases from files into SOURCE_DB\n" +" -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" " --result-trace Show the results of each SQL command\n" " --sqlid N Use only SQL where sqlid=N\n" @@ -612,12 +613,12 @@ static void showHelp(void){ int main(int argc, char **argv){ sqlite3_int64 iBegin; /* Start time of this program */ - const char *zSourceDb = 0; /* Source database filename */ int quietFlag = 0; /* True if --quiet or -q */ int verboseFlag = 0; /* True if --verbose or -v */ char *zInsSql = 0; /* SQL statement for --load-db or --load-sql */ int iFirstInsArg = 0; /* First argv[] to use for --load-db or --load-sql */ sqlite3 *db = 0; /* The open database connection */ + sqlite3_stmt *pStmt; /* A prepared statement */ int rc; /* Result code from SQLite interface calls */ Blob *pSql; /* For looping over SQL scripts */ Blob *pDb; /* For looping over template databases */ @@ -626,6 +627,12 @@ int main(int argc, char **argv){ int onlyDbid = -1; /* --dbid */ int nativeFlag = 0; /* --native-vfs */ int runFlags = 0; /* Flags sent to runSql() */ + char *zMsg = 0; /* Add this message */ + int nSrcDb = 0; /* Number of source databases */ + char **azSrcDb = 0; /* Array of source database names */ + int iSrcDb; /* Loop over all source databases */ + int nTest = 0; /* Total number of tests performed */ + char *zDbName = ""; /* Appreviated name of a source database */ iBegin = timeOfDay(); g.zArgv0 = argv[0]; @@ -652,6 +659,10 @@ int main(int argc, char **argv){ iFirstInsArg = i+1; break; }else + if( strcmp(z,"m")==0 ){ + if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); + zMsg = argv[++i]; + }else if( strcmp(z,"native-vfs")==0 ){ nativeFlag = 1; }else @@ -675,133 +686,169 @@ int main(int argc, char **argv){ fatalError("unknown option: %s", argv[i]); } }else{ - if( zSourceDb ) fatalError("extra argument: %s", argv[i]); - zSourceDb = argv[i]; + nSrcDb++; + azSrcDb = safe_realloc(azSrcDb, nSrcDb*sizeof(azSrcDb[0])); + azSrcDb[nSrcDb-1] = argv[i]; } } - if( zSourceDb==0 ) fatalError("no source database specified"); - rc = sqlite3_open(zSourceDb, &db); - if( rc ){ - fatalError("cannot open source database %s - %s", - zSourceDb, sqlite3_errmsg(db)); - } - rc = sqlite3_exec(db, - "CREATE TABLE IF NOT EXISTS db(\n" - " dbid INTEGER PRIMARY KEY, -- database id\n" - " dbcontent BLOB -- database disk file image\n" - ");\n" - "CREATE TABLE IF NOT EXISTS xsql(\n" - " sqlid INTEGER PRIMARY KEY, -- SQL script id\n" - " sqltext TEXT -- Text of SQL statements to run\n" - ");", 0, 0, 0); - if( rc ) fatalError("cannot create schema: %s", sqlite3_errmsg(db)); - if( zInsSql ){ - sqlite3_stmt *pStmt; - sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, - readfileFunc, 0, 0); - rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0); - if( rc ) fatalError("cannot prepare statement [%s]: %s", - zInsSql, sqlite3_errmsg(db)); - rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); - if( rc ) fatalError("cannot start a transaction"); - for(i=iFirstInsArg; i1 ){ + if( zMsg ){ + fatalError("cannot change the description of more than one database"); + } + if( zInsSql ){ + fatalError("cannot import into more than one database"); } - sqlite3_finalize(pStmt); - rc = sqlite3_exec(db, "COMMIT", 0, 0, 0); - if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db)); - sqlite3_close(db); - return 0; } - /* Load all SQL script content and all initial database images from the - ** source db - */ - blobListLoadFromDb(db, "SELECT sqlid, sqltext FROM xsql", onlySqlid, - &g.nSql, &g.pFirstSql); - if( g.nSql==0 ) fatalError("need at least one SQL script"); - blobListLoadFromDb(db, "SELECT dbid, dbcontent FROM db", onlyDbid, - &g.nDb, &g.pFirstDb); - if( g.nDb==0 ){ - g.pFirstDb = safe_realloc(0, sizeof(Blob)); - memset(g.pFirstDb, 0, sizeof(Blob)); - g.pFirstDb->id = 1; - g.pFirstDb->seq = 0; - g.nDb = 1; - } - - - /* Close the source database. Verify that no SQLite memory allocations are - ** outstanding. - */ - sqlite3_close(db); - if( sqlite3_memory_used()>0 ){ - fatalError("SQLite has memory in use before the start of testing"); - } - - /* Register the in-memory virtual filesystem - */ - formatVfs(); - inmemVfsRegister(); - - /* Run a test using each SQL script against each database. - */ - if( !verboseFlag && !quietFlag ){ - int i; - i = strlen(zSourceDb) - 1; - while( i>0 && zSourceDb[i-1]!='/' && zSourceDb[i-1]!='\\' ){ i--; } - printf("%s:", &zSourceDb[i]); - } - for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){ - for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){ - int openFlags; - const char *zVfs = "inmem"; - sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d", - pSql->id, pDb->id); - if( verboseFlag ){ - printf("%s\n", g.zTestName); - fflush(stdout); - }else if( !quietFlag ){ - static int prevAmt = -1; - int idx = pSql->seq*g.nDb + pDb->id - 1; - int amt = idx*10/(g.nDb*g.nSql); - if( amt!=prevAmt ){ - printf(" %d%%", amt*10); - fflush(stdout); - prevAmt = amt; - } + /* Process each source database separately */ + for(iSrcDb=0; iSrcDbsz, pDb->a); - openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; - if( nativeFlag && pDb->sz==0 ){ - openFlags |= SQLITE_OPEN_MEMORY; - zVfs = 0; - } - rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); - if( rc ) fatalError("cannot open inmem database"); - runSql(db, (char*)pSql->a, runFlags); + sqlite3_finalize(pStmt); + rc = sqlite3_exec(db, "COMMIT", 0, 0, 0); + if( rc ) fatalError("cannot commit the transaction: %s", sqlite3_errmsg(db)); sqlite3_close(db); - if( sqlite3_memory_used()>0 ) fatalError("memory leak"); - reformatVfs(); - g.zTestName[0] = 0; + return 0; } - } + + /* Load all SQL script content and all initial database images from the + ** source db + */ + blobListLoadFromDb(db, "SELECT sqlid, sqltext FROM xsql", onlySqlid, + &g.nSql, &g.pFirstSql); + if( g.nSql==0 ) fatalError("need at least one SQL script"); + blobListLoadFromDb(db, "SELECT dbid, dbcontent FROM db", onlyDbid, + &g.nDb, &g.pFirstDb); + if( g.nDb==0 ){ + g.pFirstDb = safe_realloc(0, sizeof(Blob)); + memset(g.pFirstDb, 0, sizeof(Blob)); + g.pFirstDb->id = 1; + g.pFirstDb->seq = 0; + g.nDb = 1; + } + + /* Print the description, if there is one */ + if( !quietFlag ){ + int i; + zDbName = azSrcDb[iSrcDb]; + i = strlen(zDbName) - 1; + while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; } + zDbName += i; + sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0); + if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ + printf("%s: %s\n", zDbName, sqlite3_column_text(pStmt,0)); + } + sqlite3_finalize(pStmt); + } + + /* Close the source database. Verify that no SQLite memory allocations are + ** outstanding. + */ + sqlite3_close(db); + if( sqlite3_memory_used()>0 ){ + fatalError("SQLite has memory in use before the start of testing"); + } + + /* Register the in-memory virtual filesystem + */ + formatVfs(); + inmemVfsRegister(); + + /* Run a test using each SQL script against each database. + */ + if( !verboseFlag && !quietFlag ) printf("%s:", zDbName); + for(pSql=g.pFirstSql; pSql; pSql=pSql->pNext){ + for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){ + int openFlags; + const char *zVfs = "inmem"; + sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "sqlid=%d,dbid=%d", + pSql->id, pDb->id); + if( verboseFlag ){ + printf("%s\n", g.zTestName); + fflush(stdout); + }else if( !quietFlag ){ + static int prevAmt = -1; + int idx = pSql->seq*g.nDb + pDb->id - 1; + int amt = idx*10/(g.nDb*g.nSql); + if( amt!=prevAmt ){ + printf(" %d%%", amt*10); + fflush(stdout); + prevAmt = amt; + } + } + createVFile("main.db", pDb->sz, pDb->a); + openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; + if( nativeFlag && pDb->sz==0 ){ + openFlags |= SQLITE_OPEN_MEMORY; + zVfs = 0; + } + rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); + if( rc ) fatalError("cannot open inmem database"); + runSql(db, (char*)pSql->a, runFlags); + sqlite3_close(db); + if( sqlite3_memory_used()>0 ) fatalError("memory leak"); + reformatVfs(); + nTest++; + g.zTestName[0] = 0; + } + } + if( !quietFlag && !verboseFlag ){ + printf(" 100%% - %d tests\n", g.nDb*g.nSql); + } + + /* Clean up at the end of processing a single source database + */ + blobListFree(g.pFirstSql); + blobListFree(g.pFirstDb); + reformatVfs(); + + } /* End loop over all source databases */ if( !quietFlag ){ sqlite3_int64 iElapse = timeOfDay() - iBegin; - if( !verboseFlag ) printf(" 100%%\n"); - printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\nSQLite %s %s\n", - g.nDb*g.nSql, (int)(iElapse/1000), (int)(iElapse%1000), + printf("fuzzcheck: 0 errors out of %d tests in %d.%03d seconds\n" + "SQLite %s %s\n", + nTest, (int)(iElapse/1000), (int)(iElapse%1000), sqlite3_libversion(), sqlite3_sourceid()); } - - /* Clean up and exit. - */ - blobListFree(g.pFirstSql); - blobListFree(g.pFirstDb); - reformatVfs(); return 0; }