Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the --result-trace option to fuzzcheck, and other interface enhancements. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c415bb7bbfd531b138462589cdd58fa0 |
User & Date: | drh 2015-05-26 00:28:08.697 |
Context
2015-05-26
| ||
03:24 | Add fuzzcheck to makefile clean targets. Also, for consistency, replace a few tabs with spaces. (check-in: eda2a43750 user: mistachkin tags: trunk) | |
00:28 | Add the --result-trace option to fuzzcheck, and other interface enhancements. (check-in: c415bb7bbf user: drh tags: trunk) | |
2015-05-25
| ||
23:14 | Fix an important bug in the xRead method of the in-memory VFS for fuzzcheck. (check-in: 58cd40e89f user: drh tags: trunk) | |
Changes
Changes to test/fuzzcheck.c.
︙ | ︙ | |||
62 63 64 65 66 67 68 69 70 71 72 73 74 75 | /* ** The value of a database file template, or of an SQL script */ typedef struct Blob Blob; struct Blob { Blob *pNext; /* Next in a list */ int id; /* Id of this Blob */ int sz; /* Size of this Blob in bytes */ unsigned char a[1]; /* Blob content. Extra space allocated as needed. */ }; /* ** Maximum number of files in the in-memory virtual filesystem. */ | > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* ** The value of a database file template, or of an SQL script */ typedef struct Blob Blob; struct Blob { Blob *pNext; /* Next in a list */ int id; /* Id of this Blob */ int seq; /* Sequence number */ int sz; /* Size of this Blob in bytes */ unsigned char a[1]; /* Blob content. Extra space allocated as needed. */ }; /* ** Maximum number of files in the in-memory virtual filesystem. */ |
︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 | head.pNext = 0; p = &head; while( SQLITE_ROW==sqlite3_step(pStmt) ){ int sz = sqlite3_column_bytes(pStmt, 1); Blob *pNew = safe_realloc(0, sizeof(*pNew)+sz ); pNew->id = sqlite3_column_int(pStmt, 0); pNew->sz = sz; pNew->pNext = 0; memcpy(pNew->a, sqlite3_column_blob(pStmt,1), sz); pNew->a[sz] = 0; p->pNext = pNew; p = pNew; | > < | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | head.pNext = 0; p = &head; while( SQLITE_ROW==sqlite3_step(pStmt) ){ int sz = sqlite3_column_bytes(pStmt, 1); Blob *pNew = safe_realloc(0, sizeof(*pNew)+sz ); pNew->id = sqlite3_column_int(pStmt, 0); pNew->sz = sz; pNew->seq = n++; pNew->pNext = 0; memcpy(pNew->a, sqlite3_column_blob(pStmt,1), sz); pNew->a[sz] = 0; p->pNext = pNew; p = pNew; } sqlite3_finalize(pStmt); *pN = n; *ppList = head.pNext; } /* |
︙ | ︙ | |||
502 503 504 505 506 507 508 509 510 511 512 | inmemVfs.xRandomness = pDefault->xRandomness; inmemVfs.xSleep = pDefault->xSleep; inmemVfs.xCurrentTime = pDefault->xCurrentTime; inmemVfs.xGetLastError = inmemGetLastError; sqlite3_vfs_register(&inmemVfs, 0); }; /* ** Run multiple commands of SQL. Similar to sqlite3_exec(), but does not ** stop if an error is encountered. */ | > > > > > > | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | inmemVfs.xRandomness = pDefault->xRandomness; inmemVfs.xSleep = pDefault->xSleep; inmemVfs.xCurrentTime = pDefault->xCurrentTime; inmemVfs.xGetLastError = inmemGetLastError; sqlite3_vfs_register(&inmemVfs, 0); }; /* ** Allowed values for the runFlags parameter to runSql() */ #define SQL_TRACE 0x0001 /* Print each SQL statement as it is prepared */ #define SQL_OUTPUT 0x0002 /* Show the SQL output */ /* ** Run multiple commands of SQL. Similar to sqlite3_exec(), but does not ** stop if an error is encountered. */ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){ const char *zMore; sqlite3_stmt *pStmt; while( zSql && zSql[0] ){ zMore = 0; pStmt = 0; sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zMore); if( zMore==zSql ) break; if( runFlags & SQL_TRACE ){ const char *z = zSql; int n; while( z<zMore && isspace(z[0]) ) z++; n = (int)(zMore - z); while( n>0 && isspace(z[n-1]) ) n--; if( n==0 ) break; if( pStmt==0 ){ printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db)); }else{ printf("TRACE: %.*s\n", n, z); } } zSql = zMore; if( pStmt ){ if( (runFlags & SQL_OUTPUT)==0 ){ while( SQLITE_ROW==sqlite3_step(pStmt) ){} }else{ int nCol = -1; while( SQLITE_ROW==sqlite3_step(pStmt) ){ int i; if( nCol<0 ){ nCol = sqlite3_column_count(pStmt); }else if( nCol>0 ){ printf("--------------------------------------------\n"); } for(i=0; i<nCol; i++){ int eType = sqlite3_column_type(pStmt,i); printf("%s = ", sqlite3_column_name(pStmt,i)); switch( eType ){ case SQLITE_NULL: { printf("NULL\n"); break; } case SQLITE_INTEGER: { printf("INT %s\n", sqlite3_column_text(pStmt,i)); break; } case SQLITE_FLOAT: { printf("FLOAT %s\n", sqlite3_column_text(pStmt,i)); break; } case SQLITE_TEXT: { printf("TEXT [%s]\n", sqlite3_column_text(pStmt,i)); break; } case SQLITE_BLOB: { printf("BLOB (%d bytes)\n", sqlite3_column_bytes(pStmt,i)); break; } } } } } sqlite3_finalize(pStmt); } } } /* ** Print sketchy documentation for this utility program |
︙ | ︙ | |||
552 553 554 555 556 557 558 559 560 561 562 563 564 565 | " --dbid N Use only the database where dbid=N\n" " --help Show this help text\n" " -q Reduced output\n" " --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" " --native-vfs Use the native VFS for initially empty database files\n" " --sqlid N Use only SQL where sqlid=N\n" " -v Increased output\n" " --verbose Increased output\n" ); } int main(int argc, char **argv){ | > | 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | " --dbid N Use only the database where dbid=N\n" " --help Show this help text\n" " -q Reduced output\n" " --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" " --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" " -v Increased output\n" " --verbose Increased output\n" ); } int main(int argc, char **argv){ |
︙ | ︙ | |||
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 | int rc; /* Result code from SQLite interface calls */ Blob *pSql; /* For looping over SQL scripts */ Blob *pDb; /* For looping over template databases */ int i; /* Loop index for the argv[] loop */ int onlySqlid = -1; /* --sqlid */ int onlyDbid = -1; /* --dbid */ int nativeFlag = 0; /* --native-vfs */ iBegin = timeOfDay(); g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ z++; if( z[0]=='-' ) z++; if( strcmp(z,"dbid")==0 ){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlyDbid = atoi(argv[++i]); }else if( strcmp(z,"help")==0 ){ showHelp(); return 0; }else if( strcmp(z,"load-sql")==0 ){ | > | > > > > | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | int rc; /* Result code from SQLite interface calls */ Blob *pSql; /* For looping over SQL scripts */ Blob *pDb; /* For looping over template databases */ int i; /* Loop index for the argv[] loop */ int onlySqlid = -1; /* --sqlid */ int onlyDbid = -1; /* --dbid */ int nativeFlag = 0; /* --native-vfs */ int runFlags = 0; /* Flags sent to runSql() */ iBegin = timeOfDay(); g.zArgv0 = argv[0]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' ){ z++; if( z[0]=='-' ) z++; if( strcmp(z,"dbid")==0 ){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlyDbid = atoi(argv[++i]); }else if( strcmp(z,"help")==0 ){ showHelp(); return 0; }else if( strcmp(z,"load-sql")==0 ){ zInsSql = "INSERT INTO xsql(sqltext) VALUES(CAST(readfile(?1) AS text))"; iFirstInsArg = i+1; break; }else if( strcmp(z,"load-db")==0 ){ zInsSql = "INSERT INTO db(dbcontent) VALUES(readfile(?1))"; iFirstInsArg = i+1; break; }else if( strcmp(z,"native-vfs")==0 ){ nativeFlag = 1; }else if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){ quietFlag = 1; verboseFlag = 0; }else if( strcmp(z,"result-trace")==0 ){ runFlags |= SQL_OUTPUT; }else if( strcmp(z,"sqlid")==0 ){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlySqlid = atoi(argv[++i]); }else if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){ quietFlag = 0; verboseFlag = 1; runFlags |= SQL_TRACE; }else { fatalError("unknown option: %s", argv[i]); } }else{ if( zSourceDb ) fatalError("extra argument: %s", argv[i]); zSourceDb = argv[i]; |
︙ | ︙ | |||
672 673 674 675 676 677 678 679 680 681 682 683 684 685 | 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.nDb = 1; } /* Close the source database. Verify that no SQLite memory allocations are ** outstanding. */ | > | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | 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. */ |
︙ | ︙ | |||
708 709 710 711 712 713 714 | 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; | | | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 | 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(); g.zTestName[0] = 0; } } 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), sqlite3_libversion(), sqlite3_sourceid()); } /* Clean up and exit. */ blobListFree(g.pFirstSql); blobListFree(g.pFirstDb); reformatVfs(); return 0; } |