Help: my Gradle script hangs during "build" at end of tests

My Gradle script hangs during “build” at end of tests.

The last test finishes and the WebBrowser (Selenium webdriver) object is not cleaned up (this is intentional)

but the test task of “build” is not letting go until I manually kill the webbrowser.

The last unit test certainly finishes ( see below) and yet it doesn’t let go.

Is this a bug in the Gradle JUnit runner?

(note : this question is similar to http://forums.gradle.org/gradle/topics/build_hangs_for_5_minutes_after_tests_finish_executing_m9 )

....
    Closing window with title "Crystal Reports Viewer".
    Finished test "WebEReport"
  my.application.reports.global.WebEReport > testWebEReport PASSED
  41 tests completed, 26 failed
:core:application:test FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':core:application:test'.
> There were failing tests. See the report at: file:///C:/Eclipse/workspace/MyTests/core/application/build/reports/tests/index.html
  * Try:
Run with --info or --debug option to get more log output.
  * Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':core:application:test'.
 at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:68)
 at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
 at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:34)
 at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter$1.run(CacheLockHandlingTaskExecuter.java:34)
 at org.gradle.cache.internal.DefaultCacheAccess$3.create(DefaultCacheAccess.java:243)
 at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:188)
 at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:241)
 at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:137)
 at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:83)
 at org.gradle.api.internal.changedetection.CacheLockHandlingTaskExecuter.execute(CacheLockHandlingTaskExecuter.java:32)
 at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:55)
 at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)
 at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:41)
 at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
 at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:52)
 at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:42)
 at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:247)
 at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.executeTask(DefaultTaskPlanExecutor.java:52)
 at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.processTask(DefaultTaskPlanExecutor.java:38)
 at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:30)
 at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:83)
 at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
 at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
 at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
 at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
 at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter$1.run(TaskCacheLockHandlingBuildExecuter.java:31)
 at org.gradle.cache.internal.DefaultCacheAccess$2.create(DefaultCacheAccess.java:118)
 at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:133)
 at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:116)
 at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:129)
 at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.useCache(DefaultTaskArtifactStateCacheAccess.java:79)
 at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter.execute(TaskCacheLockHandlingBuildExecuter.java:29)
 at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
 at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
 at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)
 at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
 at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)
 at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)
 at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:158)
 at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113)
 at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81)
 at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:63)
 at org.gradle.tooling.internal.provider.DelegatingBuildModelAction.run(DelegatingBuildModelAction.java:44)
 at org.gradle.tooling.internal.provider.ConfiguringBuildAction.run(ConfiguringBuildAction.java:95)
 at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:39)
 at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:45)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:42)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:70)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:68)
 at org.gradle.util.Swapper.swap(Swapper.java:38)
 at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:68)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:61)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:45)
 at org.gradle.launcher.daemon.server.DaemonStateCoordinator.runCommand(DaemonStateCoordinator.java:185)
 at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49)
 at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:36)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32)
 at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:126)
 at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:52)
 at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.handleCommand(DefaultIncomingConnectionHandler.java:142)
 at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.run(DefaultIncomingConnectionHandler.java:116)
 at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
Caused by: org.gradle.api.GradleException: There were failing tests. See the report at: file:///C:/Eclipse/workspace/MyTests/core/application/build/reports/tests/index.html
 at org.gradle.api.tasks.testing.Test.handleTestFailures(Test.java:982)
 at org.gradle.api.tasks.testing.Test.executeTests(Test.java:413)
 at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:216)
 at org.gradle.api.internal.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:122)
 at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:147)
 at org.gradle.api.tasks.testing.Test_Decorated.invokeMethod(Unknown Source)
 at org.gradle.util.ReflectionUtil.invoke(ReflectionUtil.groovy:23)
 at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:161)
 at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$4.execute(AnnotationProcessingTaskFactory.java:156)
 at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:472)
 at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:461)
 at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:60)
 ... 79 more

It’s a bug in Selenium. It’s opening non daemonised threads that are holding the test JVM open.

Are you using the latest version of selenium?

Yes, I use Gradle dependency management, which assures me I am on the latest Selenium at all times: currently 2.28

Since this is the case, is it possible to code something that could kill the hung Selenium threads? Personally, I don’t think its a Selenium bug since this problem does not occur when running these tests (without using Gradle) from a JUnit test suite class.

What driver are you using?

In this case it is WebDriver Firefox .

If I put a “kill browser” at the end of the last test in the suite, then it wraps up correctly.

Maybe its something I am doing wrong? My instance of WebDriver is a statically imported member available to all tests: do you think that would cause it?

Maybe a JUNit test can’t garbage collect a static member that is not part of the particular test?

Here is a sample project I made that shows a general idea of how I am doing it: https://github.com/djangofan/WebDriverTestingTemplate

what do I need to do with this project to reproduce the behaviour?

I am suspecting (thought I don’t know for sure) that if you checked out my project and then removed the “driver.close()” methods from all tearDown methods in all tests, that it might reproduce the issue. I will try it myself sometime during the next week and try to comment on this thread again.

Luke,

Ok, I have my project arranged so that you should be able to run it (without Eclipse) and reproduce the problem.

Just checkout my project from GitHub and run the “gradle.bat --gui” and run this favorite:

identify core:show core:clean core:build core:google:show core:google:clean core:google:build

https://github.com/djangofan/WebDriverTestingTemplate

The tests will hang after the last test is finished executing the @AfterClass method.

To force the tests to completely finish, just manually close the browser at the end of the tests and the test report will be generated.

I also provide a “gradle_run.bat” script at the root of my project if you prefer to use that.

Thanks for your help. I don’t imaging that looking at this would take you more than 5-10 minutes.

-Jon

Getting a compilation error with master/HEAD…

/Users/ld/Projects/WebDriverTestingTemplate/core/google/src/main/java/qa/webdriver/util/GoogleSearchPage.java:52: error: cannot find symbol

selectInGoogleDropdown( ele );

^

symbol:

method selectInGoogleDropdown(String)

location: class GoogleSearchPage.GSPFluentInterface 1 error

Is there a stable commit I can use?

Yes, the last Jan 13th commit is good.

I broke a couple things on the 14th when I implemented some changes but I will fix those tonight (the 15th).

Also, do you think this problem I am having is related to this bug? http://issues.gradle.org/browse/GRADLE-2622

or http://issues.gradle.org/browse/GRADLE-1638

Luke, I fixed the code. Now todays build January 15th AM will work.

I had changed how the logging works and broke some things but now they are fixed I think. I downoaded the .zip project archive and verified it runs out-of-the-box and is able to reproduce this issue.

Ok, I think I figured out what the problem might be.

My “closeAllBrowserWindows()” method isn’t working correctly.

Until I figure out why it isn’t working, I am still looking for the absolute solution.

I spent more time on this and still couldn’t figure it out.

I posted to Stack Overflow in hopes of getting an answer from someone who knows the JUnit parameterized tests better.

http://stackoverflow.com/questions/14372191/my-junit-test-locks-up-because-a-static-object-cant-be-cleaned-up-before-afterc

Ok, I finally resolved the bug.

I just need to add a “driver.quit()” call to my “closeAllBrowserWindows()” method.

Evidently, “driver.close()” was not enough to release the resources completely.