blob: 6d55d5fa1aeb7b88d7099113a25d2732b33a1523 [file] [log] [blame]
drh348784e2000-05-29 20:41:49 +00001# Copyright (c) 1999, 2000 D. Richard Hipp
2#
3# This program is free software; you can redistribute it and/or
4# modify it under the terms of the GNU General Public
5# License as published by the Free Software Foundation; either
6# version 2 of the License, or (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11# General Public License for more details.
12#
13# You should have received a copy of the GNU General Public
14# License along with this library; if not, write to the
15# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16# Boston, MA 02111-1307, USA.
17#
18# Author contact information:
19# drh@hwaci.com
20# http://www.hwaci.com/drh/
21#
22#***********************************************************************
23# This file implements some common TCL routines used for regression
24# testing the SQLite library
25#
drhdb25e382001-03-15 18:21:22 +000026# $Id: tester.tcl,v 1.11 2001/03/15 18:21:22 drh Exp $
drh348784e2000-05-29 20:41:49 +000027
drhbec2bf42000-05-29 23:48:22 +000028# Create a test database
29#
drh767c2002000-10-19 14:10:08 +000030if {![info exists dbprefix]} {
31 if {[info exists env(SQLITE_PREFIX)]} {
32 set dbprefix $env(SQLITE_PREFIX):
33 } else {
34 set dbprefix "gdbm:"
35 }
36}
37switch $dbprefix {
38 gdbm: {
drh17a68932001-01-31 13:28:08 +000039 if {[catch {file delete -force testdb}]} {
40 exec rm -rf testdb
41 }
drh767c2002000-10-19 14:10:08 +000042 file mkdir testdb
43 }
44 memory: {
45 # do nothing
46 }
47}
48sqlite db ${dbprefix}testdb
drhbec2bf42000-05-29 23:48:22 +000049
50# Abort early if this script has been run before.
51#
52if {[info exists nTest]} return
53
54# Set the test counters to zero
55#
drh348784e2000-05-29 20:41:49 +000056set nErr 0
57set nTest 0
drhdb25e382001-03-15 18:21:22 +000058set nProb 0
drh767c2002000-10-19 14:10:08 +000059set skip_test 0
drh348784e2000-05-29 20:41:49 +000060
61# Invoke the do_test procedure to run a single test
62#
63proc do_test {name cmd expected} {
drh767c2002000-10-19 14:10:08 +000064 global argv nErr nTest skip_test
65 if {$skip_test} {
66 set skip_test 0
67 return
68 }
69 if {[llength $argv]==0} {
drh348784e2000-05-29 20:41:49 +000070 set go 1
71 } else {
72 set go 0
73 foreach pattern $argv {
74 if {[string match $pattern $name]} {
75 set go 1
76 break
77 }
78 }
79 }
80 if {!$go} return
81 incr nTest
drh767c2002000-10-19 14:10:08 +000082 puts -nonewline $::dbprefix$name...
drh348784e2000-05-29 20:41:49 +000083 flush stdout
84 if {[catch {uplevel #0 "$cmd;\n"} result]} {
85 puts "\nError: $result"
86 incr nErr
87 } elseif {[string compare $result $expected]} {
88 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
89 incr nErr
90 } else {
91 puts " Ok"
92 }
93}
94
drhdb25e382001-03-15 18:21:22 +000095# Invoke this procedure on a test that is probabilistic
96# and might fail sometimes.
97#
98proc do_probtest {name cmd expected} {
99 global argv nProb nTest skip_test
100 if {$skip_test} {
101 set skip_test 0
102 return
103 }
104 if {[llength $argv]==0} {
105 set go 1
106 } else {
107 set go 0
108 foreach pattern $argv {
109 if {[string match $pattern $name]} {
110 set go 1
111 break
112 }
113 }
114 }
115 if {!$go} return
116 incr nTest
117 puts -nonewline $::dbprefix$name...
118 flush stdout
119 if {[catch {uplevel #0 "$cmd;\n"} result]} {
120 puts "\nError: $result"
121 incr nErr
122 } elseif {[string compare $result $expected]} {
123 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
124 puts "NOTE: The results of the previous test depend on system load"
125 puts "and processor speed. The test may sometimes fail even if the"
126 puts "library is working correctly."
127 incr nProb
128 } else {
129 puts " Ok"
130 }
131}
132
drh767c2002000-10-19 14:10:08 +0000133# Skip a test based on the dbprefix
134#
135proc skipif {args} {
136 foreach a $args {
137 if {$::dbprefix==$a} {
138 set ::skip_test 1
139 return
140 }
141 }
142}
143
144# Run the next test only if the dbprefix is among the listed arguments
145#
146proc testif {args} {
147 foreach a $args {
148 if {$::dbprefix==$a} {
149 set ::skip_test 0
150 return
151 }
152 }
153 set ::skip_test 1
154}
155
drh8c82b352000-12-10 18:23:50 +0000156# The procedure uses the special "--malloc-stats--" macro of SQLite
157# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
158# to see how many malloc()s have not been free()ed. The number
159# of surplus malloc()s is stored in the global variable $::Leak.
160# If the value in $::Leak grows, it may mean there is a memory leak
161# in the library.
162#
163proc memleak_check {} {
164 set r [execsql {--malloc-stats--}]
165 if {$r==""} return
166 set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
167 # puts "*** $::Leak mallocs have not been freed ***"
168}
169
drh348784e2000-05-29 20:41:49 +0000170# Run this routine last
171#
172proc finish_test {} {
drhdb25e382001-03-15 18:21:22 +0000173 global nTest nErr nProb
drh8c82b352000-12-10 18:23:50 +0000174 memleak_check
drh6e142f52000-06-08 13:36:40 +0000175 catch {db close}
drh348784e2000-05-29 20:41:49 +0000176 puts "$nErr errors out of $nTest tests"
drhdb25e382001-03-15 18:21:22 +0000177 if {$nProb>0} {
178 puts "$nProb probabilistic tests also failed, but this does"
179 puts "not necessarily indicate a malfunction."
180 }
181 exit [expr {$nErr>0}]
drh348784e2000-05-29 20:41:49 +0000182}
183
drh348784e2000-05-29 20:41:49 +0000184# A procedure to execute SQL
185#
186proc execsql {sql} {
drhacbcdc42001-01-22 00:31:53 +0000187 # puts "SQL = $sql"
drh6d313162000-09-21 13:01:35 +0000188 return [db eval $sql]
drh348784e2000-05-29 20:41:49 +0000189}
drh3aadb2e2000-05-31 17:59:25 +0000190
191# Another procedure to execute SQL. This one includes the field
192# names in the returned list.
193#
194proc execsql2 {sql} {
195 set result {}
196 db eval $sql data {
197 foreach f $data(*) {
198 lappend result $f $data($f)
199 }
200 }
201 return $result
202}
drh17a68932001-01-31 13:28:08 +0000203
204# Delete a file or directory
205#
206proc forcedelete {filename} {
207 if {[catch {file delete -force $filename}]} {
208 exec rm -rf $filename
209 }
210}