1# See the file LICENSE for redistribution information.
2#
3# Copyright (c) 2005-2009 Oracle.  All rights reserved.
4#
5# $Id$
6#
7# TEST	log007
8# TEST	Test of in-memory logging bugs. [#11505]
9# TEST
10# TEST	Test db_printlog with in-memory logs.
11#
12proc log007 { } {
13	global testdir
14	global util_path
15	set tnum "007"
16
17	puts "Log$tnum: Test in-memory logs with db_printlog."
18
19	# Log size is small so we quickly create more than one.
20	# Since we are in-memory the buffer is larger than the
21	# file size.
22	set pagesize 4096
23	append args " -pagesize $pagesize "
24	set log_max [expr $pagesize * 2]
25	set log_buf [expr $log_max * 2]
26
27	# We have 13-byte records.  We want to fill slightly more
28	# than one virtual log file on each iteration.  The first
29	# record always has an offset of 28.
30	#
31	set recsize 13
32	set recsperfile [expr [expr $log_max - 28] / $recsize]
33	set nrecs [expr $recsperfile + 1]
34
35	# Open environment.
36	env_cleanup $testdir
37	set flags " -create -txn -home $testdir \
38	    -log_inmemory -log_buffer $log_buf -log_max $log_max"
39	set env [eval {berkdb_env} $flags]
40	error_check_good env_open [is_valid_env $env] TRUE
41
42	set iter 15
43	set lastfile 1
44	for { set i 0 } { $i < $iter } { incr i } {
45		puts "\tLog$tnum.a.$i: Writing $nrecs 13-byte log records."
46		set lsn_list {}
47		for { set j 0 } { $j < $nrecs } { incr j } {
48			set rec "1"
49			# Make the first record one byte larger for each
50			# successive log file so we hit the end of the
51			# log file at each of the 13 possibilities.
52			set nentries [expr [expr $i * $nrecs] + $j]
53			if { [expr $nentries % 628] == 0 } {
54				append firstrec a
55				set ret [$env log_put $firstrec]
56			} else {
57				set ret [$env log_put $rec]
58			}
59			error_check_bad log_put [is_substr $ret log_cmd] 1
60			lappend lsn_list $ret
61		}
62
63		# Open a log cursor.
64		set m_logc [$env log_cursor]
65		error_check_good m_logc [is_valid_logc $m_logc $env] TRUE
66
67		# Check that we're in the expected virtual log file.
68		set first [$m_logc get -first]
69		error_check_good first_lsn [lindex $first 0] "[expr $i + 1] 28"
70		set last [$m_logc get -last]
71
72		puts "\tLog$tnum.b.$i: Read log records sequentially."
73		set j 0
74		for { set logrec [$m_logc get -first] } \
75		    { [llength $logrec] != 0 } \
76		    { set logrec [$m_logc get -next]} {
77			set file [lindex [lindex $logrec 0] 0]
78			if { $file != $lastfile } {
79				# We have entered a new virtual log file.
80				set lastfile $file
81			}
82			set offset [lindex [lindex $logrec 0] 1]
83			set lsn($j) "\[$file\]\[$offset\]"
84			incr j
85		}
86		error_check_good cursor_close [$m_logc close] 0
87
88		puts "\tLog$tnum.c.$i: Compare printlog to log records."
89		set stat [catch {eval exec $util_path/db_printlog \
90		    -h $testdir > $testdir/prlog} result]
91		error_check_good stat_prlog $stat 0
92
93		# Make sure the results of printlog contain all the same
94		# LSNs we saved when walking the files with the log cursor.
95		set j 0
96		set fd [open $testdir/prlog r]
97		while { [gets $fd record] >= 0 } {
98			# A log record begins with "[".
99			if { [string match {\[*} $record] == 1 } {
100				error_check_good \
101				    check_prlog [is_substr $record $lsn($j)] 1
102				incr j
103			}
104		}
105		close $fd
106	}
107
108	error_check_good env_close [$env close] 0
109	error_check_good env_remove [berkdb envremove -home $testdir] 0
110}
111