I decided to try and get my code running on Windows… On Appveyor, the following code:
mktempdir() do tmpdir
cd(tmpdir)
info("running tests in: $(pwd())")
run_all_tests()
end
appears to fail at the end, with the error:
ERROR: LoadError: SystemError (with C:\Users\appveyor\AppData\Local\Temp\1\jl_59FC.tmp): rmdir: Permission denied
Stacktrace:
[1] #systemerror#51 at .\error.jl:64 [inlined]
[2] (::Base.#kw##systemerror)(::Array{Any,1}, ::Base.#systemerror, ::Symbol, ::Bool) at .\<missing>:0
[3] #rm#7(::Bool, ::Bool, ::Function, ::String) at .\file.jl:159
[4] (::Base.Filesystem.#kw##rm)(::Array{Any,1}, ::Base.Filesystem.#rm, ::String) at .\<missing>:0
[5] mktempdir(::##1#2, ::String) at .\file.jl:388
[6] mktempdir(::Function) at .\file.jl:384
[7] include_from_node1(::String) at .\loading.jl:532
[8] include(::String) at .\sysimg.jl:14
[9] process_options(::Base.JLOptions) at .\client.jl:308
[10] _start() at .\client.jl:374
which I presume is what happens when the mktempdir()
block finishes. Is there some magic incantation which lets the test run with some basic deleting powers? Or have I configured something wrong?
This is probably not an actual permissions issue. If you have permission to mktempdir()
you should have permission to delete. While *nix file systems can de-link inodes with open handles, Windows has no mechanism to delete files in use, and doesn’t return any error more specific than “Permission denied” when failing to delete an open file.
I’m not sure of the best way to deal with this (workspace()
might help), but you could clear tmp data from the driver script – Appveyor yml supports dos and powershell commands – and could likely get away with not doing anything; the test VMs should be reset upon completion.
I think it was Tony who told me I should delete temp files created during testing, but doing it file by file would be painful. Perhaps my test should use the mktempdir
block on *nix only…
Most likely you have file handles still open to something you just created. So it’s not just the creation of the temp dir that needs a do-block, but also opening of any file handles to things you create within it.
I think I’ve fixed this problem. On Unix, you can do this:
mktempdir() do tmpdir
cd(tmpdir)
run_all_tests()
end
But if you want this to run on Windows as well, you must do this:
mktempdir() do tmpdir
olddir = pwd()
cd(tmpdir)
run_all_tests()
cd(olddir)
end
If you’re in a directory, you can’t delete it. (It’s sort of obvious, although it’s easy to say that now!)
Unix lets you do this. But if you do, you can get into trouble:
julia> pwd()
"/private/tmp"
julia> mktempdir() do tmpdir
cd(tmpdir)
....
end
julia> pwd()
ERROR: getcwd: no such file or directory (ENOENT)
in uv_error(::Symbol, ::Int32) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in pwd() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in pwd() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
shell> cd /tmp
ERROR: getcwd: no such file or directory (ENOENT)
in uv_error(::Symbol, ::Int32) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in pwd() at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in repl_cmd(::Cmd, ::Base.Terminals.TTYTerminal) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
in repl_cmd(::Cmd, ::Base.Terminals.TTYTerminal) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
shell> ls
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
Julia to the rescue, though!
julia> cd("/tmp")
julia> readdir()
12-element Array{String,1}:
".DS_Store"
"2794a5d9ca14d45de4fd32232844b4a5"
"587495bd1c52b"
"5877bd5dc6915"
"5879d3cb47af2"
"587e78c1cbfc4"
"58806b685b1c2"
"Atom Crashes"
"com.apple.launchd.sV7M48F9gC"
"com.apple.launchd.ztFinGyRSO"
"hypotrochoid.png"
"stellarium"
2 Likes
cd has a do block form too, so you don’t have to save oldpwd manually.
Ah, that’s good to know. Thanks!
I wonder if it would make sense to have a mktempdir(; cd::Bool=false)
keyword argument that takes care of this correctly with a single try/catch block and a single level of indentation.
1 Like