1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2001-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST  rep001
8# TEST	Replication rename and forced-upgrade test.
9# TEST
10# TEST	Run rep_test in a replicated master environment.
11# TEST	Verify that the database on the client is correct.
12# TEST	Next, remove the database, close the master, upgrade the
13# TEST	client, reopen the master, and make sure the new master can
14# TEST	correctly run rep_test and propagate it in the other direction.
15
16proc rep001 { method { niter 1000 } { tnum "001" } args } {
17	global passwd
18	global has_crypto
19	global databases_in_memory
20	global repfiles_in_memory
21
22	source ./include.tcl
23	if { $is_windows9x_test == 1 } {
24		puts "Skipping replication test on Win9x platform."
25		return
26	}
27
28	if { $checking_valid_methods } {
29		return "ALL"
30	}
31
32	# It's possible to run this test with in-memory databases.
33	set msg "with named databases"
34	if { $databases_in_memory } {
35		set msg "with in-memory named databases"
36		if { [is_queueext $method] == 1 } {
37			puts "Skipping rep$tnum for method $method"
38			return
39		}
40	}
41
42	set msg2 "and on-disk replication files"
43	if { $repfiles_in_memory } {
44		set msg2 "and in-memory replication files"
45	}
46
47	# Run tests with and without recovery.  If we're doing testing
48	# of in-memory logging, skip the combination of recovery
49	# and in-memory logging -- it doesn't make sense.
50	set logsets [create_logsets 2]
51	set saved_args $args
52
53	foreach recopt $test_recopts {
54		foreach l $logsets {
55			set logindex [lsearch -exact $l "in-memory"]
56			if { $recopt == "-recover" && $logindex != -1 } {
57				puts "Skipping test with -recover for in-memory logs."
58				continue
59			}
60			set envargs ""
61			set args $saved_args
62			puts -nonewline "Rep$tnum: Replication sanity test "
63			puts "($method $recopt) $msg $msg2."
64			puts "Rep$tnum: Master logs are [lindex $l 0]"
65			puts "Rep$tnum: Client logs are [lindex $l 1]"
66			rep001_sub $method $niter $tnum $envargs $l $recopt $args
67
68			# Skip encrypted tests if not supported.
69			if { $has_crypto == 0 || $databases_in_memory } {
70				continue
71			}
72
73			# Run the same tests with security.  In-memory
74			# databases don't work with encryption.
75			append envargs " -encryptaes $passwd "
76			append args " -encrypt "
77			puts "Rep$tnum: Replication and security sanity test\
78			    ($method $recopt)."
79			puts "Rep$tnum: Master logs are [lindex $l 0]"
80			puts "Rep$tnum: Client logs are [lindex $l 1]"
81			rep001_sub $method \
82			    $niter $tnum $envargs $l $recopt $args
83		}
84	}
85}
86
87proc rep001_sub { method niter tnum envargs logset recargs largs } {
88	source ./include.tcl
89	global testdir
90	global encrypt
91	global databases_in_memory
92	global repfiles_in_memory
93	global rep_verbose
94	global verbose_type
95
96	set verbargs ""
97	if { $rep_verbose == 1 } {
98		set verbargs " -verbose {$verbose_type on} "
99	}
100
101	set repmemargs ""
102	if { $repfiles_in_memory } {
103		set repmemargs "-rep_inmem_files "
104	}
105
106	env_cleanup $testdir
107
108	replsetup $testdir/MSGQUEUEDIR
109
110	set masterdir $testdir/MASTERDIR
111	set clientdir $testdir/CLIENTDIR
112
113	file mkdir $masterdir
114	file mkdir $clientdir
115
116	set m_logtype [lindex $logset 0]
117	set c_logtype [lindex $logset 1]
118
119	set verify_subset \
120	    [expr { $m_logtype == "in-memory" || $c_logtype == "in-memory" }]
121
122	# In-memory logs require a large log buffer, and cannot
123	# be used with -txn nosync.  Adjust the args for master
124	# and client.
125	set m_logargs [adjust_logargs $m_logtype]
126	set c_logargs [adjust_logargs $c_logtype]
127	set m_txnargs [adjust_txnargs $m_logtype]
128	set c_txnargs [adjust_txnargs $c_logtype]
129
130	# Open a master.
131	repladd 1
132	set env_cmd(M) "berkdb_env_noerr -create $repmemargs \
133	    -log_max 1000000 $envargs $m_logargs $recargs $verbargs \
134	    -home $masterdir -errpfx MASTER $m_txnargs -rep_master \
135	    -rep_transport \[list 1 replsend\]"
136	set masterenv [eval $env_cmd(M)]
137
138	# Open a client
139	repladd 2
140	set env_cmd(C) "berkdb_env_noerr -create $repmemargs \
141	    -log_max 1000000 $envargs $c_logargs $recargs $verbargs \
142	    -home $clientdir -errpfx CLIENT $c_txnargs -rep_client \
143	    -rep_transport \[list 2 replsend\]"
144	set clientenv [eval $env_cmd(C)]
145
146	# Bring the client online by processing the startup messages.
147	set envlist "{$masterenv 1} {$clientenv 2}"
148	process_msgs $envlist
149
150	# Clobber replication's 30-second anti-archive timer, which will have
151	# been started by client sync-up internal init, so that we can do a
152	# db_remove in a moment.
153	#
154	$masterenv test force noarchive_timeout
155
156	# Run rep_test in the master (and update client).
157	puts "\tRep$tnum.a:\
158	    Running rep_test in replicated env ($envargs $recargs)."
159	eval rep_test $method $masterenv NULL $niter 0 0 0 $largs
160	process_msgs $envlist
161
162	puts "\tRep$tnum.b: Verifying client database contents."
163	if { $databases_in_memory } {
164		set dbname { "" "test.db" }
165	} else {
166		set dbname "test.db"
167	}
168
169	rep_verify $masterdir $masterenv \
170	    $clientdir $clientenv $verify_subset 1 1
171
172	# Remove the file (and update client).
173	puts "\tRep$tnum.c: Remove the file on the master and close master."
174	error_check_good remove \
175	    [eval {$masterenv dbremove} -auto_commit $dbname] 0
176	error_check_good masterenv_close [$masterenv close] 0
177	process_msgs $envlist
178
179	puts "\tRep$tnum.d: Upgrade client."
180	set newmasterenv $clientenv
181	error_check_good upgrade_client [$newmasterenv rep_start -master] 0
182
183	# Run rep_test in the new master
184	puts "\tRep$tnum.e: Running rep_test in new master."
185	eval rep_test $method $newmasterenv NULL $niter 0 0 0 $largs
186	set envlist "{$newmasterenv 2}"
187	process_msgs $envlist
188
189	puts "\tRep$tnum.f: Reopen old master as client and catch up."
190	# Throttle master so it can't send everything at once
191	$newmasterenv rep_limit 0 [expr 64 * 1024]
192	set newclientenv [eval {berkdb_env_noerr -create -recover} \
193	    $envargs $m_logargs $m_txnargs -errpfx NEWCLIENT $verbargs $repmemargs \
194	    {-home $masterdir -rep_client -rep_transport [list 1 replsend]}]
195	set envlist "{$newclientenv 1} {$newmasterenv 2}"
196	process_msgs $envlist
197
198	# If we're running with a low number of iterations, we might
199	# not have had to throttle the data transmission; skip the check.
200	if { $niter > 200 } {
201		set nthrottles \
202		    [stat_field $newmasterenv rep_stat "Transmission limited"]
203		error_check_bad nthrottles $nthrottles -1
204		error_check_bad nthrottles $nthrottles 0
205	}
206
207	# Run a modified rep_test in the new master (and update client).
208	puts "\tRep$tnum.g: Running rep_test in new master."
209	eval rep_test $method \
210	    $newmasterenv NULL $niter $niter $niter 0 $largs
211	process_msgs $envlist
212
213	# Verify the database in the client dir.
214	puts "\tRep$tnum.h: Verifying new client database contents."
215
216	rep_verify $masterdir $newmasterenv \
217	    $clientdir $newclientenv $verify_subset 1 1
218
219	error_check_good newmasterenv_close [$newmasterenv close] 0
220	error_check_good newclientenv_close [$newclientenv close] 0
221
222	if { [lsearch $envargs "-encrypta*"] !=-1 } {
223		set encrypt 1
224	}
225	error_check_good verify \
226	    [verify_dir $clientdir "\tRep$tnum.k: " 0 0 1] 0
227
228	replclose $testdir/MSGQUEUEDIR
229}
230