blob: 852a1a8eeaa41fd65d20e6aad3d436889046c61e [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#
drha1b351a2001-09-14 16:42:12 +000026# $Id: tester.tcl,v 1.17 2001/09/14 16:42:13 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
drha1b351a2001-09-14 16:42:12 +000071set failList {}
drh348784e2000-05-29 20:41:49 +000072
73# Invoke the do_test procedure to run a single test
74#
75proc do_test {name cmd expected} {
drh767c2002000-10-19 14:10:08 +000076 global argv nErr nTest skip_test
77 if {$skip_test} {
78 set skip_test 0
79 return
80 }
81 if {[llength $argv]==0} {
drh348784e2000-05-29 20:41:49 +000082 set go 1
83 } else {
84 set go 0
85 foreach pattern $argv {
86 if {[string match $pattern $name]} {
87 set go 1
88 break
89 }
90 }
91 }
92 if {!$go} return
93 incr nTest
drh5edc3122001-09-13 21:53:09 +000094 puts -nonewline $name...
drh348784e2000-05-29 20:41:49 +000095 flush stdout
96 if {[catch {uplevel #0 "$cmd;\n"} result]} {
97 puts "\nError: $result"
98 incr nErr
drha1b351a2001-09-14 16:42:12 +000099 lappend ::failList $name
100 if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
drh348784e2000-05-29 20:41:49 +0000101 } elseif {[string compare $result $expected]} {
102 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
103 incr nErr
drha1b351a2001-09-14 16:42:12 +0000104 lappend ::failList $name
105 if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
drh348784e2000-05-29 20:41:49 +0000106 } else {
107 puts " Ok"
108 }
109}
110
drhdb25e382001-03-15 18:21:22 +0000111# Invoke this procedure on a test that is probabilistic
112# and might fail sometimes.
113#
114proc do_probtest {name cmd expected} {
115 global argv nProb nTest skip_test
116 if {$skip_test} {
117 set skip_test 0
118 return
119 }
120 if {[llength $argv]==0} {
121 set go 1
122 } else {
123 set go 0
124 foreach pattern $argv {
125 if {[string match $pattern $name]} {
126 set go 1
127 break
128 }
129 }
130 }
131 if {!$go} return
132 incr nTest
drh5edc3122001-09-13 21:53:09 +0000133 puts -nonewline $name...
drhdb25e382001-03-15 18:21:22 +0000134 flush stdout
135 if {[catch {uplevel #0 "$cmd;\n"} result]} {
136 puts "\nError: $result"
137 incr nErr
138 } elseif {[string compare $result $expected]} {
139 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
140 puts "NOTE: The results of the previous test depend on system load"
141 puts "and processor speed. The test may sometimes fail even if the"
142 puts "library is working correctly."
143 incr nProb
144 } else {
145 puts " Ok"
146 }
147}
148
drhdaffd0e2001-04-11 14:28:42 +0000149# The procedure uses the special "sqlite_malloc_stat" command
drh8c82b352000-12-10 18:23:50 +0000150# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
151# to see how many malloc()s have not been free()ed. The number
152# of surplus malloc()s is stored in the global variable $::Leak.
153# If the value in $::Leak grows, it may mean there is a memory leak
154# in the library.
155#
156proc memleak_check {} {
drhdaffd0e2001-04-11 14:28:42 +0000157 if {[info command sqlite_malloc_stat]!=""} {
158 set r [sqlite_malloc_stat]
159 set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
160 }
drh8c82b352000-12-10 18:23:50 +0000161}
162
drh348784e2000-05-29 20:41:49 +0000163# Run this routine last
164#
165proc finish_test {} {
drha1b351a2001-09-14 16:42:12 +0000166 finalize_testing
167}
168proc finalize_testing {} {
drhdb25e382001-03-15 18:21:22 +0000169 global nTest nErr nProb
drha1b351a2001-09-14 16:42:12 +0000170 if {$nErr==0} memleak_check
drh6e142f52000-06-08 13:36:40 +0000171 catch {db close}
drh348784e2000-05-29 20:41:49 +0000172 puts "$nErr errors out of $nTest tests"
drha1b351a2001-09-14 16:42:12 +0000173 puts "Failures on these tests: $::failList"
drhdb25e382001-03-15 18:21:22 +0000174 if {$nProb>0} {
175 puts "$nProb probabilistic tests also failed, but this does"
176 puts "not necessarily indicate a malfunction."
177 }
178 exit [expr {$nErr>0}]
drh348784e2000-05-29 20:41:49 +0000179}
180
drh348784e2000-05-29 20:41:49 +0000181# A procedure to execute SQL
182#
drhc4a3c772001-04-04 11:48:57 +0000183proc execsql {sql {db db}} {
drhacbcdc42001-01-22 00:31:53 +0000184 # puts "SQL = $sql"
drhc4a3c772001-04-04 11:48:57 +0000185 return [$db eval $sql]
drh348784e2000-05-29 20:41:49 +0000186}
drh3aadb2e2000-05-31 17:59:25 +0000187
188# Another procedure to execute SQL. This one includes the field
189# names in the returned list.
190#
191proc execsql2 {sql} {
192 set result {}
193 db eval $sql data {
194 foreach f $data(*) {
195 lappend result $f $data($f)
196 }
197 }
198 return $result
199}
drh17a68932001-01-31 13:28:08 +0000200
201# Delete a file or directory
202#
203proc forcedelete {filename} {
204 if {[catch {file delete -force $filename}]} {
205 exec rm -rf $filename
206 }
207}