blob: 549645857aa00e6056c0685b599468fd7c006868 [file] [log] [blame]
drhb19a2bc2001-09-16 00:13:26 +00001# 2001 September 15
drh348784e2000-05-29 20:41:49 +00002#
drhb19a2bc2001-09-16 00:13:26 +00003# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
drh348784e2000-05-29 20:41:49 +00005#
drhb19a2bc2001-09-16 00:13:26 +00006# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
drh348784e2000-05-29 20:41:49 +00009#
10#***********************************************************************
11# This file implements some common TCL routines used for regression
12# testing the SQLite library
13#
drhb19a2bc2001-09-16 00:13:26 +000014# $Id: tester.tcl,v 1.18 2001/09/16 00:13:28 drh Exp $
drhfbc3eab2001-04-06 16:13:42 +000015
16# Make sure tclsqlite was compiled correctly. Abort now with an
17# error message if not.
18#
19if {[sqlite -tcl-uses-utf]} {
20 if {"\u1234"=="u1234"} {
21 puts stderr "***** BUILD PROBLEM *****"
22 puts stderr "$argv0 was linked against an older version"
23 puts stderr "of TCL that does not support Unicode, but uses a header"
24 puts stderr "file (\"tcl.h\") from a new TCL version that does support"
25 puts stderr "Unicode. This combination causes internal errors."
26 puts stderr "Recompile using a TCL library and header file that match"
27 puts stderr "and try again.\n**************************"
28 exit 1
29 }
30} else {
31 if {"\u1234"!="u1234"} {
32 puts stderr "***** BUILD PROBLEM *****"
33 puts stderr "$argv0 was linked against an newer version"
34 puts stderr "of TCL that supports Unicode, but uses a header file"
35 puts stderr "(\"tcl.h\") from a old TCL version that does not support"
36 puts stderr "Unicode. This combination causes internal errors."
37 puts stderr "Recompile using a TCL library and header file that match"
38 puts stderr "and try again.\n**************************"
39 exit 1
40 }
41}
drh348784e2000-05-29 20:41:49 +000042
drhbec2bf42000-05-29 23:48:22 +000043# Create a test database
44#
drh5edc3122001-09-13 21:53:09 +000045file delete -force ./test.db
46file delete -force ./test.db-journal
47sqlite db ./test.db
drhbec2bf42000-05-29 23:48:22 +000048
49# Abort early if this script has been run before.
50#
51if {[info exists nTest]} return
52
53# Set the test counters to zero
54#
drh348784e2000-05-29 20:41:49 +000055set nErr 0
56set nTest 0
drhdb25e382001-03-15 18:21:22 +000057set nProb 0
drh767c2002000-10-19 14:10:08 +000058set skip_test 0
drha1b351a2001-09-14 16:42:12 +000059set failList {}
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
drh5edc3122001-09-13 21:53:09 +000082 puts -nonewline $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
drha1b351a2001-09-14 16:42:12 +000087 lappend ::failList $name
88 if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
drh348784e2000-05-29 20:41:49 +000089 } elseif {[string compare $result $expected]} {
90 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
91 incr nErr
drha1b351a2001-09-14 16:42:12 +000092 lappend ::failList $name
93 if {$nErr>10} {puts "*** Giving up..."; finalize_testing}
drh348784e2000-05-29 20:41:49 +000094 } else {
95 puts " Ok"
96 }
97}
98
drhdb25e382001-03-15 18:21:22 +000099# Invoke this procedure on a test that is probabilistic
100# and might fail sometimes.
101#
102proc do_probtest {name cmd expected} {
103 global argv nProb nTest skip_test
104 if {$skip_test} {
105 set skip_test 0
106 return
107 }
108 if {[llength $argv]==0} {
109 set go 1
110 } else {
111 set go 0
112 foreach pattern $argv {
113 if {[string match $pattern $name]} {
114 set go 1
115 break
116 }
117 }
118 }
119 if {!$go} return
120 incr nTest
drh5edc3122001-09-13 21:53:09 +0000121 puts -nonewline $name...
drhdb25e382001-03-15 18:21:22 +0000122 flush stdout
123 if {[catch {uplevel #0 "$cmd;\n"} result]} {
124 puts "\nError: $result"
125 incr nErr
126 } elseif {[string compare $result $expected]} {
127 puts "\nExpected: \[$expected\]\n Got: \[$result\]"
128 puts "NOTE: The results of the previous test depend on system load"
129 puts "and processor speed. The test may sometimes fail even if the"
130 puts "library is working correctly."
131 incr nProb
132 } else {
133 puts " Ok"
134 }
135}
136
drhdaffd0e2001-04-11 14:28:42 +0000137# The procedure uses the special "sqlite_malloc_stat" command
drh8c82b352000-12-10 18:23:50 +0000138# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
139# to see how many malloc()s have not been free()ed. The number
140# of surplus malloc()s is stored in the global variable $::Leak.
141# If the value in $::Leak grows, it may mean there is a memory leak
142# in the library.
143#
144proc memleak_check {} {
drhdaffd0e2001-04-11 14:28:42 +0000145 if {[info command sqlite_malloc_stat]!=""} {
146 set r [sqlite_malloc_stat]
147 set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
148 }
drh8c82b352000-12-10 18:23:50 +0000149}
150
drh348784e2000-05-29 20:41:49 +0000151# Run this routine last
152#
153proc finish_test {} {
drha1b351a2001-09-14 16:42:12 +0000154 finalize_testing
155}
156proc finalize_testing {} {
drhdb25e382001-03-15 18:21:22 +0000157 global nTest nErr nProb
drha1b351a2001-09-14 16:42:12 +0000158 if {$nErr==0} memleak_check
drh6e142f52000-06-08 13:36:40 +0000159 catch {db close}
drh348784e2000-05-29 20:41:49 +0000160 puts "$nErr errors out of $nTest tests"
drha1b351a2001-09-14 16:42:12 +0000161 puts "Failures on these tests: $::failList"
drhdb25e382001-03-15 18:21:22 +0000162 if {$nProb>0} {
163 puts "$nProb probabilistic tests also failed, but this does"
164 puts "not necessarily indicate a malfunction."
165 }
166 exit [expr {$nErr>0}]
drh348784e2000-05-29 20:41:49 +0000167}
168
drh348784e2000-05-29 20:41:49 +0000169# A procedure to execute SQL
170#
drhc4a3c772001-04-04 11:48:57 +0000171proc execsql {sql {db db}} {
drhacbcdc42001-01-22 00:31:53 +0000172 # puts "SQL = $sql"
drhc4a3c772001-04-04 11:48:57 +0000173 return [$db eval $sql]
drh348784e2000-05-29 20:41:49 +0000174}
drh3aadb2e2000-05-31 17:59:25 +0000175
176# Another procedure to execute SQL. This one includes the field
177# names in the returned list.
178#
179proc execsql2 {sql} {
180 set result {}
181 db eval $sql data {
182 foreach f $data(*) {
183 lappend result $f $data($f)
184 }
185 }
186 return $result
187}
drh17a68932001-01-31 13:28:08 +0000188
189# Delete a file or directory
190#
191proc forcedelete {filename} {
192 if {[catch {file delete -force $filename}]} {
193 exec rm -rf $filename
194 }
195}