File: rep092.tcl

package info (click to toggle)
db5.3 5.3.28%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 158,500 kB
  • sloc: ansic: 448,411; java: 111,824; tcl: 80,544; sh: 44,264; cs: 33,697; cpp: 21,604; perl: 14,557; xml: 10,799; makefile: 4,077; javascript: 1,998; yacc: 1,003; awk: 965; sql: 801; erlang: 342; python: 216; php: 24; asm: 14
file content (325 lines) | stat: -rw-r--r-- 9,533 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# See the file LICENSE for redistribution information.
#
# Copyright (c) 2010, 2013 Oracle and/or its affiliates.  All rights reserved.
#
# TEST	rep092
# TEST	Read-your-writes consistency.
# TEST	Test events in one thread (process) waking up another sleeping thread,
# TEST	before a timeout expires.
# 

proc rep092 { method { niter 20 } { tnum "092" } args } {
	source ./include.tcl
	global repfiles_in_memory

	# Skip for all methods except btree.
	if { $checking_valid_methods } {
		set test_methods { btree }
		return $test_methods
	}
	if { [is_btree $method] == 0 } {
		puts "Rep005: Skipping for method $method."
		return
	}

	puts "Rep$tnum: read-your-writes consistency, multi-thread wake-up"
	foreach pad_flag { no yes } {
		foreach txn_flag { no yes } {
			rep092a_sub $method $niter \
			    $tnum $pad_flag $txn_flag $args
			rep092b_sub $method $niter \
			    $tnum $pad_flag $txn_flag $args
		}
	}
}

proc rep092a_sub { method niter tnum pad in_txn largs } {
	source ./include.tcl
	global rep_verbose
	global testdir
	global verbose_type
	global repfiles_in_memory

	set verbargs ""
	if { $rep_verbose == 1 } {
		set verbargs " -verbose {$verbose_type on} "
	}

	set repmemargs ""
	if { $repfiles_in_memory } {
		set repmemargs "-rep_inmem_files "
	}

	env_cleanup $testdir

	replsetup $testdir/MSGQUEUEDIR

	set masterdir $testdir/MASTERDIR
	set clientdir $testdir/CLIENTDIR

	file mkdir $masterdir
	file mkdir $clientdir

	puts "\tRep$tnum.a: Create master and client."
	repladd 1
	set ma_envcmd "berkdb_env_noerr -create -txn -errpfx MASTER \
	    $repmemargs \
	    $verbargs -home $masterdir -rep_transport \[list 1 replsend\]"
	set masterenv [eval $ma_envcmd -rep_master]

	repladd 2
	set cl_envcmd "berkdb_env_noerr -create -txn -errpfx CLIENT \
	    $repmemargs -errfile /dev/stderr \
	    $verbargs -home $clientdir -rep_transport \[list 2 replsend\]"
	set clientenv [eval $cl_envcmd -rep_client]

	set envlist "{$masterenv 1} {$clientenv 2}"
	process_msgs $envlist

	puts "\tRep$tnum.b: Create and replicate a few warm-up txns."
	set start 0
	eval rep_test $method $masterenv NULL $niter $start $start 0 $largs
	incr start $niter
	process_msgs $envlist

	puts "\tRep$tnum.c: Write txn and get its commit token."
	if { $pad } {
		eval rep_test $method $masterenv \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}
	set omethod [convert_method $method]
	set dbargs [convert_args $method $largs]
	set db [eval berkdb_open_noerr -env $masterenv -auto_commit \
		-create $omethod $dbargs test.db ]
	set txn [$masterenv txn -token]
	$db put -txn $txn "key1" "data1"
	set token [$txn commit]
	$db close
	if { $pad } {
		eval rep_test $method $masterenv \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}

	# Don't process msgs just yet.  We want to test the behavior when the
	# client checks/waits for the transaction more quickly than the client
	# receives it.  In order to do that in a test, we simulate the
	# replication being rather slow, by pausing for a moment after starting
	# up the txn_applied thread (in a separate child Tcl process).
	# 
	set pause 5

	# Define an emergency upper limit on the sleeping time, so that in case
	# the code is broken the test won't hang forever.  The child process
	# should complete promptly, as soon as we apply the transaction.
	# 
	set limit 60
	set tolerance 1

	# Spawn a process to call txn_applied
	# 
	puts "\tRep$tnum.d: Spawn child process, and pause to let it get started."
	set timeout [expr $limit * 1000000]
	error_check_good binary_scan [binary scan $token H40 token_chars] 1
	set listing $testdir/repscript.log
	set pid [exec $tclsh_path $test_path/wrap.tcl \
	    rep092script.tcl $listing $clientdir \
	    $token_chars $timeout $in_txn $rep_verbose $verbose_type &]
	tclsleep $pause

	puts "\tRep$tnum.e: Apply the transaction at the client."
	process_msgs $envlist

	watch_procs $pid 1
	set fd [open $listing]
	puts "\tRep$tnum.f: Examine the sub-process results."
	set report [split [read $fd] "\n"]
	close $fd
	set result [lindex [lsearch -inline $report RESULT*] 1]
	error_check_good wait_result $result 0
	set duration [lindex [lsearch -inline $report DURATION*] 1]
	error_check_good no_timeout \
	    [expr $duration < $limit - $tolerance] 1

	# Add a third client.
	# 
	set clientdir2 $testdir/CLIENTDIR2
	file mkdir $clientdir2
	
	puts "\tRep$tnum.g: Add another client, and make it master."
	repladd 3
	set cl_envcmd2 "berkdb_env_noerr -create -txn -errpfx CLIENT2 \
	    $repmemargs \
	    $verbargs -home $clientdir2 -rep_transport \[list 3 replsend\]"
	set clientenv2 [eval $cl_envcmd2 -rep_client]

	lappend envlist "$clientenv2 3"
	process_msgs $envlist

	# Swap roles between master and client2.  First client will eventually
	# see a gen change, while waiting.
	# 
	$masterenv rep_start -client
	$clientenv2 rep_start -master
	if { $pad } {
		eval rep_test $method $clientenv2 \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}
	set db [eval berkdb_open_noerr -env $clientenv2 -auto_commit \
		-create $omethod $dbargs test.db ]
	set txn [$clientenv2 txn -token]
	$db put -txn $txn "key2" "data2"
	set token [$txn commit]
	$db close
	if { $pad } {
		eval rep_test $method $clientenv2 \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}

	puts "\tRep$tnum.h: Spawn another child process."
	error_check_good binary_scan [binary scan $token H40 token_chars] 1
	set pid [exec $tclsh_path $test_path/wrap.tcl \
	    rep092script.tcl $listing $clientdir \
	    $token_chars $timeout $in_txn $rep_verbose $verbose_type &]
	tclsleep 5

	puts "\tRep$tnum.i: Apply the transaction at the client."
	process_msgs $envlist

	watch_procs $pid 1
	set fd [open $listing]
	puts "\tRep$tnum.j: Examine the sub-process results."
	set report [split [read $fd] "\n"]
	close $fd
	set result [lindex [lsearch -inline $report RESULT*] 1]
	error_check_good wait_result $result 0
	set duration [lindex [lsearch -inline $report DURATION*] 1]
	error_check_good no_timeout2 \
	    [expr $duration < $limit - $tolerance] 1

	$clientenv close
	$masterenv close
	$clientenv2 close

	replclose $testdir/MSGQUEUEDIR
}

