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