1*1da57d55SToomas Soome#
2c5c4113dSnw141292# 2001 September 15
3c5c4113dSnw141292#
4c5c4113dSnw141292# The author disclaims copyright to this source code.  In place of
5c5c4113dSnw141292# a legal notice, here is a blessing:
6c5c4113dSnw141292#
7c5c4113dSnw141292#    May you do good and not evil.
8c5c4113dSnw141292#    May you find forgiveness for yourself and forgive others.
9c5c4113dSnw141292#    May you share freely, never taking more than you give.
10c5c4113dSnw141292#
11c5c4113dSnw141292#***********************************************************************
12c5c4113dSnw141292# This file implements regression tests for SQLite library.  The
13c5c4113dSnw141292# focus of this script is btree database backend
14c5c4113dSnw141292#
15c5c4113dSnw141292# $Id: btree2.test,v 1.10 2002/02/19 13:39:23 drh Exp $
16c5c4113dSnw141292
17c5c4113dSnw141292
18c5c4113dSnw141292set testdir [file dirname $argv0]
19c5c4113dSnw141292source $testdir/tester.tcl
20c5c4113dSnw141292
21c5c4113dSnw141292if {[info commands btree_open]!=""} {
22c5c4113dSnw141292
23c5c4113dSnw141292# Create a new database file containing no entries.  The database should
24c5c4113dSnw141292# contain 5 tables:
25c5c4113dSnw141292#
26c5c4113dSnw141292#     2   The descriptor table
27c5c4113dSnw141292#     3   The foreground table
28c5c4113dSnw141292#     4   The background table
29c5c4113dSnw141292#     5   The long key table
30c5c4113dSnw141292#     6   The long data table
31c5c4113dSnw141292#
32c5c4113dSnw141292# An explanation for what all these tables are used for is provided below.
33c5c4113dSnw141292#
34c5c4113dSnw141292do_test btree2-1.1 {
35c5c4113dSnw141292  expr srand(1)
36c5c4113dSnw141292  file delete -force test2.bt
37c5c4113dSnw141292  file delete -force test2.bt-journal
38c5c4113dSnw141292  set ::b [btree_open test2.bt]
39c5c4113dSnw141292  btree_begin_transaction $::b
40c5c4113dSnw141292  btree_create_table $::b
41c5c4113dSnw141292} {3}
42c5c4113dSnw141292do_test btree2-1.2 {
43c5c4113dSnw141292  btree_create_table $::b
44c5c4113dSnw141292} {4}
45c5c4113dSnw141292do_test btree2-1.3 {
46c5c4113dSnw141292  btree_create_table $::b
47c5c4113dSnw141292} {5}
48c5c4113dSnw141292do_test btree2-1.4 {
49c5c4113dSnw141292  btree_create_table $::b
50c5c4113dSnw141292} {6}
51c5c4113dSnw141292do_test btree2-1.5 {
52c5c4113dSnw141292  set ::c2 [btree_cursor $::b 2 1]
53c5c4113dSnw141292  btree_insert $::c2 {one} {1}
54c5c4113dSnw141292  btree_delete $::c2
55c5c4113dSnw141292  btree_close_cursor $::c2
56c5c4113dSnw141292  btree_commit $::b
57c5c4113dSnw141292  btree_integrity_check $::b 2 3 4 5 6
58c5c4113dSnw141292} {}
59c5c4113dSnw141292
60c5c4113dSnw141292# This test module works by making lots of pseudo-random changes to a
61c5c4113dSnw141292# database while simultaneously maintaining an invariant on that database.
62c5c4113dSnw141292# Periodically, the script does a sanity check on the database and verifies
63c5c4113dSnw141292# that the invariant is satisfied.
64c5c4113dSnw141292#
65c5c4113dSnw141292# The invariant is as follows:
66c5c4113dSnw141292#
67c5c4113dSnw141292#   1.  The descriptor table always contains 2 enters.  An entry keyed by
68c5c4113dSnw141292#       "N" is the number of elements in the foreground and background tables
69c5c4113dSnw141292#       combined.  The entry keyed by "L" is the number of digits in the keys
70c5c4113dSnw141292#       for foreground and background tables.
71c5c4113dSnw141292#
72c5c4113dSnw141292#   2.  The union of the foreground an background tables consists of N entries
73c5c4113dSnw141292#       where each entry an L-digit key.  (Actually, some keys can be longer
74c5c4113dSnw141292#       than L characters, but they always start with L digits.)  The keys
75c5c4113dSnw141292#       cover all integers between 1 and N.  Whenever an entry is added to
76c5c4113dSnw141292#       the foreground it is removed form the background and vice versa.
77c5c4113dSnw141292#
78c5c4113dSnw141292#   3.  Some entries in the foreground and background tables have keys that
79c5c4113dSnw141292#       begin with an L-digit number but are followed by additional characters.
80c5c4113dSnw141292#       For each such entry there is a corresponding entry in the long key
81c5c4113dSnw141292#       table.  The long key table entry has a key which is just the L-digit
82c5c4113dSnw141292#       number and data which is the length of the key in the foreground and
83c5c4113dSnw141292#       background tables.
84c5c4113dSnw141292#
85c5c4113dSnw141292#   4.  The data for both foreground and background entries is usually a
86c5c4113dSnw141292#       short string.  But some entries have long data strings.  For each
87c5c4113dSnw141292#       such entries there is an entry in the long data type.  The key to
88c5c4113dSnw141292#       long data table is an L-digit number.  (The extension on long keys
89c5c4113dSnw141292#       is omitted.)  The data is the number of charaters in the data of the
90c5c4113dSnw141292#       foreground or background entry.
91c5c4113dSnw141292#
92c5c4113dSnw141292# The following function builds a database that satisfies all of the above
93c5c4113dSnw141292# invariants.
94c5c4113dSnw141292#
95c5c4113dSnw141292proc build_db {N L} {
96c5c4113dSnw141292  for {set i 2} {$i<=6} {incr i} {
97c5c4113dSnw141292    catch {btree_close_cursor [set ::c$i]}
98c5c4113dSnw141292    btree_clear_table $::b $i
99c5c4113dSnw141292    set ::c$i [btree_cursor $::b $i 1]
100c5c4113dSnw141292  }
101c5c4113dSnw141292  btree_insert $::c2 N $N
102c5c4113dSnw141292  btree_insert $::c2 L $L
103c5c4113dSnw141292  set format %0${L}d
104c5c4113dSnw141292  for {set i 1} {$i<=$N} {incr i} {
105c5c4113dSnw141292    set key [format $format $i]
106c5c4113dSnw141292    set data $key
107c5c4113dSnw141292    btree_insert $::c3 $key $data
108c5c4113dSnw141292  }
109c5c4113dSnw141292}
110c5c4113dSnw141292
111c5c4113dSnw141292# Given a base key number and a length, construct the full text of the key
112c5c4113dSnw141292# or data.
113c5c4113dSnw141292#
114c5c4113dSnw141292proc make_payload {keynum L len} {
115c5c4113dSnw141292  set key [format %0${L}d $keynum]
116c5c4113dSnw141292  set r $key
117c5c4113dSnw141292  set i 1
118c5c4113dSnw141292  while {[string length $r]<$len} {
119c5c4113dSnw141292    append r " ($i) $key"
120c5c4113dSnw141292    incr i
121c5c4113dSnw141292  }
122c5c4113dSnw141292  return [string range $r 0 [expr {$len-1}]]
123c5c4113dSnw141292}
124c5c4113dSnw141292
125c5c4113dSnw141292# Verify the invariants on the database.  Return an empty string on
126c5c4113dSnw141292# success or an error message if something is amiss.
127c5c4113dSnw141292#
128c5c4113dSnw141292proc check_invariants {} {
129c5c4113dSnw141292  set ck [btree_integrity_check $::b 2 3 4 5 6]
130c5c4113dSnw141292  if {$ck!=""} {
131c5c4113dSnw141292    puts "\n*** SANITY:\n$ck"
132c5c4113dSnw141292    exit
133c5c4113dSnw141292    return $ck
134c5c4113dSnw141292  }
135c5c4113dSnw141292  btree_move_to $::c3 {}
136c5c4113dSnw141292  btree_move_to $::c4 {}
137c5c4113dSnw141292  btree_move_to $::c2 N
138c5c4113dSnw141292  set N [btree_data $::c2]
139c5c4113dSnw141292  btree_move_to $::c2 L
140c5c4113dSnw141292  set L [btree_data $::c2]
141c5c4113dSnw141292  set LM1 [expr {$L-1}]
142c5c4113dSnw141292  for {set i 1} {$i<=$N} {incr i} {
143c5c4113dSnw141292    set key [btree_key $::c3]
144c5c4113dSnw141292    if {[scan $key %d k]<1} {set k 0}
145c5c4113dSnw141292    if {$k!=$i} {
146c5c4113dSnw141292      set key [btree_key $::c4]
147c5c4113dSnw141292      if {[scan $key %d k]<1} {set k 0}
148c5c4113dSnw141292      if {$k!=$i} {
149c5c4113dSnw141292        # puts "MISSING $i"
150c5c4113dSnw141292        # puts {Page 3:}; btree_page_dump $::b 3
151c5c4113dSnw141292        # puts {Page 4:}; btree_page_dump $::b 4
152c5c4113dSnw141292        # exit
153c5c4113dSnw141292        return "Key $i is missing from both foreground and background"
154c5c4113dSnw141292      }
155c5c4113dSnw141292      set data [btree_data $::c4]
156c5c4113dSnw141292      btree_next $::c4
157c5c4113dSnw141292    } else {
158c5c4113dSnw141292      set data [btree_data $::c3]
159c5c4113dSnw141292      btree_next $::c3
160c5c4113dSnw141292    }
161c5c4113dSnw141292    set skey [string range $key 0 $LM1]
162c5c4113dSnw141292    if {[btree_move_to $::c5 $skey]==0} {
163c5c4113dSnw141292      set keylen [btree_data $::c5]
164c5c4113dSnw141292    } else {
165c5c4113dSnw141292      set keylen $L
166c5c4113dSnw141292    }
167c5c4113dSnw141292    if {[string length $key]!=$keylen} {
168c5c4113dSnw141292      return "Key $i is the wrong size.\
169c5c4113dSnw141292              Is \"$key\" but should be \"[make_payload $k $L $keylen]\""
170c5c4113dSnw141292    }
171c5c4113dSnw141292    if {[make_payload $k $L $keylen]!=$key} {
172c5c4113dSnw141292      return "Key $i has an invalid extension"
173c5c4113dSnw141292    }
174c5c4113dSnw141292    if {[btree_move_to $::c6 $skey]==0} {
175c5c4113dSnw141292      set datalen [btree_data $::c6]
176c5c4113dSnw141292    } else {
177c5c4113dSnw141292      set datalen $L
178c5c4113dSnw141292    }
179c5c4113dSnw141292    if {[string length $data]!=$datalen} {
180c5c4113dSnw141292      return "Data for $i is the wrong size.\
181c5c4113dSnw141292              Is [string length $data] but should be $datalen"
182c5c4113dSnw141292    }
183c5c4113dSnw141292    if {[make_payload $k $L $datalen]!=$data} {
184c5c4113dSnw141292      return "Entry $i has an incorrect data"
185c5c4113dSnw141292    }
186c5c4113dSnw141292  }
187c5c4113dSnw141292}
188c5c4113dSnw141292
189c5c4113dSnw141292# Make random changes to the database such that each change preserves
190c5c4113dSnw141292# the invariants.  The number of changes is $n*N where N is the parameter
191c5c4113dSnw141292# from the descriptor table.  Each changes begins with a random key.
192c5c4113dSnw141292# the entry with that key is put in the foreground table with probability
193c5c4113dSnw141292# $I and it is put in background with probability (1.0-$I).  It gets
194c5c4113dSnw141292# a long key with probability $K and long data with probability $D.
195c5c4113dSnw141292#
196c5c4113dSnw141292set chngcnt 0
197c5c4113dSnw141292proc random_changes {n I K D} {
198c5c4113dSnw141292  btree_move_to $::c2 N
199c5c4113dSnw141292  set N [btree_data $::c2]
200c5c4113dSnw141292  btree_move_to $::c2 L
201c5c4113dSnw141292  set L [btree_data $::c2]
202c5c4113dSnw141292  set LM1 [expr {$L-1}]
203c5c4113dSnw141292  set total [expr {int($N*$n)}]
204c5c4113dSnw141292  set format %0${L}d
205c5c4113dSnw141292  for {set i 0} {$i<$total} {incr i} {
206c5c4113dSnw141292    set k [expr {int(rand()*$N)+1}]
207c5c4113dSnw141292    set insert [expr {rand()<=$I}]
208c5c4113dSnw141292    set longkey [expr {rand()<=$K}]
209c5c4113dSnw141292    set longdata [expr {rand()<=$D}]
210c5c4113dSnw141292    # incr ::chngcnt
211c5c4113dSnw141292    # if {$::chngcnt==251} {btree_tree_dump $::b 3}
212c5c4113dSnw141292    # puts "CHANGE $::chngcnt: $k $insert $longkey $longdata"
213c5c4113dSnw141292    if {$longkey} {
214c5c4113dSnw141292      set x [expr {rand()}]
215c5c4113dSnw141292      set keylen [expr {int($x*$x*$x*$x*3000)+10}]
216c5c4113dSnw141292    } else {
217c5c4113dSnw141292      set keylen $L
218c5c4113dSnw141292    }
219c5c4113dSnw141292    set key [make_payload $k $L $keylen]
220c5c4113dSnw141292    if {$longdata} {
221c5c4113dSnw141292      set x [expr {rand()}]
222c5c4113dSnw141292      set datalen [expr {int($x*$x*$x*$x*3000)+10}]
223c5c4113dSnw141292    } else {
224c5c4113dSnw141292      set datalen $L
225c5c4113dSnw141292    }
226c5c4113dSnw141292    set data [make_payload $k $L $datalen]
227c5c4113dSnw141292    set basekey [format $format $k]
228c5c4113dSnw141292    if {[set c [btree_move_to $::c3 $basekey]]==0} {
229c5c4113dSnw141292      btree_delete $::c3
230c5c4113dSnw141292    } else {
231c5c4113dSnw141292      if {$c<0} {btree_next $::c3}
232c5c4113dSnw141292      if {[string match $basekey* [btree_key $::c3]]} {
233c5c4113dSnw141292        btree_delete $::c3
234c5c4113dSnw141292      }
235c5c4113dSnw141292    }
236c5c4113dSnw141292    if {[set c [btree_move_to $::c4 $basekey]]==0} {
237c5c4113dSnw141292      btree_delete $::c4
238c5c4113dSnw141292    } else {
239c5c4113dSnw141292      if {$c<0} {btree_next $::c4}
240c5c4113dSnw141292      if {[string match $basekey* [btree_key $::c4]]} {
241c5c4113dSnw141292        btree_delete $::c4
242c5c4113dSnw141292      }
243c5c4113dSnw141292    }
244c5c4113dSnw141292    if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
245c5c4113dSnw141292    if {$kx==$k} {
246c5c4113dSnw141292      btree_delete $::c4
247c5c4113dSnw141292    }
248c5c4113dSnw141292    if {$insert} {
249c5c4113dSnw141292      btree_insert $::c3 $key $data
250c5c4113dSnw141292    } else {
251c5c4113dSnw141292      btree_insert $::c4 $key $data
252c5c4113dSnw141292    }
253c5c4113dSnw141292    if {$longkey} {
254c5c4113dSnw141292      btree_insert $::c5 $basekey $keylen
255c5c4113dSnw141292    } elseif {[btree_move_to $::c5 $basekey]==0} {
256c5c4113dSnw141292      btree_delete $::c5
257c5c4113dSnw141292    }
258c5c4113dSnw141292    if {$longdata} {
259c5c4113dSnw141292      btree_insert $::c6 $basekey $datalen
260c5c4113dSnw141292    } elseif {[btree_move_to $::c6 $basekey]==0} {
261c5c4113dSnw141292      btree_delete $::c6
262c5c4113dSnw141292    }
263c5c4113dSnw141292    # set ck [btree_integrity_check $::b 2 3 4 5 6]
264c5c4113dSnw141292    # if {$ck!=""} {
265c5c4113dSnw141292    #   puts "\nSANITY CHECK FAILED!\n$ck"
266c5c4113dSnw141292    #   exit
267c5c4113dSnw141292    # }
268c5c4113dSnw141292    # puts "PAGE 3:"; btree_page_dump $::b 3
269c5c4113dSnw141292    # puts "PAGE 4:"; btree_page_dump $::b 4
270c5c4113dSnw141292  }
271c5c4113dSnw141292}
272c5c4113dSnw141292
273c5c4113dSnw141292# Repeat this test sequence on database of various sizes
274c5c4113dSnw141292#
275c5c4113dSnw141292set testno 2
276c5c4113dSnw141292foreach {N L} {
277c5c4113dSnw141292  10 2
278c5c4113dSnw141292  50 2
279c5c4113dSnw141292  200 3
280c5c4113dSnw141292  2000 5
281c5c4113dSnw141292} {
282c5c4113dSnw141292  puts "**** N=$N L=$L ****"
283c5c4113dSnw141292  set hash [md5file test2.bt]
284c5c4113dSnw141292  do_test btree2-$testno.1 [subst -nocommands {
285c5c4113dSnw141292    set ::c2 [btree_cursor $::b 2 1]
286c5c4113dSnw141292    set ::c3 [btree_cursor $::b 3 1]
287c5c4113dSnw141292    set ::c4 [btree_cursor $::b 4 1]
288c5c4113dSnw141292    set ::c5 [btree_cursor $::b 5 1]
289c5c4113dSnw141292    set ::c6 [btree_cursor $::b 6 1]
290c5c4113dSnw141292    btree_begin_transaction $::b
291c5c4113dSnw141292    build_db $N $L
292c5c4113dSnw141292    check_invariants
293c5c4113dSnw141292  }] {}
294c5c4113dSnw141292  do_test btree2-$testno.2 {
295c5c4113dSnw141292    btree_close_cursor $::c2
296c5c4113dSnw141292    btree_close_cursor $::c3
297c5c4113dSnw141292    btree_close_cursor $::c4
298c5c4113dSnw141292    btree_close_cursor $::c5
299c5c4113dSnw141292    btree_close_cursor $::c6
300c5c4113dSnw141292    btree_rollback $::b
301c5c4113dSnw141292    md5file test2.bt
302c5c4113dSnw141292  } $hash
303c5c4113dSnw141292  do_test btree2-$testno.3 [subst -nocommands {
304c5c4113dSnw141292    btree_begin_transaction $::b
305c5c4113dSnw141292    set ::c2 [btree_cursor $::b 2 1]
306c5c4113dSnw141292    set ::c3 [btree_cursor $::b 3 1]
307c5c4113dSnw141292    set ::c4 [btree_cursor $::b 4 1]
308c5c4113dSnw141292    set ::c5 [btree_cursor $::b 5 1]
309c5c4113dSnw141292    set ::c6 [btree_cursor $::b 6 1]
310c5c4113dSnw141292    build_db $N $L
311c5c4113dSnw141292    check_invariants
312c5c4113dSnw141292  }] {}
313c5c4113dSnw141292  do_test btree2-$testno.4 {
314c5c4113dSnw141292    btree_commit $::b
315c5c4113dSnw141292    check_invariants
316c5c4113dSnw141292  } {}
317c5c4113dSnw141292  do_test btree2-$testno.5  {
318c5c4113dSnw141292    lindex [btree_pager_stats $::b] 1
319c5c4113dSnw141292  } {6}
320c5c4113dSnw141292  do_test btree2-$testno.6  {
321c5c4113dSnw141292    btree_close_cursor $::c2
322c5c4113dSnw141292    btree_close_cursor $::c3
323c5c4113dSnw141292    btree_close_cursor $::c4
324c5c4113dSnw141292    btree_close_cursor $::c5
325c5c4113dSnw141292    btree_close_cursor $::c6
326c5c4113dSnw141292    lindex [btree_pager_stats $::b] 1
327c5c4113dSnw141292  } {0}
328c5c4113dSnw141292  do_test btree2-$testno.7 {
329c5c4113dSnw141292    btree_close $::b
330c5c4113dSnw141292  } {}
331c5c4113dSnw141292after 100
332c5c4113dSnw141292  # For each database size, run various changes tests.
333c5c4113dSnw141292  #
334c5c4113dSnw141292  set num2 1
335c5c4113dSnw141292  foreach {n I K D} {
336c5c4113dSnw141292    0.5 0.5 0.1 0.1
337c5c4113dSnw141292    1.0 0.2 0.1 0.1
338c5c4113dSnw141292    1.0 0.8 0.1 0.1
339c5c4113dSnw141292    2.0 0.0 0.1 0.1
340c5c4113dSnw141292    2.0 1.0 0.1 0.1
341c5c4113dSnw141292    2.0 0.0 0.0 0.0
342c5c4113dSnw141292    2.0 1.0 0.0 0.0
343c5c4113dSnw141292  } {
344c5c4113dSnw141292    set testid btree2-$testno.8.$num2
345c5c4113dSnw141292    set hash [md5file test2.bt]
346c5c4113dSnw141292    do_test $testid.0 {
347c5c4113dSnw141292      set ::b [btree_open test2.bt]
348c5c4113dSnw141292      set ::c2 [btree_cursor $::b 2 1]
349c5c4113dSnw141292      set ::c3 [btree_cursor $::b 3 1]
350c5c4113dSnw141292      set ::c4 [btree_cursor $::b 4 1]
351c5c4113dSnw141292      set ::c5 [btree_cursor $::b 5 1]
352c5c4113dSnw141292      set ::c6 [btree_cursor $::b 6 1]
353c5c4113dSnw141292      check_invariants
354c5c4113dSnw141292    } {}
355c5c4113dSnw141292    set cnt 6
356c5c4113dSnw141292    for {set i 2} {$i<=6} {incr i} {
357c5c4113dSnw141292      if {[lindex [btree_cursor_dump [set ::c$i]] 0]!=$i} {incr cnt}
358c5c4113dSnw141292    }
359c5c4113dSnw141292    do_test $testid.1 {
360c5c4113dSnw141292      btree_begin_transaction $::b
361c5c4113dSnw141292      lindex [btree_pager_stats $::b] 1
362c5c4113dSnw141292    } $cnt
363c5c4113dSnw141292    # exec cp test2.bt test2.bt.bu1
364c5c4113dSnw141292    do_test $testid.2 [subst {
365c5c4113dSnw141292      random_changes $n $I $K $D
366c5c4113dSnw141292    }] {}
367c5c4113dSnw141292    do_test $testid.3 {
368c5c4113dSnw141292      check_invariants
369c5c4113dSnw141292    } {}
370c5c4113dSnw141292    do_test $testid.4 {
371c5c4113dSnw141292      btree_close_cursor $::c2
372c5c4113dSnw141292      btree_close_cursor $::c3
373c5c4113dSnw141292      btree_close_cursor $::c4
374c5c4113dSnw141292      btree_close_cursor $::c5
375c5c4113dSnw141292      btree_close_cursor $::c6
376c5c4113dSnw141292      btree_rollback $::b
377c5c4113dSnw141292      md5file test2.bt
378c5c4113dSnw141292    } $hash
379c5c4113dSnw141292    # exec cp test2.bt test2.bt.bu2
380c5c4113dSnw141292    btree_begin_transaction $::b
381c5c4113dSnw141292    set ::c2 [btree_cursor $::b 2 1]
382c5c4113dSnw141292    set ::c3 [btree_cursor $::b 3 1]
383c5c4113dSnw141292    set ::c4 [btree_cursor $::b 4 1]
384c5c4113dSnw141292    set ::c5 [btree_cursor $::b 5 1]
385c5c4113dSnw141292    set ::c6 [btree_cursor $::b 6 1]
386c5c4113dSnw141292    do_test $testid.5 [subst {
387c5c4113dSnw141292      random_changes $n $I $K $D
388c5c4113dSnw141292    }] {}
389c5c4113dSnw141292    do_test $testid.6 {
390c5c4113dSnw141292      check_invariants
391c5c4113dSnw141292    } {}
392c5c4113dSnw141292    do_test $testid.7 {
393c5c4113dSnw141292      btree_commit $::b
394c5c4113dSnw141292      check_invariants
395c5c4113dSnw141292    } {}
396c5c4113dSnw141292    set hash [md5file test2.bt]
397c5c4113dSnw141292    do_test $testid.8 {
398c5c4113dSnw141292      btree_close_cursor $::c2
399c5c4113dSnw141292      btree_close_cursor $::c3
400c5c4113dSnw141292      btree_close_cursor $::c4
401c5c4113dSnw141292      btree_close_cursor $::c5
402c5c4113dSnw141292      btree_close_cursor $::c6
403c5c4113dSnw141292      lindex [btree_pager_stats $::b] 1
404c5c4113dSnw141292    } {0}
405c5c4113dSnw141292    do_test $testid.9 {
406c5c4113dSnw141292      btree_close $::b
407c5c4113dSnw141292      set ::b [btree_open test2.bt]
408c5c4113dSnw141292      set ::c2 [btree_cursor $::b 2 1]
409c5c4113dSnw141292      set ::c3 [btree_cursor $::b 3 1]
410c5c4113dSnw141292      set ::c4 [btree_cursor $::b 4 1]
411c5c4113dSnw141292      set ::c5 [btree_cursor $::b 5 1]
412c5c4113dSnw141292      set ::c6 [btree_cursor $::b 6 1]
413c5c4113dSnw141292      check_invariants
414c5c4113dSnw141292    } {}
415c5c4113dSnw141292    do_test $testid.10 {
416c5c4113dSnw141292      btree_close_cursor $::c2
417c5c4113dSnw141292      btree_close_cursor $::c3
418c5c4113dSnw141292      btree_close_cursor $::c4
419c5c4113dSnw141292      btree_close_cursor $::c5
420c5c4113dSnw141292      btree_close_cursor $::c6
421c5c4113dSnw141292      lindex [btree_pager_stats $::b] 1
422c5c4113dSnw141292    } {0}
423c5c4113dSnw141292    do_test $testid.11 {
424c5c4113dSnw141292      btree_close $::b
425c5c4113dSnw141292    } {}
426c5c4113dSnw141292    incr num2
427c5c4113dSnw141292  }
428c5c4113dSnw141292  incr testno
429c5c4113dSnw141292  set ::b [btree_open test2.bt]
430c5c4113dSnw141292}
431c5c4113dSnw141292
432c5c4113dSnw141292# Testing is complete.  Shut everything down.
433c5c4113dSnw141292#
434c5c4113dSnw141292do_test btree-999.1 {
435c5c4113dSnw141292  lindex [btree_pager_stats $::b] 1
436c5c4113dSnw141292} {0}
437c5c4113dSnw141292do_test btree-999.2 {
438c5c4113dSnw141292  btree_close $::b
439c5c4113dSnw141292} {}
440c5c4113dSnw141292do_test btree-999.3 {
441c5c4113dSnw141292  file delete -force test2.bt
442c5c4113dSnw141292  file exists test2.bt-journal
443c5c4113dSnw141292} {0}
444c5c4113dSnw141292
445c5c4113dSnw141292} ;# end if( not mem: and has pager_open command );
446c5c4113dSnw141292
447c5c4113dSnw141292finish_test
448