From f858740ce94a313f1e7fbe418b660f7fed6d8ff3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 8 Jan 2008 16:03:49 +0000 Subject: [PATCH] Add crash4.test with additional crash testing. (CVS 4695) FossilOrigin-Name: 87b4ac4b73fb84411ced9e9a859dd0e2d211c4b3 --- manifest | 13 ++--- manifest.uuid | 2 +- test/crash4.test | 128 +++++++++++++++++++++++++++++++++++++++++++++++ test/tester.tcl | 15 ++++-- 4 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 test/crash4.test diff --git a/manifest b/manifest index 16e81f9397..ab75ca1531 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sadditional\srandomness\sto\scrash\stests.\s(CVS\s4694) -D 2008-01-08T15:18:52 +C Add\scrash4.test\swith\sadditional\scrash\stesting.\s(CVS\s4695) +D 2008-01-08T16:03:50 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -242,6 +242,7 @@ F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff F test/crash.test 1b6ac8410689ff78028887f445062dc897c9ac89 F test/crash2.test 26d7a4c5520201e5de2c696ea51ab946b59dc0e9 F test/crash3.test 0b09687ae1a3ccbcefdfaeb4b963e26e36255d76 +F test/crash4.test 97c5b44f432b7b00d58edea76b8e9823e38ce825 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272 F test/date.test b2bd57ff2ab6185b9322306f7b68fa647d63c857 @@ -443,7 +444,7 @@ F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455 F test/tableapi.test 92651a95c23cf955e92407928e640536402fa3cc F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9 F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125 -F test/tester.tcl cfe051326b216c5a6ade6fa6e4d2ee4fd460a0aa +F test/tester.tcl 669599b9f84ecdba979ebf202fde11dfa405fe1a F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7 F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 @@ -604,7 +605,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P b9bf509e39f5ac38c2149d2a648f68e5df5ae9e3 -R f86b7697fbcfb346b78b785f78b0e5e6 +P 3ccce1f58be46787f8a35f0fa6d738ed126c0f07 +R 08ffd7abd6eb20dcba62b11485234765 U drh -Z 70a8e75efdd2439fff3e31be8bea7e10 +Z 5dde2337304e00b23d140f7351ff735d diff --git a/manifest.uuid b/manifest.uuid index 3a2f8b985b..c98ad89974 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ccce1f58be46787f8a35f0fa6d738ed126c0f07 \ No newline at end of file +87b4ac4b73fb84411ced9e9a859dd0e2d211c4b3 \ No newline at end of file diff --git a/test/crash4.test b/test/crash4.test new file mode 100644 index 0000000000..ccff7dfa88 --- /dev/null +++ b/test/crash4.test @@ -0,0 +1,128 @@ +# 2008 January 8 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains additional tests to verify that SQLite database +# file survive a power loss or OS crash. +# +# $Id: crash4.test,v 1.1 2008/01/08 16:03:50 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !crashtest { + finish_test + return +} + +# Generate a checksum based on the contents of the database. If the +# checksum of two databases is the same, and the integrity-check passes +# for both, the two databases are identical. +# +proc cksum {db} { + set ret [list] + ifcapable tempdb { + set sql { + SELECT name FROM sqlite_master WHERE type = 'table' UNION + SELECT name FROM sqlite_temp_master WHERE type = 'table' UNION + SELECT 'sqlite_master' UNION + SELECT 'sqlite_temp_master' + } + } else { + set sql { + SELECT name FROM sqlite_master WHERE type = 'table' UNION + SELECT 'sqlite_master' + } + } + set tbllist [$db eval $sql] + set txt {} + foreach tbl $tbllist { + append txt [$db eval "SELECT * FROM $tbl"] + } + return [md5 $txt] +} + +# A sequence of SQL commands: +# +set sql_cmd_list { + {CREATE TABLE a(id INTEGER, name CHAR(50))} + {INSERT INTO a(id,name) VALUES(1,'one')} + {INSERT INTO a(id,name) VALUES(2,'two')} + {INSERT INTO a(id,name) VALUES(3,'three')} + {INSERT INTO a(id,name) VALUES(4,'four')} + {INSERT INTO a(id,name) VALUES(5,'five')} + {INSERT INTO a(id,name) VALUES(6,'six')} + {INSERT INTO a(id,name) VALUES(7,'seven')} + {INSERT INTO a(id,name) VALUES(8,'eight')} + {INSERT INTO a(id,name) VALUES(9,'nine')} + {INSERT INTO a(id,name) VALUES(10,'ten')} + {UPDATE A SET name='new text for row 3' WHERE id=3} +} + +# Assume that a database is created by evaluating the SQL statements +# in $sql_cmd_list. Compute a set of checksums that capture the state +# of the database after each statement. Also include a checksum for +# the state of the database prior to any of these statements. +# +set crash4_cksum_set {} +lappend crash4_cksum_set [cksum db] +foreach cmd $sql_cmd_list { + db eval $cmd + lappend crash4_cksum_set [cksum db] +} + +# Run the sequence of SQL statements shown above repeatedly. +# Close and reopen the database right before the UPDATE statement. +# On each repetition, introduce database corruption typical of +# what might be seen in a power loss or OS crash. +# +# Slowly increase the delay before the crash, repeating the test +# over and over. Stop testing when the entire sequence of SQL +# statements runs to completing without hitting the crash. +# +for {set cnt 1; set fin 0} {!$fin} {incr cnt} { + db close + file delete -force test.db test.db-journal + do_test crash4-1.$cnt.1 { + set seed [expr {int(abs(rand()*10000))}] + set delay [expr {int($cnt/50)+1}] + set file [expr {($cnt&1)?"test.db":"test.db-journal"}] + set c [crashsql -delay $delay -file $file -seed $seed -tclbody { + db eval {CREATE TABLE a(id INTEGER, name CHAR(50))} + db eval {INSERT INTO a(id,name) VALUES(1,'one')} + db eval {INSERT INTO a(id,name) VALUES(2,'two')} + db eval {INSERT INTO a(id,name) VALUES(3,'three')} + db eval {INSERT INTO a(id,name) VALUES(4,'four')} + db eval {INSERT INTO a(id,name) VALUES(5,'five')} + db eval {INSERT INTO a(id,name) VALUES(6,'six')} + db eval {INSERT INTO a(id,name) VALUES(7,'seven')} + db eval {INSERT INTO a(id,name) VALUES(8,'eight')} + db eval {INSERT INTO a(id,name) VALUES(9,'nine')} + db eval {INSERT INTO a(id,name) VALUES(10,'ten')} + db close + sqlite3 db test.db + db eval {UPDATE A SET name='new text for row 3' WHERE id=3} + db close + } {}] + if {$c==[list 0 {}]} { + set ::fin 1 + set c [list 1 {child process exited abnormally}] + } + set c + } {1 {child process exited abnormally}} + sqlite3 db test.db + integrity_check crash4-1.$cnt.2 + do_test crash4-1.$cnt.3 { + set x [lsearch $::crash4_cksum_set [cksum db]] + expr {$x>=0} + } {1} +} + +finish_test diff --git a/test/tester.tcl b/test/tester.tcl index aeb8f8a5d9..6b292090d8 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.97 2008/01/08 15:18:52 drh Exp $ +# $Id: tester.tcl,v 1.98 2008/01/08 16:03:50 drh Exp $ set tcl_precision 15 @@ -353,6 +353,7 @@ proc crashsql {args} { set blocksize "" set crashdelay 1 set prngseed 0 + set tclbody {} set crashfile "" set dc "" set sql [lindex $args end] @@ -365,6 +366,7 @@ proc crashsql {args} { if {$n>1 && [string first $z -delay]==0} {set crashdelay $z2} \ elseif {$n>1 && [string first $z -seed]==0} {set prngseed $z2} \ elseif {$n>1 && [string first $z -file]==0} {set crashfile $z2} \ + elseif {$n>1 && [string first $z -tclbody]==0} {set tclbody $z2} \ elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \ elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \ else { error "Unrecognized option: $z" } @@ -394,9 +396,14 @@ proc crashsql {args} { puts $f "db eval {SELECT randomblob($seed)}" } - puts $f "db eval {" - puts $f "$sql" - puts $f "}" + if {[string length $tclbody]>0} { + puts $f $tclbody + } + if {[string length $sql]>0} { + puts $f "db eval {" + puts $f "$sql" + puts $f "}" + } close $f set r [catch { -- 2.47.3