Summary

When running unit tests on Windows, failures caused by file operation errors often happen.
This is caused for Windows disallows deleting and overwriting a file when a process holds a handle of the file.
This page describes how to avoid those problems.

Contents

hudson.util.IOException2: Failed to clean up temp dirs

This happens in tearDown phase of tests.
This is often caused for JVM holds a handle of a file in a temporary directory, and Windows fails to delete the temporary directory.
You can see what file failed to be deleted in target/sunfire-reports/(Test Class).txt as following:

-------------------------------------------------------------------------------
Test set: hudson.plugins.parameterizedtrigger.test.NodeParametersTest
-------------------------------------------------------------------------------
Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 43.091 sec <<< FAILURE!
test(hudson.plugins.parameterizedtrigger.test.NodeParametersTest)  Time elapsed: 19.291 sec  <<< ERROR!
hudson.util.IOException2: Failed to clean up temp dirs
	at org.jvnet.hudson.test.TemporaryDirectoryAllocator.dispose(TemporaryDirectoryAllocator.java:87)
	at org.jvnet.hudson.test.TestEnvironment.dispose(TestEnvironment.java:53)
	at org.jvnet.hudson.test.HudsonTestCase.tearDown(HudsonTestCase.java:352)
...
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Caused by: java.io.IOException: Unable to delete (The name of file failed to be deleted)
	at hudson.Util.deleteFile(Util.java:266)
	at hudson.Util.deleteRecursive(Util.java:316)
	at hudson.Util.deleteContentsRecursive(Util.java:227)

Unable to delete slave-slaveX.log

This happens when:

This seems happens for a slave node stays opening a log file, it prevents deleting the temporary directory.
This can be resolved with any of following ways:

other files

503 Service Unavailable from Jenkins

This is often caused for a failure in launching Jenkins.
For the problem happens not in a thread a test function runs but in a thread launching a server, you cannot see the root cause from a console output.
You can see the root cause in target/sunfire-reports/TEST-(Test Class).xml as following:

