diff options
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/crash3.test')
-rw-r--r-- | libraries/sqlite/unix/sqlite-3.5.1/test/crash3.test | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/crash3.test b/libraries/sqlite/unix/sqlite-3.5.1/test/crash3.test new file mode 100644 index 0000000..5154de6 --- /dev/null +++ b/libraries/sqlite/unix/sqlite-3.5.1/test/crash3.test | |||
@@ -0,0 +1,191 @@ | |||
1 | # 2007 August 23 | ||
2 | # | ||
3 | # The author disclaims copyright to this source code. In place of | ||
4 | # a legal notice, here is a blessing: | ||
5 | # | ||
6 | # May you do good and not evil. | ||
7 | # May you find forgiveness for yourself and forgive others. | ||
8 | # May you share freely, never taking more than you give. | ||
9 | # | ||
10 | #*********************************************************************** | ||
11 | # | ||
12 | # This file contains tests that verify that SQLite can correctly rollback | ||
13 | # databases after crashes when using the special IO modes triggered | ||
14 | # by device IOCAP flags. | ||
15 | # | ||
16 | # $Id: crash3.test,v 1.3 2007/08/24 11:52:29 danielk1977 Exp $ | ||
17 | |||
18 | set testdir [file dirname $argv0] | ||
19 | source $testdir/tester.tcl | ||
20 | |||
21 | ifcapable !crashtest { | ||
22 | finish_test | ||
23 | return | ||
24 | } | ||
25 | |||
26 | proc do_test2 {name tcl res1 res2} { | ||
27 | set script [subst -nocommands { | ||
28 | do_test $name { | ||
29 | set res1 {$res1} | ||
30 | set res2 {$res2} | ||
31 | set res [eval {$tcl}] | ||
32 | if {[set res] eq [set res1] || [set res] eq [set res2]} { | ||
33 | set res "{[set res1]} or {[set res2]}" | ||
34 | } | ||
35 | set res | ||
36 | } {{$res1} or {$res2}} | ||
37 | }] | ||
38 | uplevel $script | ||
39 | } | ||
40 | |||
41 | # This block tests crash-recovery when the IOCAP_ATOMIC flags is set. | ||
42 | # | ||
43 | # Each iteration of the following loop sets up the database to contain | ||
44 | # the following schema and data: | ||
45 | # | ||
46 | # CREATE TABLE abc(a, b, c); | ||
47 | # INSERT INTO abc VALUES(1, 2, 3); | ||
48 | # | ||
49 | # Then execute the SQL statement, scheduling a crash for part-way through | ||
50 | # the first sync() of either the database file or the journal file (often | ||
51 | # the journal file is not required - meaning no crash occurs). | ||
52 | # | ||
53 | # After the crash (or absence of a crash), open the database and | ||
54 | # verify that: | ||
55 | # | ||
56 | # * The integrity check passes, and | ||
57 | # * The contents of table abc is either {1 2 3} or the value specified | ||
58 | # to the right of the SQL statement below. | ||
59 | # | ||
60 | # The procedure is repeated 10 times for each SQL statement. Five times | ||
61 | # with the crash scheduled for midway through the first journal sync (if | ||
62 | # any), and five times with the crash midway through the database sync. | ||
63 | # | ||
64 | set tn 1 | ||
65 | foreach {sql res2} [list \ | ||
66 | {INSERT INTO abc VALUES(4, 5, 6)} {1 2 3 4 5 6} \ | ||
67 | {DELETE FROM abc} {} \ | ||
68 | {INSERT INTO abc SELECT * FROM abc} {1 2 3 1 2 3} \ | ||
69 | {UPDATE abc SET a = 2} {2 2 3} \ | ||
70 | {INSERT INTO abc VALUES(4, 5, randstr(1000,1000))} {n/a} \ | ||
71 | {CREATE TABLE def(d, e, f)} {n/a} \ | ||
72 | ] { | ||
73 | for {set ii 0} {$ii < 10} {incr ii} { | ||
74 | |||
75 | db close | ||
76 | file delete -force test.db test.db-journal | ||
77 | sqlite3 db test.db | ||
78 | do_test crash3-1.$tn.1 { | ||
79 | execsql { | ||
80 | PRAGMA page_size = 1024; | ||
81 | BEGIN; | ||
82 | CREATE TABLE abc(a, b, c); | ||
83 | INSERT INTO abc VALUES(1, 2, 3); | ||
84 | COMMIT; | ||
85 | } | ||
86 | } {} | ||
87 | db close | ||
88 | |||
89 | set crashfile test.db | ||
90 | if {($ii%2)==0} { append crashfile -journal } | ||
91 | set rand "SELECT randstr($tn,$tn);" | ||
92 | do_test crash3-1.$tn.2 [subst { | ||
93 | crashsql -file $crashfile -char atomic {$rand $sql} | ||
94 | sqlite3 db test.db | ||
95 | execsql { PRAGMA integrity_check; } | ||
96 | }] {ok} | ||
97 | |||
98 | do_test2 crash3-1.$tn.3 { | ||
99 | execsql { SELECT * FROM abc } | ||
100 | } {1 2 3} $res2 | ||
101 | |||
102 | incr tn | ||
103 | } | ||
104 | } | ||
105 | |||
106 | # This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags. | ||
107 | # | ||
108 | db close | ||
109 | file delete -force test.db test.db-journal | ||
110 | sqlite3 db test.db | ||
111 | do_test crash3-2.0 { | ||
112 | execsql { | ||
113 | BEGIN; | ||
114 | CREATE TABLE abc(a PRIMARY KEY, b, c); | ||
115 | CREATE TABLE def(d PRIMARY KEY, e, f); | ||
116 | PRAGMA default_cache_size = 10; | ||
117 | INSERT INTO abc VALUES(randstr(10,1000),randstr(10,1000),randstr(10,1000)); | ||
118 | INSERT INTO abc | ||
119 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
120 | INSERT INTO abc | ||
121 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
122 | INSERT INTO abc | ||
123 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
124 | INSERT INTO abc | ||
125 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
126 | INSERT INTO abc | ||
127 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
128 | INSERT INTO abc | ||
129 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) FROM abc; | ||
130 | COMMIT; | ||
131 | } | ||
132 | } {} | ||
133 | |||
134 | set tn 1 | ||
135 | foreach {::crashfile ::delay ::char} { | ||
136 | test.db 1 sequential | ||
137 | test.db 1 safe_append | ||
138 | test.db-journal 1 sequential | ||
139 | test.db-journal 1 safe_append | ||
140 | test.db-journal 2 safe_append | ||
141 | test.db-journal 2 sequential | ||
142 | test.db-journal 3 sequential | ||
143 | test.db-journal 3 safe_append | ||
144 | } { | ||
145 | for {set ii 0} {$ii < 100} {incr ii} { | ||
146 | set ::SQL [subst { | ||
147 | SELECT randstr($ii,$ii+10); | ||
148 | BEGIN; | ||
149 | DELETE FROM abc WHERE random()%5; | ||
150 | INSERT INTO abc | ||
151 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) | ||
152 | FROM abc | ||
153 | WHERE (random()%5)==0; | ||
154 | DELETE FROM def WHERE random()%5; | ||
155 | INSERT INTO def | ||
156 | SELECT randstr(10,1000),randstr(10,1000),randstr(10,1000) | ||
157 | FROM def | ||
158 | WHERE (random()%5)==0; | ||
159 | COMMIT; | ||
160 | }] | ||
161 | |||
162 | do_test crash3-2.$tn.$ii { | ||
163 | crashsql -file $::crashfile -delay $::delay -char $::char $::SQL | ||
164 | db close | ||
165 | sqlite3 db test.db | ||
166 | execsql {PRAGMA integrity_check} | ||
167 | } {ok} | ||
168 | } | ||
169 | incr tn | ||
170 | } | ||
171 | |||
172 | # The following block tests an interaction between IOCAP_ATOMIC and | ||
173 | # IOCAP_SEQUENTIAL. At one point, if both flags were set, small | ||
174 | # journal files that contained only a single page, but were required | ||
175 | # for some other reason (i.e. nTrunk) were not being written to | ||
176 | # disk. | ||
177 | # | ||
178 | for {set ii 0} {$ii < 10} {incr ii} { | ||
179 | db close | ||
180 | file delete -force test.db test.db-journal | ||
181 | crashsql -file test.db -char {sequential atomic} { | ||
182 | CREATE TABLE abc(a, b, c); | ||
183 | } | ||
184 | sqlite3 db test.db | ||
185 | do_test crash3-3.$ii { | ||
186 | execsql {PRAGMA integrity_check} | ||
187 | } {ok} | ||
188 | } | ||
189 | |||
190 | finish_test | ||
191 | |||