Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tcltest unable to remove files - permission denied

821 views
Skip to first unread message

Glenn Halstead

unread,
Jun 1, 2004, 6:48:49 PM6/1/04
to
Hi Folks,

I have a problem with tcltest not being able to remove files it has created.

I use tcltest::makeFile to create the file and tcltest::removeFile to
remove it but I get a permission denied error.

I reported this (or very similar) problem some time ago when I was on
win98 and was advised to raise a tip against it - I never did because I
had no problem on linux at work so I assumed it was just a win 98 thing
and hence wouldn't be encountered by many folks.

Has anyone seen this problem?

Here's the tcltest script:

### Start

if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
}
eval tcltest::configure $argv
tcltest::configure -verbose error


# tcltest::removeFile test.
tcltest::test "removefile_1" "create and remove afile" -setup {
# Create empty file.
tcltest::makeFile "" bob.cfg
} -body {
set lFilePtr [open bob.cfg]
set lBobContent [read $lFilePtr]
return $lBobContent
} -cleanup {
# Remove file
tcltest::removeFile bob.cfg
} \
-returnCodes "0" \
-result ""

::tcltest::cleanupTests
return

### End

Thanks for any help

Glenn

Don Porter

unread,
Jun 1, 2004, 7:08:24 PM6/1/04
to
Glenn Halstead wrote:
> I use tcltest::makeFile to create the file and tcltest::removeFile to
> remove it but I get a permission denied error.

Please file this as a bug report so it doesn't get forgotten.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Don Porter

unread,
Jun 1, 2004, 7:20:15 PM6/1/04
to
Glenn Halstead wrote:
> Has anyone seen this problem?

Take a good look at the test; it's broken:

> tcltest::test "removefile_1" "create and remove afile" -setup {
> # Create empty file.
> tcltest::makeFile "" bob.cfg
> } -body {
> set lFilePtr [open bob.cfg]
> set lBobContent [read $lFilePtr]
> return $lBobContent

Here you use [return], causing the body script to have
a return code of TCL_RETURN (= 2), but...

> } -cleanup {
> # Remove file
> tcltest::removeFile bob.cfg
> } \
> -returnCodes "0" \

Here you insist that the return code must be TCL_OK (= 0).
That mismatch causes the test to fail.

> -result ""

Even though the test is failing, the [removeFile] in the
cleanup script is removing the file that [makeFile] created.
What made you think it was not?

Glenn Halstead

unread,
Jun 1, 2004, 7:48:19 PM6/1/04
to
Hi Don,

I didn't think the return was a problem but I have changed it to set
instead.

I've trimmed the test down and included the output:

Test script
-----


if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
}
eval tcltest::configure $argv
tcltest::configure -verbose error

# tcltest::removeFile test.


tcltest::test "removefile_1" "create and remove afile" -setup {
# Create empty file.
tcltest::makeFile "" bob.cfg
} -body {
set lFilePtr [open bob.cfg]
set lBobContent [read $lFilePtr]

} -cleanup {
# Remove file
tcltest::removeFile bob.cfg

} -result ""

::tcltest::cleanupTests
return
--------
end script

Output
------
D:\TCL\CoDo\codo.vfs\lib\app-codo>tclsh testfile.test

==== removefile_1 create and remove afile FAILED
---- Result was:


---- Result should have been (exact matching):

---- Test cleanup failed:
error deleting "D:/TCL/CoDo/codo.vfs/lib/app-codo/bob.cfg": permission
denied
==== removefile_1 FAILED

testfile.test: Total 1 Passed 0 Skipped 0 Failed 1
Warning: files left behind:
testfile.test: bob.cfg

D:\TCL\CoDo\codo.vfs\lib\app-codo>
-------
End output

Message has been deleted

Darren New

unread,
Jun 2, 2004, 12:14:35 AM6/2/04
to
Glenn Halstead wrote:
> I use tcltest::makeFile to create the file and tcltest::removeFile to
> remove it but I get a permission denied error.

You open the file for reading, but you never close it in the body. Tcl
under Windows opens files for reading without delete privileges (i.e.,
you're not allowed to delete it while it's open).

Try adding "close lFilePtr" before the return in the body.

Steve Bold

unread,
Jun 2, 2004, 12:20:59 AM6/2/04
to
It appears that you are opening and reading from channel $lFilePtr
but never closing it.

On UNIX, you can delete an open file, on PC you cannot.

"Glenn Halstead" <gl...@abc.glennh.com> wrote in message news:984638667288b6ab...@news.teranews.com...

Glenn Halstead

unread,
Jun 2, 2004, 1:56:24 AM6/2/04
to
Thanks for this Darren, you helped me get to the bottom of the problem.
Here's a bit more of the story:

I'm using tdom to parse xml files. (code snippet:

set lFilePtr [open $aPath]
set lXmlDocPtr [dom parse -channel $lFilePtr]
close $lFilePtr


One of my tcltests uses a badly formed xml file. tdom throws an error
(as expected) when parsing the file BUT it seems that it retains the
file channel and the 'close $lFilePtr' command is not working and not
throwing an error.

