1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1996,2008 Oracle.  All rights reserved.
4#
5# $Id: memp003.tcl,v 12.6 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	memp003
8# TEST	Test reader-only/writer process combinations; we use the access methods
9# TEST	for testing.
10proc memp003 { } {
11	global rand_init
12	error_check_good set_random_seed [berkdb srand $rand_init] 0
13	#
14	# Multiple processes not supported by private memory so don't
15	# run memp003_body with -private.
16	#
17	memp003_body ""
18	memp003_body "-system_mem -shm_key 1"
19}
20
21proc memp003_body { flags } {
22	global alphabet
23	source ./include.tcl
24
25	puts "Memp003: {$flags} Reader/Writer tests"
26
27	if { [mem_chk $flags] == 1 } {
28		return
29	}
30
31	env_cleanup $testdir
32	set psize 1024
33	set nentries 500
34	set testfile mpool.db
35	set t1 $testdir/t1
36
37	# Create an environment that the two processes can share, with
38	# 20 pages per cache.
39	set c [list 0 [expr $psize * 20 * 3] 3]
40	set dbenv [eval {berkdb_env \
41	    -create -lock -home $testdir -cachesize $c} $flags]
42	error_check_good dbenv [is_valid_env $dbenv] TRUE
43
44	# First open and create the file.
45	set db [berkdb_open -env $dbenv -create \
46	    -mode 0644 -pagesize $psize -btree $testfile]
47	error_check_good dbopen/RW [is_valid_db $db] TRUE
48
49	set did [open $dict]
50	set txn ""
51	set count 0
52
53	puts "\tMemp003.a: create database"
54	set keys ""
55	# Here is the loop where we put and get each key/data pair
56	while { [gets $did str] != -1 && $count < $nentries } {
57		lappend keys $str
58
59		set ret [eval {$db put} $txn {$str $str}]
60		error_check_good put $ret 0
61
62		set ret [eval {$db get} $txn {$str}]
63		error_check_good get $ret [list [list $str $str]]
64
65		incr count
66	}
67	close $did
68	error_check_good close [$db close] 0
69
70	# Now open the file for read-only
71	set db [berkdb_open -env $dbenv -rdonly $testfile]
72	error_check_good dbopen/RO [is_substr $db db] 1
73
74	puts "\tMemp003.b: verify a few keys"
75	# Read and verify a couple of keys; saving them to check later
76	set testset ""
77	for { set i 0 } { $i < 10 } { incr i } {
78		set ndx [berkdb random_int 0 [expr $nentries - 1]]
79		set key [lindex $keys $ndx]
80		if { [lsearch $testset $key] != -1 } {
81			incr i -1
82			continue;
83		}
84
85		# The remote process stuff is unhappy with
86		# zero-length keys;  make sure we don't pick one.
87		if { [llength $key] == 0 } {
88			incr i -1
89			continue
90		}
91
92		lappend testset $key
93
94		set ret [eval {$db get} $txn {$key}]
95		error_check_good get/RO $ret [list [list $key $key]]
96	}
97
98	puts "\tMemp003.c: retrieve and modify keys in remote process"
99	# Now open remote process where we will open the file RW
100	set f1 [open |$tclsh_path r+]
101	puts $f1 "source $test_path/test.tcl"
102	puts $f1 "flush stdout"
103	flush $f1
104
105	set c [concat "{" [list 0 [expr $psize * 20 * 3] 3] "}" ]
106	set remote_env [send_cmd $f1 \
107	    "berkdb_env -create -lock -home $testdir -cachesize $c $flags"]
108	error_check_good remote_dbenv [is_valid_env $remote_env] TRUE
109
110	set remote_db [send_cmd $f1 "berkdb_open -env $remote_env $testfile"]
111	error_check_good remote_dbopen [is_valid_db $remote_db] TRUE
112
113	foreach k $testset {
114		# Get the key
115		set ret [send_cmd $f1 "$remote_db get $k"]
116		error_check_good remote_get $ret [list [list $k $k]]
117
118		# Now replace the key
119		set ret [send_cmd $f1 "$remote_db put $k $k$k"]
120		error_check_good remote_put $ret 0
121	}
122
123	puts "\tMemp003.d: verify changes in local process"
124	foreach k $testset {
125		set ret [eval {$db get} $txn {$key}]
126		error_check_good get_verify/RO $ret [list [list $key $key$key]]
127	}
128
129	puts "\tMemp003.e: Fill up the cache with dirty buffers"
130	foreach k $testset {
131		# Now rewrite the keys with BIG data
132		set data [replicate $alphabet 32]
133		set ret [send_cmd $f1 "$remote_db put $k $data"]
134		error_check_good remote_put $ret 0
135	}
136
137	puts "\tMemp003.f: Get more pages for the read-only file"
138	dump_file $db $txn $t1 nop
139
140	puts "\tMemp003.g: Sync from the read-only file"
141	error_check_good db_sync [$db sync] 0
142	error_check_good db_close [$db close] 0
143
144	set ret [send_cmd $f1 "$remote_db close"]
145	error_check_good remote_get $ret 0
146
147	# Close the environment both remotely and locally.
148	set ret [send_cmd $f1 "$remote_env close"]
149	error_check_good remote:env_close $ret 0
150	close $f1
151
152	reset_env $dbenv
153}
154