proc rep092b_sub { method niter tnum pad in_txn largs } {
	source ./include.tcl
	global rep_verbose
	global testdir
	global verbose_type

	set verbargs ""
	if { $rep_verbose == 1 } {
		set verbargs " -verbose {$verbose_type on} "
	}

	# This part of the test only makes sense with INMEM
	# 
	set repmemargs "-rep_inmem_files "

	env_cleanup $testdir

	replsetup $testdir/MSGQUEUEDIR

	set masterdir $testdir/MASTERDIR
	set clientdir $testdir/CLIENTDIR

	file mkdir $masterdir
	file mkdir $clientdir

	puts "\tRep$tnum.a: Create master and client."
	repladd 1
	set ma_envcmd "berkdb_env_noerr -create -txn -errpfx MASTER \
	    $repmemargs \
	    $verbargs -home $masterdir -rep_transport \[list 1 replsend\]"
	set masterenv [eval $ma_envcmd -rep_master]

	repladd 2
	set cl_envcmd "berkdb_env_noerr -create -txn -errpfx CLIENT \
	    $repmemargs -errfile /dev/stderr \
	    $verbargs -home $clientdir -rep_transport \[list 2 replsend\]"
	set clientenv [eval $cl_envcmd -rep_client]

	set envlist "{$masterenv 1} {$clientenv 2}"
	process_msgs $envlist

	puts "\tRep$tnum.b: Create and replicate a few warm-up txns."
	set start 0
	eval rep_test $method $masterenv NULL $niter $start $start 0 $largs
	incr start $niter
	process_msgs $envlist

	puts "\tRep$tnum.x: Shut down client."
	$clientenv close

	puts "\tRep$tnum.c: Write txn and get its commit token."
	if { $pad } {
		eval rep_test $method $masterenv \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}
	set omethod [convert_method $method]
	set dbargs [convert_args $method $largs]
	set db [eval berkdb_open_noerr -env $masterenv -auto_commit \
		-create $omethod $dbargs test.db ]
	set txn [$masterenv txn -token]
	$db put -txn $txn "key1" "data1"
	set token [$txn commit]
	$db close
	if { $pad } {
		eval rep_test $method $masterenv \
		    NULL $niter $start $start 0 $largs
		incr start $niter
	}

	puts "\tRep$tnum.x: Restart client, get partway through sync."
	set clientenv [eval $cl_envcmd -rep_client -recover]
	set envlist "{$masterenv 1} {$clientenv 2}"
	
	# This will put the client into a state where it doesn't have the LSN
	# history database, at a time when it needs to read it.  Therefore, it
	# will wait for it to be materialized in the "abbreviated internal init"
	# cycle that is needed when in-memory databases are involved.
	#
	proc_msgs_once $envlist
	proc_msgs_once $envlist

	set pause 5
	set limit 60
	set tolerance 1

	# Spawn a process to call txn_applied
	# 
	puts "\tRep$tnum.d: Spawn child process, and pause to let it get started."
	set timeout [expr $limit * 1000000]
	error_check_good binary_scan [binary scan $token H40 token_chars] 1
	set listing $testdir/repscript.log
	set pid [exec $tclsh_path $test_path/wrap.tcl \
	    rep092script.tcl $listing $clientdir \
	    $token_chars $timeout $in_txn $rep_verbose $verbose_type &]
	tclsleep $pause

	puts "\tRep$tnum.e: Apply the transaction at the client."
	process_msgs $envlist

	watch_procs $pid 1
	set fd [open $listing]
	puts "\tRep$tnum.f: Examine the sub-process results."
	set report [split [read $fd] "\n"]
	close $fd
	set result [lindex [lsearch -inline $report RESULT*] 1]
	error_check_good wait_result $result 0
	set duration [lindex [lsearch -inline $report DURATION*] 1]
	error_check_good no_timeout \
	    [expr $duration < $limit - $tolerance] 1

	$clientenv close
	$masterenv close

	replclose $testdir/MSGQUEUEDIR
}