My code now looks like this which works fine:

set lFilePtr [open $aPath]
set lXmlData [read $lFilePtr]
close $lFilePtr
set lXmlDocPtr [dom parse $lXmlData]

You see I'm not giving tdom access to the file channel.

I'll see about logging a defect with the tdom project.

Thanks to all for your help

Glenn

Ralf Fassel

unread,
Jun 2, 2004, 5:16:34 AM6/2/04
to
* Glenn Halstead <gl...@abc.glennh.com>

| I'm using tdom to parse xml files. (code snippet:
|
| set lFilePtr [open $aPath]
| set lXmlDocPtr [dom parse -channel $lFilePtr]
| close $lFilePtr
--<snip-snip>--

| I'll see about logging a defect with the tdom project.

I don't think this is a problem in tdom. Just `catch' the `parse' and
handle the error after closing the channel.

set lXmlDocPtr [dom parse -channel $lFilePtr]

=>
set err [catch {dom parse -channel $lFilePtr} lXmlDocPtr]
close $lFilePtr
if {$err} {
error $lXmlDocPtr
}

R'


Glenn Halstead

unread,
Jun 2, 2004, 5:21:37 PM6/2/04
to
Hi Ralf et all,

Well this is turning into fun. I am back to blaming tcltest -
specifically how it deals with error return codes. (no, hang on, we
don't have a 'blame' culture here do we ;-)

I have two minimal scripts which test / demonstrate the behavior of the
tdom 'dom parse -channel' command:

The first uses pure tcl with 'catch' to catch the expected error from
tdom due to the badly formed xml.

The second uses tcltest to do the same thing.

The pure tcl script behaves just as expected. The test.xml file is
deleted successfully.

The tcltest script fails to delete the test.xml file - permission denied.

The difference here is between using catch in the pure tcl script and
the error catching mechanism in the tcltest script.

The two scripts are below and rely on tdom 0.7.8 being available.

any thoughts?

Glenn


Pure tcl script
---------------
# Get tdom package.
lappend auto_path .
package require tdom 0.7.8

# Create bad xml file.
set lXmlData {testdata>
<child1>Text for child 1</child1>
<child2></child2>
</testdata>
}
set lFilePtr [open test.xml w]
puts $lFilePtr $lXmlData
close $lFilePtr

# Open the xml file and parse it using tdom, using catch to catch the
expected error.
set lFilePtr [open test.xml]
set lReturn [catch {dom parse -channel $lFilePtr} lResult]
close $lFilePtr
puts "dom parse -channel $lFilePtr return: $lReturn"
puts "dom parse -channel $lFilePtr result: $lResult"

# Delete the test.xml file.
file delete test.xml


Tcltest script
--------------
# Get tdom package.
lappend auto_path .
package require tdom 0.7.8

# Get tcltest package.
package require tcltest 2
tcltest::configure -verbose error

# tcltest test.
tcltest::test "GetRoot" "Bad xml file." -setup {
# Create bad xml file.
set lXmlData {testdata>
<child1>Text for child 1</child1>
<child2></child2>
</testdata>
}
tcltest::makeFile $lXmlData test.xml
} -body {
# Open the xml file and parse it using tdom.
# An error will be thrown due to the badly formed xml.
# The tcltest option -ReturnCodes "1" will deal with this
# e.g. thats how we tell tcltest that we expect an error.
set lFilePtr [open test.xml]
set lRootNode [dom parse -channel $lFilePtr]
close $lFilePtr
} -cleanup {
# Delete the test.xml file.
tcltest::removeFile test.xml
} \
-returnCodes "1" \
-result "error \"syntax error\" at line \[0-9\] character \[0-9\]" \
-match regexp

::tcltest::cleanupTests

Bruce Hartweg

unread,
Jun 2, 2004, 6:20:14 PM6/2/04
to

Glenn Halstead wrote:

> Hi Ralf et all,
>
> Well this is turning into fun. I am back to blaming tcltest -
> specifically how it deals with error return codes. (no, hang on, we
> don't have a 'blame' culture here do we ;-)
>
> I have two minimal scripts which test / demonstrate the behavior of the
> tdom 'dom parse -channel' command:
>
> The first uses pure tcl with 'catch' to catch the expected error from
> tdom due to the badly formed xml.
>
> The second uses tcltest to do the same thing.
>
> The pure tcl script behaves just as expected. The test.xml file is
> deleted successfully.
>
> The tcltest script fails to delete the test.xml file - permission denied.
>
> The difference here is between using catch in the pure tcl script and
> the error catching mechanism in the tcltest script.
>
> The two scripts are below and rely on tdom 0.7.8 being available.
>
> any thoughts?
>

The problem is still in your script, not with tcltest.

by not having your own catch, you are indeed relying on tcltest
to catch for you - which works - the scruipt doesn't completly
abort. The problem is when dom errors none of the rest of your body
executes - meaning that the file is NOT being closed, meaning that
you cannot delete it. You still need to catch the error yourself
so you can close the file - you can then retrhow the erro if desired.
You could also read the data as a string, close the file, then try
the [dom parse ...] so if it errors you are not left with open files.

Bruce

Glenn Halstead

unread,
Jun 2, 2004, 6:55:44 PM6/2/04
to
Hi Bruce.

OK, thanks for clearing that up, I will take that action in my tcltest
scripts in future.

I have already done as you suggest - reading the file contents into a
string and sending that to dom parse in my application. I was following
this up to understand exactly what was the cause.

Thanks to all who commented, I do have a better understanding of exactly
what's happening in my tcltests now.

Cheers

Glenn

Don Porter

unread,
Jun 2, 2004, 7:22:17 PM6/2/04
to
Glenn Halstead wrote:
> tcltest::test "GetRoot" "Bad xml file." -setup {
> # Create bad xml file.
> set lXmlData {testdata>
> <child1>Text for child 1</child1>
> <child2></child2>
></testdata>
> }
> tcltest::makeFile $lXmlData test.xml
> } -body {
> # Open the xml file and parse it using tdom.
> # An error will be thrown due to the badly formed xml.

You expect an error.

> # The tcltest option -ReturnCodes "1" will deal with this
> # e.g. thats how we tell tcltest that we expect an error.
> set lFilePtr [open test.xml]
> set lRootNode [dom parse -channel $lFilePtr]

You expect the command above to error...

> close $lFilePtr

So you expect the [close] not to be reached.

> } -cleanup {

So your [close] really belongs here in the
cleanup script, so it will run even when the
body script errors.

If you want to be really careful, use
[catch {close $lFilePtr}] just in case
the [open] failed.

> # Delete the test.xml file.
> tcltest::removeFile test.xml
> } \
> -returnCodes "1" \

See, you expect the error, so write your test to
handle it.

> -result "error \"syntax error\" at line \[0-9\] character \[0-9\]" \
> -match regexp

--

R. T. Wurth

unread,
Jun 2, 2004, 8:28:41 PM6/2/04
to
In article <6479e1f2c3ed762b...@news.teranews.com>, Glenn Halstead <gl...@abc.glennh.com> wrote:
> Hi Ralf et all,
>
> Well this is turning into fun. I am back to blaming tcltest -
> specifically how it deals with error return codes. (no, hang on, we
> don't have a 'blame' culture here do we ;-)
>
> I have two minimal scripts which test / demonstrate the behavior of the
> tdom 'dom parse -channel' command:
>
[..]

> any thoughts?
>
> Glenn
>
>
> Pure tcl script
> ---------------
> # Get tdom package.
> lappend auto_path .
> package require tdom 0.7.8
>
> # Create bad xml file.
> set lXmlData {testdata>
> <child1>Text for child 1</child1>
> <child2></child2>
> </testdata>
> }
> set lFilePtr [open test.xml w]
> puts $lFilePtr $lXmlData
> close $lFilePtr
>
[...]

I'm not all that familiar with tcltest, but it looks like either
their a cut/paste error, or your -setup clause isn't really
creating the file at all. I see you setting up the string you
intend to write, but I don't see the [open] or the [puts] that
would be needed to write the string to the file.
--
Rich Wurth / rwu...@att.net / Rumson, NJ USA

Glenn Halstead

unread,
Jun 3, 2004, 4:54:52 AM6/3/04
to
Ahhhhhhhhhhh...... click........ of course......... Doh!, goes the brain.

Thanks Don

Glenn

Glenn Halstead

unread,
Jun 3, 2004, 8:44:16 AM6/3/04
to
tcltest::makeFile 'contents' 'filename' 'optional directory' creates the
file

Glenn

GlennH

unread,
Jun 3, 2004, 4:28:07 PM6/3/04
to
Don Porter wrote:

Hi Don,

There was something nagging at the back of my mind.......

In my real code The file is opened and the file pointer is stored in a
local variable. This means the value of the file pointer is not
available in the scope of the tcltest.

Glenn

Don Porter

unread,
Jun 3, 2004, 4:45:45 PM6/3/04
to
| tcltest::test "GetRoot" "Bad xml file." -setup {
| set lXmlData {testdata>
| <child1>Text for child 1</child1>
| <child2></child2>
| </testdata>
| }
| tcltest::makeFile $lXmlData test.xml
| } -body {
| set lFilePtr [open test.xml]
| set lRootNode [dom parse -channel $lFilePtr]
| } -cleanup {
| close $lFilePtr

| tcltest::removeFile test.xml
| } \
| -returnCodes 1 \
| -result {error "syntax error" at line [0-9] character [0-9]} \
| -match regexp

GlennH wrote:
> In my real code The file is opened and the file pointer is stored in a
> local variable. This means the value of the file pointer is not
> available in the scope of the tcltest.

I don't follow what you mean by a "local variable". Are you testing
the functioning of a proc? If so, then shouldn't part of the
proper operation of that proc be the proper cleanup of resources
before the proc is allowed to exit, even in the event of an error?

GlennH

unread,
Jun 3, 2004, 5:14:33 PM6/3/04
to
Yup......... It is now :-)

Glenn

0 new messages