|
1 # 2001 September 15 |
|
2 # |
|
3 # Portions Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiaries. All rights reserved. |
|
4 # |
|
5 # The author disclaims copyright to this source code. In place of |
|
6 # a legal notice, here is a blessing: |
|
7 # |
|
8 # May you do good and not evil. |
|
9 # May you find forgiveness for yourself and forgive others. |
|
10 # May you share freely, never taking more than you give. |
|
11 # |
|
12 #*********************************************************************** |
|
13 # This file implements regression tests for SQLite library. The |
|
14 # focus of this script is page cache subsystem. |
|
15 # |
|
16 # $Id: pager.test,v 1.31 2008/08/20 14:49:25 danielk1977 Exp $ |
|
17 |
|
18 |
|
19 set testdir [file dirname $argv0] |
|
20 source $testdir/tester.tcl |
|
21 |
|
22 if {[info commands pager_open]!=""} { |
|
23 db close |
|
24 |
|
25 # Basic sanity check. Open and close a pager. |
|
26 # |
|
27 do_test pager-1.0 { |
|
28 catch {file delete -force ptf1.db} |
|
29 catch {file delete -force ptf1.db-journal} |
|
30 set v [catch { |
|
31 set ::p1 [pager_open ptf1.db 10] |
|
32 } msg] |
|
33 } {0} |
|
34 do_test pager-1.1 { |
|
35 pager_stats $::p1 |
|
36 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} |
|
37 do_test pager-1.2 { |
|
38 pager_pagecount $::p1 |
|
39 } {0} |
|
40 do_test pager-1.3 { |
|
41 pager_stats $::p1 |
|
42 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} |
|
43 do_test pager-1.4 { |
|
44 pager_close $::p1 |
|
45 } {} |
|
46 |
|
47 # Try to write a few pages. |
|
48 # |
|
49 do_test pager-2.1 { |
|
50 set v [catch { |
|
51 set ::p1 [pager_open ptf1.db 10] |
|
52 } msg] |
|
53 } {0} |
|
54 #do_test pager-2.2 { |
|
55 # set v [catch { |
|
56 # set ::g1 [page_get $::p1 0] |
|
57 # } msg] |
|
58 # lappend v $msg |
|
59 #} {1 SQLITE_ERROR} |
|
60 do_test pager-2.3.1 { |
|
61 set ::gx [page_lookup $::p1 1] |
|
62 } {} |
|
63 do_test pager-2.3.2 { |
|
64 pager_stats $::p1 |
|
65 } {ref 0 page 0 max 10 size -1 state 0 err 0 hit 0 miss 0 ovfl 0} |
|
66 do_test pager-2.3.3 { |
|
67 set v [catch { |
|
68 set ::g1 [page_get $::p1 1] |
|
69 } msg] |
|
70 if {$v} {lappend v $msg} |
|
71 set v |
|
72 } {0} |
|
73 do_test pager-2.3.3 { |
|
74 pager_stats $::p1 |
|
75 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} |
|
76 do_test pager-2.3.4 { |
|
77 set ::gx [page_lookup $::p1 1] |
|
78 expr {$::gx!=""} |
|
79 } {1} |
|
80 do_test pager-2.3.5 { |
|
81 page_unref $::gx |
|
82 pager_stats $::p1 |
|
83 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} |
|
84 do_test pager-2.3.6 { |
|
85 expr {$::g1==$::gx} |
|
86 } {1} |
|
87 do_test pager-2.3.7 { |
|
88 pager_stats $::p1 |
|
89 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} |
|
90 do_test pager-2.4 { |
|
91 pager_stats $::p1 |
|
92 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} |
|
93 do_test pager-2.5 { |
|
94 pager_pagecount $::p1 |
|
95 } {0} |
|
96 do_test pager-2.6 { |
|
97 pager_stats $::p1 |
|
98 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 0 miss 1 ovfl 0} |
|
99 do_test pager-2.7 { |
|
100 page_number $::g1 |
|
101 } {1} |
|
102 do_test pager-2.8 { |
|
103 page_read $::g1 |
|
104 } {} |
|
105 do_test pager-2.9 { |
|
106 page_unref $::g1 |
|
107 } {} |
|
108 |
|
109 # Update 24/03/2007: Even though the ref-count has dropped to zero, the |
|
110 # pager-cache still contains some pages. Previously, it was always true |
|
111 # that if there were no references to a pager it was empty. |
|
112 do_test pager-2.10 { |
|
113 pager_stats $::p1 |
|
114 } {ref 0 page 1 max 10 size -1 state 0 err 0 hit 0 miss 1 ovfl 0} |
|
115 do_test pager-2.11 { |
|
116 set ::g1 [page_get $::p1 1] |
|
117 expr {$::g1!=0} |
|
118 } {1} |
|
119 do_test pager-2.12 { |
|
120 page_number $::g1 |
|
121 } {1} |
|
122 do_test pager-2.13 { |
|
123 pager_stats $::p1 |
|
124 } {ref 1 page 1 max 10 size 0 state 1 err 0 hit 1 miss 1 ovfl 0} |
|
125 do_test pager-2.14 { |
|
126 set v [catch { |
|
127 page_write $::g1 "Page-One" |
|
128 } msg] |
|
129 lappend v $msg |
|
130 } {0 {}} |
|
131 do_test pager-2.15 { |
|
132 pager_stats $::p1 |
|
133 } {ref 1 page 1 max 10 size 1 state 2 err 0 hit 1 miss 1 ovfl 0} |
|
134 do_test pager-2.16 { |
|
135 page_read $::g1 |
|
136 } {Page-One} |
|
137 do_test pager-2.17 { |
|
138 set v [catch { |
|
139 pager_commit $::p1 |
|
140 } msg] |
|
141 lappend v $msg |
|
142 } {0 {}} |
|
143 do_test pager-2.20 { |
|
144 pager_stats $::p1 |
|
145 } {ref 1 page 1 max 10 size -1 state 1 err 0 hit 2 miss 1 ovfl 0} |
|
146 do_test pager-2.19 { |
|
147 pager_pagecount $::p1 |
|
148 } {1} |
|
149 do_test pager-2.21 { |
|
150 pager_stats $::p1 |
|
151 } {ref 1 page 1 max 10 size 1 state 1 err 0 hit 2 miss 1 ovfl 0} |
|
152 do_test pager-2.22 { |
|
153 page_unref $::g1 |
|
154 } {} |
|
155 do_test pager-2.23 { |
|
156 pager_stats $::p1 |
|
157 } {ref 0 page 1 max 10 size -1 state 0 err 0 hit 2 miss 1 ovfl 0} |
|
158 do_test pager-2.24 { |
|
159 set v [catch { |
|
160 page_get $::p1 1 |
|
161 } ::g1] |
|
162 if {$v} {lappend v $::g1} |
|
163 set v |
|
164 } {0} |
|
165 do_test pager-2.25 { |
|
166 page_read $::g1 |
|
167 } {Page-One} |
|
168 do_test pager-2.26 { |
|
169 set v [catch { |
|
170 page_write $::g1 {page-one} |
|
171 } msg] |
|
172 lappend v $msg |
|
173 } {0 {}} |
|
174 do_test pager-2.27 { |
|
175 page_read $::g1 |
|
176 } {page-one} |
|
177 do_test pager-2.28 { |
|
178 set v [catch { |
|
179 pager_rollback $::p1 |
|
180 } msg] |
|
181 lappend v $msg |
|
182 } {0 {}} |
|
183 do_test pager-2.29 { |
|
184 page_unref $::g1 |
|
185 set ::g1 [page_get $::p1 1] |
|
186 page_read $::g1 |
|
187 } {Page-One} |
|
188 do_test pager-2.99 { |
|
189 page_unref $::g1 |
|
190 pager_close $::p1 |
|
191 } {} |
|
192 |
|
193 do_test pager-3.1 { |
|
194 set v [catch { |
|
195 set ::p1 [pager_open ptf1.db 15] |
|
196 } msg] |
|
197 if {$v} {lappend v $msg} |
|
198 set v |
|
199 } {0} |
|
200 do_test pager-3.2 { |
|
201 pager_pagecount $::p1 |
|
202 } {1} |
|
203 do_test pager-3.3 { |
|
204 set v [catch { |
|
205 set ::g(1) [page_get $::p1 1] |
|
206 } msg] |
|
207 if {$v} {lappend v $msg} |
|
208 set v |
|
209 } {0} |
|
210 do_test pager-3.4 { |
|
211 page_read $::g(1) |
|
212 } {Page-One} |
|
213 do_test pager-3.5 { |
|
214 for {set i 2} {$i<=20} {incr i} { |
|
215 set gx [page_get $::p1 $i] |
|
216 page_write $gx "Page-$i" |
|
217 page_unref $gx |
|
218 } |
|
219 pager_commit $::p1 |
|
220 page_unref $::g(1) |
|
221 } {} |
|
222 for {set i 2} {$i<=20} {incr i} { |
|
223 do_test pager-3.6.[expr {$i-1}] [subst { |
|
224 set gx \[page_get $::p1 $i\] |
|
225 set v \[page_read \$gx\] |
|
226 page_unref \$gx |
|
227 set v |
|
228 }] "Page-$i" |
|
229 } |
|
230 for {set i 1} {$i<=20} {incr i} { |
|
231 regsub -all CNT { |
|
232 set ::g1 [page_get $::p1 CNT] |
|
233 set ::g2 [page_get $::p1 CNT] |
|
234 set ::vx [page_read $::g2] |
|
235 expr {$::g1==$::g2} |
|
236 } $i body; |
|
237 do_test pager-3.7.$i.1 $body {1} |
|
238 regsub -all CNT { |
|
239 page_unref $::g2 |
|
240 set vy [page_read $::g1] |
|
241 expr {$vy==$::vx} |
|
242 } $i body; |
|
243 do_test pager-3.7.$i.2 $body {1} |
|
244 regsub -all CNT { |
|
245 page_unref $::g1 |
|
246 set gx [page_get $::p1 CNT] |
|
247 set vy [page_read $gx] |
|
248 page_unref $gx |
|
249 expr {$vy==$::vx} |
|
250 } $i body; |
|
251 do_test pager-3.7.$i.3 $body {1} |
|
252 } |
|
253 do_test pager-3.99 { |
|
254 pager_close $::p1 |
|
255 } {} |
|
256 |
|
257 # tests of the checkpoint mechanism and api |
|
258 # |
|
259 do_test pager-4.0 { |
|
260 set v [catch { |
|
261 file delete -force ptf1.db |
|
262 set ::p1 [pager_open ptf1.db 15] |
|
263 } msg] |
|
264 if {$v} {lappend v $msg} |
|
265 set v |
|
266 } {0} |
|
267 do_test pager-4.1 { |
|
268 set g1 [page_get $::p1 1] |
|
269 page_write $g1 "Page-1 v0" |
|
270 for {set i 2} {$i<=20} {incr i} { |
|
271 set gx [page_get $::p1 $i] |
|
272 page_write $gx "Page-$i v0" |
|
273 page_unref $gx |
|
274 } |
|
275 pager_commit $::p1 |
|
276 } {} |
|
277 for {set i 1} {$i<=20} {incr i} { |
|
278 do_test pager-4.2.$i { |
|
279 set gx [page_get $p1 $i] |
|
280 set v [page_read $gx] |
|
281 page_unref $gx |
|
282 set v |
|
283 } "Page-$i v0" |
|
284 } |
|
285 do_test pager-4.3 { |
|
286 lrange [pager_stats $::p1] 0 1 |
|
287 } {ref 1} |
|
288 do_test pager-4.4 { |
|
289 lrange [pager_stats $::p1] 8 9 |
|
290 } {state 1} |
|
291 |
|
292 for {set i 1} {$i<20} {incr i} { |
|
293 do_test pager-4.5.$i.0 { |
|
294 set res {} |
|
295 for {set j 2} {$j<=20} {incr j} { |
|
296 set gx [page_get $p1 $j] |
|
297 set value [page_read $gx] |
|
298 page_unref $gx |
|
299 set shouldbe "Page-$j v[expr {$i-1}]" |
|
300 if {$value!=$shouldbe} { |
|
301 lappend res $value $shouldbe |
|
302 } |
|
303 } |
|
304 set res |
|
305 } {} |
|
306 do_test pager-4.5.$i.1 { |
|
307 page_write $g1 "Page-1 v$i" |
|
308 lrange [pager_stats $p1] 8 9 |
|
309 } {state 2} |
|
310 do_test pager-4.5.$i.2 { |
|
311 for {set j 2} {$j<=20} {incr j} { |
|
312 set gx [page_get $p1 $j] |
|
313 page_write $gx "Page-$j v$i" |
|
314 page_unref $gx |
|
315 if {$j==$i} { |
|
316 pager_stmt_begin $p1 |
|
317 } |
|
318 } |
|
319 } {} |
|
320 do_test pager-4.5.$i.3 { |
|
321 set res {} |
|
322 for {set j 2} {$j<=20} {incr j} { |
|
323 set gx [page_get $p1 $j] |
|
324 set value [page_read $gx] |
|
325 page_unref $gx |
|
326 set shouldbe "Page-$j v$i" |
|
327 if {$value!=$shouldbe} { |
|
328 lappend res $value $shouldbe |
|
329 } |
|
330 } |
|
331 set res |
|
332 } {} |
|
333 do_test pager-4.5.$i.4 { |
|
334 pager_rollback $p1 |
|
335 set res {} |
|
336 for {set j 2} {$j<=20} {incr j} { |
|
337 set gx [page_get $p1 $j] |
|
338 set value [page_read $gx] |
|
339 page_unref $gx |
|
340 set shouldbe "Page-$j v[expr {$i-1}]" |
|
341 if {$value!=$shouldbe} { |
|
342 lappend res $value $shouldbe |
|
343 } |
|
344 } |
|
345 set res |
|
346 } {} |
|
347 do_test pager-4.5.$i.5 { |
|
348 page_write $g1 "Page-1 v$i" |
|
349 lrange [pager_stats $p1] 8 9 |
|
350 } {state 2} |
|
351 do_test pager-4.5.$i.6 { |
|
352 for {set j 2} {$j<=20} {incr j} { |
|
353 set gx [page_get $p1 $j] |
|
354 page_write $gx "Page-$j v$i" |
|
355 page_unref $gx |
|
356 if {$j==$i} { |
|
357 pager_stmt_begin $p1 |
|
358 } |
|
359 } |
|
360 } {} |
|
361 do_test pager-4.5.$i.7 { |
|
362 pager_stmt_rollback $p1 |
|
363 for {set j 2} {$j<=20} {incr j} { |
|
364 set gx [page_get $p1 $j] |
|
365 set value [page_read $gx] |
|
366 page_unref $gx |
|
367 if {$j<=$i || $i==1} { |
|
368 set shouldbe "Page-$j v$i" |
|
369 } else { |
|
370 set shouldbe "Page-$j v[expr {$i-1}]" |
|
371 } |
|
372 if {$value!=$shouldbe} { |
|
373 lappend res $value $shouldbe |
|
374 } |
|
375 } |
|
376 set res |
|
377 } {} |
|
378 do_test pager-4.5.$i.8 { |
|
379 for {set j 2} {$j<=20} {incr j} { |
|
380 set gx [page_get $p1 $j] |
|
381 page_write $gx "Page-$j v$i" |
|
382 page_unref $gx |
|
383 if {$j==$i} { |
|
384 pager_stmt_begin $p1 |
|
385 } |
|
386 } |
|
387 } {} |
|
388 do_test pager-4.5.$i.9 { |
|
389 pager_stmt_commit $p1 |
|
390 for {set j 2} {$j<=20} {incr j} { |
|
391 set gx [page_get $p1 $j] |
|
392 set value [page_read $gx] |
|
393 page_unref $gx |
|
394 set shouldbe "Page-$j v$i" |
|
395 if {$value!=$shouldbe} { |
|
396 lappend res $value $shouldbe |
|
397 } |
|
398 } |
|
399 set res |
|
400 } {} |
|
401 do_test pager-4.5.$i.10 { |
|
402 pager_commit $p1 |
|
403 lrange [pager_stats $p1] 8 9 |
|
404 } {state 1} |
|
405 } |
|
406 |
|
407 # Test that nothing bad happens when sqlite3pager_set_cachesize() is |
|
408 # called with a negative argument. |
|
409 do_test pager-4.6.1 { |
|
410 pager_close [pager_open ptf2.db -15] |
|
411 } {} |
|
412 |
|
413 # Test truncate on an in-memory database is Ok. |
|
414 ifcapable memorydb { |
|
415 do_test pager-4.6.2 { |
|
416 set ::p2 [pager_open :memory: 10] |
|
417 pager_truncate $::p2 5 |
|
418 } {} |
|
419 do_test pager-4.6.3 { |
|
420 for {set i 1} {$i<5} {incr i} { |
|
421 set p [page_get $::p2 $i] |
|
422 page_write $p "Page $i" |
|
423 pager_commit $::p2 |
|
424 page_unref $p |
|
425 } |
|
426 # pager_truncate $::p2 3 |
|
427 } {} |
|
428 do_test pager-4.6.4 { |
|
429 pager_close $::p2 |
|
430 } {} |
|
431 } |
|
432 |
|
433 do_test pager-4.99 { |
|
434 page_unref $::g1 |
|
435 pager_close $::p1 |
|
436 } {} |
|
437 |
|
438 |
|
439 |
|
440 file delete -force ptf1.db |
|
441 |
|
442 } ;# end if( not mem: and has pager_open command ); |
|
443 |
|
444 if 0 { |
|
445 # Ticket #615: an assertion fault inside the pager. It is a benign |
|
446 # fault, but we might as well test for it. |
|
447 # |
|
448 do_test pager-5.1 { |
|
449 sqlite3 db test.db |
|
450 execsql { |
|
451 BEGIN; |
|
452 CREATE TABLE t1(x); |
|
453 PRAGMA synchronous=off; |
|
454 COMMIT; |
|
455 } |
|
456 } {} |
|
457 } |
|
458 |
|
459 # The following tests cover rolling back hot journal files. |
|
460 # They can't be run on windows because the windows version of |
|
461 # SQLite holds a mandatory exclusive lock on journal files it has open. |
|
462 # |
|
463 if {$tcl_platform(platform)!="windows" && $tcl_platform(platform)!="symbian"} { |
|
464 do_test pager-6.1 { |
|
465 file delete -force test2.db |
|
466 file delete -force test2.db-journal |
|
467 sqlite3 db2 test2.db |
|
468 execsql { |
|
469 PRAGMA synchronous = 0; |
|
470 CREATE TABLE abc(a, b, c); |
|
471 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
472 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
473 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
474 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
475 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
476 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
477 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
478 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
479 INSERT INTO abc VALUES(1, 2, randstr(200,200)); |
|
480 BEGIN; |
|
481 UPDATE abc SET c = randstr(200,200); |
|
482 } db2 |
|
483 copy_file test2.db test.db |
|
484 copy_file test2.db-journal test.db-journal |
|
485 |
|
486 set f [open test.db-journal a] |
|
487 fconfigure $f -encoding binary |
|
488 seek $f [expr [file size test.db-journal] - 1032] start |
|
489 puts -nonewline $f "\00\00\00\00" |
|
490 close $f |
|
491 |
|
492 sqlite3 db test.db |
|
493 execsql { |
|
494 SELECT sql FROM sqlite_master |
|
495 } |
|
496 } {{CREATE TABLE abc(a, b, c)}} |
|
497 |
|
498 do_test pager-6.2 { |
|
499 copy_file test2.db test.db |
|
500 copy_file test2.db-journal test.db-journal |
|
501 |
|
502 set f [open test.db-journal a] |
|
503 fconfigure $f -encoding binary |
|
504 seek $f [expr [file size test.db-journal] - 1032] start |
|
505 puts -nonewline $f "\00\00\00\FF" |
|
506 close $f |
|
507 |
|
508 sqlite3 db test.db |
|
509 execsql { |
|
510 SELECT sql FROM sqlite_master |
|
511 } |
|
512 } {{CREATE TABLE abc(a, b, c)}} |
|
513 |
|
514 do_test pager-6.3 { |
|
515 copy_file test2.db test.db |
|
516 copy_file test2.db-journal test.db-journal |
|
517 |
|
518 set f [open test.db-journal a] |
|
519 fconfigure $f -encoding binary |
|
520 seek $f [expr [file size test.db-journal] - 4] start |
|
521 puts -nonewline $f "\00\00\00\00" |
|
522 close $f |
|
523 |
|
524 sqlite3 db test.db |
|
525 execsql { |
|
526 SELECT sql FROM sqlite_master |
|
527 } |
|
528 } {{CREATE TABLE abc(a, b, c)}} |
|
529 |
|
530 do_test pager-6.4.1 { |
|
531 execsql { |
|
532 BEGIN; |
|
533 SELECT sql FROM sqlite_master; |
|
534 } |
|
535 copy_file test2.db-journal test.db-journal; |
|
536 sqlite3 db3 test.db |
|
537 catchsql { |
|
538 BEGIN; |
|
539 SELECT sql FROM sqlite_master; |
|
540 } db3; |
|
541 } {1 {database is locked}} |
|
542 do_test pager-6.4.2 { |
|
543 file delete -force test.db-journal |
|
544 catchsql { |
|
545 SELECT sql FROM sqlite_master; |
|
546 } db3; |
|
547 } {0 {{CREATE TABLE abc(a, b, c)}}} |
|
548 do_test pager-6.4.3 { |
|
549 db3 close |
|
550 execsql { |
|
551 COMMIT; |
|
552 } |
|
553 } {} |
|
554 |
|
555 do_test pager-6.5 { |
|
556 copy_file test2.db test.db |
|
557 copy_file test2.db-journal test.db-journal |
|
558 |
|
559 set f [open test.db-journal a] |
|
560 fconfigure $f -encoding binary |
|
561 puts -nonewline $f "hello" |
|
562 puts -nonewline $f "\x00\x00\x00\x05\x01\x02\x03\x04" |
|
563 puts -nonewline $f "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" |
|
564 close $f |
|
565 |
|
566 sqlite3 db test.db |
|
567 execsql { |
|
568 SELECT sql FROM sqlite_master |
|
569 } |
|
570 } {{CREATE TABLE abc(a, b, c)}} |
|
571 |
|
572 do_test pager-6.5 { |
|
573 db2 close |
|
574 } {} |
|
575 } |
|
576 finish_test |