summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/all.tcl8
-rw-r--r--tests/async.test40
-rw-r--r--tests/chanio.test17
-rw-r--r--tests/env.test399
-rw-r--r--tests/exec.test25
-rw-r--r--tests/expr.test9
-rw-r--r--tests/http11.test7
-rw-r--r--tests/io.test15
-rw-r--r--tests/ioCmd.test17
-rw-r--r--tests/iogt.test2
-rw-r--r--tests/main.test2
-rw-r--r--tests/pkgIndex.tcl6
-rw-r--r--tests/platform.test6
-rw-r--r--tests/safe.test12
-rw-r--r--tests/tailcall.test20
-rw-r--r--tests/tcltest.test7
-rw-r--r--tests/tcltests.tcl11
-rw-r--r--tests/thread.test67
-rw-r--r--tests/utf.test27
19 files changed, 438 insertions, 259 deletions
diff --git a/tests/all.tcl b/tests/all.tcl
index 69a16ba..e14bd9c 100644
--- a/tests/all.tcl
+++ b/tests/all.tcl
@@ -13,10 +13,14 @@
package prefer latest
package require Tcl 8.5-
package require tcltest 2.2
-namespace import tcltest::*
-configure {*}$argv -testdir [file dir [info script]]
+namespace import ::tcltest::*
+
+configure {*}$argv -testdir [file dirname [file dirname [file normalize [
+ info script]/...]]]
+
if {[singleProcess]} {
interp debug {} -frame 1
}
+
runAllTests
proc exit args {}
diff --git a/tests/async.test b/tests/async.test
index 6de814b..34c2fdc 100644
--- a/tests/async.test
+++ b/tests/async.test
@@ -156,17 +156,24 @@ test async-4.1 {async interrupting bytecode sequence} -constraints {
}
} -body {
apply {{handle} {
- global aresult
- set aresult {Async event not delivered}
- testasync marklater $handle
- for {set i 0} {
- $i < 2500000 && $aresult eq "Async event not delivered"
- } {incr i} {
- nothing
- }
+ global aresult
+ set aresult {Async event not delivered}
+ testasync marklater $handle
+ # allow plenty of time to pass in case valgrind is running
+ set start [clock seconds]
+ while {
+ [clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
+ } {
+ # be less busy
+ after 100
+ nothing
+ }
return $aresult
}} $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
test async-4.2 {async interrupting straight bytecode sequence} -constraints {
@@ -178,12 +185,20 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints {
global aresult
set aresult {Async event not delivered}
testasync marklater $handle
- for {set i 0} {
- $i < 2500000 && $aresult eq "Async event not delivered"
- } {incr i} {}
+ # allow plenty of time to pass in case valgrind is running
+ set start [clock seconds]
+ while {
+ [clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
+ } {
+ # be less busy
+ after 100
+ }
return $aresult
}} $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
@@ -200,6 +215,9 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
return $aresult
}]] $hm
} -result {test pattern} -cleanup {
+ # give other threads some time to go way so that valgrind doesn't pick up
+ # "still reachable" cases from early thread termination
+ after 100
testasync delete $hm
}
diff --git a/tests/chanio.test b/tests/chanio.test
index 97e7e70..e7f51b3 100644
--- a/tests/chanio.test
+++ b/tests/chanio.test
@@ -13,16 +13,11 @@
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# TODO: This test is likely worthless. Confirm and remove
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
- namespace import -force ::tcltest::*
}
-::tcltest::loadTestedCommands
-catch [list package require -exact Tcltest [info patchlevel]]
-
-testConstraint testbytestring [llength [info commands testbytestring]]
-
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
@@ -35,18 +30,16 @@ namespace eval ::tcl::test::io {
variable msg
variable expected
- ::tcltest::loadTestedCommands
+ loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
-
+ package require tcltests
+
+ testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testchannel [llength [info commands testchannel]]
- testConstraint exec [llength [info commands exec]]
testConstraint openpipe 1
- testConstraint fileevent [llength [info commands fileevent]]
- testConstraint fcopy [llength [info commands fcopy]]
testConstraint testfevent [llength [info commands testfevent]]
testConstraint testchannelevent [llength [info commands testchannelevent]]
testConstraint testmainthread [llength [info commands testmainthread]]
- testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
# You need a *very* special environment to do some tests. In particular,
# many file systems do not support large-files...
diff --git a/tests/env.test b/tests/env.test
index 0dd4f98..2c077b1 100644
--- a/tests/env.test
+++ b/tests/env.test
@@ -16,49 +16,96 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
namespace import -force ::tcltest::*
}
-# Some tests require the "exec" command.
-# Skip them if exec is not defined.
-testConstraint exec [llength [info commands exec]]
+package require tcltests
+
+# [exec] is required here to see the actual environment received by child
+# processes.
+proc getenv {} {
+ global printenvScript
+ catch {exec [interpreter] $printenvScript} out
+ if {$out eq "child process exited abnormally"} {
+ set out {}
+ }
+ return $out
+}
+
+
+proc envrestore {} {
+ # Restore the environment variables at the end of the test.
+ global env
+ variable env2
+
+ foreach name [array names env] {
+ unset env($name)
+ }
+ array set env $env2
+ return
+}
+
+
+proc envprep {} {
+ # Save the current environment variables at the start of the test.
+ global env
+ variable keep
+ variable env2
+
+ set env2 [array get env]
+ foreach name [array names env] {
+ # Keep some environment variables that support operation of the tcltest
+ # package.
+ if {[string toupper $name] ni $keep} {
+ unset env($name)
+ }
+ }
+ return
+}
+
+
+proc encodingrestore {} {
+ variable sysenc
+ encoding system $sysenc
+ return
+}
+
+
+proc encodingswitch encoding {
+ variable sysenc
+ # Need to run [getenv] in known encoding, so save the current one here...
+ set sysenc [encoding system]
+ encoding system $encoding
+ return
+}
+
+
+proc setup1 {} {
+ global env
+ envprep
+ encodingswitch iso8859-1
+}
+
+proc setup2 {} {
+ global env
+ setup1
+ set env(NAME1) {test string}
+ set env(NAME2) {new value}
+ set env(XYZZY) {garbage}
+}
+
+
+proc cleanup1 {} {
+ encodingrestore
+ envrestore
+}
-#
-# These tests will run on any platform (and indeed crashed on the Mac). So put
-# them before you test for the existance of exec.
-#
-test env-1.1 {propagation of env values to child interpreters} -setup {
- catch {interp delete child}
- catch {unset env(test)}
-} -body {
- interp create child
- set env(test) garbage
- child eval {set env(test)}
-} -cleanup {
- interp delete child
- unset env(test)
-} -result {garbage}
-#
-# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
-# runs.
-#
-test env-1.2 {lappend to env value} -setup {
- catch {unset env(test)}
-} -body {
- set env(test) aaaaaaaaaaaaaaaa
- append env(test) bbbbbbbbbbbbbb
- unset env(test)
+variable keep {
+ TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
+ SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+ DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+ SECURITYSESSIONID LANG WINDIR TERM
+ CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432
}
-test env-1.3 {reflection of env by "array names"} -setup {
- catch {interp delete child}
- catch {unset env(test)}
-} -body {
- interp create child
- child eval {set env(test) garbage}
- expr {"test" in [array names env]}
-} -cleanup {
- interp delete child
- catch {unset env(test)}
-} -result {1}
-set printenvScript [makeFile {
+variable printenvScript [makeFile [string map [list @keep@ [list $keep]] {
encoding system iso8859-1
proc lrem {listname name} {
upvar $listname list
@@ -70,7 +117,7 @@ set printenvScript [makeFile {
}
proc mangle s {
regsub -all {\[|\\|\]} $s {\\&} s
- regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar &]} s
+ regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar {&}]} s
return [subst -novariables $s]
}
proc manglechar c {
@@ -84,161 +131,154 @@ set printenvScript [makeFile {
lrem names ComSpec
lrem names ""
}
- foreach name {
- TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
- SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
- DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
- __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
- CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
- } {
+ foreach name @keep@ {
lrem names $name
}
foreach p $names {
- puts "[mangle $p]=[mangle $env($p)]"
+ puts [mangle $p]=[mangle $env($p)]
}
exit
-} printenv]
+}] printenv]
-# [exec] is required here to see the actual environment received by child
-# processes.
-proc getenv {} {
- global printenvScript tcltest
- catch {exec [interpreter] $printenvScript} out
- if {$out eq "child process exited abnormally"} {
- set out {}
- }
- return $out
-}
-# Save the current environment variables at the start of the test.
-
-set env2 [array get env]
-foreach name [array names env] {
- # Keep some environment variables that support operation of the tcltest
- # package.
- if {[string toupper $name] ni {
- TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
- SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
- DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
- SECURITYSESSIONID LANG WINDIR TERM
- CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432
- }} {
- unset env($name)
- }
+test env-1.1 {propagation of env values to child interpreters} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ set env(test) garbage
+ child eval {set env(test)}
+} -cleanup {
+ interp delete child
+ unset env(test)
+} -result {garbage}
+
+
+# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
+# runs.
+test env-1.2 {lappend to env value} -setup {
+ catch {unset env(test)}
+} -body {
+ set env(test) aaaaaaaaaaaaaaaa
+ append env(test) bbbbbbbbbbbbbb
+ unset env(test)
}
-# Need to run 'getenv' in known encoding, so save the current one here...
-set sysenc [encoding system]
-test env-2.1 {adding environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
- getenv
+test env-1.3 {reflection of env by "array names"} -setup {
+ catch {interp delete child}
+ catch {unset env(test)}
+} -body {
+ interp create child
+ child eval {set env(test) garbage}
+ expr {"test" in [array names env]}
} -cleanup {
- encoding system $sysenc
-} -result {}
-test env-2.2 {adding environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+ interp delete child
+ catch {unset env(test)}
+} -result 1
+
+
+test env-2.1 {
+ adding environment variables
+} -constraints exec -setup setup1 -body {
+ getenv
+} -cleanup cleanup1 -result {}
+
+
+test env-2.2 {
+ adding environment variables
+} -constraints exec -setup setup1 -body {
set env(NAME1) "test string"
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string}
-test env-2.3 {adding environment variables} -setup {
- encoding system iso8859-1
+} -cleanup cleanup1 -result {NAME1=test string}
+
+
+test env-2.3 {adding environment variables} -constraints exec -setup {
+ setup1
set env(NAME1) "test string"
-} -constraints {exec} -body {
+} -body {
set env(NAME2) "more"
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string
+} -cleanup cleanup1 -result {NAME1=test string
NAME2=more}
-test env-2.4 {adding environment variables} -setup {
- encoding system iso8859-1
+
+
+test env-2.4 {
+ adding environment variables
+} -constraints exec -setup {
+ setup1
set env(NAME1) "test string"
set env(NAME2) "more"
-} -constraints {exec} -body {
+} -body {
set env(XYZZY) "garbage"
getenv
-} -cleanup {
- encoding system $sysenc
+} -cleanup { cleanup1
} -result {NAME1=test string
NAME2=more
XYZZY=garbage}
-set env(NAME1) "test string"
-set env(NAME2) "new value"
-set env(XYZZY) "garbage"
-test env-3.1 {changing environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+
+test env-3.1 {
+ changing environment variables
+} -constraints exec -setup setup2 -body {
set result [getenv]
unset env(NAME2)
set result
} -cleanup {
- encoding system $sysenc
+ cleanup1
} -result {NAME1=test string
NAME2=new value
XYZZY=garbage}
-unset -nocomplain env(NAME2)
-test env-4.1 {unsetting environment variables: default} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+
+test env-4.1 {
+ unsetting environment variables
+} -constraints exec -setup setup2 -body {
+ unset -nocomplain env(NAME2)
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {NAME1=test string
+} -cleanup cleanup1 -result {NAME1=test string
XYZZY=garbage}
-test env-4.2 {unsetting environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
- unset env(NAME1)
- getenv
-} -cleanup {
- unset env(XYZZY)
- encoding system $sysenc
-} -result {XYZZY=garbage}
-unset -nocomplain env(NAME1) env(XYZZY)
-test env-4.3 {setting international environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+
+# env-4.2 is deleted
+
+test env-4.3 {
+ setting international environment variables
+} -constraints exec -setup setup1 -body {
set env(\ua7) \ub6
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {\u00a7=\u00b6}
-test env-4.4 {changing international environment variables} -setup {
- encoding system iso8859-1
-} -constraints {exec} -body {
+} -cleanup cleanup1 -result {\u00a7=\u00b6}
+
+
+test env-4.4 {
+ changing international environment variables
+} -constraints exec -setup setup1 -body {
set env(\ua7) \ua7
getenv
-} -cleanup {
- encoding system $sysenc
-} -result {\u00a7=\u00a7}
-test env-4.5 {unsetting international environment variables} -setup {
- encoding system iso8859-1
+} -cleanup cleanup1 -result {\u00a7=\u00a7}
+
+
+test env-4.5 {
+ unsetting international environment variables
+} -constraints exec -setup {
+ setup1
set env(\ua7) \ua7
} -body {
set env(\ub6) \ua7
unset env(\ua7)
getenv
-} -constraints {exec} -cleanup {
- unset env(\ub6)
- encoding system $sysenc
-} -result {\u00b6=\u00a7}
+} -cleanup cleanup1 -result {\u00b6=\u00a7}
-test env-5.0 {corner cases - set a value, it should exist} -body {
+test env-5.0 {
+ corner cases - set a value, it should exist
+} -setup setup1 -body {
set env(temp) a
set env(temp)
-} -cleanup {
- unset env(temp)
-} -result {a}
-test env-5.1 {corner cases - remove one elem at a time} -setup {
- set x [array get env]
-} -body {
+} -cleanup cleanup1 -result a
+
+
+test env-5.1 {
+ corner cases - remove one elem at a time
+} -setup setup1 -body {
# When no environment variables exist, the env var will contain no
# entries. The "array names" call synchs up the C-level environ array with
# the Tcl level env array. Make sure an empty Tcl array is created.
@@ -246,9 +286,9 @@ test env-5.1 {corner cases - remove one elem at a time} -setup {
unset env($e)
}
array size env
-} -cleanup {
- array set env $x
-} -result {0}
+} -cleanup cleanup1 -result 0
+
+
test env-5.2 {corner cases - unset the env array} -setup {
interp create i
} -body {
@@ -262,42 +302,54 @@ test env-5.2 {corner cases - unset the env array} -setup {
} -cleanup {
interp delete i
} -result {0}
+
+
test env-5.3 {corner cases: unset the env in master should unset child} -setup {
+ setup1
interp create i
} -body {
# Variables deleted in a master interp should be deleted in child interp
# too.
- i eval { set env(THIS_SHOULD_EXIST) a}
+ i eval {set env(THIS_SHOULD_EXIST) a}
set result [set env(THIS_SHOULD_EXIST)]
unset env(THIS_SHOULD_EXIST)
lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
} -cleanup {
+ cleanup1
interp delete i
} -result {a 1}
+
+
test env-5.4 {corner cases - unset the env array} -setup {
+ setup1
interp create i
} -body {
# The info exists command should be in synch with the env array.
# Know Bug: 1737
- i eval { set env(THIS_SHOULD_EXIST) a}
+ i eval {set env(THIS_SHOULD_EXIST) a}
set result [info exists env(THIS_SHOULD_EXIST)]
lappend result [set env(THIS_SHOULD_EXIST)]
lappend result [info exists env(THIS_SHOULD_EXIST)]
} -cleanup {
+ cleanup1
interp delete i
} -result {1 a 1}
-test env-5.5 {corner cases - cannot have null entries on Windows} -constraints win -body {
+
+
+test env-5.5 {
+ corner cases - cannot have null entries on Windows
+} -constraints win -body {
set env() a
catch {set env()}
-} -result 1
+} -cleanup cleanup1 -result 1
-test env-6.1 {corner cases - add lots of env variables} -body {
+test env-6.1 {corner cases - add lots of env variables} -setup setup1 -body {
set size [array size env]
for {set i 0} {$i < 100} {incr i} {
set env(BOGUS$i) $i
}
expr {[array size env] - $size}
-} -result 100
+} -cleanup cleanup1 -result 100
test env-7.1 {[219226]: whole env array should not be unset by read} -body {
set n [array size env]
@@ -310,16 +362,20 @@ test env-7.1 {[219226]: whole env array should not be unset by read} -body {
return $n
} -result 0
-test env-7.2 {[219226]: links to env elements should not be removed by read} -body {
+test env-7.2 {
+ [219226]: links to env elements should not be removed by read
+} -setup setup1 -body {
apply {{} {
set ::env(test7_2) ok
upvar env(test7_2) elem
set ::env(PATH)
return $elem
}}
-} -result ok
+} -cleanup cleanup1 -result ok
-test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy trace} -body {
+test env-7.3 {
+ [9b4702]: testing existence of env(some_thing) should not destroy trace
+} -setup setup1 -body {
apply {{} {
catch {unset ::env(test7_3)}
proc foo args {
@@ -330,16 +386,25 @@ test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy
set ::env(not_yet_existent) "Now I'm here";
return [info exists ::env(test7_3)]
}}
-} -result 1
+} -cleanup cleanup1 -result 1
-# Restore the environment variables at the end of the test.
+test env-8.0 {
+ memory usage - valgrind does not report reachable memory
+} -body {
+ set res [set env(__DUMMY__) {i'm with dummy}]
+ unset env(__DUMMY__)
+ return $res
+} -result {i'm with dummy}
+
-foreach name [array names env] {
- unset env($name)
-}
-array set env $env2
# cleanup
+rename getenv {}
+rename envrestore {}
+rename envprep {}
+rename encodingrestore {}
+rename encodingswitch {}
+
removeFile $printenvScript
::tcltest::cleanupTests
return
diff --git a/tests/exec.test b/tests/exec.test
index 3d1cd56..dfc44c4 100644
--- a/tests/exec.test
+++ b/tests/exec.test
@@ -11,9 +11,14 @@
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# There is no point in running Valgrind on cases where [exec] forks but then
+# fails and the child process doesn't go through full cleanup.
+
package require tcltest 2
namespace import -force ::tcltest::*
+package require tcltests
+
# All tests require the "exec" command.
# Skip them if exec is not defined.
testConstraint exec [llength [info commands exec]]
@@ -325,11 +330,11 @@ test exec-8.2 {long input and output} {exec} {
# Commands that return errors.
-test exec-9.1 {commands returning errors} {exec} {
+test exec-9.1 {commands returning errors} {exec notValgrind} {
set x [catch {exec gorp456} msg]
list $x [string tolower $msg] [string tolower $errorCode]
} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
-test exec-9.2 {commands returning errors} {exec} {
+test exec-9.2 {commands returning errors} {exec notValgrind} {
string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
@@ -339,7 +344,7 @@ test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
} -returnCodes error -result {foo bar
child process exited abnormally}
-test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
+test exec-9.5 {commands returning errors} -constraints {exec stdio notValgrind} -body {
exec gorp456 | [interpreter] echo a b c
} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
test exec-9.6 {commands returning errors} -constraints {exec} -body {
@@ -428,13 +433,13 @@ test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
exec cat >@ $f
} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
close $f
-test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
+test exec-10.20 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec ~non_existent_user/foo/bar
} -returnCodes error -result {user "non_existent_user" doesn't exist}
-test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
+test exec-10.21 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec [interpreter] true | ~xyzzy_bad_user/x | false
} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
-test exec-10.22 {errors in exec invocation} -constraints exec -body {
+test exec-10.22 {errors in exec invocation} -constraints {exec notValgrind} -body {
exec echo test > ~non_existent_user/foo/bar
} -returnCodes error -result {user "non_existent_user" doesn't exist}
# Commands in background.
@@ -510,7 +515,7 @@ test exec-13.1 {setting errorCode variable} {exec} {
test exec-13.2 {setting errorCode variable} {exec} {
list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
} {1 {posix enoent {no such file or directory}}}
-test exec-13.3 {setting errorCode variable} {exec} {
+test exec-13.3 {setting errorCode variable} {exec notValgrind} {
set x [catch {exec _weird_cmd_} msg]
list $x [string tolower $msg] [lindex $errorCode 0] \
[string tolower [lrange $errorCode 2 end]]
@@ -548,7 +553,7 @@ test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
test exec-14.3 {unknown switch} -constraints {exec} -body {
exec -gorp
} -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --}
-test exec-14.4 {-- switch} -constraints {exec} -body {
+test exec-14.4 {-- switch} -constraints {exec notValgrind} -body {
exec -- -gorp
} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
test exec-14.5 {-ignorestderr switch} {exec} {
@@ -662,7 +667,7 @@ test exec-18.2 {exec cat deals with weird file names} -body {
# Note that this test cannot be adapted to work on Windows; that platform has
# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
# that there is a POSIX shell...
-test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
+test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix notValgrind} -setup {
set tmpfile [makeFile {0} tmpfile.exec-19.1]
} -body {
# Note that we have to allow for the current contents of the temporary
@@ -675,7 +680,7 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
{for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
exec /bin/sh -c \
{for a in d e f; do sleep 1; echo $a >&2; done} 2>>$tmpfile &
- # The above four shell invokations take about 3 seconds to finish, so allow
+ # The above four shell invocations take about 3 seconds to finish, so allow
# 5s (in case the machine is busy)
after 5000
# Check that no bytes have got lost through mixups with overlapping
diff --git a/tests/expr.test b/tests/expr.test
index de6eb4a..abaf31d 100644
--- a/tests/expr.test
+++ b/tests/expr.test
@@ -7157,6 +7157,15 @@ test expr-51.1 {test round-to-even on input} {
expr 6.9294956446009195e15
} 6929495644600920.0
+test expr-52.1 {
+ comparison with empty string does not generate string representation
+} {
+ set a [list one two three]
+ list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [
+ string match {*no string representation*} [
+ ::tcl::unsupported::representation $a]]
+} {0 0 1 1}
+
# cleanup
diff --git a/tests/http11.test b/tests/http11.test
index c9ded0b..2e50837 100644
--- a/tests/http11.test
+++ b/tests/http11.test
@@ -666,6 +666,13 @@ test http11-4.3 "normal post request, check channel query length" -setup {
# -------------------------------------------------------------------------
+# Eliminate valgrind "still reachable" reports on outstanding "Detached"
+# structures in the detached list which stem from PipeClose2Proc not waiting
+# around for background processes to complete, meaning that previous calls to
+# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
+after 10
+exec [info nameofexecutable] << {}
+
foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
if {[llength [info proc $p]]} {rename $p {}}
}
diff --git a/tests/io.test b/tests/io.test
index 20bb565..683a1b2 100644
--- a/tests/io.test
+++ b/tests/io.test
@@ -15,14 +15,8 @@
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
- namespace import -force ::tcltest::*
}
-::tcltest::loadTestedCommands
-catch [list package require -exact Tcltest [info patchlevel]]
-
-testConstraint testbytestring [llength [info commands testbytestring]]
-
namespace eval ::tcl::test::io {
namespace import ::tcltest::*
@@ -35,15 +29,16 @@ namespace eval ::tcl::test::io {
variable msg
variable expected
+ loadTestedCommands
+ catch [list package require -exact Tcltest [info patchlevel]]
+ package require tcltests
+
+testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint exec [llength [info commands exec]]
testConstraint openpipe 1
-testConstraint fileevent [llength [info commands fileevent]]
-testConstraint fcopy [llength [info commands fcopy]]
testConstraint testfevent [llength [info commands testfevent]]
testConstraint testchannelevent [llength [info commands testchannelevent]]
testConstraint testmainthread [llength [info commands testmainthread]]
-testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
testConstraint testobj [llength [info commands testobj]]
# You need a *very* special environment to do some tests. In
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index cab4e97..948671e 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -21,10 +21,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
::tcltest::loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
+package require tcltests
+
# Custom constraints used in this file
-testConstraint fcopy [llength [info commands fcopy]]
testConstraint testchannel [llength [info commands testchannel]]
-testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
#----------------------------------------------------------------------
@@ -395,7 +395,7 @@ test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
-test iocmd-11.4 {I/O to command pipelines} unixOrPc {
+test iocmd-11.4 {I/O to command pipelines} {notValgrind unixOrPc} {
list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
@@ -3781,7 +3781,6 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
# Use constraints to skip this test while valgrinding so this expected leak
# doesn't prevent a finding of "leak-free".
#
-testConstraint notValgrind [expr {![testConstraint valgrind]}]
test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
#puts <<$tcltest::mainThread>>main
@@ -3834,6 +3833,16 @@ test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -mat
rename track {}
# cleanup
+
+
+# Eliminate valgrind "still reachable" reports on outstanding "Detached"
+# structures in the detached list which stem from PipeClose2Proc not waiting
+# around for background processes to complete, meaning that previous calls to
+# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
+after 10
+exec [info nameofexecutable] << {}
+
+
foreach file [list test1 test2 test3 test4] {
removeFile $file
}
diff --git a/tests/iogt.test b/tests/iogt.test
index aa579bf..3cac2cf 100644
--- a/tests/iogt.test
+++ b/tests/iogt.test
@@ -608,7 +608,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
variable copy 1
}
} -constraints {testchannel knownBug} -body {
- # This test to check the validity of aquired Tcl_Channel references is not
+ # This test to check the validity of acquired Tcl_Channel references is not
# possible because even a backgrounded fcopy will immediately start to
# copy data, without waiting for the event loop. This is done only in case
# of an underflow on the read size!. So stacking transforms after the
diff --git a/tests/main.test b/tests/main.test
index ab66b38..5b43b43 100644
--- a/tests/main.test
+++ b/tests/main.test
@@ -1210,8 +1210,6 @@ namespace eval ::tcl::test::main {
Bug 1775878
} -constraints {
exec Tcltest
- } -setup {
- catch {set f [open "|[list [interpreter]]" w+]}
} -body {
exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
set f [open result]
diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl
new file mode 100644
index 0000000..854b943
--- /dev/null
+++ b/tests/pkgIndex.tcl
@@ -0,0 +1,6 @@
+#! /usr/bin/env tclsh
+
+package ifneeded tcltests 0.1 "
+ source [list $dir/tcltests.tcl]
+ package provide tcltests 0.1
+"
diff --git a/tests/platform.test b/tests/platform.test
index 8a68351..fa533e8 100644
--- a/tests/platform.test
+++ b/tests/platform.test
@@ -10,6 +10,7 @@
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require tcltest 2
+package require tcltests
namespace eval ::tcl::test::platform {
namespace import ::tcltest::testConstraint
@@ -67,7 +68,10 @@ test platform-3.1 {CPU ID on Windows/UNIX} \
# format of string it produces consists of two non-empty words separated by a
# hyphen.
package require platform
-test platform-4.1 {format of platform::identify result} -match regexp -body {
+test platform-4.1 {format of platform::identify result} -constraints notValgrind -match regexp -body {
+ # [identify] may attempt to [exec] dpkg-architecture, which may not exist,
+ # in which case fork will not be followed by exec, and valgrind will issue
+ # "still reachable" reports.
platform::identify
} -result {^([^-]+-)+[^-]+$}
test platform-4.2 {format of platform::generic result} -match regexp -body {
diff --git a/tests/safe.test b/tests/safe.test
index df60de6..217507e 100644
--- a/tests/safe.test
+++ b/tests/safe.test
@@ -308,14 +308,10 @@ test safe-8.7 {safe source control on file} -setup {
unset log
safe::interpDelete $i
} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
-test safe-8.8 {safe source forbids -rsrc} -setup {
- catch {safe::interpDelete $i}
- safe::interpCreate $i
-} -body {
- $i eval {source -rsrc Init}
-} -returnCodes error -cleanup {
- safe::interpDelete $i
-} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.8 {safe source forbids -rsrc} emptyTest {
+ # Disabled this test. It was only useful for long unsupported
+ # Mac OS 9 systems. [Bug 860a9f1945]
+} {}
test safe-8.9 {safe source and return} -setup {
set returnScript [makeFile {return "ok"} return.tcl]
catch {safe::interpDelete $i}
diff --git a/tests/tailcall.test b/tests/tailcall.test
index ce506a7..9174167 100644
--- a/tests/tailcall.test
+++ b/tests/tailcall.test
@@ -688,6 +688,26 @@ if {[testConstraint testnrelevels]} {
namespace delete testnre
}
+test tailcall-14.1 {in a deleted namespace} -body {
+ namespace eval ns {
+ proc p args {
+ tailcall [namespace current] $args
+ }
+ namespace delete [namespace current]
+ p
+ }
+} -returnCodes 1 -result {namespace "::ns" not found}
+
+test tailcall-14.1-bc {{in a deleted namespace} {byte compiled}} -body {
+ namespace eval ns {
+ proc p args {
+ tailcall [namespace current] {*}$args
+ }
+ namespace delete [namespace current]
+ p
+ }
+} -returnCodes 1 -result {namespace "::ns" not found}
+
# cleanup
::tcltest::cleanupTests
diff --git a/tests/tcltest.test b/tests/tcltest.test
index 17fa926..0bcf342 100644
--- a/tests/tcltest.test
+++ b/tests/tcltest.test
@@ -908,7 +908,9 @@ removeFile load.tcl
# [interpreter]
test tcltest-13.1 {interpreter} {
+ -constraints notValgrind
-setup {
+ #to do: Why is $::tcltest::tcltest being saved and restored here?
set old $::tcltest::tcltest
set ::tcltest::tcltest tcltest
}
@@ -920,6 +922,11 @@ test tcltest-13.1 {interpreter} {
}
-result {tcltest tclsh tclsh}
-cleanup {
+ # writing ::tcltest::tcltest triggers a trace that sets up the stdio
+ # constraint, which involves a call to [exec] that might fail after
+ # "fork" and before "exec", in which case the forked process will not
+ # have a chance to clean itself up before exiting, which causes
+ # valgrind to issue numerous "still reachable" reports.
set ::tcltest::tcltest $old
}
}
diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl
new file mode 100644
index 0000000..74d1b40
--- /dev/null
+++ b/tests/tcltests.tcl
@@ -0,0 +1,11 @@
+#! /usr/bin/env tclsh
+
+package require tcltest 2.2
+namespace import ::tcltest::*
+
+testConstraint exec [llength [info commands exec]]
+testConstraint fcopy [llength [info commands fcopy]]
+testConstraint fileevent [llength [info commands fileevent]]
+testConstraint thread [
+ expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
diff --git a/tests/thread.test b/tests/thread.test
index cc4c871..eaaaa41 100644
--- a/tests/thread.test
+++ b/tests/thread.test
@@ -11,25 +11,19 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest 2.2
- namespace import -force ::tcltest::*
-}
+
+# when thread::release is used, -wait is passed in order allow the thread to
+# be fully finalized, which avoids valgrind "still reachable" reports.
+
+package require tcltests
::tcltest::loadTestedCommands
catch [list package require -exact Tcltest [info patchlevel]]
# Some tests require the testthread command
-testConstraint testthread [expr {[info commands testthread] != {}}]
-
-# Some tests require the Thread package
-
-testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint testthread [expr {[info commands testthread] ne {}}]
-# Some tests may not work under valgrind
-
-testConstraint notValgrind [expr {![testConstraint valgrind]}]
set threadSuperKillScript {
rename catch ""
@@ -72,6 +66,17 @@ proc ThreadError {id info} {
set threadSawError($id) true; # signal main thread to exit [vwait].
}
+proc threadSuperKill id {
+ variable threadSuperKillScript
+ try {
+ thread::send $id $::threadSuperKillScript
+ } on error {tres topts} {
+ if {$tres ne {target thread died}} {
+ return -options $topts $tres
+ }
+ }
+}
+
if {[testConstraint thread]} {
thread::errorproc ThreadError
}
@@ -96,22 +101,22 @@ test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
set serverthread [thread::create -preserved]
set numthreads [llength [thread::names]]
- thread::release $serverthread
+ thread::release -wait $serverthread
set numthreads
-} {2}
+} 2
test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
thread::create {set x 5}
foreach try {0 1 2 4 5 6} {
- # Try various ways to yield
- update
- after 10
- set l [llength [thread::names]]
- if {$l == 1} {
- break
- }
+ # Try various ways to yield
+ update
+ after 10
+ set l [llength [thread::names]]
+ if {$l == 1} {
+ break
+ }
}
set l
-} {1}
+} 1
test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
thread::create {{*}{}}
update
@@ -121,13 +126,13 @@ test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
set serverthread [thread::create -preserved]
set five [thread::send $serverthread {set x 5}]
- thread::release $serverthread
+ thread::release -wait $serverthread
set five
} 5
test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
set five [thread::send $serverthread {set z}]
- thread::release $serverthread
+ thread::release -wait $serverthread
set five
} 5
@@ -159,7 +164,7 @@ test thread-3.1 {TclThreadList} {thread} {
set l2 [thread::names]
set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
foreach t $l1 {
- thread::release $t
+ thread::release -wait $t
}
list $len $c
} {1 0}
@@ -887,7 +892,7 @@ test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainE
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::cancel $serverthread]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -929,7 +934,7 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::cancel $serverthread]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1029,7 +1034,7 @@ test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode lo
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {interp cancel}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1071,7 +1076,7 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {interp cancel}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1111,7 +1116,7 @@ test thread-7.30 {cancel: send async thread cancel nested catch inside pure byte
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
@@ -1153,7 +1158,7 @@ test thread-7.31 {cancel: send async thread cancel nested catch pure inside-comm
# wait for other thread to signal "ready to cancel"
vwait ::threadIdStarted; after 1000
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
- thread::send $serverthread $::threadSuperKillScript
+ threadSuperKill $serverthread
vwait ::threadSawError($serverthread)
thread::join $serverthread; drainEventQueue
list $res [expr {[info exists ::threadIdStarted] ? \
diff --git a/tests/utf.test b/tests/utf.test
index 9dd8017..e820359 100644
--- a/tests/utf.test
+++ b/tests/utf.test
@@ -44,6 +44,18 @@ test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring {
test utf-1.7 {Tcl_UniCharToUtf: 4 byte sequences} -constraints testbytestring -body {
expr {"\U014e4e" eq [testbytestring "\xf0\x94\xb9\x8e"]}
} -result 1
+test utf-1.8 {Tcl_UniCharToUtf: 3 byte sequence, upper surrogate} testbytestring {
+ expr {"\ud842" eq [testbytestring "\xed\xa1\x82"]}
+} 1
+test utf-1.9 {Tcl_UniCharToUtf: 3 byte sequence, lower surrogate} testbytestring {
+ expr {"\udc42" eq [testbytestring "\xed\xb1\x82"]}
+} 1
+test utf-1.10 {Tcl_UniCharToUtf: 3 byte sequence, upper surrogate} testbytestring {
+ expr {[format %c 0xd842] eq [testbytestring "\xed\xa1\x82"]}
+} 1
+test utf-1.11 {Tcl_UniCharToUtf: 3 byte sequence, lower surrogate} testbytestring {
+ expr {[format %c 0xdc42] eq [testbytestring "\xed\xb1\x82"]}
+} 1
test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
string length "abc"
@@ -146,6 +158,12 @@ test utf-8.3 {Tcl_UniCharAtIndex: index > 0} {
test utf-8.4 {Tcl_UniCharAtIndex: index > 0} {
string index \u4e4e\u25a\xff\u543 2
} "\uff"
+test utf-8.5 {Tcl_UniCharAtIndex: upper surrogate} {
+ string index \ud842 0
+} "\ud842"
+test utf-8.5 {Tcl_UniCharAtIndex: lower surrogate} {
+ string index \udc42 0
+} "\udc42"
test utf-9.1 {Tcl_UtfAtIndex: index = 0} {
string range abcd 0 2
@@ -251,6 +269,9 @@ test utf-11.4 {Tcl_UtfToUpper} {
test utf-11.5 {Tcl_UtfToUpper Georgian (new in Unicode 11)} {
string toupper \u10d0\u1c90
} \u1c90\u1c90
+test utf-11.6 {Tcl_UtfToUpper low/high surrogate)} {
+ string toupper \udc24\ud824
+} \udc24\ud824
test utf-12.1 {Tcl_UtfToLower} {
string tolower {}
@@ -267,6 +288,9 @@ test utf-12.4 {Tcl_UtfToLower} {
test utf-12.5 {Tcl_UtfToLower Georgian (new in Unicode 11)} {
string tolower \u10d0\u1c90
} \u10d0\u10d0
+test utf-12.6 {Tcl_UtfToUpper low/high surrogate)} {
+ string tolower \udc24\ud824
+} \udc24\ud824
test utf-13.1 {Tcl_UtfToTitle} {
string totitle {}
@@ -286,6 +310,9 @@ test utf-13.5 {Tcl_UtfToTitle Georgian (new in Unicode 11)} {
test utf-13.6 {Tcl_UtfToTitle Georgian (new in Unicode 11)} {
string totitle \u1c90\u10d0
} \u1c90\u10d0
+test utf-13.7 {Tcl_UtfToTitle low/high surrogate)} {
+ string totitle \udc24\ud824
+} \udc24\ud824
test utf-14.1 {Tcl_UtfNcasecmp} {
string compare -nocase a b