1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2004-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST	rep027
8# TEST	Replication and secondary indexes.
9# TEST
10# TEST	Set up a secondary index on the master and make sure
11# TEST 	it can be accessed from the client.
12
13proc rep027 { method { niter 1000 } { tnum "027" } 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	# Renumbering recno is not permitted on a primary database.
24	if { $checking_valid_methods } {
25		set test_methods {}
26		foreach method $valid_methods {
27			if { [is_rrecno $method] != 1 } {
28				lappend test_methods $method
29			}
30		}
31		return $test_methods
32	}
33	if { [is_rrecno $method] == 1 } {
34		puts "Skipping rep027 for -rrecno."
35		return
36	}
37
38	set args [convert_args $method $args]
39	set logsets [create_logsets 2]
40
41	set msg2 "and on-disk replication files"
42	if { $repfiles_in_memory } {
43		set msg2 "and in-memory replication files"
44	}
45
46	# Run the body of the test with and without recovery.
47	foreach r $test_recopts {
48		foreach l $logsets {
49			set logindex [lsearch -exact $l "in-memory"]
50			if { $r == "-recover" && $logindex != -1 } {
51				puts "Rep$tnum: Skipping\
52				    for in-memory logs with -recover."
53				continue
54			}
55			puts "Rep$tnum ($method $r):\
56			    Replication and secondary indices $msg2."
57			puts "Rep$tnum: Master logs are [lindex $l 0]"
58			puts "Rep$tnum: Client logs are [lindex $l 1]"
59			rep027_sub $method $niter $tnum $l $r $args
60		}
61	}
62}
63
64proc rep027_sub { method niter tnum logset recargs largs } {
65	source ./include.tcl
66	global repfiles_in_memory
67	global verbose_check_secondaries
68	global rep_verbose
69	global verbose_type
70
71	set verbargs ""
72	if { $rep_verbose == 1 } {
73		set verbargs " -verbose {$verbose_type on} "
74	}
75
76	set repmemargs ""
77	if { $repfiles_in_memory } {
78		set repmemargs "-rep_inmem_files "
79	}
80
81	set omethod [convert_method $method]
82	env_cleanup $testdir
83
84	replsetup $testdir/MSGQUEUEDIR
85
86	set masterdir $testdir/MASTERDIR
87	set clientdir $testdir/CLIENTDIR
88
89	file mkdir $masterdir
90	file mkdir $clientdir
91
92	set m_logtype [lindex $logset 0]
93	set c_logtype [lindex $logset 1]
94
95	# In-memory logs require a large log buffer, and cannot
96	# be used with -txn nosync.
97	set m_logargs [adjust_logargs $m_logtype]
98	set c_logargs [adjust_logargs $c_logtype]
99	set m_txnargs [adjust_txnargs $m_logtype]
100	set c_txnargs [adjust_txnargs $c_logtype]
101
102	# Open a master.
103	repladd 1
104	set env_cmd(M) "berkdb_env_noerr -create $verbargs $repmemargs \
105	    -log_max 1000000 -home $masterdir -errpfx MASTER \
106	    $m_txnargs $m_logargs -rep_master -rep_transport \
107	    \[list 1 replsend\]"
108	set masterenv [eval $env_cmd(M) $recargs]
109
110	# Open a client
111	repladd 2
112	set env_cmd(C) "berkdb_env_noerr -create $verbargs $repmemargs \
113	    $c_txnargs $c_logargs -home $clientdir -errpfx CLIENT \
114	    -rep_client -rep_transport \[list 2 replsend\]"
115	set clientenv [eval $env_cmd(C) $recargs]
116
117	# Bring the client online by processing the startup messages.
118	set envlist "{$masterenv 1} {$clientenv 2}"
119	process_msgs $envlist
120
121	# Set up database and secondary index on master.
122	puts "\tRep$tnum.a: Set up database with secondary index."
123	set pname "primary$tnum.db"
124	set sname "secondary$tnum.db"
125
126	# Open the primary.
127	set pdb [eval {berkdb_open_noerr -create \
128	    -auto_commit -env} $masterenv $omethod $largs $pname]
129	error_check_good primary_open [is_valid_db $pdb] TRUE
130	process_msgs $envlist
131
132	# Open and associate a secondary.
133	set sdb [eval {berkdb_open_noerr -create \
134	    -auto_commit -env} $masterenv -btree $sname]
135	error_check_good second_open [is_valid_db $sdb] TRUE
136	error_check_good db_associate [$pdb associate [callback_n 0] $sdb] 0
137
138	# Propagate to client.
139	process_msgs $envlist
140
141	# Put some data in the master.
142	set did [open $dict]
143	for { set n 0 } { [gets $did str] != -1 && $n < $niter } { incr n } {
144		if { [is_record_based $method] == 1 } {
145			set key [expr $n + 1]
146			set datum $str
147		} else {
148			set key $str
149			gets $did datum
150		}
151		set keys($n) $key
152		set data($n) [pad_data $method $datum]
153
154		set ret [$pdb put $key [chop_data $method $datum]]
155		error_check_good put($n) $ret 0
156	}
157	close $did
158	process_msgs $envlist
159
160	# Check secondaries on master.
161	set verbose_check_secondaries 1
162	puts "\tRep$tnum.b: Check secondaries on master."
163	check_secondaries $pdb $sdb $niter keys data "Rep$tnum.b"
164	error_check_good pdb_close [$pdb close] 0
165	error_check_good sdb_close [$sdb close] 0
166	process_msgs $envlist
167
168	# Get handles on primary and secondary db on client.
169	set clientpdb [eval {berkdb_open -auto_commit -env} $clientenv $pname]
170	error_check_good client_pri [is_valid_db $clientpdb] TRUE
171	set clientsdb [eval {berkdb_open -auto_commit -env} $clientenv $sname]
172	error_check_good client_sec [is_valid_db $clientsdb] TRUE
173	error_check_good client_associate \
174	    [$clientpdb associate [callback_n 0] $clientsdb] 0
175
176	# Check secondaries on client.
177	puts "\tRep$tnum.c: Check secondaries on client."
178	check_secondaries $clientpdb $clientsdb $niter keys data "Rep$tnum.c"
179
180	# Clean up.
181	error_check_good clientpdb_close [$clientpdb close] 0
182	error_check_good clientsdb_close [$clientsdb close] 0
183	error_check_good masterenv_close [$masterenv close] 0
184	error_check_good clientenv_close [$clientenv close] 0
185
186	error_check_good verify \
187	    [verify_dir $clientdir "\tRep$tnum.e: " 0 0 1] 0
188	replclose $testdir/MSGQUEUEDIR
189}
190