1# See the file LICENSE for redistribution information.
2#
3# Copyright (c)-2009 Oracle.  All rights reserved.
4#
5# TEST repmgr026
6# TEST Repmgr site address discovery via NEWSITE
7# TEST
8# TEST New client, previously unknown to (main) master process, connects to an
9# TEST existing client, which broadcasts NEWSITE message.
10# TEST This causes master to discover its address, and connect to it.
11# TEST Other new clients may also have been added to master's configuration in
12# TEST the interim (via a subordinate master process).
13
14proc repmgr026 { } {
15	foreach sitelist { {} {2} {3 2} {3 2 4} {3} } {
16		repmgr026_sub $sitelist
17	}
18}
19
20proc repmgr026_sub { extras } {
21	source ./include.tcl
22
23	set tnum "026"
24	puts "Repmgr$tnum:\
25	    Repmgr and NEWSITE, with these extra clients: {$extras}"
26	set site_prog [setup_site_prog]
27
28	env_cleanup $testdir
29
30	set ports [available_ports 5]
31	set master_port [lindex $ports 0]
32	set portB [lindex $ports 1]
33	set portC [lindex $ports 2]
34
35	set i 0
36	foreach site_id "A B C D E" {
37		set d "$testdir/$site_id"
38		set dirs($i) $d
39		file mkdir $d
40		incr i
41	}
42	set masterdir $dirs(0)
43	set dirB $dirs(1)
44	set dirC $dirs(2)
45
46	puts "\tRepmgr$tnum.a: Start 2 processes at master."
47	make_dbconfig $masterdir {{rep_set_nsites 5}
48		{rep_set_timeout DB_REP_CONNECTION_RETRY 300000000}}
49	set m1 [open "| $site_prog" "r+"]
50	fconfigure $m1 -buffering line
51	puts $m1 "home $masterdir"
52	puts $m1 "local $master_port"
53	puts $m1 "output $testdir/m1output"
54	puts $m1 "open_env"
55	puts $m1 "start master"
56	gets $m1
57
58	set m2 [open "| $site_prog" "r+"]
59	fconfigure $m2 -buffering line
60	puts $m2 "home $masterdir"
61	puts $m2 "output $testdir/m2output"
62	puts $m2 "open_env"
63	puts $m2 "echo done"
64	gets $m2
65
66	puts "\tRepmgr$tnum.b: Start client B, connecting to master."
67	make_dbconfig $dirB {{rep_set_nsites 5}}
68	set b [open "| $site_prog" "r+"]
69	fconfigure $b -buffering line
70	puts $b "home $dirB"
71	puts $b "local $portB"
72	puts $b "remote localhost $master_port"
73	puts $b "output $testdir/boutput"
74	puts $b "open_env"
75	puts $b "start client"
76	gets $b
77
78	set envB [berkdb_env -home $dirB]
79	await_startup_done $envB
80
81	# Add some newly arrived client configurations to the master, but do it
82	# via the subordinate process A2, so that the main process doesn't
83	# notice them until it gets the NEWSITE message.  Note that these
84	# clients aren't running yet.
85	#
86	puts "\tRepmgr$tnum.c: Add new client addresses at master."
87	foreach client_index $extras {
88		puts $m2 "remote localhost [lindex $ports $client_index]"
89		if {$client_index == 2} {
90			# Start client C last, below.
91			continue;
92		}
93		make_dbconfig $dirs($client_index) {{rep_set_nsites 5}}
94		set x [open "| $site_prog" "r+"]
95		fconfigure $x -buffering line
96		puts $x "home $dirs($client_index)"
97		puts $x "local [lindex $ports $client_index]"
98		puts $x "output $testdir/c${client_index}output"
99		puts $x "open_env"
100		puts $x "start client"
101		gets $x
102		set sites($client_index) $x
103	}
104	puts $m2 "echo done"
105	gets $m2
106
107	# Start client C, triggering the NEWSITE mechanism at the master.
108	#
109	puts "\tRepmgr$tnum.d: Start client C, connecting first only to B."
110	make_dbconfig $dirC {{rep_set_nsites 5}}
111	set c [open "| $site_prog" "r+"]
112	fconfigure $c -buffering line
113	puts $c "home $dirC"
114	puts $c "local $portC"
115	puts $c "remote localhost $portB"
116	puts $c "output $testdir/coutput"
117	puts $c "open_env"
118	puts $c "start client"
119	gets $c
120
121	# First check for startup-done at site C.
122	#
123	set envC [berkdb_env -home $dirC]
124	await_startup_done $envC 15
125	$envC close
126
127	# Then check for startup-done at any other clients.
128	#
129	foreach client_index $extras {
130		if {$client_index == 2} {
131			continue;
132		}
133		set envx [berkdb_env -home $dirs($client_index)]
134		await_startup_done $envx 20
135		$envx close
136	}
137
138	# If we've gotten this far, we know that everything must have worked
139	# fine, because otherwise the clients wouldn't have been able to
140	# complete their start-up.  But let's check the master's site list
141	# anyway, to make sure it knows about site C at the list index location
142	# we think should be correct.
143	#
144	# Site C's address appears at the position indicated in the "extras"
145	# list, or right after that if it didn't appear in extras.
146	#
147	set pos [lsearch -exact $extras 2]
148	if {$pos == -1} {
149		set pos [llength $extras]
150	}
151	incr pos;			# make allowance for site B which is
152					# always there
153
154	puts "\tRepmgr$tnum.e: Check address lists."
155	set masterenv [berkdb_env -home $masterdir]
156	error_check_good master_knows_clientC \
157	    [lindex [$masterenv repmgr_site_list] $pos 2 ] $portC
158
159	set envC [berkdb_env -home $dirC]
160	error_check_good C_knows_master \
161	    [lindex [$envC repmgr_site_list] 1 2] $master_port
162
163	puts "\tRepmgr$tnum.f: Clean up."
164	$envC close
165	$envB close
166	$masterenv close
167
168	close $c
169
170	foreach client_index $extras {
171		if {$client_index == 2} {
172			continue;
173		}
174		close $sites($client_index)
175	}
176	close $b
177	close $m2
178	close $m1
179}
180