<NME> GPXImporterTest.java
<BEF> package cgeo.geocaching.files;

import cgeo.geocaching.SearchResult;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.gc.GCUtils;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.models.Geocache;
import cgeo.geocaching.models.Waypoint;
import cgeo.geocaching.storage.DataStore;
import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase;
import cgeo.geocaching.test.R;
import cgeo.geocaching.utils.DisposableHandler;
import cgeo.geocaching.utils.FileUtils;
import cgeo.geocaching.utils.Log;

import android.net.Uri;
import android.os.HandlerThread;
import android.os.Looper;
import org.apache.commons.lang3.StringUtils;

import android.net.Uri;
import android.os.Message;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
    private TestHandler progressHandler;
import java.util.List;

public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
    private final TestHandler importStepHandler = new TestHandler();
    private final TestHandler progressHandler = new TestHandler();
    private int listId;
    private File tempDir;
    private boolean importCacheStaticMaps;
    private boolean importWpStaticMaps;

    public void testGetWaypointsFileNameForGpxFile() throws IOException {
        final String[] gpxFiles = new String[] { "1234567.gpx", "1.gpx", "1234567.9.gpx",
            final String wptsFileName = wptsFiles[i];
            final File gpx = new File(tempDir, gpxFileName);
            final File wpts = new File(tempDir, wptsFileName);
            // the files need to exist - we create them
            assertThat(gpx.createNewFile()).isTrue();
            assertThat(wpts.createNewFile()).isTrue();
            // the "real" method check
            assertThat(GPXImporter.getWaypointsFileNameForGpxFile(gpx)).isEqualTo(wptsFileName);
            // they also need to be deleted, because of case sensitive tests that will not work correct on case insensitive file systems
            FileUtils.delete(gpx);
            FileUtils.delete(wpts);
        }
        final File gpx1 = new File(tempDir, "abc.gpx");
        assertThat(GPXImporter.getWaypointsFileNameForGpxFile(gpx1)).isNull();
    }

    public void testImportGpx() throws IOException {
        final String geocode = "GC31J2H";
        removeCacheCompletely(geocode);
        final File gc31j2h = new File(tempDir, "gc31j2h.gpx");
        copyResourceToFile(R.raw.gc31j2h, gc31j2h);

        final ImportGpxFileThread importThread = new ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);

        assertThat(cache.getWaypoints()).isEmpty();
    }

    public void testImportOcGpx() throws IOException {
        final String geocode = "OCDDD2";
        removeCacheCompletely(geocode);
        final File ocddd2 = new File(tempDir, "ocddd2.gpx");
        copyResourceToFile(R.raw.ocddd2, ocddd2);

        final ImportGpxFileThread importThread = new ImportGpxFileThread(ocddd2, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);

        assertThat(cache.getWaypoints()).as("Number of imported waypoints").hasSize(4);
    }

    public void testImportOcGpxEmptyCoord() throws IOException {
        final String geocode = "OCDDD2";
        removeCacheCompletely(geocode);
        final File ocddd2 = new File(tempDir, "ocddd2_empty_coord.gpx");
        copyResourceToFile(R.raw.ocddd2_empty_coord, ocddd2);

        final ImportGpxFileThread importThread = new ImportGpxFileThread(ocddd2, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);

        final List<Waypoint> waypointList = cache.getWaypoints();
        assertThat(waypointList).isNotNull();
        assertThat(waypointList).as("Number of imported waypoints").hasSize(8);
        assertThat(waypointList.get(3).getCoords()).as("Not empty coordinates").isNotNull();
        assertThat(waypointList.get(4).getCoords()).as("Empty coordinates").isNull();
        assertThat(waypointList.get(5).getCoords()).as("Empty coordinates").isNull();
        } catch (final InterruptedException e) {
            Log.e("GPXImporterTest.runImportThread", e);
        }
        importStepHandler.waitForCompletion();
    }

        final File gc31j2h = new File(tempDir, "gc31j2h.gpx");
        copyResourceToFile(R.raw.gc31j2h, gc31j2h);
        copyResourceToFile(R.raw.gc31j2h_wpts, new File(tempDir, "gc31j2h-wpts.gpx"));

        final ImportGpxFileThread importThread = new ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);
        assertThat(cache.getWaypoints()).hasSize(2);
    }

    public void testImportGpxWithWaypointsEmptyCoord() throws IOException {
        final String geocode = "GC31J2H";
        removeCacheCompletely(geocode);

        final File gc31j2h = new File(tempDir, "gc31j2h.gpx");
        copyResourceToFile(R.raw.gc31j2h, gc31j2h);
        copyResourceToFile(R.raw.gc31j2h_wpts_empty_coord, new File(tempDir, "gc31j2h-wpts.gpx"));

        final ImportGpxFileThread importThread = new ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);

        final List<Waypoint> waypointList = cache.getWaypoints();
        assertThat(waypointList).isNotNull();
        assertThat(waypointList).as("Number of imported waypoints").hasSize(2);
        assertThat(waypointList.get(1).getCoords()).as("Empty Coordinates").isNull();
    }

    public void testImportGpxWithLowercaseNames() throws IOException {
        final File tc2012 = new File(tempDir, "tc2012.gpx");
        copyResourceToFile(R.raw.tc2012, tc2012);

        final ImportGpxFileThread importThread = new ImportGpxFileThread(tc2012, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache("AID1", LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);
        assertThat(cache.getName()).isEqualTo("First Aid Station #1");
    }


    private void runImportThread(final AbstractImportThread importThread) {
        importThread.start();
        try {
            importThread.join();
        } catch (final InterruptedException e) {
            Log.e("GPXImporterTest.runImportThread", e);
        }
        importStepHandler.sendEmptyMessage(TestHandler.TERMINATION_MESSAGE); // send End Message

        importStepHandler.waitForCompletion();
    }

    private void assertImportStepMessages(final int... expectedSteps) {
        final ArrayList<Message> messages = new ArrayList<>(importStepHandler.messages); // copy to avoid CME
        assertThat(messages).hasSize(expectedSteps.length);
        for (int i = 0; i < Math.min(expectedSteps.length, messages.size()); i++) {
            assertThat(messages.get(i).what).isEqualTo(expectedSteps[i]);
        }
    }

    public void testImportLoc() throws IOException {
        final File oc5952 = new File(tempDir, "oc5952.loc");
        copyResourceToFile(R.raw.oc5952_loc, oc5952);

        final ImportLocFileThread importThread = new ImportLocFileThread(oc5952, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache("OC5952", LoadFlags.LOAD_CACHE_OR_DB);
        assertCacheProperties(cache);
    }

    private static void assertCacheProperties(final Geocache cache) {
        assertThat(cache).isNotNull();
        assertThat(cache.getLocation().startsWith(",")).isFalse();
        if (GCConnector.getInstance().equals(ConnectorFactory.getConnector(cache))) {
            assertThat(String.valueOf(GCUtils.gcCodeToGcId(cache.getGeocode()))).isEqualTo(cache.getCacheId());
        }
    }

    public void testImportGpxError() throws IOException {
        final File gc31j2h = new File(tempDir, "gc31j2h.gpx");
        copyResourceToFile(R.raw.gc31j2h_err, gc31j2h);

        final ImportGpxFileThread importThread = new ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_FINISHED_WITH_ERROR);
    }

    public void testImportGpxCancel() throws IOException {
        final File gc31j2h = new File(tempDir, "gc31j2h.gpx");
        copyResourceToFile(R.raw.gc31j2h, gc31j2h);

        progressHandler.dispose();
        final ImportGpxFileThread importThread = new ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_CANCELED);
    }

    public void testImportGpxAttachment() {
        final String geocode = "GC31J2H";
        removeCacheCompletely(geocode);
        final Uri uri = Uri.parse("android.resource://cgeo.geocaching.test/raw/gc31j2h");

        final ImportGpxAttachmentThread importThread = new ImportGpxAttachmentThread(uri, getInstrumentation().getContext().getContentResolver(), listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);

        assertThat(cache.getWaypoints()).isEmpty();
    }

    public void testImportGpxZip() throws IOException {
        final String geocode = "GC31J2H";
        removeCacheCompletely(geocode);
        final File pq7545915 = new File(tempDir, "7545915.zip");
        copyResourceToFile(R.raw.pq7545915, pq7545915);

        final ImportGpxZipFileThread importThread = new ImportGpxZipFileThread(pq7545915, listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, /*GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,*/ GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        final ImportGpxZipAttachmentThread importThread = new ImportGpxZipAttachmentThread(uri, getInstrumentation().getContext().getContentResolver(), listId, importStepHandler, progressHandler);
        runImportThread(importThread);

        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED);
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        assertThat(cache).isNotNull();
        assertCacheProperties(cache);
        assertThat(cache.getWaypoints()).hasSize(1); // this is the original pocket query result without test waypoint
    }

    static class TestHandler extends CancellableHandler {
        private final List<Message> messages = new ArrayList<>();
        private long lastMessage = System.currentTimeMillis();

        @Override
        public synchronized void handleRegularMessage(final Message msg) {
            final Message msg1 = Message.obtain();
            msg1.copyFrom(msg);
            messages.add(msg1);
            lastMessage = System.currentTimeMillis();
            notifyAll();
        }

        public synchronized void waitForCompletion(final long milliseconds) {
            try {
                while (System.currentTimeMillis() - lastMessage <= milliseconds && !hasTerminatingMessage()) {
                    wait(milliseconds);
                }
            } catch (final InterruptedException e) {
        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
        assert cache != null;
        }

        private boolean hasTerminatingMessage() {
            final Message recentMessage = messages.get(messages.size() - 1);
            return recentMessage.what == GPXImporter.IMPORT_STEP_CANCELED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED_WITH_ERROR;
        }

        public void waitForCompletion() {
        private final List<Message> messages = new ArrayList<>();
        private long lastMessage = System.currentTimeMillis();
        private boolean receivedTerminationMessage = false;
        private static final int TERMINATION_MESSAGE = 9999;

        TestHandler(final Looper serviceLooper) {
    protected void setUp() throws Exception {
        super.setUp();

        final String globalTempDir = System.getProperty("java.io.tmpdir");
        assertThat(StringUtils.isNotBlank(globalTempDir)).overridingErrorMessage("java.io.tmpdir is not defined").isTrue();

            lastMessage = System.currentTimeMillis();
            notifyAll();
        }

        public synchronized void waitForCompletion(final long milliseconds) {
            try {
                while ((System.currentTimeMillis() - lastMessage <= milliseconds) && !hasTerminatingMessage()) {
                    wait(milliseconds);
                }
            } catch (final InterruptedException e) {
                // intentionally left blank
            }
        }

        private boolean hasTerminatingMessage() {
            return receivedTerminationMessage;
        }

        public void waitForCompletion() {
            // wait a maximum of 10 seconds
        FileUtils.deleteDirectory(tempDir);
        TestSettings.setStoreOfflineMaps(importCacheStaticMaps);
        TestSettings.setStoreOfflineWpMaps(importWpStaticMaps);
        super.tearDown();
    }
}

        serviceThread = new HandlerThread("[" + getClass().getSimpleName() + "Thread]");
        serviceThread.start();
        final Looper serviceLooper = serviceThread.getLooper();
        importStepHandler = new TestHandler(serviceLooper);
        progressHandler = new TestHandler(serviceLooper);

        final String globalTempDir = System.getProperty("java.io.tmpdir");
        assertThat(StringUtils.isNotBlank(globalTempDir)).overridingErrorMessage("java.io.tmpdir is not defined").isTrue();

        tempDir = new File(globalTempDir, "cgeogpxesTest");
        FileUtils.mkdirs(tempDir);
        assertThat(tempDir).overridingErrorMessage("Could not create directory %s", tempDir.getPath()).exists();
        // workaround to get storage initialized
        DataStore.getAllStoredCachesCount(PseudoList.HISTORY_LIST.id);
        listId = DataStore.createList("cgeogpxesTest");
    }

    @Override
    protected void tearDown() throws Exception {
        final SearchResult search = DataStore.getBatchOfStoredCaches(null, listId);
        final List<Geocache> cachesInList = new ArrayList<>(search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB));
        DataStore.markDropped(cachesInList);
        DataStore.removeList(listId);
        FileUtils.deleteDirectory(tempDir);
        serviceThread.quit();
        super.tearDown();
    }
}

