~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/test/recd012.tcl

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# See the file LICENSE for redistribution information.
2
 
#
3
 
# Copyright (c) 2000-2002
4
 
#       Sleepycat Software.  All rights reserved.
5
 
#
6
 
# $Id$
7
 
#
8
 
# TEST  recd012
9
 
# TEST  Test of log file ID management. [#2288]
10
 
# TEST  Test recovery handling of file opens and closes.
11
 
proc recd012 { method {start 0} \
12
 
    {niter 49} {noutiter 25} {niniter 100} {ndbs 5} args } {
13
 
        source ./include.tcl
14
 
 
15
 
        set tnum 12
16
 
        set pagesize 512
17
 
 
18
 
        if { $is_qnx_test } {
19
 
                set niter 40
20
 
        }
21
 
 
22
 
        puts "Recd0$tnum $method ($args): Test recovery file management."
23
 
        set pgindex [lsearch -exact $args "-pagesize"]
24
 
        if { $pgindex != -1 } {
25
 
                puts "Recd012: skipping for specific pagesizes"
26
 
                return
27
 
        }
28
 
 
29
 
        for { set i $start } { $i <= $niter } { incr i } {
30
 
                env_cleanup $testdir
31
 
 
32
 
                # For repeatability, we pass in the iteration number
33
 
                # as a parameter and use that in recd012_body to seed
34
 
                # the random number generator to randomize our operations.
35
 
                # This lets us re-run a potentially failing iteration
36
 
                # without having to start from the beginning and work
37
 
                # our way to it.
38
 
                #
39
 
                # The number of databases ranges from 4 to 8 and is
40
 
                # a function of $niter
41
 
                # set ndbs [expr ($i % 5) + 4]
42
 
 
43
 
                recd012_body \
44
 
                    $method $ndbs $i $noutiter $niniter $pagesize $tnum $args
45
 
        }
46
 
}
47
 
 
48
 
