libdb/test/tcl/rep085.tcl
2011-09-13 13:44:24 -04:00

167 lines
5 KiB
Tcl

# See the file LICENSE for redistribution information.
#
# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved.
#
# TEST rep085
# TEST Skipping unnecessary abbreviated internal init.
# TEST
# TEST Make sure that once we've materialized NIMDBs, we don't bother
# TEST trying to do it again on subsequent sync without recovery. Make
# TEST sure we do probe for the need to materialize NIMDBs, but don't do
# TEST any internal init at all if there are no NIMDBs. Note that in order to
# TEST do this test we don't even need any NIMDBs.
proc rep085 { method {niter 20} {tnum 085} args } {
source ./include.tcl
# Run for btree and queue only. Since this is a NIMDB test,
# skip queueext.
if { $checking_valid_methods } {
set test_methods {}
foreach method $valid_methods {
if { [is_btree $method] == 1 || [is_queue $method] == 1 } {
if { [is_queueext $method] == 0 } {
lappend test_methods $method
}
}
}
return $test_methods
}
if { [is_btree $method] != 1 && [is_queue $method] != 1 } {
puts "Skipping internal init test rep$tnum for method $method."
return
}
if { [is_queueext $method] == 1 } {
puts "Skipping in-memory database test rep$tnum for method $method."
return
}
set args [convert_args $method $args]
rep085_sub $method $niter $tnum $args
}
proc rep085_sub { method niter tnum largs } {
global testdir
global env_private
global rep_verbose
global verbose_type
global rep085_page_msg_count rep085_update_req_count
set msg3 ""
if { $env_private } {
set msg3 "with private env"
}
puts "Rep$tnum ($method):\
Skipping unnecessary abbreviated internal init $msg3."
set verbargs ""
if { $rep_verbose == 1 } {
set verbargs " -verbose {$verbose_type on} "
}
set privargs ""
if { $env_private == 1 } {
set privargs " -private "
}
env_cleanup $testdir
replsetup $testdir/MSGQUEUEDIR
file mkdir [set dirs(A) $testdir/SITE_A]
file mkdir [set dirs(B) $testdir/SITE_B]
file mkdir [set dirs(C) $testdir/SITE_C]
set rep085_page_msg_count 0
set rep085_update_req_count 0
puts "\tRep$tnum.a: Create master"
repladd 1
set env_A_cmd "berkdb_env_noerr -create -txn \
$verbargs $privargs \
-errpfx SITE_A -errfile /dev/stderr \
-home $dirs(A) -rep_transport \[list 1 rep085_send\]"
set envs(A) [eval $env_A_cmd -rep_master]
puts "\tRep$tnum.b: create (only) a regular DB"
set start 0
eval rep_test $method $envs(A) NULL $niter $start $start 0 $largs
puts "\tRep$tnum.c: Create two clients"
repladd 2
set env_B_cmd "berkdb_env_noerr -create -txn \
$verbargs $privargs \
-errpfx SITE_B -errfile /dev/stderr \
-home $dirs(B) -rep_transport \[list 2 rep085_send\]"
set envs(B) [eval $env_B_cmd -rep_client]
repladd 3
set env_C_cmd "berkdb_env_noerr -create -txn \
$verbargs $privargs \
-errpfx SITE_C -errfile /dev/stderr \
-home $dirs(C) -rep_transport \[list 3 rep085_send\]"
set envs(C) [eval $env_C_cmd -rep_client]
set envlist "{$envs(A) 1} {$envs(B) 2} {$envs(C) 3}"
process_msgs $envlist
# Note that the initial internal init that we've just done should have
# the effect of setting this flag. The flag indicates that any NIMDBs
# have been loaded, and any full internal init of course accomplishes
# that. If there are no NIMDBs whatsoever (which is the case here),
# then the condition "any NIMDBs are loaded" is trivially satisfied.
#
if { !$env_private } {
assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 1
}
# Restart client C with recovery, which forces it to check for NIMDBs
# even though a full internal init is not necessary.
#
puts "\tRep$tnum.d: Bounce client C"
$envs(C) close
set envs(C) [eval $env_C_cmd -rep_client -recover]
if { !$env_private } {
assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 0
}
set upd_before $rep085_update_req_count
set pg_before $rep085_page_msg_count
set envlist "{$envs(A) 1} {$envs(B) 2} {$envs(C) 3}"
process_msgs $envlist
error_check_good update.msg.sent \
$rep085_update_req_count [incr upd_before]
error_check_good no.page.msg $rep085_page_msg_count $pg_before
if { !$env_private } {
assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 1
}
# Switch masters, forcing client C to re-sync. But this time it already
# knows it has NIMDBs, so even an UPDATE_REQ shouldn't be necessary.
#
puts "\tRep$tnum.e: Switch master to site B"
$envs(A) rep_start -client
$envs(B) rep_start -master
set upd_before $rep085_update_req_count
set pg_before $rep085_page_msg_count
process_msgs $envlist
error_check_good no.update.msg $rep085_update_req_count $upd_before
error_check_good no.page.msg.2 $rep085_page_msg_count $pg_before
$envs(A) close
$envs(B) close
$envs(C) close
replclose $testdir/MSGQUEUEDIR
}
proc rep085_send { control rec fromid toid flags lsn } {
global rep085_page_msg_count rep085_update_req_count
if {[berkdb msgtype $control] eq "page"} {
incr rep085_page_msg_count
} elseif {[berkdb msgtype $control] eq "update_req"} {
incr rep085_update_req_count
}
return [replsend $control $rec $fromid $toid $flags $lsn]
}