wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 # 2007 March 24
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.
12 #
13 # $Id: exclusive2.test,v 1.10 2008/11/27 02:22:11 drh Exp $
14  
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17  
18 # Do not use a codec for tests in this file, as the database file is
19 # manipulated directly using tcl scripts (using the [hexio_write] command).
20 #
21 do_not_use_codec
22  
23 ifcapable {!pager_pragmas} {
24 finish_test
25 return
26 }
27  
28 # This module does not work right if the cache spills at unexpected
29 # moments. So disable the soft-heap-limit.
30 #
31 sqlite3_soft_heap_limit 0
32  
33 proc pagerChangeCounter {filename new {fd ""}} {
34 if {$fd==""} {
35 set fd [open $filename RDWR]
36 fconfigure $fd -translation binary -encoding binary
37 set needClose 1
38 } else {
39 set needClose 0
40 }
41 if {$new ne ""} {
42 seek $fd 24
43 set a [expr {($new&0xFF000000)>>24}]
44 set b [expr {($new&0x00FF0000)>>16}]
45 set c [expr {($new&0x0000FF00)>>8}]
46 set d [expr {($new&0x000000FF)}]
47 puts -nonewline $fd [binary format cccc $a $b $c $d]
48 flush $fd
49 }
50  
51 seek $fd 24
52 foreach {a b c d} [list 0 0 0 0] {}
53 binary scan [read $fd 4] cccc a b c d
54 set ret [expr ($a&0x000000FF)<<24]
55 incr ret [expr ($b&0x000000FF)<<16]
56 incr ret [expr ($c&0x000000FF)<<8]
57 incr ret [expr ($d&0x000000FF)<<0]
58  
59 if {$needClose} {close $fd}
60 return $ret
61 }
62  
63 proc readPagerChangeCounter {filename} {
64 set fd [open $filename RDONLY]
65 fconfigure $fd -translation binary -encoding binary
66  
67 seek $fd 24
68 foreach {a b c d} [list 0 0 0 0] {}
69 binary scan [read $fd 4] cccc a b c d
70 set ret [expr ($a&0x000000FF)<<24]
71 incr ret [expr ($b&0x000000FF)<<16]
72 incr ret [expr ($c&0x000000FF)<<8]
73 incr ret [expr ($d&0x000000FF)<<0]
74  
75 close $fd
76 return $ret
77 }
78  
79  
80 proc t1sig {{db db}} {
81 execsql {SELECT count(*), md5sum(a) FROM t1} $db
82 }
83 do_test exclusive2-1.0 {
84 readPagerChangeCounter test.db
85 } {0}
86  
87 #-----------------------------------------------------------------------
88 # The following tests - exclusive2-1.X - check that:
89 #
90 # 1-3: Build a database with connection 1, calculate a signature.
91 # 4-7: Modify the database using a second connection in a way that
92 # does not modify the freelist, then reset the pager change-counter
93 # to the value it had before the modifications.
94 # 8: Check that using the first connection, the database signature
95 # is still the same. This is because it uses the in-memory cache.
96 # It can't tell the db has changed because we reset the change-counter.
97 # 9: Increment the change-counter.
98 # 10: Ensure that the first connection now sees the updated database. It
99 # sees the change-counter has been incremented and discards the
100 # invalid in-memory cache.
101 #
102 # This will only work if the database cache is large enough to hold
103 # the entire database. In the case of 1024 byte pages, this means
104 # the cache size must be at least 17. Otherwise, some pages will be
105 # loaded from the database file in step 8.
106 #
107 # For similar reasons, this test does not work with the memsubsys1 permutation.
108 # Permutation memsubsys1 configures the pcache subsystem to use a static
109 # allocation of 24 pages (shared between all pagers). This is not enough for
110 # this test.
111 #
112 do_test exclusive2-1.1 {
113 execsql {
114 BEGIN;
115 CREATE TABLE t1(a, b);
116 INSERT INTO t1(a) VALUES(randstr(10, 400));
117 INSERT INTO t1(a) VALUES(randstr(10, 400));
118 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
119 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
120 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
121 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
122 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
123 COMMIT;
124 SELECT count(*) FROM t1;
125 }
126 } {64}
127 do_test exclusive2-1.2.1 {
128 # Make sure the pager cache is large enough to store the
129 # entire database.
130 set nPage [expr [file size test.db]/1024]
131 if {$::SQLITE_DEFAULT_CACHE_SIZE < $nPage} {
132 execsql "PRAGMA cache_size = $nPage"
133 }
134 expr {[execsql {PRAGMA cache_size}] >= $nPage}
135 } {1}
136 do_test exclusive2-1.2 {
137 set ::sig [t1sig]
138 readPagerChangeCounter test.db
139 } {1}
140 do_test exclusive2-1.3 {
141 t1sig
142 } $::sig
143 do_test exclusive2-1.4 {
144 sqlite3 db2 test.db
145 t1sig db2
146 } $::sig
147 do_test exclusive2-1.5 {
148 execsql {
149 UPDATE t1 SET b=a, a=NULL;
150 } db2
151 expr {[t1sig db2] eq $::sig}
152 } 0
153 do_test exclusive2-1.6 {
154 readPagerChangeCounter test.db
155 } {2}
156 do_test exclusive2-1.7 {
157 pagerChangeCounter test.db 1
158 } {1}
159 if {[permutation] != "memsubsys1"} {
160 do_test exclusive2-1.9 {
161 t1sig
162 expr {[t1sig] eq $::sig}
163 } {1}
164 }
165 do_test exclusive2-1.10 {
166 pagerChangeCounter test.db 2
167 } {2}
168 do_test exclusive2-1.11 {
169 expr {[t1sig] eq $::sig}
170 } {0}
171 db2 close
172  
173 #--------------------------------------------------------------------
174 # These tests - exclusive2-2.X - are similar to exclusive2-1.X,
175 # except that they are run with locking_mode=EXCLUSIVE.
176 #
177 # 1-3: Build a database with exclusive-access connection 1,
178 # calculate a signature.
179 # 4: Corrupt the database by writing 10000 bytes of garbage
180 # starting at the beginning of page 2. Check that connection 1
181 # still works. It should be accessing the in-memory cache.
182 # 5-6: Modify the dataase change-counter. Connection 1 still works
183 # entirely from in-memory cache, because it doesn't check the
184 # change-counter.
185 # 7-8 Set the locking-mode back to normal. After the db is unlocked,
186 # SQLite detects the modified change-counter and discards the
187 # in-memory cache. Then it finds the corruption caused in step 4....
188 #
189 # As above, this test is only applicable if the pager cache is
190 # large enough to hold the entire database. With 1024 byte pages,
191 # this means 19 pages. We also need to disable the soft-heap-limit
192 # to prevent memory-induced cache spills.
193 #
194 do_test exclusive2-2.1 {
195 execsql {PRAGMA cache_size=1000;}
196 execsql {PRAGMA locking_mode = exclusive;}
197 execsql {
198 BEGIN;
199 DELETE FROM t1;
200 INSERT INTO t1(a) VALUES(randstr(10, 400));
201 INSERT INTO t1(a) VALUES(randstr(10, 400));
202 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
203 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
204 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
205 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
206 INSERT INTO t1(a) SELECT randstr(10, 400) FROM t1;
207 COMMIT;
208 SELECT count(*) FROM t1;
209 }
210 } {64}
211 do_test exclusive2-2.2.1 {
212 # Make sure the pager cache is large enough to store the
213 # entire database.
214 set nPage [expr [file size test.db]/1024]
215 if {$::SQLITE_DEFAULT_CACHE_SIZE < $nPage} {
216 execsql "PRAGMA cache_size = $nPage"
217 }
218 expr {[execsql {PRAGMA cache_size}] >= $nPage}
219 } {1}
220 do_test exclusive2-2.2 {
221 set ::sig [t1sig]
222 readPagerChangeCounter test.db
223 } {3}
224 do_test exclusive2-2.3 {
225 t1sig
226 } $::sig
227  
228 do_test exclusive2-2.4 {
229 set ::fd [open test.db RDWR]
230 fconfigure $::fd -translation binary
231 seek $::fd 1024
232 puts -nonewline $::fd [string repeat [binary format c 0] 10000]
233 flush $::fd
234 t1sig
235 } $::sig
236  
237 do_test exclusive2-2.5 {
238 pagerChangeCounter test.db 5 $::fd
239 } {5}
240 do_test exclusive2-2.6 {
241 t1sig
242 } $::sig
243 do_test exclusive2-2.7 {
244 execsql {PRAGMA locking_mode = normal}
245 t1sig
246 } $::sig
247  
248 do_test exclusive2-2.8 {
249 set rc [catch {t1sig} msg]
250 list $rc $msg
251 } {1 {database disk image is malformed}}
252  
253 #--------------------------------------------------------------------
254 # These tests - exclusive2-3.X - verify that the pager change-counter
255 # is only incremented by the first change when in exclusive access
256 # mode. In normal mode, the change-counter is incremented once
257 # per write-transaction.
258 #
259  
260 db close
261 catch {close $::fd}
262 file delete -force test.db
263 file delete -force test.db-journal
264  
265 do_test exclusive2-3.0 {
266 sqlite3 db test.db
267 execsql {
268 BEGIN;
269 CREATE TABLE t1(a UNIQUE);
270 INSERT INTO t1 VALUES(randstr(200, 200));
271 INSERT INTO t1 VALUES(randstr(200, 200));
272 COMMIT;
273 }
274 readPagerChangeCounter test.db
275 } {1}
276 do_test exclusive2-3.1 {
277 execsql {
278 INSERT INTO t1 VALUES(randstr(200, 200));
279 }
280 readPagerChangeCounter test.db
281 } {2}
282 do_test exclusive2-3.2 {
283 execsql {
284 INSERT INTO t1 VALUES(randstr(200, 200));
285 }
286 readPagerChangeCounter test.db
287 } {3}
288 do_test exclusive2-3.3 {
289 execsql {
290 PRAGMA locking_mode = exclusive;
291 INSERT INTO t1 VALUES(randstr(200, 200));
292 }
293 readPagerChangeCounter test.db
294 } {4}
295 do_test exclusive2-3.4 {
296 breakpoint
297 execsql {
298 INSERT INTO t1 VALUES(randstr(200, 200));
299 }
300 readPagerChangeCounter test.db
301 } {4}
302 do_test exclusive2-3.5 {
303 execsql {
304 PRAGMA locking_mode = normal;
305 INSERT INTO t1 VALUES(randstr(200, 200));
306 }
307 readPagerChangeCounter test.db
308 } {4}
309 do_test exclusive2-3.6 {
310 execsql {
311 INSERT INTO t1 VALUES(randstr(200, 200));
312 }
313 readPagerChangeCounter test.db
314 } {5}
315 sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
316  
317 finish_test