proc recd012_body { method {ndbs 5} iter noutiter niniter psz tnum {largs ""} } {
49
 
        global alphabet rand_init fixed_len recd012_ofkey recd012_ofckptkey
50
 
        source ./include.tcl
51
 
 
52
 
        set largs [convert_args $method $largs]
53
 
        set omethod [convert_method $method]
54
 
 
55
 
        puts "\tRecd0$tnum $method ($largs): Iteration $iter"
56
 
        puts "\t\tRecd0$tnum.a: Create environment and $ndbs databases."
57
 
 
58
 
        # We run out of lockers during some of the recovery runs, so
59
 
        # we need to make sure that we specify a DB_CONFIG that will
60
 
        # give us enough lockers.
61
 
        set f [open $testdir/DB_CONFIG w]
62
 
        puts $f "set_lk_max_lockers     5000"
63
 
        close $f
64
 
 
65
 
        set flags "-create -txn -home $testdir"
66
 
        set env_cmd "berkdb_env $flags"
67
 
        error_check_good env_remove [berkdb envremove -home $testdir] 0
68
 
        set dbenv [eval $env_cmd]
69
 
        error_check_good dbenv [is_valid_env $dbenv] TRUE
70
 
 
71
 
        # Initialize random number generator based on $iter.
72
 
        berkdb srand [expr $iter + $rand_init]
73
 
 
74
 
        # Initialize database that keeps track of number of open files (so
75
 
        # we don't run out of descriptors).
76
 
        set ofname of.db
77
 
        set txn [$dbenv txn]
78
 
        error_check_good open_txn_begin [is_valid_txn $txn $dbenv] TRUE
79
 
        set ofdb [berkdb_open -env $dbenv -txn $txn\
80
 
            -create -dup -mode 0644 -btree -pagesize 512 $ofname]
81
 
        error_check_good of_open [is_valid_db $ofdb] TRUE
82
 
        error_check_good open_txn_commit [$txn commit] 0
83
 
        set oftxn [$dbenv txn]
84
 
        error_check_good of_txn [is_valid_txn $oftxn $dbenv] TRUE
85
 
        error_check_good of_put [$ofdb put -txn $oftxn $recd012_ofkey 1] 0
86
 
        error_check_good of_put2 [$ofdb put -txn $oftxn $recd012_ofckptkey 0] 0
87
 
        error_check_good of_put3 [$ofdb put -txn $oftxn $recd012_ofckptkey 0] 0
88
 
        error_check_good of_txn_commit [$oftxn commit] 0
89
 
        error_check_good of_close [$ofdb close] 0
90
 
 
91
 
        # Create ndbs databases to work in, and a file listing db names to
92
 
        # pick from.
93
 
        set f [open $testdir/dblist w]
94
 
 
95
 
        set oflags "-auto_commit -env $dbenv \
96
 
            -create -mode 0644 -pagesize $psz $largs $omethod"
97
 
        for { set i 0 } { $i < $ndbs } { incr i } {
98
 
                # 50-50 chance of being a subdb, unless we're a queue.
99
 
                if { [berkdb random_int 0 1] || [is_queue $method] } {
100
 
                        # not a subdb
101
 
                        set dbname recd0$tnum-$i.db
102
 
                } else {
103
 
                        # subdb
104
 
                        set dbname "recd0$tnum-subdb.db s$i"
105
 
                }
106
 
                puts $f $dbname
107
 
                set db [eval berkdb_open $oflags $dbname]
108
 
                error_check_good db($i) [is_valid_db $db] TRUE
109
 
                error_check_good db($i)_close [$db close] 0
110
 
        }
111
 
        close $f
112
 
        error_check_good env_close [$dbenv close] 0
113
 
 
114
 
        # Now we get to the meat of things.  Our goal is to do some number
115
 
        # of opens, closes, updates, and shutdowns (simulated here by a
116
 
        # close of all open handles and a close/reopen of the environment,
117
 
        # with or without an envremove), matching the regular expression
118
 
        #
119
 
        #       ((O[OUC]+S)+R+V)
120
 
        #
121
 
        # We'll repeat the inner + a random number up to $niniter times,
122
 
        # and the outer + a random number up to $noutiter times.
123
 
        #
124
 
        # In order to simulate shutdowns, we'll perform the opens, closes,
125
 
        # and updates in a separate process, which we'll exit without closing
126
 
        # all handles properly.  The environment will be left lying around
127
 
        # before we run recovery 50% of the time.
128
 
        set out [berkdb random_int 1 $noutiter]
129
 
        puts \
130
 
    "\t\tRecd0$tnum.b: Performing $out recoveries of up to $niniter ops."
131
 
        for { set i 0 } { $i < $out } { incr i } {
132
 
                set child [open "|$tclsh_path" w]
133
 
 
134
 
                # For performance, don't source everything,
135
 
                # just what we'll need.
136
 
                puts $child "load $tcllib"
137
 
                puts $child "set fixed_len $fixed_len"
138
 
                puts $child "source $src_root/test/testutils.tcl"
139
 
                puts $child "source $src_root/test/recd0$tnum.tcl"
140
 
 
141
 
                set rnd [expr $iter * 10000 + $i * 100 + $rand_init]
142
 
 
143
 
                # Go.
144
 
                berkdb debug_check
145
 
                puts $child "recd012_dochild {$env_cmd} $rnd $i $niniter\
146
 
                    $ndbs $tnum $method $ofname $largs"
147
 
                close $child
148
 
 
149
 
                # Run recovery 0-3 times.
150
 
                set nrecs [berkdb random_int 0 3]
151
 
                for { set j 0 } { $j < $nrecs } { incr j } {
152
 
                        berkdb debug_check
153
 
                        set ret [catch {exec $util_path/db_recover \
154
 
                            -h $testdir} res]
155
 
                        if { $ret != 0 } {
156
 
                                puts "FAIL: db_recover returned with nonzero\
157
 
                                    exit status, output as follows:"
158
 
                                file mkdir /tmp/12out
159
 
                                set fd [open /tmp/12out/[pid] w]
160
 
                                puts $fd $res
161
 
                                close $fd
162
 
                        }
163
 
                        error_check_good recover($j) $ret 0
164
 
                }
165
 
        }
166
 
 
167
 
        # Run recovery one final time;  it doesn't make sense to
168
 
        # check integrity if we do not.
169
 
        set ret [catch {exec $util_path/db_recover -h $testdir} res]
170
 
        if { $ret != 0 } {
171
 
                puts "FAIL: db_recover returned with nonzero\
172
 
                    exit status, output as follows:"
173
 
                puts $res
174
 
        }
175
 
 
176
 
        # Make sure each datum is the correct filename.
177
 
        puts "\t\tRecd0$tnum.c: Checking data integrity."
178
 
        set dbenv [berkdb_env -create -private -home $testdir]
179
 
        error_check_good env_open_integrity [is_valid_env $dbenv] TRUE
180
 
        set f [open $testdir/dblist r]
181
 
        set i 0
182
 
        while { [gets $f dbinfo] > 0 } {
183
 
                set db [eval berkdb_open -env $dbenv $dbinfo]
184
 
                error_check_good dbopen($dbinfo) [is_valid_db $db] TRUE
185
 
 
186
 
                set dbc [$db cursor]
187
 
                error_check_good cursor [is_valid_cursor $dbc $db] TRUE
188
 
 
189
 
                for { set dbt [$dbc get -first] } { [llength $dbt] > 0 } \
190
 
                    { set dbt [$dbc get -next] } {
191
 
                        error_check_good integrity [lindex [lindex $dbt 0] 1] \
192
 
                            [pad_data $method $dbinfo]
193
 
                }
194
 
                error_check_good dbc_close [$dbc close] 0
195
 
                error_check_good db_close [$db close] 0
196
 
        }
197
 
        close $f
198
 
        error_check_good env_close_integrity [$dbenv close] 0
199
 
 
200
 
        # Verify
201
 
        error_check_good verify \
202
 
            [verify_dir $testdir "\t\tRecd0$tnum.d: " 0 0 1] 0
203
 
}
204
 
 
205
 
