1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2004,2008 Oracle.  All rights reserved.
4#
5# $Id: rep029.tcl,v 12.27 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	rep029
8# TEST	Test of internal initialization.
9# TEST
10# TEST	One master, one client.
11# TEST	Generate several log files.
12# TEST	Remove old master log files.
13# TEST	Delete client files and restart client.
14# TEST	Put one more record to the master.
15#
16proc rep029 { method { niter 200 } { tnum "029" } args } {
17
18	source ./include.tcl
19	if { $is_windows9x_test == 1 } {
20		puts "Skipping replication test on Win 9x platform."
21		return
22	}
23	if { $checking_valid_methods } {
24		return "ALL"
25	}
26	global passwd
27	global has_crypto
28
29	set args [convert_args $method $args]
30	set saved_args $args
31
32	# Rep057 runs rep029 with in-memory named databases.
33	set inmem 0
34	set msg "using regular named databases"
35	if { $tnum == "057" } {
36		set inmem 1
37		set msg "using in-memory named databases"
38		if { [is_queueext $method] == 1 } {
39			puts "Skipping rep$tnum for method $method"
40			return
41		}
42	}
43
44	# This test needs to set its own pagesize.
45	set pgindex [lsearch -exact $args "-pagesize"]
46	if { $pgindex != -1 } {
47		puts "Rep$tnum: skipping for specific pagesizes"
48		return
49	}
50
51	set logsets [create_logsets 2]
52
53	# Run the body of the test with and without recovery,
54	# and with and without cleaning.  Skip recovery with in-memory
55	# logging - it doesn't make sense.
56	set opts { bulk clean noclean }
57	foreach r $test_recopts {
58		foreach c $opts {
59			foreach l $logsets {
60				set logindex [lsearch -exact $l "in-memory"]
61				if { $r == "-recover" && $logindex != -1 } {
62					puts "Skipping rep$tnum for -recover\
63					    with in-memory logs."
64					continue
65				}
66				set envargs ""
67				set args $saved_args
68				puts "Rep$tnum ($method $envargs $r $c $args):\
69				    Test of internal initialization $msg."
70				puts "Rep$tnum: Master logs are [lindex $l 0]"
71				puts "Rep$tnum: Client logs are [lindex $l 1]"
72				rep029_sub $method $niter $tnum $envargs \
73				    $l $r $c $inmem $args
74
75				# Skip encrypted tests if not supported.
76				if { $has_crypto == 0 || $inmem } {
77					continue
78				}
79
80				# Run same set of tests with security.
81				#
82				append envargs " -encryptaes $passwd "
83				append args " -encrypt "
84				puts "Rep$tnum ($method $envargs $r $c $args):\
85				    Test of internal initialization with $msg."
86				puts "Rep$tnum: Master logs are [lindex $l 0]"
87				puts "Rep$tnum: Client logs are [lindex $l 1]"
88				rep029_sub $method $niter $tnum $envargs \
89				    $l $r $c $inmem $args
90			}
91		}
92	}
93}
94
95proc rep029_sub { method niter tnum envargs logset recargs opts inmem largs } {
96	global testdir
97	global passwd
98	global util_path
99	global rep_verbose
100	global verbose_type
101
102	set verbargs ""
103	if { $rep_verbose == 1 } {
104		set verbargs " -verbose {$verbose_type on} "
105	}
106
107	env_cleanup $testdir
108
109	replsetup $testdir/MSGQUEUEDIR
110
111	set masterdir $testdir/MASTERDIR
112	set clientdir $testdir/CLIENTDIR
113
114	file mkdir $masterdir
115	file mkdir $clientdir
116
117	# Log size is small so we quickly create more than one.
118	# The documentation says that the log file must be at least
119	# four times the size of the in-memory log buffer.
120	set pagesize 4096
121	append largs " -pagesize $pagesize "
122	set log_max [expr $pagesize * 8]
123
124	set m_logtype [lindex $logset 0]
125	set c_logtype [lindex $logset 1]
126
127	# In-memory logs cannot be used with -txn nosync.
128	set m_logargs [adjust_logargs $m_logtype]
129	set c_logargs [adjust_logargs $c_logtype]
130	set m_txnargs [adjust_txnargs $m_logtype]
131	set c_txnargs [adjust_txnargs $c_logtype]
132
133	# Open a master.
134	repladd 1
135	set ma_envcmd "berkdb_env_noerr -create $m_txnargs \
136	    $m_logargs -log_max $log_max $envargs $verbargs \
137	    -errpfx MASTER -home $masterdir \
138	    -rep_transport \[list 1 replsend\]"
139	set masterenv [eval $ma_envcmd $recargs -rep_master]
140
141	# Open a client
142	repladd 2
143	set cl_envcmd "berkdb_env_noerr -create $c_txnargs \
144	    $c_logargs -log_max $log_max $envargs $verbargs \
145	    -errpfx CLIENT -home $clientdir \
146	    -rep_transport \[list 2 replsend\]"
147	set clientenv [eval $cl_envcmd $recargs -rep_client]
148
149	# Bring the clients online by processing the startup messages.
150	set envlist "{$masterenv 1} {$clientenv 2}"
151	process_msgs $envlist
152
153	# Clobber replication's 30-second anti-archive timer, which will have
154	# been started by client sync-up internal init, so that we can do a
155	# log_archive in a moment.
156	#
157	$masterenv test force noarchive_timeout
158
159	# Run rep_test in the master (and update client).
160	puts "\tRep$tnum.a: Running rep_test in replicated env."
161	set start 0
162	eval rep_test \
163	    $method $masterenv NULL $niter $start $start 0 $inmem $largs
164	incr start $niter
165	process_msgs $envlist 0 NONE err
166	error_check_good process_msgs $err 0
167
168	if { [lsearch $envargs "-encrypta*"] !=-1 } {
169		set enc "-P $passwd"
170	} else {
171		set enc ""
172	}
173
174	# Find out what exists on the client.  We need to loop until
175	# the first master log file > last client log file.
176	puts "\tRep$tnum.b: Close client."
177	if { $c_logtype != "in-memory" } {
178		set res [eval exec $util_path/db_archive $enc -l -h $clientdir]
179	}
180	set last_client_log [get_logfile $clientenv last]
181	error_check_good client_close [$clientenv close] 0
182
183	set stop 0
184	while { $stop == 0 } {
185		# Run rep_test in the master (don't update client).  Each time
186		# through the loop, start at the same $start value (i.e., don't
187		# increment $start).  Since all we're trying to do is to fill up
188		# the log, it doesn't matter whether we insert new records or
189		# rewrite existing ones.  But if we insert new records we might
190		# fill up the cache, which is fatal in the in-memory database
191		# case.
192		#
193		puts "\tRep$tnum.c: Running rep_test in replicated env."
194	 	eval rep_test \
195		    $method $masterenv NULL $niter $start $start 0 $inmem $largs
196		replclear 2
197
198		puts "\tRep$tnum.d: Run db_archive on master."
199		if { $m_logtype != "in-memory"} {
200			set res [eval exec $util_path/db_archive $enc -d -h $masterdir]
201		}
202		set first_master_log [get_logfile $masterenv first]
203		if { $first_master_log > $last_client_log } {
204			set stop 1
205		}
206	}
207
208	puts "\tRep$tnum.e: Reopen client ($opts)."
209	if { $opts == "clean" } {
210		env_cleanup $clientdir
211	}
212	if { $opts == "bulk" } {
213		error_check_good bulk [$masterenv rep_config {bulk on}] 0
214	}
215	set clientenv [eval $cl_envcmd $recargs -rep_client]
216	error_check_good client_env [is_valid_env $clientenv] TRUE
217	set envlist "{$masterenv 1} {$clientenv 2}"
218	process_msgs $envlist 0 NONE err
219	error_check_good process_msgs $err 0
220	if { $opts != "clean" } {
221		puts "\tRep$tnum.e.1: Trigger log request"
222		#
223		# When we don't clean, starting the client doesn't
224		# trigger any events.  We need to generate some log
225		# records so that the client requests the missing
226		# logs and that will trigger it.
227		#
228		set entries 10
229		eval rep_test\
230		    $method $masterenv NULL $entries $start $start 0 $inmem $largs
231		incr start $entries
232		process_msgs $envlist 0 NONE err
233		error_check_good process_msgs $err 0
234	}
235
236	puts "\tRep$tnum.f: Verify databases"
237	#
238	# If doing bulk testing, turn it off now so that it forces us
239	# to flush anything currently in the bulk buffer.  We need to
240	# do this because rep_test might have aborted a transaction on
241	# its last iteration and those log records would still be in
242	# the bulk buffer causing the log comparison to fail.
243	#
244	if { $opts == "bulk" } {
245		puts "\tRep$tnum.f.1: Turn off bulk transfers."
246		error_check_good bulk [$masterenv rep_config {bulk off}] 0
247		process_msgs $envlist 0 NONE err
248		error_check_good process_msgs $err 0
249	}
250
251	#
252	# !!! This test CANNOT use rep_verify due to encryption.
253	# Just compare databases.  We either have to copy in
254	# all the code in rep_verify to adjust the beginning LSN
255	# or skip the log check for just this one test.
256	if { $inmem == 1 } {
257		set dbname { "" "test.db" }
258	} else {
259		set dbname "test.db"
260	}
261
262	rep_verify $masterdir $masterenv $clientdir $clientenv 1 1 0 $dbname
263
264	# Add records to the master and update client.
265	puts "\tRep$tnum.g: Add more records and check again."
266	set entries 10
267	eval rep_test \
268	    $method $masterenv NULL $entries $start $start 0 $inmem $largs
269	incr start $entries
270	process_msgs $envlist 0 NONE err
271	error_check_good process_msgs $err 0
272
273	rep_verify $masterdir $masterenv $clientdir $clientenv 1 1 0 $dbname
274
275	set bulkxfer [stat_field $masterenv rep_stat "Bulk buffer transfers"]
276	if { $opts == "bulk" } {
277		error_check_bad bulkxferon $bulkxfer 0
278	} else {
279		error_check_good bulkxferoff $bulkxfer 0
280	}
281
282	error_check_good masterenv_close [$masterenv close] 0
283	error_check_good clientenv_close [$clientenv close] 0
284	replclose $testdir/MSGQUEUEDIR
285}
286
287