blob: 6d2bd2f22799682424426ff27a1d99b1d89ac624 [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#
drh5edc3122001-09-13 21:53:09 +000026# $Id: tester.tcl,v 1.16 2001/09/13 21:53:10 drh Exp $
drhfbc3eab2001-04-06 16:13:42 +000027
28# Make sure tclsqlite was compiled correctly. Abort now with an
29# error message if not.
30#
31if {[sqlite -tcl-uses-utf]} {
32 if {"\u1234"=="u1234"} {
33 puts stderr "***** BUILD PROBLEM *****"
34 puts stderr "$argv0 was linked against an older version"
35 puts stderr "of TCL that does not support Unicode, but uses a header"
36 puts stderr "file (\"tcl.h\") from a new TCL version that does support"
37 puts stderr "Unicode. This combination causes internal errors."
38 puts stderr "Recompile using a TCL library and header file that match"
39 puts stderr "and try again.\n**************************"
40 exit 1
41 }
42} else {
43 if {"\u1234"!="u1234"} {
44 puts stderr "***** BUILD PROBLEM *****"
45 puts stderr "$argv0 was linked against an newer version"
46 puts stderr "of TCL that supports Unicode, but uses a header file"
47 puts stderr "(\"tcl.h\") from a old TCL version that does not support"
48 puts stderr "Unicode. This combination causes internal errors."
49 puts stderr "Recompile using a TCL library and header file that match"
50 puts stderr "and try again.\n**************************"
51 exit 1
52 }
53}
drh348784e2000-05-29 20:41:49 +000054
drhbec2bf42000-05-29 23:48:22 +000055# Create a test database
56#
drh5edc3122001-09-13 21:53:09 +000057file delete -force ./test.db
58file delete -force ./test.db-journal
59sqlite db ./test.db
drhbec2bf42000-05-29 23:48:22 +000060
61# Abort early if this script has been run before.
62#
63if {[info exists nTest]} return
64
65# Set the test counters to zero
66#
drh348784e2000-05-29 20:41:49 +000067set nErr 0
68set nTest 0
drhdb25e382001-03-15 18:21:22 +000069set nProb 0
drh767c2002000-10-19 14:10:08 +000070set skip_test 0
drh348784e2000-05-29 20:41:49 +000071
72# Invoke the do_test procedure to run a single test
73#
74proc do_test {name cmd expected} {
drh767c2002000-10-19 14:10:08 +000075 global argv nErr nTest skip_test
76 if {$skip_test} {
77 set skip_test 0
78 return
79 }
80 if {[llength $argv]==0} {
drh348784e2000-05-29 20:41:49 +000081 set go 1
82 } else {
83 set go 0
84 foreach pattern $argv {
85 if {[string match $pattern $name]} {
86 set go 1
87 break
88 }
89 }
90 }
91 if {!$go} return
92 incr nTest
drh5edc3122001-09-13 21:53:09 +000093 puts -nonewline $name...
drh348784e2000-05-29 20:41:49 +000094 flush stdout
95 if {[catch {uplevel #0 "$cmd;\n"} result]} {
96 puts "\nError: $result"
97 incr nErr
drh5edc3122001-09-13 21:53:09 +000098 if {$nErr>10} {puts "*** Giving up..."; exit 1}
drh348784e2000-05-29 20:41:49 +000099 } elseif {[string compare $result $expected]} {
100 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
101 incr nErr
drh5edc3122001-09-13 21:53:09 +0000102 if {$nErr>10} {puts "*** Giving up..."; exit 1}
drh348784e2000-05-29 20:41:49 +0000103 } else {
104 puts " Ok"
105 }
106}
107
drhdb25e382001-03-15 18:21:22 +0000108# Invoke this procedure on a test that is probabilistic
109# and might fail sometimes.
110#
111proc do_probtest {name cmd expected} {
112 global argv nProb nTest skip_test
113 if {$skip_test} {
114 set skip_test 0
115 return
116 }
117 if {[llength $argv]==0} {
118 set go 1
119 } else {
120 set go 0
121 foreach pattern $argv {
122 if {[string match $pattern $name]} {
123 set go 1
124 break
125 }
126 }
127 }
128 if {!$go} return
129 incr nTest
drh5edc3122001-09-13 21:53:09 +0000130 puts -nonewline $name...
drhdb25e382001-03-15 18:21:22 +0000131 flush stdout
132 if {[catch {uplevel #0 "$cmd;\n"} result]} {
133 puts "\nError: $result"
134 incr nErr
135 } elseif {[string compare $result $expected]} {
136 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
137 puts "NOTE: The results of the previous test depend on system load"
138 puts "and processor speed. The test may sometimes fail even if the"
139 puts "library is working correctly."
140 incr nProb
141 } else {
142 puts " Ok"
143 }
144}
145
drhdaffd0e2001-04-11 14:28:42 +0000146# The procedure uses the special "sqlite_malloc_stat" command
drh8c82b352000-12-10 18:23:50 +0000147# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
148# to see how many malloc()s have not been free()ed. The number
149# of surplus malloc()s is stored in the global variable $::Leak.
150# If the value in $::Leak grows, it may mean there is a memory leak
151# in the library.
152#
153proc memleak_check {} {
drhdaffd0e2001-04-11 14:28:42 +0000154 if {[info command sqlite_malloc_stat]!=""} {
155 set r [sqlite_malloc_stat]
156 set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
157 }
drh8c82b352000-12-10 18:23:50 +0000158}
159
drh348784e2000-05-29 20:41:49 +0000160# Run this routine last
161#
162proc finish_test {} {
drhdb25e382001-03-15 18:21:22 +0000163 global nTest nErr nProb
drh8c82b352000-12-10 18:23:50 +0000164 memleak_check
drh6e142f52000-06-08 13:36:40 +0000165 catch {db close}
drh348784e2000-05-29 20:41:49 +0000166 puts "$nErr errors out of $nTest tests"
drhdb25e382001-03-15 18:21:22 +0000167 if {$nProb>0} {
168 puts "$nProb probabilistic tests also failed, but this does"
169 puts "not necessarily indicate a malfunction."
170 }
171 exit [expr {$nErr>0}]
drh348784e2000-05-29 20:41:49 +0000172}
173
drh348784e2000-05-29 20:41:49 +0000174# A procedure to execute SQL
175#
drhc4a3c772001-04-04 11:48:57 +0000176proc execsql {sql {db db}} {
drhacbcdc42001-01-22 00:31:53 +0000177 # puts "SQL = $sql"
drhc4a3c772001-04-04 11:48:57 +0000178 return [$db eval $sql]
drh348784e2000-05-29 20:41:49 +0000179}
drh3aadb2e2000-05-31 17:59:25 +0000180
181# Another procedure to execute SQL. This one includes the field
182# names in the returned list.
183#
184proc execsql2 {sql} {
185 set result {}
186 db eval $sql data {
187 foreach f $data(*) {
188 lappend result $f $data($f)
189 }
190 }
191 return $result
192}
drh17a68932001-01-31 13:28:08 +0000193
194# Delete a file or directory
195#
196proc forcedelete {filename} {
197 if {[catch {file delete -force $filename}]} {
198 exec rm -rf $filename
199 }
200}