1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 1996,2008 Oracle.  All rights reserved.
4#
5# $Id: rsrc003.tcl,v 12.7 2008/01/08 20:58:53 bostic Exp $
6#
7# TEST	rsrc003
8# TEST	Recno backing file test.  Try different patterns of adding
9# TEST	records and making sure that the corresponding file matches.
10proc rsrc003 { } {
11	source ./include.tcl
12	global fixed_len
13
14	puts "Rsrc003: Basic recno backing file writeback tests fixed length"
15
16	# We run this test essentially twice, once with a db file
17	# and once without (an in-memory database).
18	#
19	# Then run with big fixed-length records
20	set rec1 "This is record 1"
21	set rec2 "This is record 2"
22	set rec3 "This is record 3"
23	set bigrec1 [replicate "This is record 1 " 512]
24	set bigrec2 [replicate "This is record 2 " 512]
25	set bigrec3 [replicate "This is record 3 " 512]
26
27	set orig_fixed_len $fixed_len
28	set rlist {
29	{{$rec1 $rec2 $rec3} "small records" }
30	{{$bigrec1 $bigrec2 $bigrec3} "large records" }}
31
32	foreach testfile { "$testdir/rsrc003.db" "" } {
33
34		foreach rec $rlist {
35			cleanup $testdir NULL
36
37			set recs [lindex $rec 0]
38			set msg [lindex $rec 1]
39
40			# Create the starting files
41			# Note that for the rest of the test, we are going
42			# to append a LF when we 'put' via DB to maintain
43			# file structure and allow us to use 'gets'.
44			set oid1 [open $testdir/rsrc.txt w]
45			set oid2 [open $testdir/check.txt w]
46			fconfigure $oid1 -translation binary
47			fconfigure $oid2 -translation binary
48			foreach record $recs {
49				set r [subst $record]
50				set fixed_len [string length $r]
51				puts $oid1 $r
52				puts $oid2 $r
53			}
54			close $oid1
55			close $oid2
56
57			set reclen [expr $fixed_len + 1]
58			if { $reclen > [string length $rec1] } {
59				set repl 512
60			} else {
61				set repl 2
62			}
63			if { $testfile == "" } {
64				puts \
65"Rsrc003: Testing with in-memory database with $msg."
66			} else {
67				puts \
68"Rsrc003: Testing with disk-backed database with $msg."
69			}
70
71			puts -nonewline \
72			    "\tRsrc003.a: Read file, rewrite last record;"
73			puts " write it out and diff"
74			set db [eval {berkdb_open -create -mode 0644 -recno \
75			    -len $reclen -source $testdir/rsrc.txt} $testfile]
76			error_check_good dbopen [is_valid_db $db] TRUE
77
78			# Read the last record; replace it (don't change it).
79			# Then close the file and diff the two files.
80			set txn ""
81			set dbc [eval {$db cursor} $txn]
82			error_check_good db_cursor \
83			    [is_valid_cursor $dbc $db] TRUE
84
85			set rec [$dbc get -last]
86			error_check_good get_last [llength [lindex $rec 0]] 2
87			set key [lindex [lindex $rec 0] 0]
88			set data [lindex [lindex $rec 0] 1]
89
90			# Get the last record from the text file
91			set oid [open $testdir/rsrc.txt]
92			set laststr ""
93			while { [gets $oid str] != -1 } {
94				append str \12
95				set laststr $str
96			}
97			close $oid
98			set data [sanitize_record $data]
99			error_check_good getlast $data $laststr
100
101			set ret [eval {$db put} $txn {$key $data}]
102			error_check_good replace_last $ret 0
103
104			error_check_good curs_close [$dbc close] 0
105			error_check_good db_sync [$db sync] 0
106			error_check_good db_sync [$db sync] 0
107			error_check_good \
108			    diff1($testdir/rsrc.txt,$testdir/check.txt) \
109			    [filecmp $testdir/rsrc.txt $testdir/check.txt] 0
110
111			puts -nonewline "\tRsrc003.b: "
112			puts "Append some records in tree and verify in file."
113			set oid [open $testdir/check.txt a]
114			for {set i 1} {$i < 10} {incr i} {
115				set rec [chop_data -frecno [replicate \
116				    "This is New Record $i" $repl]]
117				puts $oid $rec
118				append rec \12
119				incr key
120				set ret [eval {$db put} $txn {-append $rec}]
121				error_check_good put_append $ret $key
122			}
123			error_check_good db_sync [$db sync] 0
124			error_check_good db_sync [$db sync] 0
125			close $oid
126			set ret [filecmp $testdir/rsrc.txt $testdir/check.txt]
127			error_check_good \
128			    diff2($testdir/{rsrc.txt,check.txt}) $ret 0
129
130			puts "\tRsrc003.c: Append by record number"
131			set oid [open $testdir/check.txt a]
132			for {set i 1} {$i < 10} {incr i} {
133				set rec [chop_data -frecno [replicate \
134				    "New Record (set 2) $i" $repl]]
135				puts $oid $rec
136				append rec \12
137				incr key
138				set ret [eval {$db put} $txn {$key $rec}]
139				error_check_good put_byno $ret 0
140			}
141
142			error_check_good db_sync [$db sync] 0
143			error_check_good db_sync [$db sync] 0
144			close $oid
145			set ret [filecmp $testdir/rsrc.txt $testdir/check.txt]
146			error_check_good \
147			    diff3($testdir/{rsrc.txt,check.txt}) $ret 0
148
149			puts \
150"\tRsrc003.d: Verify proper syncing of changes on close."
151			error_check_good Rsrc003:db_close [$db close] 0
152			set db [eval {berkdb_open -create -mode 0644 -recno \
153			    -len $reclen -source $testdir/rsrc.txt} $testfile]
154			set oid [open $testdir/check.txt a]
155			for {set i 1} {$i < 10} {incr i} {
156				set rec [chop_data -frecno [replicate \
157				    "New Record (set 3) $i" $repl]]
158				puts $oid $rec
159				append rec \12
160				set ret [eval {$db put} $txn {-append $rec}]
161				# Don't bother checking return;
162				# we don't know what
163				# the key number is, and we'll pick up a failure
164				# when we compare.
165			}
166			error_check_good Rsrc003:db_close [$db close] 0
167			close $oid
168			set ret [filecmp $testdir/rsrc.txt $testdir/check.txt]
169			error_check_good \
170			    diff5($testdir/{rsrc,check}.txt) $ret 0
171		}
172	}
173	set fixed_len $orig_fixed_len
174	return
175}
176