blob: 9d83d56e556f83e9094e2f2d3ef268f09d39ce06 [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#
drhc4a3c772001-04-04 11:48:57 +000026# $Id: tester.tcl,v 1.13 2001/04/04 11:48:58 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: {
drh3494ffe2001-03-20 12:55:13 +000039 foreach f [glob -nocomplain testdb/*] {
40 catch {file delete -force $f}
41 }
drh17a68932001-01-31 13:28:08 +000042 if {[catch {file delete -force testdb}]} {
43 exec rm -rf testdb
44 }
drh767c2002000-10-19 14:10:08 +000045 file mkdir testdb
46 }
47 memory: {
48 # do nothing
49 }
50}
51sqlite db ${dbprefix}testdb
drhbec2bf42000-05-29 23:48:22 +000052
53# Abort early if this script has been run before.
54#
55if {[info exists nTest]} return
56
57# Set the test counters to zero
58#
drh348784e2000-05-29 20:41:49 +000059set nErr 0
60set nTest 0
drhdb25e382001-03-15 18:21:22 +000061set nProb 0
drh767c2002000-10-19 14:10:08 +000062set skip_test 0
drh348784e2000-05-29 20:41:49 +000063
64# Invoke the do_test procedure to run a single test
65#
66proc do_test {name cmd expected} {
drh767c2002000-10-19 14:10:08 +000067 global argv nErr nTest skip_test
68 if {$skip_test} {
69 set skip_test 0
70 return
71 }
72 if {[llength $argv]==0} {
drh348784e2000-05-29 20:41:49 +000073 set go 1
74 } else {
75 set go 0
76 foreach pattern $argv {
77 if {[string match $pattern $name]} {
78 set go 1
79 break
80 }
81 }
82 }
83 if {!$go} return
84 incr nTest
drh767c2002000-10-19 14:10:08 +000085 puts -nonewline $::dbprefix$name...
drh348784e2000-05-29 20:41:49 +000086 flush stdout
87 if {[catch {uplevel #0 "$cmd;\n"} result]} {
88 puts "\nError: $result"
89 incr nErr
90 } elseif {[string compare $result $expected]} {
91 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
92 incr nErr
93 } else {
94 puts " Ok"
95 }
96}
97
drhdb25e382001-03-15 18:21:22 +000098# Invoke this procedure on a test that is probabilistic
99# and might fail sometimes.
100#
101proc do_probtest {name cmd expected} {
102 global argv nProb nTest skip_test
103 if {$skip_test} {
104 set skip_test 0
105 return
106 }
107 if {[llength $argv]==0} {
108 set go 1
109 } else {
110 set go 0
111 foreach pattern $argv {
112 if {[string match $pattern $name]} {
113 set go 1
114 break
115 }
116 }
117 }
118 if {!$go} return
119 incr nTest
120 puts -nonewline $::dbprefix$name...
121 flush stdout
122 if {[catch {uplevel #0 "$cmd;\n"} result]} {
123 puts "\nError: $result"
124 incr nErr
125 } elseif {[string compare $result $expected]} {
126 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
127 puts "NOTE: The results of the previous test depend on system load"
128 puts "and processor speed. The test may sometimes fail even if the"
129 puts "library is working correctly."
130 incr nProb
131 } else {
132 puts " Ok"
133 }
134}
135
drh767c2002000-10-19 14:10:08 +0000136# Skip a test based on the dbprefix
137#
138proc skipif {args} {
139 foreach a $args {
140 if {$::dbprefix==$a} {
141 set ::skip_test 1
142 return
143 }
144 }
145}
146
147# Run the next test only if the dbprefix is among the listed arguments
148#
149proc testif {args} {
150 foreach a $args {
151 if {$::dbprefix==$a} {
152 set ::skip_test 0
153 return
154 }
155 }
156 set ::skip_test 1
157}
158
drh8c82b352000-12-10 18:23:50 +0000159# The procedure uses the special "--malloc-stats--" macro of SQLite
160# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
161# to see how many malloc()s have not been free()ed. The number
162# of surplus malloc()s is stored in the global variable $::Leak.
163# If the value in $::Leak grows, it may mean there is a memory leak
164# in the library.
165#
166proc memleak_check {} {
167 set r [execsql {--malloc-stats--}]
168 if {$r==""} return
169 set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
170 # puts "*** $::Leak mallocs have not been freed ***"
171}
172
drh348784e2000-05-29 20:41:49 +0000173# Run this routine last
174#
175proc finish_test {} {
drhdb25e382001-03-15 18:21:22 +0000176 global nTest nErr nProb
drh8c82b352000-12-10 18:23:50 +0000177 memleak_check
drh6e142f52000-06-08 13:36:40 +0000178 catch {db close}
drh348784e2000-05-29 20:41:49 +0000179 puts "$nErr errors out of $nTest tests"
drhdb25e382001-03-15 18:21:22 +0000180 if {$nProb>0} {
181 puts "$nProb probabilistic tests also failed, but this does"
182 puts "not necessarily indicate a malfunction."
183 }
184 exit [expr {$nErr>0}]
drh348784e2000-05-29 20:41:49 +0000185}
186
drh348784e2000-05-29 20:41:49 +0000187# A procedure to execute SQL
188#
drhc4a3c772001-04-04 11:48:57 +0000189proc execsql {sql {db db}} {
drhacbcdc42001-01-22 00:31:53 +0000190 # puts "SQL = $sql"
drhc4a3c772001-04-04 11:48:57 +0000191 return [$db eval $sql]
drh348784e2000-05-29 20:41:49 +0000192}
drh3aadb2e2000-05-31 17:59:25 +0000193
194# Another procedure to execute SQL. This one includes the field
195# names in the returned list.
196#
197proc execsql2 {sql} {
198 set result {}
199 db eval $sql data {
200 foreach f $data(*) {
201 lappend result $f $data($f)
202 }
203 }
204 return $result
205}
drh17a68932001-01-31 13:28:08 +0000206
207# Delete a file or directory
208#
209proc forcedelete {filename} {
210 if {[catch {file delete -force $filename}]} {
211 exec rm -rf $filename
212 }
213}