OLD | NEW |
| (Empty) |
1 # 2001 October 12 | |
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 # This file implements regression tests for SQLite library. The | |
12 # focus of this file is testing for correct handling of I/O errors | |
13 # such as writes failing because the disk is full. | |
14 # | |
15 # The tests in this file use special facilities that are only | |
16 # available in the SQLite test fixture. | |
17 # | |
18 # $Id: incrvacuum_ioerr.test,v 1.6 2008/07/12 14:52:20 drh Exp $ | |
19 | |
20 set testdir [file dirname $argv0] | |
21 source $testdir/tester.tcl | |
22 | |
23 # If this build of the library does not support auto-vacuum, omit this | |
24 # whole file. | |
25 ifcapable {!autovacuum} { | |
26 finish_test | |
27 return | |
28 } | |
29 | |
30 do_ioerr_test incrvacuum-ioerr-1 -cksum 1 -sqlprep { | |
31 PRAGMA auto_vacuum = 'incremental'; | |
32 CREATE TABLE abc(a); | |
33 INSERT INTO abc VALUES(randstr(1500,1500)); | |
34 } -sqlbody { | |
35 BEGIN; | |
36 CREATE TABLE abc2(a); | |
37 DELETE FROM abc; | |
38 PRAGMA incremental_vacuum; | |
39 COMMIT; | |
40 } | |
41 | |
42 # do_ioerr_test incrvacuum-ioerr-3 -start 1 -cksum 1 -tclprep { | |
43 # db eval { | |
44 # PRAGMA auto_vacuum = 'full'; | |
45 # PRAGMA cache_size = 10; | |
46 # BEGIN; | |
47 # CREATE TABLE abc(a, UNIQUE(a)); | |
48 # } | |
49 # for {set ii 0} {$ii < 25} {incr ii} { | |
50 # db eval {INSERT INTO abc VALUES(randstr(1500,1500))} | |
51 # } | |
52 # db eval COMMIT | |
53 # } -sqlbody { | |
54 # BEGIN; | |
55 # DELETE FROM abc WHERE (oid%3)==0; | |
56 # INSERT INTO abc SELECT a || '1234567890' FROM abc WHERE oid%2; | |
57 # CREATE INDEX abc_i ON abc(a); | |
58 # DELETE FROM abc WHERE (oid%2)==0; | |
59 # DROP INDEX abc_i; | |
60 # COMMIT; | |
61 # } | |
62 | |
63 do_ioerr_test incrvacuum-ioerr-2 -start 1 -cksum 1 -tclprep { | |
64 db eval { | |
65 PRAGMA auto_vacuum = 'full'; | |
66 PRAGMA cache_size = 10; | |
67 BEGIN; | |
68 CREATE TABLE abc(a, UNIQUE(a)); | |
69 } | |
70 for {set ii 0} {$ii < 25} {incr ii} { | |
71 db eval {INSERT INTO abc VALUES(randstr(1500,1500))} | |
72 } | |
73 db eval COMMIT | |
74 } -sqlbody { | |
75 BEGIN; | |
76 PRAGMA incremental_vacuum; | |
77 DELETE FROM abc WHERE (oid%3)==0; | |
78 PRAGMA incremental_vacuum; | |
79 INSERT INTO abc SELECT a || '1234567890' FROM abc WHERE oid%2; | |
80 PRAGMA incremental_vacuum; | |
81 CREATE INDEX abc_i ON abc(a); | |
82 DELETE FROM abc WHERE (oid%2)==0; | |
83 PRAGMA incremental_vacuum; | |
84 DROP INDEX abc_i; | |
85 PRAGMA incremental_vacuum; | |
86 COMMIT; | |
87 } | |
88 | |
89 do_ioerr_test incrvacuum-ioerr-3 -start 1 -cksum 1 -tclprep { | |
90 db eval { | |
91 PRAGMA auto_vacuum = 'incremental'; | |
92 BEGIN; | |
93 CREATE TABLE a(i integer, b blob); | |
94 INSERT INTO a VALUES(1, randstr(1500,1500)); | |
95 INSERT INTO a VALUES(2, randstr(1500,1500)); | |
96 } | |
97 db eval COMMIT | |
98 db eval {DELETE FROM a WHERE oid} | |
99 } -sqlbody { | |
100 PRAGMA incremental_vacuum(5); | |
101 } -cleanup { | |
102 sqlite3 db test.db | |
103 integrity_check incrvacuum-ioerr-2.$n.integritycheck | |
104 db close | |
105 } | |
106 | |
107 | |
108 ifcapable shared_cache { | |
109 | |
110 catch { db close } | |
111 forcedelete test.db | |
112 set ::enable_shared_cache [sqlite3_enable_shared_cache 1] | |
113 | |
114 # Create two connections to a single shared-cache: | |
115 # | |
116 sqlite3 db1 test.db | |
117 sqlite3 db2 test.db | |
118 | |
119 # Create a database with around 20 free pages. | |
120 # | |
121 do_test incrvacuum-ioerr-4.0 { | |
122 execsql { | |
123 PRAGMA page_size = 1024; | |
124 PRAGMA locking_mode = exclusive; | |
125 PRAGMA auto_vacuum = 'incremental'; | |
126 BEGIN; | |
127 CREATE TABLE a(i integer, b blob); | |
128 } db1 | |
129 for {set ii 0} {$ii < 20} {incr ii} { | |
130 execsql { INSERT INTO a VALUES($ii, randstr(800,1500)); } db1 | |
131 } | |
132 execsql COMMIT db1 | |
133 execsql {DELETE FROM a WHERE oid} db1 | |
134 } {} | |
135 | |
136 set ::rc 1 | |
137 for {set iTest 1} {$::rc && $iTest<2000} {incr iTest} { | |
138 | |
139 # Figure out how big the database is and how many free pages it | |
140 # has before running incremental-vacuum. | |
141 # | |
142 set nFree [execsql {pragma freelist_count} db1] | |
143 set nPage [execsql {pragma page_count} db1] | |
144 puts "nFree=$nFree nPage=$nPage" | |
145 | |
146 # Now run incremental-vacuum to vacuum 5 pages from the db file. | |
147 # The iTest'th I/O call is set to fail. | |
148 # | |
149 set ::sqlite_io_error_pending $iTest | |
150 set ::sqlite_io_error_persist 1 | |
151 do_test incrvacuum-ioerr-4.$iTest.1 { | |
152 set ::rc [catch {execsql {pragma incremental_vacuum(5)} db1} msg] | |
153 expr {$::rc==0 || $msg eq "disk I/O error"} | |
154 } {1} | |
155 | |
156 set ::sqlite_io_error_pending 0 | |
157 set ::sqlite_io_error_persist 0 | |
158 set ::sqlite_io_error_hit 0 | |
159 set ::sqlite_io_error_hardhit 0 | |
160 | |
161 set nFree2 [execsql {pragma freelist_count} db1] | |
162 set nPage2 [execsql {pragma page_count} db1] | |
163 | |
164 do_test incrvacuum-ioerr-4.$iTest.2 { | |
165 set shrink [expr {$nPage-$nPage2}] | |
166 expr {$shrink==0 || $shrink==5 || ($nFree<5 && $shrink==$nFree)} | |
167 } {1} | |
168 | |
169 do_test incrvacuum-ioerr-4.$iTest.3 { | |
170 expr {$nPage - $nPage2} | |
171 } [expr {$nFree - $nFree2}] | |
172 } | |
173 | |
174 # Close the two database connections and restore the default | |
175 # shared-cache mode setting. | |
176 # | |
177 db1 close | |
178 db2 close | |
179 sqlite3_enable_shared_cache $::enable_shared_cache | |
180 } | |
181 | |
182 finish_test | |
OLD | NEW |