INFO: NO JSP Support for , did not find org.apache.jasper.servlet.JspServlet
May 18, 2013 10:58:54 AM org.mortbay.log.Slf4jLog info
INFO: Copy C:\Users\user\workspace\reproduce-jenkins-17774\target\jenkins-for-test to work\Jetty_0_0_0_0_0_jenkins.for.test___.bj8wp3\webapp
May 18, 2013 10:58:55 AM org.mortbay.log.Slf4jLog warn
WARNING: Failed startup of context org.mortbay.jetty.webapp.WebAppContext@423e36e6{,C:\Users\user\Desktop\workspace\reproduce-jenkins-17774\.\target\jenkins-for-test}
java.io.FileNotFoundException: work\Jetty_0_0_0_0_0_jenkins.for.test___.bj8wp3\webapp\images\48x48\computer-x.png (requested operation can't be performed on file with user-mapped section open)
	at java.io.FileOutputStream.open(Native Method)
	at java.io.FileOutputStream.&lt;init&gt;(FileOutputStream.java:194)
	at java.io.FileOutputStream.&lt;init&gt;(FileOutputStream.java:145)

requested operation can't be performed on file with user-mapped section open

This happens when:

Jenkins webapp directory gets to be overwritten for each test method in Jenkins 1.457 in Windows. It sometimes causes an overwriting failure when some process holds a file in webapp directory. It often happens when TortoiseXXX (like TortoiseGit) is installed.

You can resolve this problem with any of following ways:

temporary directory grows up

JVM uses %TMP% (java.io.tmpdir) as a temporary directory. For example, C:\Users\user\AppData\Local\Temp in Windows 8.
When running a test of a plugin, following directories are created in the temporary directory, where XXXXXXXXXXs are random numbers.

It often happens that these directories are left even after a test finishes. There are several reasons:

%TMP%\hudsonXXXXXXXXXXtest is left even after tests

This happens when:

This can be resolved with any of following ways:

%TMP%\hudsonXXXXXXXXXXtmp is left even after tests

Why %TMP%\hudsonXXXXXXXXXXtmp is left?

This is caused for TestPluginManager expands plugins to that directory.
There are several reasons why this directory is left:

Reason

Jenkins <= 1.509

1.510 <= Jenkins <= 1.518

Jenkins 1.519

1.520 <= Jenkins

No deletion code

x

 

 

 

Plugins are not released

x

x

x

 

Jenkins core caches and keep file handles

 

 

x

x

No deletion code

The deletion code is introduced in a4d4305124 (1.510).
Do as #Plugins are not released.

Plugins are not released

Jenkins tries to delete the directory, but you see following logs (the name of the jar file may differ):

...
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 30.876 sec
Failed to load native POSIX impl; falling back on Java impl. Unsupported OS.
java.io.IOException: Unable to delete C:\Users\user\AppData\Local\Temp\hudson4413809435965306193tmp\credentials\WEB-INF\lib\findbugs-annotations-1.3.9-1.jar
	at hudson.Util.deleteFile(Util.java:256)
	at hudson.Util.deleteRecursive(Util.java:308)
	at hudson.Util.deleteContentsRecursive(Util.java:205)
	at hudson.Util.deleteRecursive(Util.java:299)
	at hudson.Util.deleteContentsRecursive(Util.java:205)
	at hudson.Util.deleteRecursive(Util.java:299)
	at hudson.Util.deleteContentsRecursive(Util.java:205)
	at hudson.Util.deleteRecursive(Util.java:299)
	at hudson.Util.deleteContentsRecursive(Util.java:205)
	at hudson.Util.deleteRecursive(Util.java:299)
	at org.jvnet.hudson.test.TestPluginManager$1.run(TestPluginManager.java:130)

Results :

Tests run: 7, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

This directory contains jar files, JVM holds the handle of these files, and the deletion of this directory triggered by JVM fails.

You can resolve this problem with following steps:

Here are sample codes:

Jenkins core caches and keep file handles

Jenkins packs files of each plugin into classes.jar to improve performance since 1.519 (f7330d7).
This is caused as JVM (to be exact, URLConnection) keeps file handles of jar files even after Jenkins released them.
You will see outputs like this:

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 62.997 sec - in hudson.plugins.copyartifact.BuildSelectorParameterTest
java.nio.file.FileSystemException: C:\Users\yasuke\AppData\Local\Temp\hudson7190248855254390892tmp\credentials\WEB-INF\lib\classes.jar: The process cannot access the file because it is being used by another process.

        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
        at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
        at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
        at java.nio.file.Files.delete(Files.java:1077)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at hudson.Util.deleteFile(Util.java:247)
        at hudson.Util.deleteRecursive(Util.java:310)
        at hudson.Util.deleteContentsRecursive(Util.java:212)
        at hudson.Util.deleteRecursive(Util.java:301)
        at hudson.Util.deleteContentsRecursive(Util.java:212)
        at hudson.Util.deleteRecursive(Util.java:301)
        at hudson.Util.deleteContentsRecursive(Util.java:212)
        at hudson.Util.deleteRecursive(Util.java:301)
        at hudson.Util.deleteContentsRecursive(Util.java:212)
        at hudson.Util.deleteRecursive(Util.java:301)
        at org.jvnet.hudson.test.TestPluginManager$1.run(TestPluginManager.java:146)

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

You can avoid this problem by disabling cache in URLConnection:

%TMP%\hudson-remotingXXXXXXXXXX, %TMP%\jenkins-remotingXXXXXXXXXX, is left even after tests

Those directories contains winp.dll or winp.x64.dll.
That DLL is generated by winp, Windows process management library and used in hudson.util.ProcessTree.Windows.

For the DLL is linked to JVM while classes in winp are loaded, JVM is unable to delete those directories.

This happens only when slaves are launched in tests.

Tests using symbolic links.