<MSG> Merge pull request #5423 from pstorch/fix_5414

fix #5414: import complete message for PQ import
<DFF> @@ -21,8 +21,12 @@ import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import android.net.Uri;
+import android.os.HandlerThread;
+import android.os.Looper;
 import android.os.Message;
 
+import junit.framework.Test;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,12 +34,13 @@ import java.util.Iterator;
 import java.util.List;
 
 public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
-    private final TestHandler importStepHandler = new TestHandler();
-    private final TestHandler progressHandler = new TestHandler();
+    private TestHandler importStepHandler;
+    private TestHandler progressHandler;
     private int listId;
     private File tempDir;
     private boolean importCacheStaticMaps;
     private boolean importWpStaticMaps;
+    private HandlerThread serviceThread;
 
     public void testGetWaypointsFileNameForGpxFile() throws IOException {
         final String[] gpxFiles = new String[] { "1234567.gpx", "1.gpx", "1234567.9.gpx",
@@ -115,6 +120,8 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
         } catch (final InterruptedException e) {
             Log.e("GPXImporterTest.runImportThread", e);
         }
+        importStepHandler.sendEmptyMessage(TestHandler.TERMINATION_MESSAGE); // send End Message
+
         importStepHandler.waitForCompletion();
     }
 
@@ -266,30 +273,58 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
         final ImportGpxZipAttachmentThread importThread = new ImportGpxZipAttachmentThread(uri, getInstrumentation().getContext().getContentResolver(), listId, importStepHandler, progressHandler);
         runImportThread(importThread);
 
