1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2004,2008 Oracle.  All rights reserved.
4#
5# $Id: rep041.tcl,v 12.21 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	rep041
8# TEST  Turn replication on and off at run-time.
9# TEST
10# TEST  Start a master with replication OFF (noop transport function).
11# TEST  Run rep_test to advance log files and archive.
12# TEST  Start up client; change master to working transport function.
13# TEST  Now replication is ON.
14# TEST  Do more ops, make sure client is up to date.
15# TEST  Close client, turn replication OFF on master, do more ops.
16# TEST  Repeat from point A.
17#
18proc rep041 { method { niter 500 } { tnum "041" } args } {
19
20	source ./include.tcl
21	if { $is_windows9x_test == 1 } {
22		puts "Skipping replication test on Win 9x platform."
23		return
24	}
25
26	# Valid for all access methods.
27	if { $checking_valid_methods } {
28		return "ALL"
29	}
30
31	set args [convert_args $method $args]
32	set saved_args $args
33
34	set logsets [create_logsets 2]
35
36	# This test needs to set its own pagesize.
37	set pgindex [lsearch -exact $args "-pagesize"]
38        if { $pgindex != -1 } {
39                puts "Rep$tnum: skipping for specific pagesizes"
40                return
41        }
42
43	# Run the body of the test with and without recovery,
44	# and with and without cleaning.  Skip recovery with in-memory
45	# logging - it doesn't make sense.
46	foreach r $test_recopts {
47		foreach l $logsets {
48			set logindex [lsearch -exact $l "in-memory"]
49			if { $r == "-recover" && $logindex != -1 } {
50				puts "Skipping rep$tnum for -recover\
51				    with in-memory logs."
52				continue
53			}
54
55			set envargs ""
56			set args $saved_args
57			puts "Rep$tnum ($method $envargs $r $args):\
58			    Turn replication on and off."
59			puts "Rep$tnum: Master logs are [lindex $l 0]"
60			puts "Rep$tnum: Client logs are [lindex $l 1]"
61			rep041_sub $method $niter $tnum $envargs \
62			    $l $r $args
63		}
64	}
65}
66
67proc rep041_sub { method niter tnum envargs logset recargs largs } {
68	global testdir
69	global util_path
70	global rep_verbose
71	global verbose_type
72
73	set verbargs ""
74	if { $rep_verbose == 1 } {
75		set verbargs " -verbose {$verbose_type on} "
76	}
77
78	env_cleanup $testdir
79
80	replsetup $testdir/MSGQUEUEDIR
81
82	set masterdir $testdir/MASTERDIR
83	set clientdir $testdir/CLIENTDIR
84
85	file mkdir $masterdir
86	file mkdir $clientdir
87
88	# Log size is small so we quickly create more than one.
89	# The documentation says that the log file must be at least
90	# four times the size of the in-memory log buffer.
91	set pagesize 4096
92	append largs " -pagesize $pagesize "
93	set log_max [expr $pagesize * 8]
94
95	set m_logtype [lindex $logset 0]
96	set c_logtype [lindex $logset 1]
97
98	# In-memory logs cannot be used with -txn nosync.
99	set m_logargs [adjust_logargs $m_logtype]
100	set c_logargs [adjust_logargs $c_logtype]
101	set m_txnargs [adjust_txnargs $m_logtype]
102	set c_txnargs [adjust_txnargs $c_logtype]
103
104	# Open a master.
105	puts "\tRep$tnum.a: Open master with replication OFF."
106	repladd 1
107	set ma_envcmd "berkdb_env_noerr -create $m_txnargs $verbargs \
108	    $m_logargs -log_max $log_max $envargs -errpfx MASTER \
109	    -home $masterdir -rep"
110	set masterenv [eval $ma_envcmd $recargs]
111	$masterenv rep_limit 0 0
112
113        # Run rep_test in the master to advance log files.
114	puts "\tRep$tnum.b: Running rep_test to create some log files."
115	set start 0
116	eval rep_test $method $masterenv NULL $niter $start $start 0 0 $largs
117	incr start $niter
118
119	# Reset transport function to replnoop, and specify that
120	# this env will be master.
121	error_check_good \
122	    transport_noop [$masterenv rep_transport {1 replnoop}] 0
123	error_check_good rep_on [$masterenv rep_start -master] 0
124
125	# If master is on-disk, archive.
126	if { $m_logtype != "in-memory" } {
127		puts "\tRep$tnum.c: Run log_archive - some logs should be removed."
128		set res [eval exec $util_path/db_archive -l -h $masterdir]
129		error_check_bad log.1.present [lsearch -exact $res log.0000000001] -1
130		set res [eval exec $util_path/db_archive -d -h $masterdir]
131		set res [eval exec $util_path/db_archive -l -h $masterdir]
132		error_check_good log.1.gone [lsearch -exact $res log.0000000001] -1
133	}
134
135        # Run rep_test some more - this simulates running without clients.
136	puts "\tRep$tnum.d: Running rep_test."
137	eval rep_test $method $masterenv NULL $niter $start $start 0 0 $largs
138	incr start $niter
139
140	# Open a client
141	puts "\tRep$tnum.e: Open client."
142	repladd 2
143	set cl_envcmd "berkdb_env_noerr -create $c_txnargs $verbargs \
144	    $c_logargs -log_max $log_max $envargs -errpfx CLIENT \
145	    -home $clientdir \
146	    -rep_transport \[list 2 replsend\]"
147	set clientenv [eval $cl_envcmd $recargs -rep_client]
148	$clientenv rep_limit 0 0
149	$clientenv rep_request 4000 128000
150
151	# Set up envlist for processing messages later.
152	set envlist "{$masterenv 1} {$clientenv 2}"
153
154	# Turn replication on and off more than once.
155	set repeats 2
156	for { set i 0 } { $i < $repeats } { incr i } {
157
158		puts "\tRep$tnum.f.$i: Turn replication ON."
159		# Reset master transport function to replsend.
160		error_check_good transport_on \
161		    [$masterenv rep_transport {1 replsend}] 0
162
163		# Have the master announce itself so messages will pass.
164		error_check_good rep_on [$masterenv rep_start -master] 0
165
166		# Create some new messages, and process them.
167		set nentries 50
168		eval rep_test \
169		    $method $masterenv NULL $nentries $start $start 0 0 $largs
170		incr start $nentries
171		process_msgs $envlist
172
173		puts "\tRep$tnum.g.$i: Verify that client is up to date."
174		# Check that master and client contents match, to verify
175		# that client is up to date.
176		set dbname "test.db"
177		rep_verify $masterdir $masterenv $clientdir $clientenv 0 1 0
178
179		# Process messages again -- the rep_verify created some.
180		process_msgs $envlist
181
182		puts "\tRep$tnum.h.$i: Turn replication OFF on master."
183		error_check_good \
184		    transport_off [$masterenv rep_transport {1 replnoop}] 0
185
186		puts "\tRep$tnum.i.$i: Running rep_test in replicated env."
187		eval rep_test \
188		    $method $masterenv NULL $niter $start $start 0 0 $largs
189		incr start $niter
190
191		puts "\tRep$tnum.j.$i:\
192		    Process messages; none should be available."
193		set nproced [proc_msgs_once $envlist NONE err]
194		error_check_good no_messages $nproced 0
195
196		# Client and master should NOT match.
197		puts "\tRep$tnum.k.$i: Master and client should NOT match."
198		rep_verify $masterdir $masterenv $clientdir $clientenv 0 0 0
199
200	}
201	error_check_good clientenv_close [$clientenv close] 0
202	error_check_good masterenv_close [$masterenv close] 0
203	replclose $testdir/MSGQUEUEDIR
204}
205