From 84d92dce1f2c07dc6a7b9f6dbd2743635d45ca77 Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Thu, 18 Feb 2016 10:05:20 +0000 Subject: [PATCH] Bug 472765: Fix occasional exception during test There was a race condition between commandTimedOutDuringSession finishing and the next test starting that checked for unterminated launches (in BaseTestCase removeTeminatedLaunchesBeforeTest). While commandTimedOutDuringSession did wait for the shutdown to be received (ICommandControlShutdownDMEvent), that can happen a few ms before the launch is fully terminated (fLaunch.isTerminated() == true) Change-Id: Ib4e6655938f6b0e3ab3ce89fd06528f1b72ee04d Signed-off-by: Jonah Graham --- .../tests/dsf/gdb/framework/BaseTestCase.java | 16 +++++++++++++--- .../tests/dsf/gdb/tests/CommandTimeoutTest.java | 14 +++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java index 8583cf90a43..8ee9698b9af 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/BaseTestCase.java @@ -403,16 +403,26 @@ public class BaseTestCase { } - @After - public void doAfterTest() throws Exception { + /** + * Assert that the launch terminates. Callers should have already + * terminated the launch in some way. + */ + protected void assertLaunchTerminates() throws Exception { if (fLaunch != null) { - fLaunch.terminate(); // Give a few seconds to allow the launch to terminate int waitCount = 100; while (!fLaunch.isTerminated() && --waitCount > 0) { Thread.sleep(TestsPlugin.massageTimeout(100)); } assertTrue("Launch failed to terminate before timeout", fLaunch.isTerminated()); + } + } + + @After + public void doAfterTest() throws Exception { + if (fLaunch != null) { + fLaunch.terminate(); + assertLaunchTerminates(); fLaunch = null; } } diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java index 29c5d56b895..664a608b57f 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/CommandTimeoutTest.java @@ -129,6 +129,11 @@ public class CommandTimeoutTest extends BaseTestCase { // Make sure we receive a shutdown event to confirm we have aborted the session shutdownEventWaitor.waitForEvent(TestsPlugin.massageTimeout(5000)); + + // It can take a moment from when the shutdown event is received to when + // the launch is actually terminated. Make sure that the launch does + // terminate itself. + assertLaunchTerminates(); } /** @@ -165,12 +170,15 @@ public class CommandTimeoutTest extends BaseTestCase { /** * Checks whether the given exception is an instance of {@link CoreException} * with the status code 20100 which indicates that a gdb command has been timed out. + * 20100 comes from GDBControl.STATUS_CODE_COMMAND_TIMED_OUT which is private */ private void processException( Exception e ) { Throwable t = getExceptionCause( e ); - Assert.assertTrue( - "Unexpected exception", - t instanceof CoreException && ((CoreException)t).getStatus().getCode() == 20100 ); + if (t instanceof CoreException && ((CoreException)t).getStatus().getCode() == 20100) { + // this is the exception we are looking for + return; + } + throw new AssertionError("Unexpected exception", e); } private Throwable getExceptionCause(Throwable e) {