1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2001-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST  rep009
8# TEST	Replication and DUPMASTERs
9# TEST  Run test001 in a replicated environment.
10# TEST
11# TEST  Declare one of the clients to also be a master.
12# TEST  Close a client, clean it and then declare it a 2nd master.
13proc rep009 { method { niter 10 } { tnum "009" } args } {
14
15	source ./include.tcl
16	global repfiles_in_memory
17
18	if { $is_windows9x_test == 1 } {
19		puts "Skipping replication test on Win 9x platform."
20		return
21	}
22
23	# Run for btree only.
24	if { $checking_valid_methods } {
25		set test_methods { btree }
26		return $test_methods
27	}
28	if { [is_btree $method] == 0 } {
29		puts "Rep009: Skipping for method $method."
30		return
31	}
32
33	set msg2 "and on-disk replication files"
34	if { $repfiles_in_memory } {
35		set msg2 "and in-memory replication files"
36	}
37
38	set logsets [create_logsets 3]
39
40	# Run the body of the test with and without recovery.
41	foreach r $test_recopts {
42		foreach l $logsets {
43			set logindex [lsearch -exact $l "in-memory"]
44			if { $r == "-recover" && $logindex != -1 } {
45				puts "Rep$tnum: Skipping\
46				    for in-memory logs with -recover."
47				continue
48			}
49			puts "Rep$tnum ($r): Replication DUPMASTER test $msg2."
50			puts "Rep$tnum: Master logs are [lindex $l 0]"
51			puts "Rep$tnum: Client1 logs are [lindex $l 1]"
52			puts "Rep$tnum: Client2 logs are [lindex $l 2]"
53			rep009_sub $method $niter $tnum 0 $l $r $args
54			rep009_sub $method $niter $tnum 1 $l $r $args
55		}
56	}
57}
58
59proc rep009_sub { method niter tnum clean logset recargs largs } {
60	global testdir
61	global repfiles_in_memory
62	global rep_verbose
63	global verbose_type
64
65	set verbargs ""
66	if { $rep_verbose == 1 } {
67		set verbargs " -verbose {$verbose_type on} "
68	}
69
70	set repmemargs ""
71	if { $repfiles_in_memory } {
72		set repmemargs "-rep_inmem_files "
73	}
74
75	env_cleanup $testdir
76
77	replsetup $testdir/MSGQUEUEDIR
78
79	set masterdir $testdir/MASTERDIR
80	set clientdir $testdir/CLIENTDIR
81	set clientdir2 $testdir/CLIENTDIR.2
82
83	file mkdir $masterdir
84	file mkdir $clientdir
85	file mkdir $clientdir2
86
87	set m_logtype [lindex $logset 0]
88	set m_logargs [adjust_logargs $m_logtype]
89	set m_txnargs [adjust_txnargs $m_logtype]
90
91	set c_logtype [lindex $logset 1]
92	set c_logargs [adjust_logargs $c_logtype]
93	set c_txnargs [adjust_txnargs $c_logtype]
94
95	set c2_logtype [lindex $logset 2]
96	set c2_logargs [adjust_logargs $c2_logtype]
97	set c2_txnargs [adjust_txnargs $c2_logtype]
98
99	# Open a master.
100	repladd 1
101	set ma_envcmd "berkdb_env_noerr -create $m_txnargs $m_logargs \
102	    -home $masterdir $verbargs -errpfx MASTER $repmemargs \
103	    -rep_transport \[list 1 replsend\]"
104	set masterenv [eval $ma_envcmd $recargs -rep_master]
105
106	# Open a client.
107	repladd 2
108	set cl_envcmd "berkdb_env_noerr -create $c_txnargs $c_logargs \
109	    -home $clientdir $verbargs -errpfx CLIENT1 $repmemargs \
110	    -rep_transport \[list 2 replsend\]"
111	set clientenv [eval $cl_envcmd $recargs -rep_client]
112
113	# Open a second client.
114	repladd 3
115	set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs $c2_logargs \
116	    -home $clientdir2 $verbargs -errpfx CLIENT2 $repmemargs \
117	    -rep_transport \[list 3 replsend\]"
118	set cl2env [eval $cl2_envcmd $recargs -rep_client]
119
120	# Bring the clients online by processing the startup messages.
121	set envlist "{$masterenv 1} {$clientenv 2} {$cl2env 3}"
122	process_msgs $envlist
123
124	# Run a modified test001 in the master (and update client).
125	puts "\tRep$tnum.a: Running test001 in replicated env."
126	eval test001 $method $niter 0 0 $tnum -env $masterenv $largs
127	process_msgs $envlist
128
129	puts "\tRep$tnum.b: Declare a client to be a master."
130	if { $clean } {
131		error_check_good clientenv_close [$clientenv close] 0
132		env_cleanup $clientdir
133		set clientenv [eval $cl_envcmd $recargs -rep_master]
134		error_check_good client_env [is_valid_env $clientenv] TRUE
135	} else {
136		error_check_good client_master [$clientenv rep_start -master] 0
137	}
138
139	#
140	# Process the messages to get them out of the db.
141	#
142	for { set i 1 } { $i <= 3 } { incr i } {
143		set seen_dup($i) 0
144	}
145	while { 1 } {
146		set nproced 0
147
148		incr nproced [replprocessqueue \
149		    $masterenv 1 0 NONE dup1 err1]
150		incr nproced [replprocessqueue \
151		    $clientenv 2 0 NONE dup2 err2]
152		incr nproced [replprocessqueue \
153		    $cl2env 3 0 NONE dup3 err3]
154		if { $dup1 != 0 } {
155			set seen_dup(1) 1
156			error_check_good downgrade1 \
157			    [$masterenv rep_start -client] 0
158		}
159		if { $dup2 != 0 } {
160			set seen_dup(2) 1
161			error_check_good downgrade1 \
162			    [$clientenv rep_start -client] 0
163		}
164		#
165		# We might get errors after downgrading as the former
166		# masters might get old messages from other clients.
167		# If we get an error make sure it is after downgrade.
168		if { $err1 != 0 } {
169			error_check_good seen_dup1_err $seen_dup(1) 1
170			error_check_good err1str [is_substr \
171			    $err1 "invalid argument"] 1
172		}
173		if { $err2 != 0 } {
174			error_check_good seen_dup2_err $seen_dup(2) 1
175			error_check_good err2str [is_substr \
176			    $err2 "invalid argument"] 1
177		}
178		#
179		# This should never happen.  We'll check below.
180		#
181		if { $dup3 != 0 } {
182			set seen_dup(3) 1
183		}
184
185		if { $nproced == 0 } {
186			break
187		}
188	}
189	error_check_good seen_dup1 $seen_dup(1) 1
190	error_check_good seen_dup2 $seen_dup(2) 1
191	error_check_bad seen_dup3 $seen_dup(3) 1
192
193	puts "\tRep$tnum.c: Close environments"
194	error_check_good master_close [$masterenv close] 0
195	error_check_good clientenv_close [$clientenv close] 0
196	error_check_good cl2_close [$cl2env close] 0
197	replclose $testdir/MSGQUEUEDIR
198}
199