aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test
diff options
context:
space:
mode:
authordan miller2007-10-20 02:49:29 +0000
committerdan miller2007-10-20 02:49:29 +0000
commite36d23a85ebff914d74bb541558c2b6082b78edb (patch)
tree54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test
parent* Fixed an issue whereby avatar chat distances were being calculated against ... (diff)
downloadopensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test502
1 files changed, 502 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test b/libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test
new file mode 100644
index 0000000..35263c1
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/test/btree2.test
@@ -0,0 +1,502 @@
1# 2001 September 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# This file implements regression tests for SQLite library. The
12# focus of this script is btree database backend
13#
14# $Id: btree2.test,v 1.15 2006/03/19 13:00:25 drh Exp $
15
16
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20if {[info commands btree_open]!=""} {
21
22# Create a new database file containing no entries. The database should
23# contain 5 tables:
24#
25# 2 The descriptor table
26# 3 The foreground table
27# 4 The background table
28# 5 The long key table
29# 6 The long data table
30#
31# An explanation for what all these tables are used for is provided below.
32#
33do_test btree2-1.1 {
34 expr srand(1)
35 file delete -force test2.bt
36 file delete -force test2.bt-journal
37 set ::b [btree_open test2.bt 2000 0]
38 btree_begin_transaction $::b
39 btree_create_table $::b 0
40} {2}
41do_test btree2-1.2 {
42 btree_create_table $::b 0
43} {3}
44do_test btree2-1.3 {
45 btree_create_table $::b 0
46} {4}
47do_test btree2-1.4 {
48 btree_create_table $::b 0
49} {5}
50do_test btree2-1.5 {
51 btree_create_table $::b 0
52} {6}
53do_test btree2-1.6 {
54 set ::c2 [btree_cursor $::b 2 1]
55 btree_insert $::c2 {one} {1}
56 btree_move_to $::c2 {one}
57 btree_delete $::c2
58 btree_close_cursor $::c2
59 btree_commit $::b
60 btree_integrity_check $::b 1 2 3 4 5 6
61} {}
62
63# This test module works by making lots of pseudo-random changes to a
64# database while simultaneously maintaining an invariant on that database.
65# Periodically, the script does a sanity check on the database and verifies
66# that the invariant is satisfied.
67#
68# The invariant is as follows:
69#
70# 1. The descriptor table always contains 2 enters. An entry keyed by
71# "N" is the number of elements in the foreground and background tables
72# combined. The entry keyed by "L" is the number of digits in the keys
73# for foreground and background tables.
74#
75# 2. The union of the foreground an background tables consists of N entries
76# where each entry has an L-digit key. (Actually, some keys can be longer
77# than L characters, but they always start with L digits.) The keys
78# cover all integers between 1 and N. Whenever an entry is added to
79# the foreground it is removed form the background and vice versa.
80#
81# 3. Some entries in the foreground and background tables have keys that
82# begin with an L-digit number but are followed by additional characters.
83# For each such entry there is a corresponding entry in the long key
84# table. The long key table entry has a key which is just the L-digit
85# number and data which is the length of the key in the foreground and
86# background tables.
87#
88# 4. The data for both foreground and background entries is usually a
89# short string. But some entries have long data strings. For each
90# such entries there is an entry in the long data type. The key to
91# long data table is an L-digit number. (The extension on long keys
92# is omitted.) The data is the number of charaters in the data of the
93# foreground or background entry.
94#
95# The following function builds a database that satisfies all of the above
96# invariants.
97#
98proc build_db {N L} {
99 for {set i 2} {$i<=6} {incr i} {
100 catch {btree_close_cursor [set ::c$i]}
101 btree_clear_table $::b $i
102 set ::c$i [btree_cursor $::b $i 1]
103 }
104 btree_insert $::c2 N $N
105 btree_insert $::c2 L $L
106 set format %0${L}d
107 for {set i 1} {$i<=$N} {incr i} {
108 set key [format $format $i]
109 set data $key
110 btree_insert $::c3 $key $data
111 }
112}
113
114# Given a base key number and a length, construct the full text of the key
115# or data.
116#
117proc make_payload {keynum L len} {
118 set key [format %0${L}d $keynum]
119 set r $key
120 set i 1
121 while {[string length $r]<$len} {
122 append r " ($i) $key"
123 incr i
124 }
125 return [string range $r 0 [expr {$len-1}]]
126}
127
128# Verify the invariants on the database. Return an empty string on
129# success or an error message if something is amiss.
130#
131proc check_invariants {} {
132 set ck [btree_integrity_check $::b 1 2 3 4 5 6]
133 if {$ck!=""} {
134 puts "\n*** SANITY:\n$ck"
135 exit
136 return $ck
137 }
138 btree_move_to $::c3 {}
139 btree_move_to $::c4 {}
140 btree_move_to $::c2 N
141 set N [btree_data $::c2]
142 btree_move_to $::c2 L
143 set L [btree_data $::c2]
144 set LM1 [expr {$L-1}]
145 for {set i 1} {$i<=$N} {incr i} {
146 set key {}
147 if {![btree_eof $::c3]} {
148 set key [btree_key $::c3]
149 }
150 if {[scan $key %d k]<1} {set k 0}
151 if {$k!=$i} {
152 set key {}
153 if {![btree_eof $::c4]} {
154 set key [btree_key $::c4]
155 }
156 if {[scan $key %d k]<1} {set k 0}
157 if {$k!=$i} {
158 return "Key $i is missing from both foreground and background"
159 }
160 set data [btree_data $::c4]
161 btree_next $::c4
162 } else {
163 set data [btree_data $::c3]
164 btree_next $::c3
165 }
166 set skey [string range $key 0 $LM1]
167 if {[btree_move_to $::c5 $skey]==0} {
168 set keylen [btree_data $::c5]
169 } else {
170 set keylen $L
171 }
172 if {[string length $key]!=$keylen} {
173 return "Key $i is the wrong size.\
174 Is \"$key\" but should be \"[make_payload $k $L $keylen]\""
175 }
176 if {[make_payload $k $L $keylen]!=$key} {
177 return "Key $i has an invalid extension"
178 }
179 if {[btree_move_to $::c6 $skey]==0} {
180 set datalen [btree_data $::c6]
181 } else {
182 set datalen $L
183 }
184 if {[string length $data]!=$datalen} {
185 return "Data for $i is the wrong size.\
186 Is [string length $data] but should be $datalen"
187 }
188 if {[make_payload $k $L $datalen]!=$data} {
189 return "Entry $i has an incorrect data"
190 }
191 }
192}
193
194# Look at all elements in both the foreground and background tables.
195# Make sure the key is always the same as the prefix of the data.
196#
197# This routine was used for hunting bugs. It is not a part of standard
198# tests.
199#
200proc check_data {n key} {
201 global c3 c4
202 incr n -1
203 foreach c [list $c3 $c4] {
204 btree_first $c ;# move_to $c $key
205 set cnt 0
206 while {![btree_eof $c]} {
207 set key [btree_key $c]
208 set data [btree_data $c]
209 if {[string range $key 0 $n] ne [string range $data 0 $n]} {
210 puts "key=[list $key] data=[list $data] n=$n"
211 puts "cursor info = [btree_cursor_info $c]"
212 btree_page_dump $::b [lindex [btree_cursor_info $c] 0]
213 exit
214 }
215 btree_next $c
216 }
217 }
218}
219
220# Make random changes to the database such that each change preserves
221# the invariants. The number of changes is $n*N where N is the parameter
222# from the descriptor table. Each changes begins with a random key.
223# the entry with that key is put in the foreground table with probability
224# $I and it is put in background with probability (1.0-$I). It gets
225# a long key with probability $K and long data with probability $D.
226#
227set chngcnt 0
228proc random_changes {n I K D} {
229 global chngcnt
230 btree_move_to $::c2 N
231 set N [btree_data $::c2]
232 btree_move_to $::c2 L
233 set L [btree_data $::c2]
234 set LM1 [expr {$L-1}]
235 set total [expr {int($N*$n)}]
236 set format %0${L}d
237 for {set i 0} {$i<$total} {incr i} {
238 set k [expr {int(rand()*$N)+1}]
239 set insert [expr {rand()<=$I}]
240 set longkey [expr {rand()<=$K}]
241 set longdata [expr {rand()<=$D}]
242 if {$longkey} {
243 set x [expr {rand()}]
244 set keylen [expr {int($x*$x*$x*$x*3000)+10}]
245 } else {
246 set keylen $L
247 }
248 set key [make_payload $k $L $keylen]
249 if {$longdata} {
250 set x [expr {rand()}]
251 set datalen [expr {int($x*$x*$x*$x*3000)+10}]
252 } else {
253 set datalen $L
254 }
255 set data [make_payload $k $L $datalen]
256 set basekey [format $format $k]
257 if {[set c [btree_move_to $::c3 $basekey]]==0} {
258 btree_delete $::c3
259 } else {
260 if {$c<0} {btree_next $::c3}
261 if {![btree_eof $::c3]} {
262 if {[string match $basekey* [btree_key $::c3]]} {
263 btree_delete $::c3
264 }
265 }
266 }
267 if {[set c [btree_move_to $::c4 $basekey]]==0} {
268 btree_delete $::c4
269 } else {
270 if {$c<0} {btree_next $::c4}
271 if {![btree_eof $::c4]} {
272 if {[string match $basekey* [btree_key $::c4]]} {
273 btree_delete $::c4
274 }
275 }
276 }
277 set kx -1
278 if {![btree_eof $::c4]} {
279 if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
280 }
281 if {$kx==$k} {
282 btree_delete $::c4
283 }
284 # For debugging - change the "0" to "1" to integrity check after
285 # every change.
286 if 0 {
287 incr chngcnt
288 puts check----$chngcnt
289 set ck [btree_integrity_check $::b 1 2 3 4 5 6]
290 if {$ck!=""} {
291 puts "\nSANITY CHECK FAILED!\n$ck"
292 exit
293 }
294 }
295 if {$insert} {
296 btree_insert $::c3 $key $data
297 } else {
298 btree_insert $::c4 $key $data
299 }
300 if {$longkey} {
301 btree_insert $::c5 $basekey $keylen
302 } elseif {[btree_move_to $::c5 $basekey]==0} {
303 btree_delete $::c5
304 }
305 if {$longdata} {
306 btree_insert $::c6 $basekey $datalen
307 } elseif {[btree_move_to $::c6 $basekey]==0} {
308 btree_delete $::c6
309 }
310 # For debugging - change the "0" to "1" to integrity check after
311 # every change.
312 if 0 {
313 incr chngcnt
314 puts check----$chngcnt
315 set ck [btree_integrity_check $::b 1 2 3 4 5 6]
316 if {$ck!=""} {
317 puts "\nSANITY CHECK FAILED!\n$ck"
318 exit
319 }
320 }
321 }
322}
323set btree_trace 0
324
325# Repeat this test sequence on database of various sizes
326#
327set testno 2
328foreach {N L} {
329 10 2
330 50 2
331 200 3
332 2000 5
333} {
334 puts "**** N=$N L=$L ****"
335 set hash [md5file test2.bt]
336 do_test btree2-$testno.1 [subst -nocommands {
337 set ::c2 [btree_cursor $::b 2 1]
338 set ::c3 [btree_cursor $::b 3 1]
339 set ::c4 [btree_cursor $::b 4 1]
340 set ::c5 [btree_cursor $::b 5 1]
341 set ::c6 [btree_cursor $::b 6 1]
342 btree_begin_transaction $::b
343 build_db $N $L
344 check_invariants
345 }] {}
346 do_test btree2-$testno.2 {
347 btree_close_cursor $::c2
348 btree_close_cursor $::c3
349 btree_close_cursor $::c4
350 btree_close_cursor $::c5
351 btree_close_cursor $::c6
352 btree_rollback $::b
353 md5file test2.bt
354 } $hash
355 do_test btree2-$testno.3 [subst -nocommands {
356 btree_begin_transaction $::b
357 set ::c2 [btree_cursor $::b 2 1]
358 set ::c3 [btree_cursor $::b 3 1]
359 set ::c4 [btree_cursor $::b 4 1]
360 set ::c5 [btree_cursor $::b 5 1]
361 set ::c6 [btree_cursor $::b 6 1]
362 build_db $N $L
363 check_invariants
364 }] {}
365 do_test btree2-$testno.4 {
366 btree_commit $::b
367 check_invariants
368 } {}
369 do_test btree2-$testno.5 {
370 lindex [btree_pager_stats $::b] 1
371 } {6}
372 do_test btree2-$testno.6 {
373 btree_cursor_info $::c2
374 btree_cursor_info $::c3
375 btree_cursor_info $::c4
376 btree_cursor_info $::c5
377 btree_cursor_info $::c6
378 btree_close_cursor $::c2
379 btree_close_cursor $::c3
380 btree_close_cursor $::c4
381 btree_close_cursor $::c5
382 btree_close_cursor $::c6
383 lindex [btree_pager_stats $::b] 1
384 } {0}
385 do_test btree2-$testno.7 {
386 btree_close $::b
387 } {}
388
389 # For each database size, run various changes tests.
390 #
391 set num2 1
392 foreach {n I K D} {
393 0.5 0.5 0.1 0.1
394 1.0 0.2 0.1 0.1
395 1.0 0.8 0.1 0.1
396 2.0 0.0 0.1 0.1
397 2.0 1.0 0.1 0.1
398 2.0 0.0 0.0 0.0
399 2.0 1.0 0.0 0.0
400 } {
401 set testid btree2-$testno.8.$num2
402 set hash [md5file test2.bt]
403 do_test $testid.0 {
404 set ::b [btree_open test2.bt 2000 0]
405 set ::c2 [btree_cursor $::b 2 1]
406 set ::c3 [btree_cursor $::b 3 1]
407 set ::c4 [btree_cursor $::b 4 1]
408 set ::c5 [btree_cursor $::b 5 1]
409 set ::c6 [btree_cursor $::b 6 1]
410 check_invariants
411 } {}
412 set cnt 6
413 for {set i 2} {$i<=6} {incr i} {
414 if {[lindex [btree_cursor_info [set ::c$i]] 0]!=$i} {incr cnt}
415 }
416 do_test $testid.1 {
417 btree_begin_transaction $::b
418 lindex [btree_pager_stats $::b] 1
419 } $cnt
420 do_test $testid.2 [subst {
421 random_changes $n $I $K $D
422 }] {}
423 do_test $testid.3 {
424 check_invariants
425 } {}
426 do_test $testid.4 {
427 btree_close_cursor $::c2
428 btree_close_cursor $::c3
429 btree_close_cursor $::c4
430 btree_close_cursor $::c5
431 btree_close_cursor $::c6
432 btree_rollback $::b
433 md5file test2.bt
434 } $hash
435 btree_begin_transaction $::b
436 set ::c2 [btree_cursor $::b 2 1]
437 set ::c3 [btree_cursor $::b 3 1]
438 set ::c4 [btree_cursor $::b 4 1]
439 set ::c5 [btree_cursor $::b 5 1]
440 set ::c6 [btree_cursor $::b 6 1]
441 do_test $testid.5 [subst {
442 random_changes $n $I $K $D
443 }] {}
444 do_test $testid.6 {
445 check_invariants
446 } {}
447 do_test $testid.7 {
448 btree_commit $::b
449 check_invariants
450 } {}
451 set hash [md5file test2.bt]
452 do_test $testid.8 {
453 btree_close_cursor $::c2
454 btree_close_cursor $::c3
455 btree_close_cursor $::c4
456 btree_close_cursor $::c5
457 btree_close_cursor $::c6
458 lindex [btree_pager_stats $::b] 1
459 } {0}
460 do_test $testid.9 {
461 btree_close $::b
462 set ::b [btree_open test2.bt 2000 0]
463 set ::c2 [btree_cursor $::b 2 1]
464 set ::c3 [btree_cursor $::b 3 1]
465 set ::c4 [btree_cursor $::b 4 1]
466 set ::c5 [btree_cursor $::b 5 1]
467 set ::c6 [btree_cursor $::b 6 1]
468 check_invariants
469 } {}
470 do_test $testid.10 {
471 btree_close_cursor $::c2
472 btree_close_cursor $::c3
473 btree_close_cursor $::c4
474 btree_close_cursor $::c5
475 btree_close_cursor $::c6
476 lindex [btree_pager_stats $::b] 1
477 } {0}
478 do_test $testid.11 {
479 btree_close $::b
480 } {}
481 incr num2
482 }
483 incr testno
484 set ::b [btree_open test2.bt 2000 0]
485}
486
487# Testing is complete. Shut everything down.
488#
489do_test btree-999.1 {
490 lindex [btree_pager_stats $::b] 1
491} {0}
492do_test btree-999.2 {
493 btree_close $::b
494} {}
495do_test btree-999.3 {
496 file delete -force test2.bt
497 file exists test2.bt-journal
498} {0}
499
500} ;# end if( not mem: and has pager_open command );
501
502finish_test