diff --git a/manifest b/manifest index 6739ca4e51..9b5a006ffa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\s'configure'\sbuild\ssystem.\sAlso\sextra\scoverage\sfor\smain.c.\s(CVS\s2204) -D 2005-01-13T02:14:24 +C Test\scases\sto\simprove\scoverage\sof\spager.c.\s(CVS\s2205) +D 2005-01-13T11:07:53 F Makefile.in 6ce51dde6a8fe82fc12f20dec750572f6a19f56a F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 @@ -53,7 +53,7 @@ F src/os_unix.c 08340c864822115bf87c6c1735780a0996278b81 F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13 F src/os_win.c 3c0b0a3bc33318cf555a1cd130232ad1b9a5a711 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c c6b29d55c9755f35bd9d711865aaf83e410f730f +F src/pager.c 4b37f741fc199166cc69cfdfdbbb1e41b30f7ede F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862 F src/parse.y ceba179b9703657180963568f54b0e75f33e36e1 F src/pragma.c ac594f74c90ffec043c43e49358719ffeb491eec @@ -66,7 +66,7 @@ F src/sqliteInt.h 641b348a109a080262d9f3603f2e94143d4383f2 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 F src/tclsqlite.c 8419f424ebcc6ae0d391f21a991638cb20c2ffc6 F src/test1.c 2e27b110ba5aa16977bad1cc2388553479d73793 -F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8 +F src/test2.c bbc2ecc58ceeab12d1e40970f831b1017524e40d F src/test3.c a72f20066cccd5a7b9f20b7b78fa9b05b47b3020 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5 @@ -80,11 +80,11 @@ F src/vdbe.c a89bb4eefa60226ddfdf8e708ea9352c0a124da3 F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181 F src/vdbeInt.h f2b5f54d9881bbc89fff02d95f3f825ade68bce2 F src/vdbeapi.c 0cf3bdc1072616bedc8eec7fc22e3f5a169d33fd -F src/vdbeaux.c 0675db9f7f801b36e2e71504f5380feeadba56bc +F src/vdbeaux.c 6c294f7390880a7bb4795c9e0bc605b1a416579a F src/vdbemem.c 62fe89471b656a922e9879be005abf690509ead3 F src/where.c 3a0d08505e298242f6f151f019a05129a4f8704c F tclinstaller.tcl 36478c3bbfc5b93ceac42d94e3c736937b808432 -F test/all.test 387e2e3bed9325bfdc538ebb7f2238cce69620e9 +F test/all.test 461ed369bfa26ab5564df7a57514a17fd54069d1 F test/alter.test 95c57a4f461fa81293e0dccef7f83889aadb169a F test/attach.test f39069efd4394422798f249df9a31489aa941ee1 F test/attach2.test eeb987770f4dbe68bd29afdbc2e8cff0142e6eb5 @@ -117,7 +117,7 @@ F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638 F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87 F test/corrupt.test 0080ddcece23e8ba47c44608c4fb73fd4d1d8ce2 F test/corrupt2.test cb1f813df7559de3021e01170af0bba31507a9a5 -F test/crash.test 637479504e137d065385c5b9379680d2b5372630 +F test/crash.test b87f2c2fe6a05c46c8832bb077e131bb4b507a8d F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/cursor.test d7c65ea0fc4e321e12fbcf5c7f3e2211ef45379b F test/date.test dda578ec1857837156bd8b32f8e09d81d7d7881c @@ -138,7 +138,7 @@ F test/insert.test 56f9c20c9adc8d707490c4ffa5d4daa94826ea03 F test/insert2.test 0bb50ff999e35a21549d8ee5dc44db8ac24d31a7 F test/interrupt.test 5b4d8389e6cf2d01b94f87cfd02d9df1073bfb2d F test/intpkey.test b57cf5236fde1bd8cbc1388fa0c91908f6fd9194 -F test/ioerr.test 0563e3eace01d94661899a90e5888b7817fb57e0 +F test/ioerr.test 259bef101273a8e7b16d004018ee5a7873a26889 F test/join.test ea8c77b9fbc377fe553cdb5ce5f1bd72021dca5d F test/join2.test c97e4c5aa65dea462145529e58212a709b4722b8 F test/join3.test 67dc0d7c8dab3fff25796d0f3c3fd9c999aeded3 @@ -150,7 +150,7 @@ F test/lock.test a19aab9a963273fe61c1058e3d1b648d6a0a2425 F test/lock2.test 59c3dd7d9b24d1bf7ec91b2d1541c37e97939d5f F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9 F test/main.test a60a1d234b5f5784097973bd395514ca56003ef1 -F test/malloc.test 73fa135dac192bc47162c75089ad93db19640a72 +F test/malloc.test a301c880f65e802cda9cbeba2f072a55a5a5cecb F test/memdb.test 532aac7128a3da494cddc4461d76c6e3988f771b F test/memleak.test f1fa233f8295dd1d955a00d5e5ee857850f27f29 F test/minmax.test e7048476940df0af11d0f2cf687572f557cd0b29 @@ -161,7 +161,7 @@ F test/misc4.test 7edc2542eadd98555c2d25c222b88a93124975ae F test/misuse.test 2d7c46160f7c214f761fc5d030684a37ae8832a6 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test 5a945790ef21b24fd602fe2c7a23847b903f8687 -F test/pager.test 394455707a079804e8a4e431d12edce831a065f0 +F test/pager.test 5ac7ce028a697283846d7e0c01622d253c8df1ef F test/pager2.test 49c0f57c7da0b060f0486b85fdd074025caa694e F test/pager3.test 647f696a9cf7409df00a1e0047c2eb55585a1b85 F test/pagesize.test 1b826d1608fd86d2303aa895b5586052ad07eba1 @@ -187,7 +187,7 @@ F test/table.test b8b0bee2ac2f3d36a674bc68344c1bdd80e99a18 F test/tableapi.test b21ab097e87a5484bb61029e69e1a4e5c5e65ede F test/tclsqlite.test f467d9062e17c1ace54467e6fba5ce3ca176c0fe F test/temptable.test 63a16e3ad19adf073cfbcdf7624c92ac5236522c -F test/tester.tcl 071ad70ee2c1d3393e20baabaac03f07e7925cfe +F test/tester.tcl 48bf84ac713c57177685d2ba1ad5b823b80b0f49 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c 97a830d53c24c42290501fdfba4a6e5bdd34748b @@ -268,7 +268,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl c3b50d3ac31c54be2a1af9b488a89d22f1e6e746 -P 1c19e8bdca24484fcb9f068b38ebfbce3e24ada5 -R b76a833a2483450473314d802bbb9364 +P 8378455f32c3010ccc28181048c746ecb8a9fa67 +R a61a3877ed12f3c97188522b730cced9 U danielk1977 -Z 5b30f3260cf2298fa7cd18908f9e112b +Z 31a1cc8df4dbfa6bc63a4e33300fff94 diff --git a/manifest.uuid b/manifest.uuid index eddebfcb78..26594ea0ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8378455f32c3010ccc28181048c746ecb8a9fa67 \ No newline at end of file +0428a1480126f7e73dc1e24b6fbfa185d2d83dd3 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 9702f741f0..945475f1ce 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.181 2005/01/11 10:25:08 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.182 2005/01/13 11:07:53 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -358,7 +358,7 @@ static const unsigned char aJournalMagic[] = { /* ** Enable reference count tracking (for debugging) here: */ -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG int pager3_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ static int cnt = 0; @@ -506,8 +506,9 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){ */ sqliteFree(*pzMaster); *pzMaster = 0; + }else{ + (*pzMaster)[len] = '\0'; } - (*pzMaster)[len] = '\0'; return SQLITE_OK; } @@ -1829,12 +1830,7 @@ int sqlite3pager_close(Pager *pPager){ ** sqlite3OsDelete(pPager->zFilename); ** } */ - if( pPager->zFilename!=(char*)&pPager[1] ){ - assert( 0 ); /* Cannot happen */ - sqliteFree(pPager->zFilename); - sqliteFree(pPager->zJournal); - sqliteFree(pPager->zDirectory); - } + sqliteFree(pPager); return SQLITE_OK; } @@ -1879,7 +1875,7 @@ static void _page_ref(PgHdr *pPg){ pPg->nRef++; REFINFO(pPg); } -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG static void page_ref(PgHdr *pPg){ if( pPg->nRef==0 ){ _page_ref(pPg); diff --git a/src/test2.c b/src/test2.c index 0ba0c2a7f6..b7c83cf56e 100644 --- a/src/test2.c +++ b/src/test2.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test2.c,v 1.27 2004/10/01 14:38:03 drh Exp $ +** $Id: test2.c,v 1.28 2005/01/13 11:07:54 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -376,6 +376,34 @@ static int page_lookup( return TCL_OK; } +/* +** Usage: pager_truncate ID PGNO +*/ +static int pager_truncate( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + const char **argv /* Text of each argument */ +){ + Pager *pPager; + int rc; + int pgno; + if( argc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ID PGNO\"", 0); + return TCL_ERROR; + } + pPager = sqlite3TextToPtr(argv[1]); + if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; + rc = sqlite3pager_truncate(pPager, pgno); + if( rc!=SQLITE_OK ){ + Tcl_AppendResult(interp, errorName(rc), 0); + return TCL_ERROR; + } + return TCL_OK; +} + + /* ** Usage: page_unref PAGE ** @@ -553,6 +581,7 @@ int Sqlitetest2_Init(Tcl_Interp *interp){ { "page_read", (Tcl_CmdProc*)page_read }, { "page_write", (Tcl_CmdProc*)page_write }, { "page_number", (Tcl_CmdProc*)page_number }, + { "pager_truncate", (Tcl_CmdProc*)pager_truncate }, { "fake_big_file", (Tcl_CmdProc*)fake_big_file }, }; int i; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f06e357ef4..0392d60367 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1034,7 +1034,7 @@ static int vdbeCommit(sqlite3 *db){ ** master journal file. If an error occurs at this point close ** and delete the master journal file. All the individual journal files ** still have 'null' as the master journal pointer, so they will roll - ** back independantly if a failure occurs. + ** back independently if a failure occurs. */ for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; diff --git a/test/all.test b/test/all.test index 6ba2571858..3674ba90a6 100644 --- a/test/all.test +++ b/test/all.test @@ -10,7 +10,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: all.test,v 1.26 2005/01/12 07:15:07 danielk1977 Exp $ +# $Id: all.test,v 1.27 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -115,7 +115,7 @@ if {$LeakList!=""} { # Run the crashtest only on unix and only once. If the library does not # always create auto-vacuum databases, also run autovacuum_crash.test. # -if {$tcl_platform(platform)=="unix"} { +if {$::tcl_platform(platform)=="unix"} { source $testdir/crash.test ifcapable !default_autovacuum { source $testdir/autovacuum_crash.test diff --git a/test/crash.test b/test/crash.test index 2373023531..3d0751518b 100644 --- a/test/crash.test +++ b/test/crash.test @@ -20,7 +20,7 @@ # The special crash-test module with its os_test.c backend only works # on Unix. # -# $Id: crash.test,v 1.13 2005/01/08 02:35:44 danielk1977 Exp $ +# $Id: crash.test,v 1.14 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -407,6 +407,30 @@ do_test crash-6.2 { signature } $sig +#-------------------------------------------------------------------------- +# These test cases test the case where the master journal file name is +# corrupted slightly so that the corruption has to be detected by the +# checksum. +do_test crash-7.1 { + crashsql 1 test.db { + ATTACH 'test2.db' AS aux; + BEGIN; + INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); + INSERT INTO abc2 VALUES(randstr(1500,1500), 0, 0); + COMMIT; + } + + # Change the checksum value for the master journal name. + set f [open test.db-journal a] + fconfigure $f -encoding binary + seek $f [expr [file size test.db-journal] - 12] + puts -nonewline $f "\00\00\00\00" + close $f +} {} +do_test crash-7.2 { + signature +} $sig + # The AUTOVACUUM was changed above. We have to reset it for # other scripts that run as part of "fulltest" # diff --git a/test/ioerr.test b/test/ioerr.test index fe56811d9b..6d277d07cb 100644 --- a/test/ioerr.test +++ b/test/ioerr.test @@ -15,7 +15,7 @@ # The tests in this file use special facilities that are only # available in the SQLite test fixture. # -# $Id: ioerr.test,v 1.11 2005/01/12 09:10:41 danielk1977 Exp $ +# $Id: ioerr.test,v 1.12 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -32,12 +32,16 @@ set ::AV [execsql {pragma auto_vacuum}] # -tclbody TCL script to run with IO error simulation. # -sqlbody TCL script to run with IO error simulation. # -exclude List of 'N' values not to test. +# -start Value of 'N' to begin with (default 1) # proc do_ioerr_test {tn args} { array set ::ioerropts $args set ::go 1 - for {set n 1} {$::go} {incr n} { + if {![info exists ::ioerropts(-start)]} { + set ::ioerropts(-start) 1 + } + for {set n $::ioerropts(-start)} {$::go} {incr n} { if {[info exists ::ioerropts(-exclude)]} { if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue @@ -45,7 +49,7 @@ proc do_ioerr_test {tn args} { do_test ioerr-$tn.$n.1 { set ::sqlite_io_error_pending 0 - db close + catch {db close} catch {file delete -force test.db} catch {file delete -force test.db-journal} catch {file delete -force test2.db} @@ -80,6 +84,7 @@ proc do_ioerr_test {tn args} { } {1} } set ::sqlite_io_error_pending 0 + unset ::ioerropts } # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error @@ -213,6 +218,9 @@ do_ioerr_test 4 -tclprep { } # Test IO errors that may occur during a multi-file commit. +# +# Test 8 is excluded when auto-vacuum is enabled for the same reason +# as in test cases ioerr-1.XXX do_ioerr_test 5 -sqlprep { ATTACH 'test2.db' AS test2; } -sqlbody { @@ -220,6 +228,63 @@ do_ioerr_test 5 -sqlprep { CREATE TABLE t1(a,b,c); CREATE TABLE test2.t2(a,b,c); COMMIT; +} -exclude [expr [execsql {pragma auto_vacuum}] ? 8 : 0] + +# Test IO errors when replaying two hot journals from a 2-file +# transaction. This test only runs on UNIX. +if {$tcl_platform(platform)=="unix"} { + do_ioerr_test 6 -tclprep { + set rc [crashsql 2 test2.db-journal { + ATTACH 'test2.db' as aux; + PRAGMA cache_size = 10; + BEGIN; + CREATE TABLE aux.t2(a, b, c); + CREATE TABLE t1(a, b, c); + COMMIT; + }] + if {$rc!="1 {child process exited abnormally}"} { + error "Wrong error message: $rc" + } + } -sqlbody { + ATTACH 'test2.db' as aux; + SELECT * FROM t1; + SELECT * FROM t2; + } } +# Test handling of IO errors that occur while rolling back hot journal +# files. +do_ioerr_test 14 -tclprep { + db close + sqlite3 db2 test2.db + db2 eval { + PRAGMA synchronous = 0; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + BEGIN; + INSERT INTO t1 VALUES(3, 4); + } + file copy -force test2.db test.db + file copy -force test2.db-journal test.db-journal + db2 close +} -tclbody { + sqlite3 db test.db + db eval { + SELECT * FROM t1; + } +} -exclude 1 + +# do_ioerr_test 15 -sqlprep { +# CREATE TABLE abc(a UNIQUE, b, c); +# INSERT INTO abc VALUES(1, 2, 3); +# } -sqlbody { +# BEGIN; +# INSERT INTO abc VALUES(1, 2, 3); +# COMMIT; +# } + finish_test + + + + diff --git a/test/malloc.test b/test/malloc.test index 33e2b63089..8d1a119fbf 100644 --- a/test/malloc.test +++ b/test/malloc.test @@ -14,7 +14,7 @@ # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # -# $Id: malloc.test,v 1.18 2005/01/13 02:14:25 danielk1977 Exp $ +# $Id: malloc.test,v 1.19 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -96,6 +96,7 @@ proc do_malloc_test {tn args} { } } {1 1} } + unset ::mallocopts } for {set go 1; set i 1} {$go} {incr i} { @@ -498,6 +499,48 @@ do_malloc_test 12 -tclbody { sqlite3_finalize $::STMT } +# Test malloc errors when replaying two hot journals from a 2-file +# transaction. This test only runs on UNIX. +if {$tcl_platform(platform)=="unix"} { + do_malloc_test 13 -tclprep { + set rc [crashsql 1 test2.db { + ATTACH 'test2.db' as aux; + PRAGMA cache_size = 10; + BEGIN; + CREATE TABLE aux.t2(a, b, c); + CREATE TABLE t1(a, b, c); + COMMIT; + }] + if {$rc!="1 {child process exited abnormally}"} { + error "Wrong error message: $rc" + } + } -sqlbody { + ATTACH 'test2.db' as aux; + SELECT * FROM t1; + SELECT * FROM t2; + } +} + +do_malloc_test 14 -tclprep { + catch {db close} + sqlite3 db2 test2.db + db2 eval { + PRAGMA synchronous = 0; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + BEGIN; + INSERT INTO t1 VALUES(3, 4); + } + file copy -force test2.db test.db + file copy -force test2.db-journal test.db-journal + db2 close +} -tclbody { + sqlite3 db test.db + db eval { + SELECT * FROM t1; + } +} + # Ensure that no file descriptors were leaked. do_test malloc-99.X { catch {db close} diff --git a/test/pager.test b/test/pager.test index 269360a5a6..26e8ee9ec9 100644 --- a/test/pager.test +++ b/test/pager.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is page cache subsystem. # -# $Id: pager.test,v 1.18 2004/09/08 20:13:06 drh Exp $ +# $Id: pager.test,v 1.19 2005/01/13 11:07:54 danielk1977 Exp $ set testdir [file dirname $argv0] @@ -396,6 +396,26 @@ for {set i 1} {$i<20} {incr i} { } {state 1} } +# Test that nothing bad happens when sqlite3pager_set_cachesize() is +# called with a negative argument. +do_test pager-4.6.1 { + pager_close [pager_open ptf2.db -15] +} {} + +# Test truncate on an in-memory database is Ok. +do_test pager-4.6.2 { + set ::p2 [pager_open :memory: 10] + pager_truncate $::p2 5 +} {} +do_test pager-4.6.3 { + for {set i 1} {$i<5} {incr i} { + set p [page_get $::p2 $i] + page_write $p "Page $i" + pager_commit $::p2 + } + pager_truncate $::p2 3 +} {} + do_test pager-4.99 { pager_close $::p1 } {} @@ -421,4 +441,76 @@ do_test pager-5.1 { } {} } +do_test pager-6.1 { + file delete -force test2.db + file delete -force test2.db-journal + sqlite3 db2 test2.db + execsql { + PRAGMA synchronous = 0; + CREATE TABLE abc(a, b, c); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + INSERT INTO abc VALUES(1, 2, randstr(200,200)); + BEGIN; + UPDATE abc SET c = randstr(200,200); + } db2 + file copy -force test2.db test.db + file copy -force test2.db-journal test.db-journal + + set f [open test.db-journal a] + fconfigure $f -encoding binary + seek $f [expr [file size test.db-journal] - 1032] start + puts -nonewline $f "\00\00\00\00" + close $f + + sqlite3 db test.db + execsql { + SELECT sql FROM sqlite_master + } +} {{CREATE TABLE abc(a, b, c)}} + +do_test pager-6.2 { + file copy -force test2.db test.db + file copy -force test2.db-journal test.db-journal + + set f [open test.db-journal a] + fconfigure $f -encoding binary + seek $f [expr [file size test.db-journal] - 1032] start + puts -nonewline $f "\00\00\00\FF" + close $f + + sqlite3 db test.db + execsql { + SELECT sql FROM sqlite_master + } +} {{CREATE TABLE abc(a, b, c)}} + +do_test pager-6.3 { + file copy -force test2.db test.db + file copy -force test2.db-journal test.db-journal + + set f [open test.db-journal a] + fconfigure $f -encoding binary + seek $f [expr [file size test.db-journal] - 4] start + puts -nonewline $f "\00\00\00\00" + close $f + + sqlite3 db test.db + execsql { + SELECT sql FROM sqlite_master + } +} {{CREATE TABLE abc(a, b, c)}} + +do_test pager-6.4 { + db2 close +} {} finish_test + + + diff --git a/test/tester.tcl b/test/tester.tcl index 7c39c723f0..e41aeb6de5 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -11,7 +11,7 @@ # This file implements some common TCL routines used for regression # testing the SQLite library # -# $Id: tester.tcl,v 1.43 2005/01/03 01:33:00 drh Exp $ +# $Id: tester.tcl,v 1.44 2005/01/13 11:07:54 danielk1977 Exp $ # Make sure tclsqlite3 was compiled correctly. Abort now with an # error message if not. @@ -246,6 +246,41 @@ proc ifcapable {expr code} { return -code [catch {uplevel 1 $code}] } +# This proc execs a seperate process that crashes midway through executing +# the SQL script $sql on database test.db. +# +# The crash occurs during a sync() of file $crashfile. When the crash +# occurs a random subset of all unsynced writes made by the process are +# written into the files on disk. Argument $crashdelay indicates the +# number of file syncs to wait before crashing. +# +# The return value is a list of two elements. The first element is a +# boolean, indicating whether or not the process actually crashed or +# reported some other error. The second element in the returned list is the +# error message. This is "child process exited abnormally" if the crash +# occured. +# +proc crashsql {crashdelay crashfile sql} { + if {$::tcl_platform(platform)!="unix"} { + error "crashsql should only be used on unix" + } + set cfile [file join [pwd] $crashfile] + + set f [open crash.tcl w] + puts $f "sqlite3_crashparams $crashdelay $cfile" + puts $f "sqlite3 db test.db" + puts $f "db eval {pragma cache_size = 10}" + puts $f "db eval {" + puts $f "$sql" + puts $f "}" + close $f + + set r [catch { + exec [file join . crashtest] crash.tcl >@stdout + } msg] + lappend r $msg +} + # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum)