1# See the file LICENSE for redistribution information. 2# 3# Copyright (c)-2009 Oracle. All rights reserved. 4# 5# TEST repmgr027 6# TEST Repmgr recognition of peer setting, across processes. 7# TEST 8# TEST Set up a master and two clients, synchronized with some data. 9# TEST Add a new client, configured to use c2c sync with one of the original 10# TEST clients. Check stats to make sure the correct c2c peer was used. 11 12proc repmgr027 { } { 13 repmgr027_sub position_chg 14 repmgr027_sub chg_site 15 repmgr027_sub chg_after_open 16 repmgr027_sub set_peer_after_open 17} 18 19proc repmgr027_sub { config } { 20 source ./include.tcl 21 22 set tnum "027" 23 puts "Repmgr$tnum: Repmgr peer, with \"$config\" configuration." 24 set site_prog [setup_site_prog] 25 26 env_cleanup $testdir 27 28 set ports [available_ports 4] 29 set mport [lindex $ports 0] 30 set portA [lindex $ports 1] 31 set portB [lindex $ports 2] 32 33 file mkdir [set masterdir $testdir/MASTER] 34 file mkdir $testdir/A 35 file mkdir $testdir/B 36 file mkdir $testdir/C 37 38 puts "\tRepmgr$tnum.a: Start master, write some data." 39 make_dbconfig $masterdir {{rep_set_nsites 4}} 40 set cmds { 41 "home $masterdir" 42 "local $mport" 43 "output $testdir/moutput" 44 "open_env" 45 "start master" 46 "open_db test.db" 47 "put key1 value1" 48 } 49 set m [open_site_prog [subst $cmds]] 50 51 puts "\tRepmgr$tnum.b:\ 52 Start initial two clients; wait for them to synchronize." 53 # Allowing both A and B to start at the same time, and synchronize 54 # concurrently would make sense. But it causes very slow performance on 55 # Windows. Since it's really only client C that's under test here, this 56 # detail doesn't matter. 57 # 58 make_dbconfig $testdir/A {{rep_set_nsites 4}} 59 set a [open_site_prog [list \ 60 "home $testdir/A" \ 61 "local $portA" \ 62 "output $testdir/aoutput" \ 63 "remote localhost $mport" \ 64 "open_env" \ 65 "start client"]] 66 set env [berkdb_env -home $testdir/A] 67 await_startup_done $env 68 $env close 69 70 make_dbconfig $testdir/B {{rep_set_nsites 4}} 71 set b [open_site_prog [list \ 72 "home $testdir/B" \ 73 "local $portB" \ 74 "output $testdir/boutput" \ 75 "remote localhost $mport" \ 76 "open_env" \ 77 "start client"]] 78 set env [berkdb_env -home $testdir/B] 79 await_startup_done $env 80 $env close 81 82 # Client C is the one whose behavior is being tested. It has two 83 # processes. "c" will be the main replication process, and "c2" the 84 # subordinate process. The initial configuration commands used to set 85 # up the two processes vary slightly with each test. The variable 86 # $config contains the name of the proc which will fill out the 87 # configuration information appropriately for each test variant. 88 # 89 puts "\tRepmgr$tnum.c: Start client under test." 90 make_dbconfig $testdir/C {{rep_set_nsites 4}} 91 92 set c2 [list \ 93 "home $testdir/C" \ 94 "local [lindex $ports 3]" \ 95 "output $testdir/c2output" \ 96 "open_env"] 97 set c [list \ 98 "home $testdir/C" \ 99 "local [lindex $ports 3]" \ 100 "output $testdir/coutput" \ 101 "open_env"] 102 set lists [repmgr027_$config $c2 $c] 103 set c2 [lindex $lists 0] 104 set c [lindex $lists 1] 105 106 # Ugly hack: in this one case, the order of opening the two client 107 # processes has to be reversed. 108 # 109 if {$config == "chg_after_open"} { 110 set c [open_site_prog $c] 111 set c2 [open_site_prog $c2] 112 } else { 113 set c2 [open_site_prog $c2] 114 set c [open_site_prog $c] 115 } 116 puts $c "start client" 117 gets $c 118 119 puts "\tRepmgr$tnum.d: Wait for startup-done at test client." 120 set env [berkdb_env -home $testdir/C] 121 await_startup_done $env 27 122 $env close 123 124 puts "\tRepmgr$tnum.e: Check stats to make sure proper peer was used." 125 set env [berkdb_env -home $testdir/A] 126 set reqs [stat_field $env rep_stat "Client service requests"] 127 error_check_good used_client_A [expr {$reqs > 0}] 1 128 $env close 129 set env [berkdb_env -home $testdir/B] 130 set reqs [stat_field $env rep_stat "Client service requests"] 131 error_check_good didnt_use_b [expr {$reqs == 0}] 1 132 $env close 133 134 puts "\tRepmgr$tnum.f: Clean up." 135 close $c2 136 close $c 137 close $b 138 close $a 139 close $m 140} 141 142# Scenario 1: client A is the peer; C2 sets B, A; C sets A. For C, this means 143# no peer change, but its position in the list changes, requiring some tricky 144# shuffling. 145# 146proc repmgr027_position_chg { c2 c } { 147 set remote_config [uplevel 1 {list \ 148 "remote localhost $mport" \ 149 "remote localhost $portB" \ 150 "remote -p localhost $portA"}] 151 set i [lsearch -exact $c2 "open_env"] 152 153 # It should be found, in the middle somewhere, or this will break. 154 set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" 155 156 set remote_config [uplevel 1 {list \ 157 "remote -p localhost $portA" \ 158 "remote localhost $mport"}] 159 set i [lsearch -exact $c "open_env"] 160 set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" 161 162 return [list $c2 $c] 163} 164 165# C2 first sets the peer as B, but then C comes along and changes it to A. 166# 167proc repmgr027_chg_site { c2 c } { 168 set remote_config [uplevel 1 {list \ 169 "remote localhost $mport" \ 170 "remote -p localhost $portB"}] 171 set i [lsearch -exact $c2 "open_env"] 172 173 # It should be found, in the middle somewhere, or this will break. 174 set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" 175 176 set remote_config [uplevel 1 {list \ 177 "remote -p localhost $portA" \ 178 "remote localhost $mport"}] 179 set i [lsearch -exact $c "open_env"] 180 set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" 181 182 return [list $c2 $c] 183} 184 185# C first sets B as its peer, and creates the env. Then C2 comes along and 186# changes it to A. C will have to learn of the change on the fly, rather than 187# at env open/join time. Even though the actual order of process creation will 188# be reversed (by the caller), we still conform to the convention of putting C2 189# first, and then C, in the ordered list. 190# 191proc repmgr027_chg_after_open { c2 c } { 192 set remote_config [uplevel 1 {list \ 193 "remote localhost $mport" \ 194 "remote -p localhost $portA"}] 195 set i [lsearch -exact $c2 "open_env"] 196 197 # It should be found, in the middle somewhere, or this will break. 198 set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" 199 200 set remote_config [uplevel 1 {list \ 201 "remote -p localhost $portB" \ 202 "remote localhost $mport"}] 203 set i [lsearch -exact $c "open_env"] 204 set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" 205 206 return [list $c2 $c] 207} 208 209# Nothing especially exotic here, except this exercises a code path where I 210# previously discovered a bug. 211# 212proc repmgr027_set_peer_after_open { c2 c } { 213 set remote_config [uplevel 1 {subst "remote -p localhost $portA"}] 214 lappend c $remote_config 215 return [list $c2 $c] 216} 217