blob: ed781b5b59165036f719e881f3a952985acb60a9 [file] [log] [blame]
danb0ac3e32010-06-16 10:55:42 +00001# 2010 June 15
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
13set testdir [file dirname $argv0]
14source $testdir/tester.tcl
15source $testdir/lock_common.tcl
16source $testdir/malloc_common.tcl
17
18set a_string_counter 1
19proc a_string {n} {
20 global a_string_counter
21 incr a_string_counter
22 string range [string repeat "${a_string_counter}." $n] 1 $n
23}
24db func a_string a_string
25
26#-------------------------------------------------------------------------
27# Test fault-injection while rolling back a hot-journal file.
28#
29do_test pagerfault-1-pre1 {
30 execsql {
31 PRAGMA journal_mode = DELETE;
32 PRAGMA cache_size = 10;
33 CREATE TABLE t1(a UNIQUE, b UNIQUE);
34 INSERT INTO t1 VALUES(a_string(200), a_string(300));
35 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
36 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
37 BEGIN;
38 INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;
39 INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;
40 INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;
41 INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;
42 }
43 faultsim_save_and_close
44} {}
45do_faultsim_test pagerfault-1 -prep {
46 faultsim_restore_and_reopen
47} -body {
48 execsql { SELECT count(*) FROM t1 }
49} -test {
50 faultsim_test_result {0 4}
51 faultsim_integrity_check
52 if {[db one { SELECT count(*) FROM t1 }] != 4} {
53 error "Database content appears incorrect"
54 }
55}
56
57#-------------------------------------------------------------------------
dande4996e2010-06-19 11:30:41 +000058# Test fault-injection while rolling back a hot-journal file with a
59# page-size different from the current value stored on page 1 of the
60# database file.
61#
62do_test pagerfault-2-pre1 {
63 testvfs tv -default 1
64 tv filter xSync
65 tv script xSyncCb
66 proc xSyncCb {filename args} {
67 if {[string match *journal filename]==0} faultsim_save
68 }
69 faultsim_delete_and_reopen
70 execsql {
71 PRAGMA page_size = 4096;
72 BEGIN;
73 CREATE TABLE abc(a, b, c);
74 INSERT INTO abc VALUES('o', 't', 't');
75 INSERT INTO abc VALUES('f', 'f', 's');
76 INSERT INTO abc SELECT * FROM abc; -- 4
77 INSERT INTO abc SELECT * FROM abc; -- 8
78 INSERT INTO abc SELECT * FROM abc; -- 16
79 INSERT INTO abc SELECT * FROM abc; -- 32
80 INSERT INTO abc SELECT * FROM abc; -- 64
81 INSERT INTO abc SELECT * FROM abc; -- 128
82 INSERT INTO abc SELECT * FROM abc; -- 256
83 COMMIT;
84 PRAGMA page_size = 1024;
85 VACUUM;
86 }
87 db close
88 tv delete
89} {}
90do_faultsim_test pagerfault-2 -prep {
91 faultsim_restore_and_reopen
92} -body {
93 execsql { SELECT * FROM abc }
94} -test {
95 set answer [split [string repeat "ottffs" 128] ""]
96 faultsim_test_result [list 0 $answer]
97 faultsim_integrity_check
98 set res [db eval { SELECT * FROM abc }]
99 if {$res != $answer} { error "Database content appears incorrect ($res)" }
100} -faults oom-transient
101
102#-------------------------------------------------------------------------
danb0ac3e32010-06-16 10:55:42 +0000103# Test fault-injection while rolling back hot-journals that were created
104# as part of a multi-file transaction.
105#
dande4996e2010-06-19 11:30:41 +0000106do_test pagerfault-3-pre1 {
danb0ac3e32010-06-16 10:55:42 +0000107 testvfs tstvfs -default 1
108 tstvfs filter xDelete
109 tstvfs script xDeleteCallback
110
111 proc xDeleteCallback {method file args} {
112 set file [file tail $file]
113 if { [string match *mj* $file] } { faultsim_save }
114 }
115
116 faultsim_delete_and_reopen
117 db func a_string a_string
118
119 execsql {
120 ATTACH 'test.db2' AS aux;
121 PRAGMA journal_mode = DELETE;
122 PRAGMA main.cache_size = 10;
123 PRAGMA aux.cache_size = 10;
124
125 CREATE TABLE t1(a UNIQUE, b UNIQUE);
126 CREATE TABLE aux.t2(a UNIQUE, b UNIQUE);
127 INSERT INTO t1 VALUES(a_string(200), a_string(300));
128 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
129 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
130 INSERT INTO t2 SELECT * FROM t1;
131
132 BEGIN;
133 INSERT INTO t1 SELECT a_string(201), a_string(301) FROM t1;
134 INSERT INTO t1 SELECT a_string(202), a_string(302) FROM t1;
135 INSERT INTO t1 SELECT a_string(203), a_string(303) FROM t1;
136 INSERT INTO t1 SELECT a_string(204), a_string(304) FROM t1;
137 REPLACE INTO t2 SELECT * FROM t1;
138 COMMIT;
139 }
140
141 db close
142 tstvfs delete
143} {}
dande4996e2010-06-19 11:30:41 +0000144do_faultsim_test pagerfault-3 -faults ioerr-persistent -prep {
danb0ac3e32010-06-16 10:55:42 +0000145 faultsim_restore_and_reopen
146} -body {
147 execsql {
148 ATTACH 'test.db2' AS aux;
149 SELECT count(*) FROM t2;
150 SELECT count(*) FROM t1;
151 }
152} -test {
153 faultsim_test_result {0 {4 4}} {1 {unable to open database: test.db2}}
154 faultsim_integrity_check
danb0ac3e32010-06-16 10:55:42 +0000155 catchsql { ATTACH 'test.db2' AS aux }
156 if {[db one { SELECT count(*) FROM t1 }] != 4
157 || [db one { SELECT count(*) FROM t2 }] != 4
158 } {
159 error "Database content appears incorrect"
160 }
161}
162
dande4996e2010-06-19 11:30:41 +0000163#-------------------------------------------------------------------------
164# Test fault-injection as part of a vanilla, no-transaction, INSERT
165# statement.
166#
167do_faultsim_test pagerfault-4 -prep {
168 faultsim_delete_and_reopen
169} -body {
170 execsql {
171 CREATE TABLE x(y);
172 INSERT INTO x VALUES('z');
173 SELECT * FROM x;
174 }
175} -test {
176 faultsim_test_result {0 z}
177 faultsim_integrity_check
178}
179
180#-------------------------------------------------------------------------
181# Test fault-injection as part of a commit when using journal_mode=PERSIST.
182#
183do_test pagerfault-5-pre1 {
184 faultsim_delete_and_reopen
185 db func a_string a_string
186 execsql {
187 CREATE TABLE t1(a UNIQUE, b UNIQUE);
188 INSERT INTO t1 VALUES(a_string(200), a_string(300));
189 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
190 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
191 }
192 faultsim_save_and_close
193} {}
194do_faultsim_test pagerfault-5.1 -prep {
195 faultsim_restore_and_reopen
196 db func a_string a_string
197 execsql { PRAGMA journal_mode = PERSIST }
198} -body {
199 execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }
200} -test {
201 faultsim_test_result {0 {}}
202 faultsim_integrity_check
203}
204do_faultsim_test pagerfault-5.2 -prep {
205 faultsim_restore_and_reopen
206 db func a_string a_string
207 execsql {
208 PRAGMA journal_mode = PERSIST;
209 PRAGMA journal_size_limit = 2048;
210 }
211} -body {
212 execsql { INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1 }
213} -test {
214 faultsim_test_result {0 {}}
215 faultsim_integrity_check
216}
217
218do_faultsim_test pagerfault-5.3 -prep {
219 faultsim_restore_and_reopen
220 db func a_string a_string
221 file delete -force test2.db test2.db-journal test2.db-wal
222 execsql {
223 PRAGMA journal_mode = PERSIST;
224 ATTACH 'test2.db' AS aux;
225 PRAGMA aux.journal_mode = PERSIST;
226 PRAGMA aux.journal_size_limit = 0;
227 }
228} -body {
229 execsql {
230 BEGIN;
231 INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
232 CREATE TABLE aux.t2 AS SELECT * FROM t1;
233 COMMIT;
234 }
235} -test {
236 faultsim_test_result {0 {}}
237}
238
danb0ac3e32010-06-16 10:55:42 +0000239finish_test