Index: third_party/sqlite/sqlite-src-3070603/test/crash3.test |
diff --git a/third_party/sqlite/sqlite-src-3070603/test/crash3.test b/third_party/sqlite/sqlite-src-3070603/test/crash3.test |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9b7a678474f95878ea230243aa27a0e5d249ac1c |
--- /dev/null |
+++ b/third_party/sqlite/sqlite-src-3070603/test/crash3.test |
@@ -0,0 +1,190 @@ |
+# 2007 August 23 |
+# |
+# 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 tests that verify that SQLite can correctly rollback |
+# databases after crashes when using the special IO modes triggered |
+# by device IOCAP flags. |
+# |
+# $Id: crash3.test,v 1.4 2008/07/12 14:52:20 drh Exp $ |
+ |
+set testdir [file dirname $argv0] |
+source $testdir/tester.tcl |
+ |
+ifcapable !crashtest { |
+ finish_test |
+ return |
+} |
+ |
+proc do_test2 {name tcl res1 res2} { |
+ set script [subst -nocommands { |
+ do_test $name { |
+ set res1 {$res1} |
+ set res2 {$res2} |
+ set res [eval {$tcl}] |
+ if {[set res] eq [set res1] || [set res] eq [set res2]} { |
+ set res "{[set res1]} or {[set res2]}" |
+ } |
+ set res |
+ } {{$res1} or {$res2}} |
+ }] |
+ uplevel $script |
+} |
+ |
+# This block tests crash-recovery when the IOCAP_ATOMIC flags is set. |
+# |
+# Each iteration of the following loop sets up the database to contain |
+# the following schema and data: |
+# |
+# CREATE TABLE abc(a, b, c); |
+# INSERT INTO abc VALUES(1, 2, 3); |
+# |
+# Then execute the SQL statement, scheduling a crash for part-way through |
+# the first sync() of either the database file or the journal file (often |
+# the journal file is not required - meaning no crash occurs). |
+# |
+# After the crash (or absence of a crash), open the database and |
+# verify that: |
+# |
+# * The integrity check passes, and |
+# * The contents of table abc is either {1 2 3} or the value specified |
+# to the right of the SQL statement below. |
+# |
+# The procedure is repeated 10 times for each SQL statement. Five times |
+# with the crash scheduled for midway through the first journal sync (if |
+# any), and five times with the crash midway through the database sync. |
+# |
+set tn 1 |
+foreach {sql res2} [list \ |
+ {INSERT INTO abc VALUES(4, 5, 6)} {1 2 3 4 5 6} \ |
+ {DELETE FROM abc} {} \ |
+ {INSERT INTO abc SELECT * FROM abc} {1 2 3 1 2 3} \ |
+ {UPDATE abc SET a = 2} {2 2 3} \ |
+ {INSERT INTO abc VALUES(4, 5, randstr(1000,1000))} {n/a} \ |
+ {CREATE TABLE def(d, e, f)} {n/a} \ |
+] { |
+ for {set ii 0} {$ii < 10} {incr ii} { |
+ |
+ db close |
+ file delete -force test.db test.db-journal |
+ sqlite3 db test.db |
+ do_test crash3-1.$tn.1 { |
+ execsql { |
+ PRAGMA page_size = 1024; |
+ BEGIN; |
+ CREATE TABLE abc(a, b, c); |
+ INSERT INTO abc VALUES(1, 2, 3); |
+ COMMIT; |
+ } |
+ } {} |
+ db close |
+ |
+ set crashfile test.db |
+ if {($ii%2)==0} { append crashfile -journal } |
+ set rand "SELECT randstr($tn,$tn);" |
+ do_test crash3-1.$tn.2 [subst { |
+ crashsql -file $crashfile -char atomic {$rand $sql} |
+ sqlite3 db test.db |
+ execsql { PRAGMA integrity_check; } |
+ }] {ok} |
+ |
+ do_test2 crash3-1.$tn.3 { |
+ execsql { SELECT * FROM abc } |
+ } {1 2 3} $res2 |
+ |
+ incr tn |
+ } |
+} |
+ |
+# This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags. |
+# |
+db close |
+file delete -force test.db test.db-journal |
+sqlite3 db test.db |
+do_test crash3-2.0 { |
+ execsql { |
+ BEGIN; |
+ CREATE TABLE abc(a PRIMARY KEY, b, c); |
+ CREATE TABLE def(d PRIMARY KEY, e, f); |
+ PRAGMA default_cache_size = 10; |
+ INSERT INTO abc VALUES(randstr(10,1000),randstr(10,1000),randstr(10,1000)); |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; |
+ COMMIT; |
+ } |
+} {} |
+ |
+set tn 1 |
+foreach {::crashfile ::delay ::char} { |
+ test.db 1 sequential |
+ test.db 1 safe_append |
+ test.db-journal 1 sequential |
+ test.db-journal 1 safe_append |
+ test.db-journal 2 safe_append |
+ test.db-journal 2 sequential |
+ test.db-journal 3 sequential |
+ test.db-journal 3 safe_append |
+} { |
+ for {set ii 0} {$ii < 100} {incr ii} { |
+ set ::SQL [subst { |
+ SELECT randstr($ii,$ii+10); |
+ BEGIN; |
+ DELETE FROM abc WHERE random()%5; |
+ INSERT INTO abc |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) |
+ FROM abc |
+ WHERE (random()%5)==0; |
+ DELETE FROM def WHERE random()%5; |
+ INSERT INTO def |
+ SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) |
+ FROM def |
+ WHERE (random()%5)==0; |
+ COMMIT; |
+ }] |
+ |
+ do_test crash3-2.$tn.$ii { |
+ crashsql -file $::crashfile -delay $::delay -char $::char $::SQL |
+ db close |
+ sqlite3 db test.db |
+ execsql {PRAGMA integrity_check} |
+ } {ok} |
+ } |
+ incr tn |
+} |
+ |
+# The following block tests an interaction between IOCAP_ATOMIC and |
+# IOCAP_SEQUENTIAL. At one point, if both flags were set, small |
+# journal files that contained only a single page, but were required |
+# for some other reason (i.e. nTrunk) were not being written to |
+# disk. |
+# |
+for {set ii 0} {$ii < 10} {incr ii} { |
+ db close |
+ file delete -force test.db test.db-journal |
+ crashsql -file test.db -char {sequential atomic} { |
+ CREATE TABLE abc(a, b, c); |
+ } |
+ sqlite3 db test.db |
+ do_test crash3-3.$ii { |
+ execsql {PRAGMA integrity_check} |
+ } {ok} |
+} |
+ |
+finish_test |