From fde55b943923359bf9018d7e4e8dd660635e5a74 Mon Sep 17 00:00:00 2001
From: Robert Scott <code@humanleg.org.uk>
Date: Sat, 12 May 2018 21:45:59 +0100
Subject: [PATCH v2 25/28] MainApplication$shutdown(): don't use isHeadless to
 detect test mode & skip shutdown calls

instead mock out these shutdown methods in ExitActionTest, allowing the test
to work similarly in both headless and non-headless modes
---
 .../openstreetmap/josm/gui/MainApplication.java    | 25 ++++++------
 .../openstreetmap/josm/actions/ExitActionTest.java | 46 ++++++++++++++++++++++
 2 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/src/org/openstreetmap/josm/gui/MainApplication.java b/src/org/openstreetmap/josm/gui/MainApplication.java
index 6e7cdebea..70fe44744 100644
--- a/src/org/openstreetmap/josm/gui/MainApplication.java
+++ b/src/org/openstreetmap/josm/gui/MainApplication.java
@@ -487,14 +487,13 @@ public class MainApplication extends Main {
 
     @Override
     protected void shutdown() {
-        if (!GraphicsEnvironment.isHeadless()) {
-            try {
-                worker.shutdown();
-            } catch (SecurityException e) {
-                Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown worker", e);
-            }
-            JCSCacheManager.shutdown();
+        try {
+            worker.shutdown();
+        } catch (SecurityException e) {
+            Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown worker", e);
         }
+        JCSCacheManager.shutdown();
+
         if (mainFrame != null) {
             mainFrame.storeState();
         }
@@ -504,12 +503,12 @@ public class MainApplication extends Main {
         // Remove all layers because somebody may rely on layerRemoved events (like AutosaveTask)
         layerManager.resetState();
         super.shutdown();
-        if (!GraphicsEnvironment.isHeadless()) {
-            try {
-                worker.shutdownNow();
-            } catch (SecurityException e) {
-                Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown worker", e);
-            }
+
+        try {
+            // in case the current task still hasn't finished
+            worker.shutdownNow();
+        } catch (SecurityException e) {
+            Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown worker", e);
         }
     }
 
diff --git a/test/unit/org/openstreetmap/josm/actions/ExitActionTest.java b/test/unit/org/openstreetmap/josm/actions/ExitActionTest.java
index 7612752b2..e4c27002a 100644
--- a/test/unit/org/openstreetmap/josm/actions/ExitActionTest.java
+++ b/test/unit/org/openstreetmap/josm/actions/ExitActionTest.java
@@ -1,10 +1,19 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.actions;
 
+import static org.junit.Assert.assertTrue;
+
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.contrib.java.lang.system.ExpectedSystemExit;
+import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.gui.progress.swing.ProgressMonitorExecutor;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+import mockit.Invocation;
+import mockit.Mock;
+import mockit.MockUp;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
@@ -32,7 +41,44 @@ public final class ExitActionTest {
     @Test
     public void testActionPerformed() {
         exit.expectSystemExitWithStatus(0);
+
+        boolean[] workerShutdownCalled = {false};
+        boolean[] workerShutdownNowCalled = {false};
+        boolean[] imageProviderShutdownCalled = {false};
+
+        // critically we don't proceed into the actual implementation in any of these mock methods -
+        // that would be quite annoying for tests following this one which were expecting to use any
+        // of these
+        new MockUp<ProgressMonitorExecutor>() {
+            @Mock
+            private void shutdown(Invocation invocation) {
+                if (invocation.getInvokedInstance() == MainApplication.worker) {
+                    workerShutdownCalled[0] = true;
+                }
+            }
+
+            @Mock
+            private void shutdownNow(Invocation invocation) {
+                if (invocation.getInvokedInstance() == MainApplication.worker) {
+                    // regular shutdown should have been called first
+                    assertTrue(workerShutdownCalled[0]);
+                    workerShutdownNowCalled[0] = true;
+                }
+            }
+        };
+        new MockUp<ImageProvider>() {
+            @Mock
+            private void shutdown(Invocation invocation) {
+                imageProviderShutdownCalled[0] = true;
+            }
+        };
+
         // No layer
+
         new ExitAction().actionPerformed(null);
+
+        assertTrue(workerShutdownCalled[0]);
+        assertTrue(workerShutdownNowCalled[0]);
+        assertTrue(imageProviderShutdownCalled[0]);
     }
 }
-- 
2.11.0