proc recd012_dochild { env_cmd rnd outiter niniter ndbs tnum method\
206
 
    ofname args } {
207
 
        global recd012_ofkey
208
 
        source ./include.tcl
209
 
        if { [is_record_based $method] } {
210
 
                set keybase ""
211
 
        } else {
212
 
                set keybase .[repeat abcdefghijklmnopqrstuvwxyz 4]
213
 
        }
214
 
 
215
 
        # Initialize our random number generator, repeatably based on an arg.
216
 
        berkdb srand $rnd
217
 
 
218
 
        # Open our env.
219
 
        set dbenv [eval $env_cmd]
220
 
        error_check_good env_open [is_valid_env $dbenv] TRUE
221
 
 
222
 
        # Find out how many databases appear to be open in the log--we
223
 
        # don't want recovery to run out of filehandles.
224
 
        set txn [$dbenv txn]
225
 
        error_check_good child_txn_begin [is_valid_txn $txn $dbenv] TRUE
226
 
        set ofdb [berkdb_open -env $dbenv -txn $txn $ofname]
227
 
        error_check_good child_txn_commit [$txn commit] 0
228
 
 
229
 
        set oftxn [$dbenv txn]
230
 
        error_check_good of_txn [is_valid_txn $oftxn $dbenv] TRUE
231
 
        set dbt [$ofdb get -txn $oftxn $recd012_ofkey]
232
 
        error_check_good of_get [lindex [lindex $dbt 0] 0] $recd012_ofkey
233
 
        set nopenfiles [lindex [lindex $dbt 0] 1]
234
 
 
235
 
        error_check_good of_commit [$oftxn commit] 0
236
 
 
237
 
        # Read our dbnames
238
 
        set f [open $testdir/dblist r]
239
 
        set i 0
240
 
        while { [gets $f dbname($i)] > 0 } {
241
 
                incr i
242
 
        }
243
 
        close $f
244
 
 
245
 
        # We now have $ndbs extant databases.
246
 
        # Open one of them, just to get us started.
247
 
        set opendbs {}
248
 
        set oflags "-env $dbenv $args"
249
 
 
250
 
        # Start a transaction, just to get us started.
251
 
        set curtxn [$dbenv txn]
252
 
        error_check_good txn [is_valid_txn $curtxn $dbenv] TRUE
253
 
 
254
 
        # Inner loop.  Do $in iterations of a random open, close, or
255
 
        # update, where $in is between 1 and $niniter.
256
 
        set in [berkdb random_int 1 $niniter]
257
 
        for { set j 0 } { $j < $in } { incr j } {
258
 
                set op [berkdb random_int 0 2]
259
 
                switch $op {
260
 
                0 {
261
 
                        # Open.
262
 
                        recd012_open
263
 
                }
264
 
                1 {
265
 
                        # Update.  Put random-number$keybase as key,
266
 
                        # filename as data, into random database.
267
 
                        set num_open [llength $opendbs]
268
 
                        if { $num_open == 0 } {
269
 
                                # If none are open, do an open first.
270
 
                                recd012_open
271
 
                        }
272
 
                        set n [berkdb random_int 0 [expr $num_open - 1]]
273
 
                        set pair [lindex $opendbs $n]
274
 
                        set udb [lindex $pair 0]
275
 
                        set uname [lindex $pair 1]
276
 
 
277
 
                        set key [berkdb random_int 1000 1999]$keybase
278
 
                        set data [chop_data $method $uname]
279
 
                        error_check_good put($uname,$udb,$key,$data) \
280
 
                            [$udb put -txn $curtxn $key $data] 0
281
 
 
282
 
                        # One time in four, commit the transaction.
283
 
                        if { [berkdb random_int 0 3] == 0 && 0 } {
284
 
                                error_check_good txn_recommit \
285
 
                                    [$curtxn commit] 0
286
 
                                set curtxn [$dbenv txn]
287
 
                                error_check_good txn_reopen \
288
 
                                    [is_valid_txn $curtxn $dbenv] TRUE
289
 
                        }
290
 
                }
291
 
                2 {
292
 
                        # Close.
293
 
                        if { [llength $opendbs] == 0 } {
294
 
                                # If none are open, open instead of closing.
295
 
                                recd012_open
296
 
                                continue
297
 
                        }
298
 
 
299
 
                        # Commit curtxn first, lest we self-deadlock.
300
 
                        error_check_good txn_recommit [$curtxn commit] 0
301
 
 
302
 
                        # Do it.
303
 
                        set which [berkdb random_int 0 \
304
 
                            [expr [llength $opendbs] - 1]]
305
 
 
306
 
                        set db [lindex [lindex $opendbs $which] 0]
307
 
                        error_check_good db_choice [is_valid_db $db] TRUE
308
 
                        global errorCode errorInfo
309
 
 
310
 
                        error_check_good db_close \
311
 
                            [[lindex [lindex $opendbs $which] 0] close] 0
312
 
 
313
 
                        set opendbs [lreplace $opendbs $which $which]
314
 
                        incr nopenfiles -1
315
 
 
316
 
                        # Reopen txn.
317
 
                        set curtxn [$dbenv txn]
318
 
                        error_check_good txn_reopen \
319
 
                            [is_valid_txn $curtxn $dbenv] TRUE
320
 
                }
321
 
                }
322
 
 
323
 
                # One time in two hundred, checkpoint.
324
 
                if { [berkdb random_int 0 199] == 0 } {
325
 
                        puts "\t\t\tRecd0$tnum:\
326
 
                            Random checkpoint after operation $outiter.$j."
327
 
                        error_check_good txn_ckpt \
328
 
                            [$dbenv txn_checkpoint] 0
329
 
                        set nopenfiles \
330
 
                            [recd012_nopenfiles_ckpt $dbenv $ofdb $nopenfiles]
331
 
                }
332
 
        }
333
 
 
334
 
        # We have to commit curtxn.  It'd be kind of nice not to, but
335
 
        # if we start in again without running recovery, we may block
336
 
        # ourselves.
337
 
        error_check_good curtxn_commit [$curtxn commit] 0
338
 
 
339
 
        # Put back the new number of open files.
340
 
        set oftxn [$dbenv txn]
341
 
        error_check_good of_txn [is_valid_txn $oftxn $dbenv] TRUE
342
 
        error_check_good of_del [$ofdb del -txn $oftxn $recd012_ofkey] 0
343
 
        error_check_good of_put \
344
 
            [$ofdb put -txn $oftxn $recd012_ofkey $nopenfiles] 0
345
 
        error_check_good of_commit [$oftxn commit] 0
346
 
        error_check_good ofdb_close [$ofdb close] 0
347
 
}
348
 
 
349
 
