From 1fc777770ed609b7e3084bada24c0833e810a9c1 Mon Sep 17 00:00:00 2001 From: Rene Schneider Date: Wed, 30 Jan 2019 11:18:02 +0100 Subject: [PATCH 1/3] fixes #223: Add console output when waiting for remote to connect --- .../de/gebit/integrity/runner/DefaultTestRunner.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/DefaultTestRunner.java b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/DefaultTestRunner.java index 0c68b7a7e..321fbf16f 100644 --- a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/DefaultTestRunner.java +++ b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/DefaultTestRunner.java @@ -772,6 +772,8 @@ public void run() { if (remotingServer != null && tempBlockForRemoting) { try { + System.out.println( + "WAITING FOR REMOTE CONTROLLER TO CONNECT ON PORT " + remotingServer.getPort() + "..."); performanceLogger.executeAndLog(TestRunnerPerformanceLogger.PERFORMANCE_LOG_CATEGORY_RUNNER, "Wait for Remoting", new TestRunnerPerformanceLogger.RunnableWithException() { @@ -864,8 +866,10 @@ protected void initializeParameterizedConstants() { String tempValue = (parameterizedConstantValues != null) ? parameterizedConstantValues.get(tempName) : null; try { - defineConstant(tempDefinition, tempValue, (tempDefinition.eContainer() instanceof SuiteDefinition) - ? ((SuiteDefinition) tempDefinition.eContainer()) : null); + defineConstant(tempDefinition, tempValue, + (tempDefinition.eContainer() instanceof SuiteDefinition) + ? ((SuiteDefinition) tempDefinition.eContainer()) + : null); } catch (ClassNotFoundException | InstantiationException | UnexecutableException exc) { // Cannot happen - parameterized constants aren't evaluated } @@ -1573,7 +1577,8 @@ protected void defineConstant(final ConstantDefinition aDefinition, Object aValu protected void defineVariable(final VariableOrConstantEntity anEntity, Object anInitialValue, final SuiteDefinition aSuite) { final Object tempInitialValue = (anInitialValue instanceof Variable) - ? variableManager.get(((Variable) anInitialValue).getName()) : anInitialValue; + ? variableManager.get(((Variable) anInitialValue).getName()) + : anInitialValue; // We need to send variable updates to forks in the main phase here. boolean tempSendToForks = (!isFork()) && shouldExecuteFixtures(); From ce9747cf2f26f92073b65050a46ad81c38fe35b4 Mon Sep 17 00:00:00 2001 From: Rene Schneider Date: Wed, 30 Jan 2019 11:18:28 +0100 Subject: [PATCH 2/3] fixes #217: Implement "Pause/Abort at first error" feature in Eclipse --- .../icons/auto_pause_abort_disabled.gif | Bin 0 -> 577 bytes .../icons/auto_pause_abort_on_abort.gif | Bin 0 -> 532 bytes .../icons/auto_pause_abort_on_pause.gif | Bin 0 -> 552 bytes .../views/IntegrityTestRunnerView.java | 137 ++++++++++++++++-- 4 files changed, 126 insertions(+), 11 deletions(-) create mode 100644 de.gebit.integrity.eclipse/icons/auto_pause_abort_disabled.gif create mode 100644 de.gebit.integrity.eclipse/icons/auto_pause_abort_on_abort.gif create mode 100644 de.gebit.integrity.eclipse/icons/auto_pause_abort_on_pause.gif diff --git a/de.gebit.integrity.eclipse/icons/auto_pause_abort_disabled.gif b/de.gebit.integrity.eclipse/icons/auto_pause_abort_disabled.gif new file mode 100644 index 0000000000000000000000000000000000000000..004f4acb6763e9c2d556af75d5b6ffd7531d1bb4 GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*ekRP*ifisKkH&p#KTU|H~_`ib-D)lfEOR@ZUfDe{j@C|Iq)T zQ6GcDKZQpAk4^laSNzh{?tg6B|E$9Q?-&06^Y;Ji$^W1C{J&lF|6b$&N4@`FuKNG( z;Qtd*|1TE&ztZ^sYSaI#&HwLA|9@}J|K~gYpUL@url2}dxFJ-uDO{{GTB1E#q9;yj z|Dy7<-9{(d4bOI)-kD*4f40+uInEE4hQ2*H^J1^r?dcBpXF1)S>2#sj>GA&Q&(Ewo zQKkLv`u?ZO^45gQOmGuFtFL&$M(_W`&a;X#|MPSH=jQ%jy7d2w75~A2VQ>S*pDc_F z3|Y#fvhGEQP=bjxzcj4ChDw?!g*7z+w;7?ozDMpH1W-@=r>bxzs;TV zzq#T6rj0l4ZO$snY^$>Tf2r)t*~U9raqmLIp3R{pc|!Ns*;DV7XP*dgSQ9RDuu%Q#tng=+cHa|H@6}a2n>+V~Pr&o6 z+^adMC){oBY3bjI4!<#N+6yPIM~P|YQxi@&SX>p8K51e7p{(qMfyHYt|C`~#drT}o zWEH$nF?wz1dC@!Ih^+3@mX;SLHqQgYFL?$X5Kwr#Xwm29){lJ?F8hX^3r|0$sDIiq zK+W|e9gyNr7Dfh!I0hY1On~BqfxWOHuBo}DwS|$Xtt*a|t-Fnjo2S2-UqDbuc#4>~ zgrt2Ua;)JtHw}e0J651Ue@#INlRCmm)*Djxzcj4ChDw?!g*7z+w;7?ozDMpH1W-@=r>bxzs#HY zr@8vihLty5ZO$61oZptZw?*va5|0ZzGPYG&{=ZcA0Ruhs5qC>5HqQ zchreq6_eiGqWt6e<{!`3pPui%rAlOboz#!#Th1*F+1{x1#?CscyqPn zk0(oi+@Er0aln>3r5`Uh|9H0Q_#E%G#ey5kC4Rix`s3+}(~Ckk)hPdXf9c2j3rA)L zuPP8+S1Ng8QS6=>!RsrPH&iO`oZz-^cI4h!VLSR<)Lc*ELW)0G7#SGK8FWA~0g4j_ z_SS~-rskH`7DlGFu5wnk?lvxNp8jTj0YM?*DPrOhl2Xz#vfV1GYU&!AT3XuWN~?97 z^$iS-j7>~T&CGXbwb|O)+dDWq9dhn+bNBEp_de~@tCN@s9 mD literal 0 HcmV?d00001 diff --git a/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java index 009ca923a..88c11e842 100644 --- a/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java +++ b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java @@ -559,6 +559,38 @@ public class IntegrityTestRunnerView extends ViewPart { */ private boolean scrollLockActive; + /** + * The action which toggles between normal mode, pause at first error or abort at first error. + */ + private Action pauseAbortAtFirstErrorAction; + + /** + * Whether the test run should be paused when the first error is encountered. + */ + private boolean pauseAtFirstErrorActive; + + /** + * Whether the test run should be aborted when the first error is encountered. + */ + private boolean abortAtFirstErrorActive; + + /** + * Will be set when the {@link #abortAtFirstErrorActive} flag triggers an abortion of test execution. + */ + private boolean lastRunWasAutoAborted; + + /** + * The threshold of accepted test failures before the {@link #pauseAtFirstErrorActive} or + * {@link #abortAtFirstErrorActive} triggers an action. + */ + private int pauseAbortAtFirstErrorFailureThreshold; + + /** + * If the last test run has reported its ending normally. This is used to distinguish between connection losses of + * unexpected nature and such losses that occur because testing has ended. + */ + private boolean lastRunEndStatusReceived; + /** * The last level of node expansion. */ @@ -589,6 +621,11 @@ public class IntegrityTestRunnerView extends ViewPart { */ private SetList setList; + /** + * Used to measure the connected time. + */ + private long connectionTimestamp; + /** * The set of breakpoints currently in use. */ @@ -1501,6 +1538,7 @@ private void fillLocalToolBar(IToolBarManager aManager) { aManager.add(stepIntoAction); aManager.add(stepOverAction); aManager.add(clearBreakpointsAction); + aManager.add(pauseAbortAtFirstErrorAction); aManager.add(new Separator()); aManager.add(connectToTestRunnerAction); } @@ -1758,6 +1796,40 @@ public void run() { scrollLockAction.setToolTipText("Toggles the scroll lock setting."); scrollLockAction.setImageDescriptor(Activator.getImageDescriptor("icons/scrolllock.gif")); + pauseAbortAtFirstErrorAction = new Action("Pause/abort at first test failure", IAction.AS_CHECK_BOX) { + @Override + public void run() { + if (!pauseAtFirstErrorActive && !abortAtFirstErrorActive) { + pauseAtFirstErrorActive = true; + setChecked(true); + setImageDescriptor(Activator.getImageDescriptor("icons/auto_pause_abort_on_pause.gif")); + setToolTipText("Will automatically pause test execution on first test failure."); + } else if (pauseAtFirstErrorActive) { + pauseAtFirstErrorActive = false; + abortAtFirstErrorActive = true; + setChecked(true); + setImageDescriptor(Activator.getImageDescriptor("icons/auto_pause_abort_on_abort.gif")); + setToolTipText("Will automatically abort test execution on first test failure."); + } else { + pauseAtFirstErrorActive = false; + abortAtFirstErrorActive = false; + setChecked(false); + setImageDescriptor(Activator.getImageDescriptor("icons/auto_pause_abort_disabled.gif")); + setToolTipText("Automatically pause or abort on first test failure is currently disabled."); + } + + if (setList != null) { + pauseAbortAtFirstErrorFailureThreshold = setList + .getNumberOfEntriesInResultState(SetListEntryResultStates.FAILED) + + setList.getNumberOfEntriesInResultState(SetListEntryResultStates.EXCEPTION); + } + }; + }; + pauseAbortAtFirstErrorAction + .setToolTipText("Automatically pause or abort on first test failure is currently disabled."); + pauseAbortAtFirstErrorAction + .setImageDescriptor(Activator.getImageDescriptor("icons/auto_pause_abort_disabled.gif")); + updateActionStatus(null); } @@ -1856,9 +1928,19 @@ public void run() { pauseAction.setEnabled(false); stepIntoAction.setEnabled(false); stepOverAction.setEnabled(false); - updateStatusRunnable( - determineIntermediateTestResultStatusString("Test execution finished (", ")")) - .run(); + if (lastRunWasAutoAborted) { + updateStatusRunnable( + determineIntermediateTestResultStatusString("Test was aborted on failure (", + ") after " + DateUtil.convertNanosecondTimespanToHumanReadableFormat( + System.nanoTime() - connectionTimestamp, true, false))).run(); + } else { + updateStatusRunnable( + determineIntermediateTestResultStatusString("Test execution finished (", + ") after " + DateUtil.convertNanosecondTimespanToHumanReadableFormat( + System.nanoTime() - connectionTimestamp, true, false))).run(); + } + lastRunWasAutoAborted = false; + lastRunEndStatusReceived = true; break; default: break; @@ -2442,6 +2524,8 @@ private void updateSetList(SetList aNewSetList) { setList = aNewSetList; breakpointSet.clear(); setListSearch = null; + pauseAbortAtFirstErrorFailureThreshold = 0; + lastRunWasAutoAborted = false; Display.getDefault().asyncExec(new Runnable() { @Override @@ -2492,11 +2576,6 @@ public boolean isSkippable() { private class RemotingListener implements IntegrityRemotingClientListener { - /** - * Used to measure the connected time. - */ - private long connectionTimestamp; - @Override public void onConnectionSuccessful(IntegrityRemotingVersionMessage aRemoteVersion, Endpoint anEndpoint) { // request set list baseline and execution state @@ -2578,9 +2657,20 @@ public void onConnectionLost(Endpoint anEndpoint) { public void run() { executionProgress.redraw(); updateActionStatusRunnable(null).run(); - updateStatusRunnable(determineIntermediateTestResultStatusString("Test Runner disconnected (", - ") after " + DateUtil.convertNanosecondTimespanToHumanReadableFormat( - System.nanoTime() - connectionTimestamp, true, false))).run(); + if (lastRunWasAutoAborted) { + updateStatusRunnable( + determineIntermediateTestResultStatusString("Test was aborted on failure (", + ") after " + DateUtil.convertNanosecondTimespanToHumanReadableFormat( + System.nanoTime() - connectionTimestamp, true, false))).run(); + } else { + if (!lastRunEndStatusReceived) { + updateStatusRunnable( + determineIntermediateTestResultStatusString("Test Runner disconnected (", + ") after " + DateUtil.convertNanosecondTimespanToHumanReadableFormat( + System.nanoTime() - connectionTimestamp, true, false))).run(); + } + } + lastRunEndStatusReceived = false; } }); @@ -2623,6 +2713,31 @@ public void onSetListUpdate(final SetListEntry[] someUpdatedEntries, final Integ if (anEntryInExecutionReference != null) { setList.setEntryInExecutionReference(anEntryInExecutionReference); } + + if (pauseAtFirstErrorActive || abortAtFirstErrorActive) { + int tempCurrentFailures = setList.getNumberOfEntriesInResultState(SetListEntryResultStates.FAILED) + + setList.getNumberOfEntriesInResultState(SetListEntryResultStates.EXCEPTION); + if (tempCurrentFailures > pauseAbortAtFirstErrorFailureThreshold) { + pauseAbortAtFirstErrorFailureThreshold = tempCurrentFailures; + if (pauseAtFirstErrorActive && isConnected()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + pauseAction.run(); + } + }); + } else if (abortAtFirstErrorActive && isConnected()) { + lastRunWasAutoAborted = true; + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + shutdownAction.run(); + } + }); + } + } + } + Display.getDefault().asyncExec(new Runnable() { @Override public void run() { From 02ef90eead800157a8d30fc2f16629c4b41a3ee9 Mon Sep 17 00:00:00 2001 From: Rene Schneider Date: Wed, 30 Jan 2019 12:16:41 +0100 Subject: [PATCH 3/3] fixes #219: Add "auto-repeat" button to Integrity Test Runner view --- .../eclipse/views/ConnectDialog.java | 62 +++++++++++++++ .../views/IntegrityTestRunnerView.java | 75 +++++++++++++++++-- 2 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/ConnectDialog.java diff --git a/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/ConnectDialog.java b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/ConnectDialog.java new file mode 100644 index 000000000..bf490c23c --- /dev/null +++ b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/ConnectDialog.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package de.gebit.integrity.eclipse.views; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; + +/** + * + * + * @author Rene Schneider - initial API and implementation + * + */ +public class ConnectDialog extends InputDialog { + + /** + * Whether auto-retry was chosen. + */ + private boolean autoRetryEnabled; + + /** + * @param parentShell + * @param aDialogTitle + * @param aDialogMessage + * @param anInitialValue + * @param aValidator + */ + public ConnectDialog(Shell aParentShell, String anInitialValue, IInputValidator aValidator) { + super(aParentShell, "Connect to test runner", "Please enter the hostname or IP address to connect to", + anInitialValue, null); + } + + @Override + protected void createButtonsForButtonBar(Composite aParent) { + super.createButtonsForButtonBar(aParent); + + createButton(aParent, IDialogConstants.RETRY_ID, "OK (retry)", false); + } + + @Override + protected void buttonPressed(int aButtonId) { + if (aButtonId == IDialogConstants.RETRY_ID) { + autoRetryEnabled = true; + super.buttonPressed(IDialogConstants.OK_ID); + } else { + super.buttonPressed(aButtonId); + } + } + + public boolean isAutoRetryEnabled() { + return autoRetryEnabled; + } + +} diff --git a/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java index 88c11e842..f5a1373d1 100644 --- a/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java +++ b/de.gebit.integrity.eclipse/src/de/gebit/integrity/eclipse/views/IntegrityTestRunnerView.java @@ -49,7 +49,6 @@ import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ArrayContentProvider; @@ -641,6 +640,11 @@ public class IntegrityTestRunnerView extends ViewPart { */ private ILaunchConfiguration launchConfiguration; + /** + * The currently active autoconnect thread. + */ + private AutoConnectThread autoConnectThread; + /** * The constructor. */ @@ -1550,8 +1554,7 @@ private void makeActions() { @Override public void run() { if (client == null || !client.isActive()) { - InputDialog tempDialog = new InputDialog(getSite().getShell(), "Connect to test runner", - "Please enter the hostname or IP address to connect to", lastHostname, null); + ConnectDialog tempDialog = new ConnectDialog(getSite().getShell(), lastHostname, null); if (tempDialog.open() == IStatus.OK && tempDialog.getValue() != null && tempDialog.getValue().length() > 0) { lastHostname = tempDialog.getValue(); @@ -1569,7 +1572,23 @@ public void run() { } tempHost = tempHost.substring(0, tempHost.indexOf(':')); } - connectToTestRunnerAsync(tempHost, tempPort); + + if (tempDialog.isAutoRetryEnabled()) { + if (autoConnectThread != null && autoConnectThread.isAlive()) { + autoConnectThread.kill(); + autoConnectThread = null; + } + if (autoConnectThread == null || !autoConnectThread.isAlive()) { + autoConnectThread = new AutoConnectThread(tempHost, tempPort); + autoConnectThread.start(); + } + } else { + connectToTestRunnerAsync(tempHost, tempPort); + } + } else { + if (autoConnectThread != null && autoConnectThread.isAlive()) { + autoConnectThread.kill(); + } } } else { disconnectFromTestRunner(); @@ -1709,7 +1728,11 @@ public void run() { executeTestAction.setEnabled(false); executeDebugTestAction.setEnabled(false); final ILaunch tempLaunch = launchConfiguration.launch(ILaunchManager.RUN_MODE, null); - new AutoConnectThread(tempLaunch).start(); + if (autoConnectThread != null && autoConnectThread.isAlive()) { + autoConnectThread.kill(); + } + autoConnectThread = new AutoConnectThread(tempLaunch); + autoConnectThread.start(); } catch (CoreException exc) { showException(exc); } @@ -1727,7 +1750,11 @@ public void run() { executeTestAction.setEnabled(false); executeDebugTestAction.setEnabled(false); final ILaunch tempLaunch = launchConfiguration.launch(ILaunchManager.DEBUG_MODE, null); - new AutoConnectThread(tempLaunch).start(); + if (autoConnectThread != null && autoConnectThread.isAlive()) { + autoConnectThread.kill(); + } + autoConnectThread = new AutoConnectThread(tempLaunch); + autoConnectThread.start(); } catch (CoreException exc) { showException(exc); } @@ -2854,6 +2881,21 @@ private class AutoConnectThread extends Thread { */ private ILaunch launch; + /** + * The host to connect to. + */ + private String host = "localhost"; + + /** + * The port to connect to. + */ + private int port = IntegrityRemotingConstants.DEFAULT_PORT; + + /** + * Used to kill this thread gracefully. + */ + private boolean killSwitch; + /** * Creates a new instance. */ @@ -2862,15 +2904,28 @@ private class AutoConnectThread extends Thread { launch = aLaunch; } + /** + * Creates a new instance. + */ + AutoConnectThread(String aHost, int aPort) { + super("Integrity Autoconnect Thread"); + host = aHost; + port = aPort; + } + + public void kill() { + killSwitch = true; + } + @Override public void run() { boolean tempSuccess = false; - while (!launch.isTerminated()) { + while (!killSwitch && (launch == null || !launch.isTerminated())) { try { if (!tempSuccess && !isConnected()) { // try to connect at least once - connectToTestRunner("localhost", IntegrityRemotingConstants.DEFAULT_PORT); + connectToTestRunner(host, IntegrityRemotingConstants.DEFAULT_PORT); tempSuccess = true; } else { // Now we'll wait until the launch has terminated @@ -2893,6 +2948,10 @@ public void run() { // don't care } } + + if (!tempSuccess) { + updateStatus("Aborted connection attempts"); + } executeTestAction.setEnabled(true); executeDebugTestAction.setEnabled(true); };