proc rep005 { method args } {
source ./include.tcl
if { [is_btree $method] == 0 } {
puts "Rep005: Skipping for method $method."
return
}
global rand_init
error_check_good set_random_seed [berkdb srand $rand_init] 0
set tnum "005"
set niter 10
set nclients 3
env_cleanup $testdir
set qdir $testdir/MSGQUEUEDIR
replsetup $qdir
set masterdir $testdir/MASTERDIR
file mkdir $masterdir
for { set i 0 } { $i < $nclients } { incr i } {
set clientdir($i) $testdir/CLIENTDIR.$i
file mkdir $clientdir($i)
}
puts -nonewline \
"Rep$tnum: Replication election error test with $nclients clients."
puts -nonewline \
" Started at: "
puts [clock format [clock seconds] -format "%H:%M %D"]
repladd 1
set env_cmd(M) "berkdb_env -create -log_max 1000000 -home $masterdir \
-txn nosync -rep_master -rep_transport \[list 1 replsend\]"
set masterenv [eval $env_cmd(M)]
error_check_good master_env [is_valid_env $masterenv] TRUE
for { set i 0 } { $i < $nclients } { incr i } {
set envid [expr $i + 2]
repladd $envid
set env_cmd($i) "berkdb_env -create -home $clientdir($i) \
-txn nosync -rep_client \
-rep_transport \[list $envid replsend\]"
set clientenv($i) [eval $env_cmd($i)]
error_check_good \
client_env($i) [is_valid_env $clientenv($i)] TRUE
}
puts "\tRep$tnum.a: Running test001 in replicated env."
eval test001 $method $niter 0 0 $tnum -env $masterenv $args
while { 1 } {
set nproced 0
incr nproced [replprocessqueue $masterenv 1]
for { set i 0 } { $i < $nclients } { incr i } {
set envid [expr $i + 2]
incr nproced [replprocessqueue $clientenv($i) $envid]
}
if { $nproced == 0 } {
break
}
}
for { set i 0 } { $i < $nclients } { incr i } {
puts "\tRep$tnum.b: Verifying contents of client database $i."
set testdir [get_home $masterenv]
set t1 $testdir/t1
set t2 $testdir/t2
set t3 $testdir/t3
open_and_dump_file test$tnum.db $clientenv($i) $testdir/t1 \
test001.check dump_file_direction "-first" "-next"
if { [string compare [convert_method $method] -recno] != 0 } {
filesort $t1 $t3
}
error_check_good diff_files($t2,$t3) [filecmp $t2 $t3] 0
verify_dir $clientdir($i) "\tRep$tnum.c: " 0 0 1
}
error_check_good master_flush [$masterenv rep_flush] 0
while { 1 } {
set nproced 0
incr nproced [replprocessqueue $masterenv 1 0]
for { set i 0 } { $i < $nclients } { incr i } {
incr nproced [replprocessqueue $clientenv($i) \
[expr $i + 2] 0]
}
if { $nproced == 0 } {
break
}
}
error_check_good masterenv_close [$masterenv close] 0
for { set i 0 } { $i < $nclients } { incr i } {
replclear [expr $i + 2]
}
set m "Rep$tnum"
set count 0
set win -1
set c0err { none electinit none none }
set c1err $c0err
set c2err $c0err
set numtests [expr [llength $c0err] * [llength $c1err] * \
[llength $c2err]]
puts "\t$m.d: Starting $numtests election with error tests"
set last_win -1
set win -1
foreach c0 $c0err {
foreach c1 $c1err {
foreach c2 $c2err {
set elist [list $c0 $c1 $c2]
rep005_elect env_cmd clientenv $qdir $m \
$count win last_win $elist
incr count
}
}
}
for { set i 0 } { $i < $nclients } { incr i } {
error_check_good clientenv_close($i) [$clientenv($i) close] 0
}
replclose $testdir/MSGQUEUEDIR
puts -nonewline \
"Rep$tnum: Completed at: "
puts [clock format [clock seconds] -format "%H:%M %D"]
}
proc rep005_elect { ecmd cenv qdir msg count winner lsn_lose elist } {
global elect_timeout elect_serial
global is_windows_test
upvar $ecmd env_cmd
upvar $cenv clientenv
upvar $winner win
upvar $lsn_lose last_win
set elect_timeout 5000000
set nclients [llength $elist]
set nsites [expr $nclients + 1]
set cl_list {}
for { set i 0 } { $i < $nclients } { incr i } {
set err_cmd($i) [lindex $elist $i]
set elect_pipe($i) INVALID
replclear [expr $i + 2]
lappend cl_list $i
}
set el 0
if { $win == -1 } {
if { $last_win != -1 } {
set cl_list [lreplace $cl_list $last_win $last_win]
set el $last_win
}
set windex [berkdb random_int 1 [expr [llength $cl_list] - 1]]
set win [lindex $cl_list $windex]
} else {
if {$win == 0} {
set el 1
}
}
for { set i 0 } { $i < $nclients } { incr i } {
if { $i == $win } {
set pri($i) 100
} elseif { $i == $last_win } {
set pri($i) 200
} else {
set pri($i) 10
}
}
puts "\t$msg.d.$count: Start election (win=client$win) $elist"
incr elect_serial
set pfx "CHILD$el.$elect_serial"
if { $is_windows_test == 1 } {
set elect_timeout [expr $elect_timeout * 3]
}
set elect_pipe($el) [start_election $pfx $qdir $env_cmd($el) \
$nsites $pri($el) $elect_timeout $err_cmd($el)]
tclsleep 2
set got_newmaster 0
set tries 10
while { 1 } {
set nproced 0
set he 0
set nm 0
set nm2 0
for { set i 0 } { $i < $nclients } { incr i } {
set he 0
set envid [expr $i + 2]
set child_done [check_election $elect_pipe($i) nm2]
if { $got_newmaster == 0 && $nm2 != 0 } {
error_check_good newmaster_is_master $nm2 \
[expr $win + 2]
set got_newmaster $nm2
if { $nm2 == $envid } {
error_check_good make_master($i) \
[$clientenv($i) rep_start -master] \
0
}
}
incr nproced \
[replprocessqueue $clientenv($i) $envid 0 he nm]
if { $he == 1 } {
if { $elect_pipe($i) != "INVALID" && \
$child_done == 1 } {
close_election $elect_pipe($i)
set elect_pipe($i) "INVALID"
}
if { $elect_pipe($i) == "INVALID" } {
incr elect_serial
set pfx "CHILD$i.$elect_serial"
set elect_pipe($i) [start_election \
$pfx $qdir \
$env_cmd($i) $nsites $pri($i) \
$elect_timeout $err_cmd($i)]
set got_hold_elect($i) 1
}
}
if { $nm != 0 } {
error_check_good newmaster_is_master $nm \
[expr $win + 2]
set got_newmaster $nm
if { $nm == $envid } {
error_check_good make_master($i) \
[$clientenv($i) rep_start -master] \
0
if { [expr $count % 10] == 0 } {
set dbname rep005.$count.db
set db [berkdb_open -env \
$clientenv($i) \
-auto_commit \
-create -btree $dbname]
error_check_good dbopen \
[is_valid_db $db] TRUE
error_check_good dbclose \
[$db close] 0
}
}
}
}
if { $nproced == 0 } {
incr tries -1
if { $tries == 0 } {
break
} else {
tclsleep 1
}
} else {
set tries 10
}
}
error_check_good "client $win wins" $got_newmaster [expr $win + 2]
cleanup_elections
while { 1 } {
set nproced 0
for { set i 0 } { $i < $nclients } { incr i } {
incr nproced [replprocessqueue $clientenv($i) \
[expr $i + 2] 0]
}
if { $nproced == 0 } {
break
}
}
set close_list { 0 0 0 1 1 1 1 1 1 1}
set close_len [expr [llength $close_list] - 1]
set close_index [berkdb random_int 0 $close_len]
if { [lindex $close_list $close_index] == 1 } {
puts -nonewline "\t$msg.e.$count: Closing "
error_check_good newmaster_close [$clientenv($win) close] 0
set lsn_win { 0 0 0 0 1 1 1 1 1 1 }
set lsn_len [expr [llength $lsn_win] - 1]
set lsn_index [berkdb random_int 0 $lsn_len]
if { [lindex $lsn_win $lsn_index] == 1 } {
set last_win $win
set dirindex [lsearch -exact $env_cmd($win) "-home"]
incr dirindex
set lsn_dir [lindex $env_cmd($win) $dirindex]
env_cleanup $lsn_dir
puts -nonewline "and cleaning "
} else {
set last_win -1
}
puts "new master, new client $win"
set clientenv($win) [eval $env_cmd($win)]
error_check_good cl($win) [is_valid_env $clientenv($win)] TRUE
set win -1
while { 1 } {
set nproced 0
for { set i 0 } { $i < $nclients } { incr i } {
incr nproced [replprocessqueue $clientenv($i) \
[expr $i + 2] 0]
}
if { $nproced == 0 } {
break
}
}
}
}