proc recd012_open { } {
350
 
        # This is basically an inline and has to modify curtxn,
351
 
        # so use upvars.
352
 
        upvar curtxn curtxn
353
 
        upvar ndbs ndbs
354
 
        upvar dbname dbname
355
 
        upvar dbenv dbenv
356
 
        upvar oflags oflags
357
 
        upvar opendbs opendbs
358
 
        upvar nopenfiles nopenfiles
359
 
 
360
 
        # Return without an open if we've already opened too many files--
361
 
        # we don't want to make recovery run out of filehandles.
362
 
        if { $nopenfiles > 30 } {
363
 
                #puts "skipping--too many open files"
364
 
                return -code break
365
 
        }
366
 
 
367
 
        # Commit curtxn first, lest we self-deadlock.
368
 
        error_check_good txn_recommit \
369
 
            [$curtxn commit] 0
370
 
 
371
 
        # Do it.
372
 
        set which [berkdb random_int 0 [expr $ndbs - 1]]
373
 
 
374
 
        set db [eval berkdb_open -auto_commit $oflags $dbname($which)]
375
 
 
376
 
        lappend opendbs [list $db $dbname($which)]
377
 
 
378
 
        # Reopen txn.
379
 
        set curtxn [$dbenv txn]
380
 
        error_check_good txn_reopen [is_valid_txn $curtxn $dbenv] TRUE
381
 
 
382
 
        incr nopenfiles
383
 
}
384
 
 
385
 