-        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED);
+        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED);
         final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
         assert cache != null;
         assertThat(cache).isNotNull();
         assertCacheProperties(cache);
-        assertThat(cache.getWaypoints()).hasSize(1); // this is the original pocket query result without test waypoint
+        assertThat(cache.getWaypoints()).hasSize(0); // this is the original pocket query result without test waypoint
+        assertThat(importThread.getSourceDisplayName()).isEqualTo("17157344_Großer Ümlaut Täst.gpx");
+    }
+
+    public void testImportGpxZipAttachmentEntities() {
+        final String geocode = "GC448A";
+        removeCacheCompletely(geocode);
+        final Uri uri = Uri.parse("android.resource://cgeo.geocaching.test/raw/pq_entities");
+
+        final ImportGpxZipAttachmentThread importThread = new ImportGpxZipAttachmentThread(uri, getInstrumentation().getContext().getContentResolver(), listId, importStepHandler, progressHandler);
+        runImportThread(importThread);
+
+        assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED);
+        final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
+        assert cache != null;
+        assertThat(cache).isNotNull();
+        assertCacheProperties(cache);
+        assertThat(cache.getWaypoints()).hasSize(0); // this is the original pocket query result without test waypoint
+        assertThat(importThread.getSourceDisplayName()).isEqualTo("17157285_Großer Ümlaut Täst.gpx");
     }
 
     static class TestHandler extends CancellableHandler {
         private final List<Message> messages = new ArrayList<>();
         private long lastMessage = System.currentTimeMillis();
+        private boolean receivedTerminationMessage = false;
+        private static final int TERMINATION_MESSAGE = 9999;
+
+        public TestHandler(Looper serviceLooper) {
+            super(serviceLooper);
+        }
 
         @Override
         public synchronized void handleRegularMessage(final Message msg) {
             final Message msg1 = Message.obtain();
             msg1.copyFrom(msg);
-            messages.add(msg1);
+            if (msg1.what == TERMINATION_MESSAGE) {
+                receivedTerminationMessage = true;
+            } else {
+                messages.add(msg1);
+            }
             lastMessage = System.currentTimeMillis();
             notifyAll();
         }
 
         public synchronized void waitForCompletion(final long milliseconds) {
             try {
-                while (System.currentTimeMillis() - lastMessage <= milliseconds && !hasTerminatingMessage()) {
+                while ((System.currentTimeMillis() - lastMessage <= milliseconds) && !hasTerminatingMessage()) {
                     wait(milliseconds);
                 }
             } catch (final InterruptedException e) {
@@ -298,8 +333,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
         }
 
         private boolean hasTerminatingMessage() {
-            final Message recentMessage = messages.get(messages.size() - 1);
-            return recentMessage.what == GPXImporter.IMPORT_STEP_CANCELED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED_WITH_ERROR;
+            return receivedTerminationMessage;
         }
 
         public void waitForCompletion() {
@@ -312,6 +346,12 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
     protected void setUp() throws Exception {
         super.setUp();
 
+        serviceThread = new HandlerThread("[" + getClass().getSimpleName() + "Thread]");
+        serviceThread.start();
+        Looper serviceLooper = serviceThread.getLooper();
+        importStepHandler = new TestHandler(serviceLooper);
+        progressHandler = new TestHandler(serviceLooper);
+
         final String globalTempDir = System.getProperty("java.io.tmpdir");
         assertThat(StringUtils.isNotBlank(globalTempDir)).overridingErrorMessage("java.io.tmpdir is not defined").isTrue();
 
@@ -338,6 +378,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
         FileUtils.deleteDirectory(tempDir);
         TestSettings.setStoreOfflineMaps(importCacheStaticMaps);
         TestSettings.setStoreOfflineWpMaps(importWpStaticMaps);
+        serviceThread.quit();
         super.tearDown();
     }
 }

Merge pull request #5423 from pstorch/fix_5414