1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1999,2008 Oracle.  All rights reserved.
4#
5# $Id: sdb013.tcl,v 12.13 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	sdb013
8# TEST	Tests in-memory subdatabases.
9# TEST	Create an in-memory subdb.  Test for persistence after
10# TEST	overflowing the cache.  Test for conflicts when we have
11# TEST	two in-memory files.
12
13proc sdb013 { method { nentries 10 } args } {
14	source ./include.tcl
15
16	set tnum "013"
17	set args [convert_args $method $args]
18	set omethod [convert_method $method]
19
20	if { [is_queueext $method] == 1 } {
21		puts "Subdb$tnum: skipping for method $method"
22		return
23	}
24
25	puts "Subdb$tnum: $method ($args) in-memory subdb tests"
26
27	# If we are using an env, then skip this test.  It needs its own.
28	set eindex [lsearch -exact $args "-env"]
29	if { $eindex != -1 } {
30		set env NULL
31		incr eindex
32		set env [lindex $args $eindex]
33		puts "Subdb$tnum skipping for env $env"
34		return
35	}
36
37	# In-memory dbs never go to disk, so we can't do checksumming.
38	# If the test module sent in the -chksum arg, get rid of it.
39	set chkindex [lsearch -exact $args "-chksum"]
40	if { $chkindex != -1 } {
41		set args [lreplace $args $chkindex $chkindex]
42	}
43
44	# Create the env, with a very small cache that we can easily
45	# fill.  If a particularly large page size is specified, make
46	# the cache a little larger, but still on the small side.
47	env_cleanup $testdir
48	set csize {0 65536 1}
49	set pgindex [lsearch -exact $args "-pagesize"]
50	if { $pgindex != -1 } {
51		incr pgindex
52		set pagesize [lindex $args $pgindex]
53		if { $pagesize > 8192 } {
54			set cache [expr 4 * $pagesize]
55			set csize "0 $cache 1"
56		}
57	}
58
59	set env [berkdb_env_noerr -create -cachesize $csize -home $testdir -txn]
60	error_check_good dbenv [is_valid_env $env] TRUE
61
62	# Set filename to NULL; this causes the creation of an in-memory
63	# subdb.
64	set testfile ""
65	set subdb subdb0
66
67	puts "\tSubdb$tnum.a: Create in-mem subdb, add data, close."
68	set sdb [eval {berkdb_open_noerr -create -mode 0644} \
69	    $args -env $env -auto_commit {$omethod $testfile $subdb}]
70	error_check_good dbopen [is_valid_db $sdb] TRUE
71
72	set ret [sdb013_populate $sdb $method $nentries]
73	error_check_good populate $ret 0
74	error_check_good sdb_close [$sdb close] 0
75
76	# Do a bunch of writing to evict all pages from the memory pool.
77	puts "\tSubdb$tnum.b: Create another db, overflow the cache."
78	set dummyfile foo.db
79	set db [eval {berkdb_open_noerr -create -mode 0644} $args -env $env\
80	    -auto_commit $omethod $dummyfile]
81	error_check_good dummy_open [is_valid_db $db] TRUE
82
83	set entries [expr $nentries * 100]
84	set ret [sdb013_populate $db $method $entries]
85	error_check_good dummy_close [$db close] 0
86
87	# Make sure we can still open the in-memory subdb.
88	puts "\tSubdb$tnum.c: Check we can still open the in-mem subdb."
89	set sdb [eval {berkdb_open_noerr} \
90	    $args -env $env -auto_commit {$omethod $testfile $subdb}]
91	error_check_good sdb_reopen [is_valid_db $sdb] TRUE
92	error_check_good sdb_close [$sdb close] 0
93
94	puts "\tSubdb$tnum.d: Remove in-mem subdb."
95	error_check_good \
96	    sdb_remove [berkdb dbremove -env $env $testfile $subdb] 0
97
98	puts "\tSubdb$tnum.e: Check we cannot open the in-mem subdb."
99	set ret [catch {eval {berkdb_open_noerr} -env $env $args \
100	    -auto_commit {$omethod $testfile $subdb}} db]
101	error_check_bad dbopen $ret 0
102
103	foreach end { commit abort } {
104		# Create an in-memory database.
105		puts "\tSubdb$tnum.f: Create in-mem subdb, add data, close."
106		set sdb [eval {berkdb_open_noerr -create -mode 0644} \
107		    $args -env $env -auto_commit {$omethod $testfile $subdb}]
108		error_check_good dbopen [is_valid_db $sdb] TRUE
109
110		set ret [sdb013_populate $sdb $method $nentries]
111		error_check_good populate $ret 0
112		error_check_good sdb_close [$sdb close] 0
113
114		# Transactionally remove the database.
115		puts "\tSubdb$tnum.g: Transactionally remove in-mem database."
116		set txn [$env txn]
117		error_check_good db_remove \
118		    [berkdb dbremove -env $env -txn $txn $testfile $subdb] 0
119
120		# Write a cacheful of data.
121		puts "\tSubdb$tnum.h: Create another db, overflow the cache."
122		set db [eval {berkdb_open_noerr -create -mode 0644} $args \
123		    -env $env -auto_commit $omethod $dummyfile]
124		error_check_good dummy_open [is_valid_db $db] TRUE
125
126		set entries [expr $nentries * 100]
127		set ret [sdb013_populate $db $method $entries]
128		error_check_good dummy_close [$db close] 0
129
130		# Finish the txn and make sure the database is either
131		# gone (if committed) or still there (if aborted).
132		error_check_good txn_$end [$txn $end] 0
133		if { $end == "abort" } {
134			puts "\tSubdb$tnum.i: Check that database still exists."
135			set sdb [eval {berkdb_open_noerr} $args \
136			    -env $env -auto_commit {$omethod $testfile $subdb}]
137			error_check_good sdb_reopen [is_valid_db $sdb] TRUE
138			error_check_good sdb_close [$sdb close] 0
139		} else {
140			puts "\tSubdb$tnum.i: Check that database is gone."
141			set ret [catch {eval {berkdb_open_noerr} -env $env \
142			    $args -auto_commit {$omethod $testfile $subdb}} res]
143			error_check_bad dbopen $ret 0
144		}
145	}
146
147	error_check_good env_close [$env close] 0
148}
149
150proc sdb013_populate { db method nentries } {
151	source ./include.tcl
152
153	set did [open $dict]
154	set count 0
155	while { [gets $did str] != -1 && $count < $nentries } {
156		if { [is_record_based $method] == 1 } {
157			set key [expr $count + 1]
158		} else {
159			set key $str
160		}
161
162		set r [ catch {$db put $key [chop_data $method $str]} ret ]
163		if { $r != 0 } {
164			close $did
165			return $ret
166		}
167
168 		incr count
169	}
170	close $did
171	return 0
172}
173
174