# Update the database containing the number of files that db_recover has
386
 
# to contend with--we want to avoid letting it run out of file descriptors.
387
 
# We do this by keeping track of the number of unclosed opens since the
388
 
# checkpoint before last.
389
 
# $recd012_ofkey stores this current value;  the two dups available
390
 
# at $recd012_ofckptkey store the number of opens since the last checkpoint
391
 
# previous.
392
 
# Thus, if the current value is 17 when we do a checkpoint, and the
393
 
# stored values are 3 and 8, the new current value (which we return)
394
 
# is 14, and the new stored values are 8 and 6.
395
 
proc recd012_nopenfiles_ckpt { env db nopenfiles } {
396
 
        global recd012_ofckptkey
397
 
        set txn [$env txn]
398
 
        error_check_good nopenfiles_ckpt_txn [is_valid_txn $txn $env] TRUE
399
 
 
400
 
        set dbc [$db cursor -txn $txn]
401
 
        error_check_good db_cursor [is_valid_cursor $dbc $db] TRUE
402
 
 
403
 
        # Get the first ckpt value and delete it.
404
 
        set dbt [$dbc get -set $recd012_ofckptkey]
405
 
        error_check_good set [llength $dbt] 1
406
 
 
407
 
        set discard [lindex [lindex $dbt 0] 1]
408
 
        error_check_good del [$dbc del] 0
409
 
 
410
 
        set nopenfiles [expr $nopenfiles - $discard]
411
 
 
412
 
        # Get the next ckpt value
413
 
        set dbt [$dbc get -nextdup]
414
 
        error_check_good set2 [llength $dbt] 1
415
 
 
416
 
        # Calculate how many opens we've had since this checkpoint before last.
417
 
        set onlast [lindex [lindex $dbt 0] 1]
418
 
        set sincelast [expr $nopenfiles - $onlast]
419
 
 
420
 
        # Put this new number at the end of the dup set.
421
 
        error_check_good put [$dbc put -keylast $recd012_ofckptkey $sincelast] 0
422
 
 
423
 
        # We should never deadlock since we're the only one in this db.
424
 
        error_check_good dbc_close [$dbc close] 0
425
 
        error_check_good txn_commit [$txn commit] 0
426
 
 
427
 
        return $nopenfiles
428
 
}
429
 
 
430
 
# globals -- it's not worth passing these around, as they're constants
431
 
set recd012_ofkey OPENFILES
432
 
set recd012_ofckptkey CKPTS