summaryrefslogtreecommitdiff
path: root/db-4.8.30/test/rep085.tcl
blob: 82dfce3e7ef610d1ab3ee742d2f6487734b30320 (plain)
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
# See the file LICENSE for redistribution information.
#
# Copyright (c) 2009 Oracle.  All rights reserved.
#
# TEST	rep085
# TEST  Skipping unnecessary abbreviated internal init.
# TEST
# TEST  Make sure that once we've materialized NIMDBs, we don't bother
# TEST  trying to do it again on subsequent sync without recovery.  Make
# TEST  sure we do probe for the need to materialize NIMDBs, but don't do
# TEST  any internal init at all if there are no NIMDBs.  Note that in order to
# TEST  do this test we don't even need any NIMDBs.

proc rep085 { method {niter 20} {tnum 085} args } {
	source ./include.tcl

	if { $is_windows9x_test == 1 } {
		puts "Skipping replication test on Win 9x platform."
		return
	}

	# Run for btree and queue only.  Since this is a NIMDB test, 
	# skip queueext. 
	if { $checking_valid_methods } {
		set test_methods {}
		foreach method $valid_methods {
			if { [is_btree $method] == 1 || [is_queue $method] == 1 } {
				if { [is_queueext $method] == 0 } {
					lappend test_methods $method
				}
			}
		}
		return $test_methods
	}
	if { [is_btree $method] != 1 && [is_queue $method] != 1 } {
		puts "Skipping internal init test rep$tnum for method $method."
		return
	}
	if { [is_queueext $method] == 1 } {
		puts "Skipping in-memory database test rep$tnum for method $method."
		return
	}

	set args [convert_args $method $args]

	rep085_sub $method $niter $tnum $args
}

proc rep085_sub { method niter tnum largs } {
	global testdir
	global rep_verbose
	global verbose_type
	global rep085_page_msg_count rep085_update_req_count
	
	puts "Rep$tnum ($method): skipping unnecessary abbreviated internal init."

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

	env_cleanup $testdir
	replsetup $testdir/MSGQUEUEDIR

	file mkdir [set dirs(A) $testdir/SITE_A]
	file mkdir [set dirs(B) $testdir/SITE_B]
	file mkdir [set dirs(C) $testdir/SITE_C]

	set rep085_page_msg_count 0
	set rep085_update_req_count 0

	puts "\tRep$tnum.a: Create master"
	repladd 1
	set env_A_cmd "berkdb_env_noerr -create -txn \
	    $verbargs \
	    -errpfx SITE_A -errfile /dev/stderr \
	    -home $dirs(A) -rep_transport \[list 1 rep085_send\]"
	set envs(A) [eval $env_A_cmd -rep_master]

	puts "\tRep$tnum.b: create (only) a regular DB"
	set start 0
	eval rep_test $method $envs(A) NULL $niter $start $start 0 $largs

	puts "\tRep$tnum.c: Create two clients"
	repladd 2
	set env_B_cmd "berkdb_env_noerr -create -txn \
	    $verbargs \
	    -errpfx SITE_B -errfile /dev/stderr \
	    -home $dirs(B) -rep_transport \[list 2 rep085_send\]"
	set envs(B) [eval $env_B_cmd -rep_client]

	repladd 3
	set env_C_cmd "berkdb_env_noerr -create -txn \
	    $verbargs \
	    -errpfx SITE_C -errfile /dev/stderr \
	    -home $dirs(C) -rep_transport \[list 3 rep085_send\]"
	set envs(C) [eval $env_C_cmd -rep_client]

	set envlist "{$envs(A) 1} {$envs(B) 2} {$envs(C) 3}"
	process_msgs $envlist

	# Note that the initial internal init that we've just done should have
	# the effect of setting this flag.  The flag indicates that any NIMDBs
	# have been loaded, and any full internal init of course accomplishes
	# that.  If there are no NIMDBs whatsoever (which is the case here),
	# then the condition "any NIMDBs are loaded" is trivially satisfied.
	# 
	assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 1

	# Restart client C with recovery, which forces it to check for NIMDBs
	# even though a full internal init is not necessary.
	# 
	puts "\tRep$tnum.d: Bounce client C"
	$envs(C) close
	set envs(C) [eval $env_C_cmd -rep_client -recover]
	assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 0
	set upd_before $rep085_update_req_count
	set pg_before $rep085_page_msg_count
	set envlist "{$envs(A) 1} {$envs(B) 2} {$envs(C) 3}"
	process_msgs $envlist
	error_check_good update.msg.sent \
	    $rep085_update_req_count [incr upd_before]
	error_check_good no.page.msg $rep085_page_msg_count $pg_before
	assert_rep_flag $dirs(C) REP_F_NIMDBS_LOADED 1

	# Switch masters, forcing client C to re-sync.  But this time it already
	# knows it has NIMDBs, so even an UPDATE_REQ shouldn't be necessary.
	# 
	puts "\tRep$tnum.e: Switch master to site B"
	$envs(A) rep_start -client
	$envs(B) rep_start -master
	set upd_before $rep085_update_req_count
	set pg_before $rep085_page_msg_count
	process_msgs $envlist
	error_check_good no.update.msg $rep085_update_req_count $upd_before
	error_check_good no.page.msg.2 $rep085_page_msg_count $pg_before

	$envs(A) close
	$envs(B) close
	$envs(C) close
	replclose $testdir/MSGQUEUEDIR
}

proc rep085_send { control rec fromid toid flags lsn } {
	global rep085_page_msg_count rep085_update_req_count

	if {[berkdb msgtype $control] eq "page"} {
		incr rep085_page_msg_count
	} elseif {[berkdb msgtype $control] eq "update_req"} {
		incr rep085_update_req_count
	}

	return [replsend $control $rec $fromid $toid $flags $lsn]
}