From a1baf856f9fd634e345676b5a8e6aa0143e0d80a Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 18 Nov 2018 16:13:47 +0000
Subject: [PATCH] Wizard: Fix cancel test button

---
 .../src/com/vuze/plugins/mlab/MLabRunner.java | 10 ++-
 .../src/edu/internet2/ndt/StatusPanel.java    | 11 ++-
 .../java/src/edu/internet2/ndt/Tcpbw100.java  | 67 +++++++++++++++----
 .../i2p/router/web/helpers/WizardHandler.java |  7 +-
 apps/routerconsole/jsp/welcome.jsp            |  7 ++
 5 files changed, 79 insertions(+), 23 deletions(-)

diff --git a/apps/routerconsole/java/src/com/vuze/plugins/mlab/MLabRunner.java b/apps/routerconsole/java/src/com/vuze/plugins/mlab/MLabRunner.java
index 9c5d4f37ed..ba640194f3 100644
--- a/apps/routerconsole/java/src/com/vuze/plugins/mlab/MLabRunner.java
+++ b/apps/routerconsole/java/src/com/vuze/plugins/mlab/MLabRunner.java
@@ -171,12 +171,16 @@ public class MLabRunner {
                         String[] args = useSSL ? new String[] { "-s", server_host } : new String[] { server_host };
                         long start = System.currentTimeMillis();
                         final Tcpbw100 test = Tcpbw100.mainSupport(args);
+                        final AtomicBoolean cancelled = new AtomicBoolean();
                         
                         run.addListener(
                             new ToolRunListener()
                             {
                                 public void cancelled() {
+                                    cancelled.set(true);
+                                    _log.warn("TRL cancelling test");
                                     test.killIt();
+                                    _log.warn("TRL cancelled test");
                                 }
 
                                 public String getStatus() {
@@ -188,7 +192,7 @@ public class MLabRunner {
                         
                         try { Thread.sleep(2000); } catch (InterruptedException ie) { return; }
                         for (int i = 0; i < 180; i++) {
-                            if (!test.isTestInProgress())
+                            if (cancelled.get() || !test.isTestInProgress())
                                 break;
                             try { Thread.sleep(1000); } catch (InterruptedException ie) { break; }
                         }
@@ -206,7 +210,9 @@ public class MLabRunner {
                         } catch(Throwable e) {}
                         
                         String result_str;
-                        if (up_bps == 0 || down_bps == 0) {
+                        if (cancelled.get()) {
+                            result_str = "Test cancelled";
+                        } else if (up_bps == 0 || down_bps == 0) {
                             result_str = "No results were received. Either the test server is unavailable or network problems are preventing the test from running correctly. Please try again.";
                         } else {
                             result_str =     
diff --git a/apps/routerconsole/java/src/edu/internet2/ndt/StatusPanel.java b/apps/routerconsole/java/src/edu/internet2/ndt/StatusPanel.java
index a9f9b63256..77add0d8b0 100644
--- a/apps/routerconsole/java/src/edu/internet2/ndt/StatusPanel.java
+++ b/apps/routerconsole/java/src/edu/internet2/ndt/StatusPanel.java
@@ -96,19 +96,16 @@ public class StatusPanel extends JPanel {
 	 * 
 	 * @return boolean indicating intention to stop or not
 	 * */
-	public boolean wantToStop() {
+	public synchronized boolean wantToStop() {
 		return _bStop;
 	}
 
 	/**
 	 * End the currently running test
+	 * Cannot be restarted.
 	 * */
-	public void endTest() {
-/****
-		_progressBarObj.setValue(_iTestsCompleted);
-		_iTestsCompleted++;
-		setTestNoLabelText();
-****/
+	public synchronized void endTest() {
+		_bStop = true;
 	}
 
 	/**
diff --git a/apps/routerconsole/java/src/edu/internet2/ndt/Tcpbw100.java b/apps/routerconsole/java/src/edu/internet2/ndt/Tcpbw100.java
index bda625305c..6812fa6e2c 100644
--- a/apps/routerconsole/java/src/edu/internet2/ndt/Tcpbw100.java
+++ b/apps/routerconsole/java/src/edu/internet2/ndt/Tcpbw100.java
@@ -301,6 +301,7 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 	private final Log _log = _context.logManager().getLog(Tcpbw100.class);
 	private final boolean _useSSL;
 	private final I2PSSLSocketFactory _sslFactory;
+	private StatusPanel _sPanel;
 
 	public Tcpbw100(boolean useSSL) {
 		super();
@@ -652,6 +653,9 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 				// number of tests
 
 				StatusPanel sPanel = new StatusPanel(testsNum, sTempEnable);
+				synchronized (Tcpbw100.this) {
+					_sPanel = sPanel;
+				}
 				getContentPane().add(BorderLayout.NORTH, sPanel);
 				getContentPane().validate();
 				getContentPane().repaint();
@@ -659,6 +663,7 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 				try {
 					while (true) {
 						if (sPanel.wantToStop()) {
+							_log.warn("cancelled");
 							break;
 						}
 						if (testsNum == 0) {
@@ -681,6 +686,7 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 						}
 						// If user stops the test, quit
 						if (sPanel.wantToStop()) {
+							_log.warn("cancelled");
 							break;
 						}
 						sPanel.setText("");
@@ -2846,6 +2852,7 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 				_sErrMsg = "\n" + _resBundDisplayMsgs.getString("stopped")
 						+ "\n";
 				_bFailed = true;
+				_log.warn(_sErrMsg);
 				return;
 			}
 			int testId = Integer.parseInt(tokenizer.nextToken());
@@ -2915,6 +2922,7 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 			ctlSocket.close();
 			_sErrMsg = _resBundDisplayMsgs.getString("stopped") + "\n";
 			_bFailed = true;
+			_log.warn(_sErrMsg);
 			return;
 		}
 
@@ -4505,24 +4513,60 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 	}
 
 	/** bigly */
-	private ThreadGroup thread_group;
+	private ThreadGroup _thread_group;
 	
-	/** bigly */
+	/**
+	 * bigly -- must have been started with main() or runIt()
+	 */
+	@SuppressWarnings("deprecation")
 	public void
 	killIt()
 	{
-		while( !thread_group.isDestroyed()){
+		final ThreadGroup thread_group;
+		synchronized(this) {
+			thread_group = _thread_group;
+			if (thread_group == null) {
+				_log.warn("No thread group to kill");
+				return;
+			}
+			// so wantToStop() returns true
+			if (_sPanel != null)
+				_sPanel.endTest();
+		}
+		_log.warn("killIt()");
+		boolean destroyed = false;
+		for (int j = 0; j < 10 && !thread_group.isDestroyed(); j++) {
 			Thread[] threads = new Thread[thread_group.activeCount()];
 			thread_group.enumerate( threads );
 			int	done = 0;
 			for ( int i=0;i<threads.length;i++){
-				if ( threads[i] != null ){
+				Thread t = threads[i];
+				if (t != null) {
+					if (_log.shouldWarn())
+						_log.warn("Interrupting TG thread " + t);
 					done++;
-					//SESecurityManager.stopThread( threads[i] );
+					try {
+						t.interrupt();
+					} catch (RuntimeException re) {
+						_log.warn("TG", re);
+					}
+					try {
+						Thread.sleep(20);
+					} catch (InterruptedException ie) {}
+					if (t.isAlive()) {
+						if (_log.shouldWarn())
+							_log.warn("Killing TG thread " + t);
+						try {
+							t.stop();
+						} catch (RuntimeException re) {
+							_log.warn("TG", re);
+						}
+					}
 				}
 			}
 			
 			if ( done == 0 ){
+				_log.warn("TG destroy");
 				try{
 					thread_group.destroy();
 					break;
@@ -4532,19 +4576,18 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 			}
 			
 			try{
-				Thread.sleep(250);
-			}catch( Throwable e ){	
-			}
+				Thread.sleep(50);
+			} catch (InterruptedException ie) {}
 		}
 	}
 	
 	/** bigly */
-	public void
+	public synchronized void
 	runIt()
 	{
 		//final AESemaphore sem = new AESemaphore( "waiter" );
 		
-		thread_group = new 
+		_thread_group = new 
 			ThreadGroup( "NDT" )
 			{
 				@Override
@@ -4557,11 +4600,11 @@ public class Tcpbw100 extends JApplet implements ActionListener {
 				}
 			};
 		
-		thread_group.setDaemon( true );
+		_thread_group.setDaemon( true );
 		
 		Thread t = 
 			new I2PAppThread( 
-				thread_group,
+				_thread_group,
 				new Runnable()
 				{
 					@Override
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/WizardHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/WizardHandler.java
index 14cc64fe7d..8a0feb7aec 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/WizardHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/WizardHandler.java
@@ -32,6 +32,9 @@ public class WizardHandler extends FormHandler {
             return;
         if (getJettyString("cancelbw") != null) {
             cancelNDT();
+            for (int i = 0; i < 20 && !_helper.isNDTComplete(); i++) {
+                try { Thread.sleep(100); } catch (InterruptedException ie) {}
+            }
             return;
         }
         if (getJettyString("next") == null)
@@ -138,7 +141,7 @@ public class WizardHandler extends FormHandler {
         if (_helper == null) {
             addFormError("Bad state for test");
         } else if (_helper.startNDT()) {
-            addFormNotice(_t("Started bandwidth test"));
+            addFormNotice(_t("Bandwidth test started"));
         } else {
             addFormError(_t("Bandwidth test is already running"));
         }
@@ -149,7 +152,7 @@ public class WizardHandler extends FormHandler {
         if (_helper == null) {
             addFormError("Bad state for test");
         } else if (_helper.cancelNDT()) {
-            addFormNotice(_t("Cancelled bandwidth test"));
+            addFormError(_t("Bandwidth test cancelled"));
         } else {
             addFormError(_t("Bandwidth test was not running"));
         }
diff --git a/apps/routerconsole/jsp/welcome.jsp b/apps/routerconsole/jsp/welcome.jsp
index 2b7b9b3bad..21c6371d74 100644
--- a/apps/routerconsole/jsp/welcome.jsp
+++ b/apps/routerconsole/jsp/welcome.jsp
@@ -174,9 +174,16 @@
 <tr><td><%=intl._t("Test server location")%></td><td><%=wizhelper.getServerLocation()%></td></tr>
 <tr><td><%=intl._t("Completion status")%></td><td><%=wizhelper.getCompletionStatus()%></td></tr>
 <tr><td><%=intl._t("Details")%></td><td><%=wizhelper.getDetailStatus()%></td></tr>
+<%
+            if (wizhelper.isNDTSuccessful()) {
+                // don't display this if test failed
+%>
 <tr><td><%=intl._t("Downstream Bandwidth")%></td><td><%=net.i2p.data.DataHelper.formatSize2Decimal(wizhelper.getDownBandwidth())%>Bps</td></tr>
 <tr><td><%=intl._t("Upstream Bandwidth")%></td><td><%=net.i2p.data.DataHelper.formatSize2Decimal(wizhelper.getUpBandwidth())%>Bps</td></tr>
 <tr><td><%=intl._t("Share of Bandwidth for I2P")%></td><td><%=Math.round(net.i2p.router.web.helpers.WizardHelper.BW_SCALE * 100)%>%</td></tr>
+<%
+            } // sucessful
+%>
 </table>
 <%
         } // skipbw
-- 
GitLab