From bb1ef084748d30e82842d9196e8da4ab4a6d7dbd Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 5 Sep 2019 22:44:27 +0200 Subject: [PATCH] Splitted TrackRecordingServiceTest into two files and fixed issue about calling Looper.prepare() only once for all tests. --- .../dennisguse/opentracks/TrackStubUtils.java | 5 +- .../importer/GpxFileTrackImporterTest.java | 4 +- .../services/TrackRecordingServiceTest.java | 309 ++++-------------- .../TrackRecordingServiceTestLooper.java | 260 +++++++++++++++ .../AnnouncementPeriodicTaskFactoryTest.java | 2 +- .../tasks/AnnouncementPeriodicTaskTest.java | 14 +- .../file/importer/GpxFileTrackImporter.java | 6 +- 7 files changed, 343 insertions(+), 257 deletions(-) create mode 100644 src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java b/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java index 9a4587e5c..a2f0f5ca5 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java +++ b/src/androidTest/java/de/dennisguse/opentracks/TrackStubUtils.java @@ -23,8 +23,8 @@ import de.dennisguse.opentracks.content.Track; import de.dennisguse.opentracks.content.sensor.SensorDataSet; /** - * Commons utilities for creating stubs of track, location. The class will be - * enriched if needs more similar stubs for test. + * Commons utilities for creating stubs of track, location. + * The class will be enriched if needs more similar stubs for test. * * @author Youtao Liu */ @@ -85,5 +85,4 @@ public class TrackStubUtils { return new SensorDataSetLocation(loc, sd); } - } diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java index f72ed7c7d..f03a402ea 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporterTest.java @@ -222,8 +222,7 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { private void testInvalidGpx(String xml) { when(contentProviderUtils.insertTrack((Track) any())).thenReturn(TRACK_ID_0_URI); - // For the following, use StubReturn since we don't care whether they are - // invoked or not. + // For the following, use StubReturn since we don't care whether they are invoked or not. when(contentProviderUtils.bulkInsertTrackPoint((Location[]) any(), anyInt(), anyLong())).thenReturn(1); when(contentProviderUtils.getFirstTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_0); when(contentProviderUtils.getLastTrackPointId(TRACK_ID_0)).thenReturn(TRACK_POINT_ID_0); @@ -234,6 +233,5 @@ public class GpxFileTrackImporterTest extends AbstractTestFileTrackImporter { GpxFileTrackImporter gpxFileTrackImporter = new GpxFileTrackImporter(context, contentProviderUtils); long trackId = gpxFileTrackImporter.importFile(inputStream); Assert.assertEquals(-1L, trackId); - verify(contentProviderUtils); } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java index 52f8b91b3..9ec4d0934 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java @@ -41,6 +41,7 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import de.dennisguse.opentracks.R; @@ -65,12 +66,23 @@ import de.dennisguse.opentracks.util.PreferencesUtils; public class TrackRecordingServiceTest { @Rule - public final ServiceTestRule mServiceRule = new ServiceTestRule(); + public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS); private ContentProviderUtils providerUtils; private Context context = ApplicationProvider.getApplicationContext(); private long trackId = Math.abs(new Random().nextLong()); + static Intent createStartIntent(Context context) { + Intent startIntent = new Intent(); + startIntent.setClass(context, TrackRecordingService.class); + return startIntent; + } + + static void updateAutoResumePrefs(Context context, int attempts, int timeoutMins) { + PreferencesUtils.setInt(context, R.string.auto_resume_track_current_retry_key, attempts); + PreferencesUtils.setInt(context, R.string.auto_resume_track_timeout_key, timeoutMins); + } + @Before public void setUp() { // Set up the mock content resolver @@ -85,7 +97,7 @@ public class TrackRecordingServiceTest { sharedPreferences.edit().clear().apply(); // Disable auto resume by default. - updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, 0); + updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, 0); // Ensure that the database is empty before every test providerUtils.deleteAllTracks(context); @@ -94,8 +106,8 @@ public class TrackRecordingServiceTest { @After public void tearDown() throws TimeoutException { // Reset service (if some previous test failed) - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); - if (service.isRecording()) { + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); + if (service.isRecording() || service.isPaused()) { service.endCurrentTrack(); } @@ -106,14 +118,14 @@ public class TrackRecordingServiceTest { @SmallTest @Test public void testStartable() throws TimeoutException { - mServiceRule.startService(createStartIntent()); - Assert.assertNotNull(mServiceRule.bindService(createStartIntent())); + mServiceRule.startService(createStartIntent(context)); + Assert.assertNotNull(mServiceRule.bindService(createStartIntent(context))); } @MediumTest @Test public void testBindable() throws TimeoutException { - IBinder service = mServiceRule.bindService(createStartIntent()); + IBinder service = mServiceRule.bindService(createStartIntent(context)); Assert.assertNotNull(service); } @@ -124,10 +136,10 @@ public class TrackRecordingServiceTest { createDummyTrack(trackId, System.currentTimeMillis(), true); // Clear the number of attempts and set the timeout to 10 min. - updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); + updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); // Start the service in "resume" mode (simulates the on-reboot action). - Intent startIntent = createStartIntent(); + Intent startIntent = createStartIntent(context); startIntent.putExtra(TrackRecordingService.RESUME_TRACK_EXTRA_NAME, true); ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(startIntent)); Assert.assertNotNull(service); @@ -140,8 +152,8 @@ public class TrackRecordingServiceTest { @MediumTest @Test public void testResumeAfterReboot_simulateReboot() throws Exception { - updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); // Simulate recording a track. @@ -152,10 +164,10 @@ public class TrackRecordingServiceTest { Assert.assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key)); // Start the service in "resume" mode (simulates the on-reboot action). - Intent startIntent = createStartIntent(); + Intent startIntent = createStartIntent(context); startIntent.putExtra(TrackRecordingService.RESUME_TRACK_EXTRA_NAME, true); mServiceRule.startService(startIntent); - service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertNotNull(service); Assert.assertTrue(service.isRecording()); @@ -168,11 +180,10 @@ public class TrackRecordingServiceTest { createDummyTrack(trackId, System.currentTimeMillis(), false); // Clear the number of attempts and set the timeout to 10 min. - updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, - PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); + updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); // Start the service in "resume" mode (simulates the on-reboot action). - Intent startIntent = createStartIntent(); + Intent startIntent = createStartIntent(context); startIntent.putExtra(TrackRecordingService.RESUME_TRACK_EXTRA_NAME, true); ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(startIntent)); Assert.assertNotNull(service); @@ -189,11 +200,10 @@ public class TrackRecordingServiceTest { createDummyTrack(trackId, System.currentTimeMillis() - 20 * 60 * 1000, true); // Clear the number of attempts and set the timeout to 10 min. - updateAutoResumePrefs(PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, - PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); + updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); // Start the service in "resume" mode (simulates the on-reboot action). - Intent startIntent = createStartIntent(); + Intent startIntent = createStartIntent(context); startIntent.putExtra(TrackRecordingService.RESUME_TRACK_EXTRA_NAME, true); ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(startIntent)); Assert.assertNotNull(service); @@ -210,10 +220,10 @@ public class TrackRecordingServiceTest { createDummyTrack(trackId, System.currentTimeMillis(), true); // Set the number of attempts to max. - updateAutoResumePrefs(TrackRecordingService.MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); + updateAutoResumePrefs(context, TrackRecordingService.MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS, PreferencesUtils.AUTO_RESUME_TRACK_TIMEOUT_DEFAULT); // Start the service in "resume" mode (simulates the on-reboot action). - Intent startIntent = createStartIntent(); + Intent startIntent = createStartIntent(context); startIntent.putExtra(TrackRecordingService.RESUME_TRACK_EXTRA_NAME, true); //Explicit start service, so `startCommand()` is executed - which would be called by BootReceiver. @@ -233,7 +243,7 @@ public class TrackRecordingServiceTest { List tracks = providerUtils.getAllTracks(); Assert.assertTrue(tracks.isEmpty()); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); // Test if we start in no-recording mode by default. Assert.assertFalse(service.isRecording()); Assert.assertEquals(-1L, service.getRecordingTrackId()); @@ -244,7 +254,7 @@ public class TrackRecordingServiceTest { public void testRecording_oldTracks() throws Exception { createDummyTrack(trackId, -1L, false); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); Assert.assertEquals(-1L, service.getRecordingTrackId()); } @@ -256,7 +266,7 @@ public class TrackRecordingServiceTest { PreferencesUtils.setLong(context, R.string.recording_track_id_key, 123L); // Make sure that the service will not start recording and will clear the bogus track. - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); Assert.assertEquals(-1L, service.getRecordingTrackId()); } @@ -274,7 +284,7 @@ public class TrackRecordingServiceTest { List tracks = providerUtils.getAllTracks(); Assert.assertTrue(tracks.isEmpty()); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); long id = service.startNewTrack(); @@ -303,7 +313,7 @@ public class TrackRecordingServiceTest { public void testStartNewTrack_alreadyRecording() throws Exception { createDummyTrack(trackId, -1L, true); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertTrue(service.isRecording()); // Starting a new track when there is a recording should just return -1L. @@ -324,7 +334,7 @@ public class TrackRecordingServiceTest { createDummyTrack(trackId, -1L, true); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertTrue(service.isRecording()); // End the current track. @@ -347,7 +357,7 @@ public class TrackRecordingServiceTest { @MediumTest @Test public void testEndCurrentTrack_noRecording() throws Exception { - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); /* @@ -359,18 +369,10 @@ public class TrackRecordingServiceTest { Assert.assertEquals(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT, service.getRecordingTrackId()); } - @MediumTest - @Test - public void testIntegration_completeRecordingSession() throws Exception { - List tracks = providerUtils.getAllTracks(); - Assert.assertTrue(tracks.isEmpty()); - fullRecordingSession(); - } - @MediumTest @Test public void testInsertStatisticsMarker_noRecordingTrack() throws Exception { - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertFalse(service.isRecording()); long waypointId = service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); @@ -382,7 +384,7 @@ public class TrackRecordingServiceTest { public void testInsertStatisticsMarker_validLocation() throws Exception { createDummyTrack(trackId, -1L, true); - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); Assert.assertTrue(service.isRecording()); Assert.assertFalse(service.isPaused()); insertLocation(service); @@ -405,149 +407,6 @@ public class TrackRecordingServiceTest { // TODO: Check waypoint 2. } - @MediumTest - @Test - public void testInsertWaypointMarker_noRecordingTrack() throws Exception { - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); - Assert.assertFalse(service.isRecording()); - - long waypointId = service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); - Assert.assertEquals(-1L, waypointId); - } - - @MediumTest - @Test - public void testInsertWaypointMarker_validWaypoint() throws Exception { - createDummyTrack(trackId, -1L, true); - - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); - Assert.assertTrue(service.isRecording()); - insertLocation(service); - - long waypointId = service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); - Assert.assertNotEquals(-1L, waypointId); - Waypoint wpt = providerUtils.getWaypoint(waypointId); - Assert.assertEquals(context.getString(R.string.marker_waypoint_icon_url), wpt.getIcon()); - Assert.assertEquals(context.getString(R.string.marker_name_format, 1), wpt.getName()); - Assert.assertEquals(WaypointType.WAYPOINT, wpt.getType()); - Assert.assertEquals(trackId, wpt.getTrackId()); - Assert.assertEquals(0.0, wpt.getLength(), 0.01); - Assert.assertNotNull(wpt.getLocation()); - Assert.assertNull(wpt.getTripStatistics()); - } - - @MediumTest - @Test - public void testWithProperties_voiceFrequencyDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.voice_frequency_key, PreferencesUtils.VOICE_FREQUENCY_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_voiceFrequencyByDistance() throws Exception { - PreferencesUtils.setInt(context, R.string.voice_frequency_key, -1); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_voiceFrequencyByTime() throws Exception { - PreferencesUtils.setInt(context, R.string.voice_frequency_key, 1); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_maxRecordingDistanceDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.max_recording_distance_key, PreferencesUtils.MAX_RECORDING_DISTANCE_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_maxRecordingDistance() throws Exception { - PreferencesUtils.setInt(context, R.string.max_recording_distance_key, 50); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRecordingDistanceDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.recording_distance_interval_key, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRecordingDistance() throws Exception { - PreferencesUtils.setInt(context, R.string.recording_distance_interval_key, 2); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_splitFrequencyDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.split_frequency_key, PreferencesUtils.SPLIT_FREQUENCY_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_splitFrequencyByDistance() throws Exception { - PreferencesUtils.setInt(context, R.string.split_frequency_key, -1); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_splitFrequencyByTime() throws Exception { - PreferencesUtils.setInt(context, R.string.split_frequency_key, 1); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_metricUnitsDefault() throws Exception { - PreferencesUtils.setString(context, R.string.stats_units_key, PreferencesUtils.STATS_UNITS_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_metricUnitsDisabled() throws Exception { - PreferencesUtils.setString(context, R.string.stats_units_key, context.getString(R.string.stats_units_imperial)); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRecordingIntervalDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.min_recording_interval_key, PreferencesUtils.MIN_RECORDING_INTERVAL_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRecordingInterval() throws Exception { - PreferencesUtils.setInt(context, R.string.min_recording_interval_key, 2); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRequiredAccuracyDefault() throws Exception { - PreferencesUtils.setInt(context, R.string.recording_gps_accuracy_key, PreferencesUtils.RECORDING_GPS_ACCURACY_DEFAULT); - fullRecordingSession(); - } - - @MediumTest - @Test - public void testWithProperties_minRequiredAccuracy() throws Exception { - PreferencesUtils.setInt(context, R.string.recording_gps_accuracy_key, 500); - fullRecordingSession(); - } - private Track createDummyTrack(long id, long stopTime, boolean isRecording) { Track dummyTrack = new Track(); dummyTrack.setId(id); @@ -559,17 +418,6 @@ public class TrackRecordingServiceTest { return dummyTrack; } - private void updateAutoResumePrefs(int attempts, int timeoutMins) { - PreferencesUtils.setInt(context, R.string.auto_resume_track_current_retry_key, attempts); - PreferencesUtils.setInt(context, R.string.auto_resume_track_timeout_key, timeoutMins); - } - - private Intent createStartIntent() { - Intent startIntent = new Intent(); - startIntent.setClass(context, TrackRecordingService.class); - return startIntent; - } - private void addTrack(Track track, boolean isRecording) { Assert.assertTrue(track.getId() >= 0); providerUtils.insertTrack(track); @@ -578,52 +426,6 @@ public class TrackRecordingServiceTest { PreferencesUtils.setBoolean(context, R.string.recording_track_paused_key, !isRecording); } - private void fullRecordingSession() throws Exception { - ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent())); - Assert.assertFalse(service.isRecording()); - - // Start a track. - long id = service.startNewTrack(); - Assert.assertTrue(id >= 0); - Assert.assertTrue(service.isRecording()); - Track track = providerUtils.getTrack(id); - Assert.assertNotNull(track); - Assert.assertEquals(id, track.getId()); - Assert.assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key)); - Assert.assertEquals(id, service.getRecordingTrackId()); - - // Insert a few points, markers and statistics. - long startTime = System.currentTimeMillis(); - for (int i = 0; i < 30; i++) { - Location loc = new Location("gps"); - loc.setLongitude(35.0f + i / 10.0f); - loc.setLatitude(45.0f - i / 5.0f); - loc.setAccuracy(5); - loc.setSpeed(10); - loc.setTime(startTime + i * 10000); - loc.setBearing(3.0f); - service.insertTrackPoint(loc); - - if (i % 10 == 0) { - service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); - } else if (i % 7 == 0) { - service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); - } - } - - // Stop the track. Validate if it has correct data. - service.endCurrentTrack(); - Assert.assertFalse(service.isRecording()); - Assert.assertEquals(-1L, service.getRecordingTrackId()); - track = providerUtils.getTrack(id); - Assert.assertNotNull(track); - Assert.assertEquals(id, track.getId()); - TripStatistics tripStatistics = track.getTripStatistics(); - Assert.assertNotNull(tripStatistics); - Assert.assertTrue(tripStatistics.getStartTime() > 0); - Assert.assertTrue(tripStatistics.getStopTime() >= tripStatistics.getStartTime()); - } - /** * Inserts a location and waits for 100ms. */ @@ -640,6 +442,37 @@ public class TrackRecordingServiceTest { Thread.sleep(200); } + @MediumTest + @Test + public void testInsertWaypointMarker_noRecordingTrack() throws Exception { + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); + Assert.assertFalse(service.isRecording()); + + long waypointId = service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); + Assert.assertEquals(-1L, waypointId); + } + + @MediumTest + @Test + public void testInsertWaypointMarker_validWaypoint() throws Exception { + createDummyTrack(trackId, -1L, true); + + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(createStartIntent(context))); + Assert.assertTrue(service.isRecording()); + insertLocation(service); + + long waypointId = service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); + Assert.assertNotEquals(-1L, waypointId); + Waypoint wpt = providerUtils.getWaypoint(waypointId); + Assert.assertEquals(context.getString(R.string.marker_waypoint_icon_url), wpt.getIcon()); + Assert.assertEquals(context.getString(R.string.marker_name_format, 1), wpt.getName()); + Assert.assertEquals(WaypointType.WAYPOINT, wpt.getType()); + Assert.assertEquals(trackId, wpt.getTrackId()); + Assert.assertEquals(0.0, wpt.getLength(), 0.01); + Assert.assertNotNull(wpt.getLocation()); + Assert.assertNull(wpt.getTripStatistics()); + } + /** * Synchronous/waitable broadcast receiver to be used in testing. */ diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java new file mode 100644 index 000000000..7ceb67a08 --- /dev/null +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLooper.java @@ -0,0 +1,260 @@ +package de.dennisguse.opentracks.services; + +import android.content.ContentProvider; +import android.content.Context; +import android.content.SharedPreferences; +import android.location.Location; +import android.os.Looper; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.MediumTest; +import androidx.test.rule.ServiceTestRule; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.content.ContentProviderUtils; +import de.dennisguse.opentracks.content.CustomContentProvider; +import de.dennisguse.opentracks.content.Track; +import de.dennisguse.opentracks.content.WaypointCreationRequest; +import de.dennisguse.opentracks.stats.TripStatistics; +import de.dennisguse.opentracks.util.PreferencesUtils; + +/** + * Tests for the track recording service, which require a {@link Looper}. + * + * @author Bartlomiej Niechwiej + *

+ * ATTENTION: This tests deletes all stored tracks in the database. + * So, if it is executed on a real device, data might be lost. + */ +@RunWith(AndroidJUnit4.class) +public class TrackRecordingServiceTestLooper { + + @Rule + public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS); + private ContentProviderUtils providerUtils; + private Context context = ApplicationProvider.getApplicationContext(); + + @BeforeClass + public static void preSetUp() { + // Prepare looper for Android's message queue + if (Looper.myLooper() == null) Looper.prepare(); + } + + @AfterClass + public static void finalTearDown() { + if (Looper.myLooper() != null) Looper.myLooper().quit(); + } + + @Before + public void setUp() { + // Set up the mock content resolver + ContentProvider customContentProvider = new CustomContentProvider() { + }; + customContentProvider.attachInfo(context, null); + + providerUtils = ContentProviderUtils.Factory.get(context); + + // Let's use default values. + SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context); + sharedPreferences.edit().clear().apply(); + + // Disable auto resume by default. + TrackRecordingServiceTest.updateAutoResumePrefs(context, PreferencesUtils.AUTO_RESUME_TRACK_CURRENT_RETRY_DEFAULT, 0); + + // Ensure that the database is empty before every test + providerUtils.deleteAllTracks(context); + } + + @After + public void tearDown() throws TimeoutException { + // Reset service (if some previous test failed) + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context))); + if (service.isRecording() || service.isPaused()) { + service.endCurrentTrack(); + } + + // Ensure that the database is empty after every test + providerUtils.deleteAllTracks(context); + } + + @MediumTest + @Test + public void testWithProperties_minRequiredAccuracy() throws Exception { + PreferencesUtils.setInt(context, R.string.recording_gps_accuracy_key, 500); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_voiceFrequencyDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.voice_frequency_key, PreferencesUtils.VOICE_FREQUENCY_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_voiceFrequencyByDistance() throws Exception { + PreferencesUtils.setInt(context, R.string.voice_frequency_key, -1); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_voiceFrequencyByTime() throws Exception { + PreferencesUtils.setInt(context, R.string.voice_frequency_key, 1); + fullRecordingSession(); + } + + + @MediumTest + @Test + public void testWithProperties_maxRecordingDistanceDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.max_recording_distance_key, PreferencesUtils.MAX_RECORDING_DISTANCE_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_maxRecordingDistance() throws Exception { + PreferencesUtils.setInt(context, R.string.max_recording_distance_key, 50); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_minRecordingDistanceDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.recording_distance_interval_key, PreferencesUtils.RECORDING_DISTANCE_INTERVAL_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_minRecordingDistance() throws Exception { + PreferencesUtils.setInt(context, R.string.recording_distance_interval_key, 2); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_splitFrequencyDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.split_frequency_key, PreferencesUtils.SPLIT_FREQUENCY_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_splitFrequencyByDistance() throws Exception { + PreferencesUtils.setInt(context, R.string.split_frequency_key, -1); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_splitFrequencyByTime() throws Exception { + PreferencesUtils.setInt(context, R.string.split_frequency_key, 1); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_metricUnitsDefault() throws Exception { + PreferencesUtils.setString(context, R.string.stats_units_key, PreferencesUtils.STATS_UNITS_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_metricUnitsDisabled() throws Exception { + PreferencesUtils.setString(context, R.string.stats_units_key, context.getString(R.string.stats_units_imperial)); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_minRecordingIntervalDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.min_recording_interval_key, PreferencesUtils.MIN_RECORDING_INTERVAL_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_minRecordingInterval() throws Exception { + PreferencesUtils.setInt(context, R.string.min_recording_interval_key, 2); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testWithProperties_minRequiredAccuracyDefault() throws Exception { + PreferencesUtils.setInt(context, R.string.recording_gps_accuracy_key, PreferencesUtils.RECORDING_GPS_ACCURACY_DEFAULT); + fullRecordingSession(); + } + + @MediumTest + @Test + public void testIntegration_completeRecordingSession() throws Exception { + List tracks = providerUtils.getAllTracks(); + Assert.assertTrue(tracks.isEmpty()); + fullRecordingSession(); + } + + private void fullRecordingSession() throws Exception { + ITrackRecordingService service = ((ITrackRecordingService) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context))); + Assert.assertFalse(service.isRecording()); + + // Start a track. + long id = service.startNewTrack(); + Assert.assertTrue(id >= 0); + Assert.assertTrue(service.isRecording()); + Track track = providerUtils.getTrack(id); + Assert.assertNotNull(track); + Assert.assertEquals(id, track.getId()); + Assert.assertEquals(id, PreferencesUtils.getLong(context, R.string.recording_track_id_key)); + Assert.assertEquals(id, service.getRecordingTrackId()); + + // Insert a few points, markers and statistics. + long startTime = System.currentTimeMillis(); + for (int i = 0; i < 30; i++) { + Location location = new Location("gps"); + location.setLongitude(35.0f + i / 10.0f); + location.setLatitude(45.0f - i / 5.0f); + location.setAccuracy(5); + location.setSpeed(10); + location.setTime(startTime + i * 10000); + location.setBearing(3.0f); + service.insertTrackPoint(location); + + if (i % 10 == 0) { + service.insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); + } else if (i % 7 == 0) { + service.insertWaypoint(WaypointCreationRequest.DEFAULT_WAYPOINT); + } + } + + // Stop the track. Validate if it has correct data. + service.endCurrentTrack(); + Assert.assertFalse(service.isRecording()); + Assert.assertEquals(-1L, service.getRecordingTrackId()); + track = providerUtils.getTrack(id); + Assert.assertNotNull(track); + Assert.assertEquals(id, track.getId()); + TripStatistics tripStatistics = track.getTripStatistics(); + Assert.assertNotNull(tripStatistics); + Assert.assertTrue(tripStatistics.getStartTime() > 0); + Assert.assertTrue(tripStatistics.getStopTime() >= tripStatistics.getStartTime()); + } +} diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskFactoryTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskFactoryTest.java index 98063baeb..f56e7bdce 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskFactoryTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskFactoryTest.java @@ -42,7 +42,7 @@ public class AnnouncementPeriodicTaskFactoryTest { @BeforeClass public static void preSetUp() { // Prepare looper for Android's message queue - Looper.prepare(); + if (Looper.myLooper() == null) Looper.prepare(); } @AfterClass diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskTest.java index ac9ae027c..d598a23b0 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/tasks/AnnouncementPeriodicTaskTest.java @@ -79,7 +79,7 @@ public class AnnouncementPeriodicTaskTest { @BeforeClass public static void preSetUp() { // Prepare looper for Android's message queue - Looper.prepare(); + if (Looper.myLooper() == null) Looper.prepare(); } @AfterClass @@ -291,7 +291,7 @@ public class AnnouncementPeriodicTaskTest { */ @Test public void testGetAnnounceTime_time_one() { - long time = 1 * 1000; // 1 second + long time = 1000; // 1 second Assert.assertEquals("0 minutes 1 second", task.getAnnounceTime(time)); } @@ -301,7 +301,7 @@ public class AnnouncementPeriodicTaskTest { */ @Test public void testGetAnnounceTime_singular_has_hour() { - long time = (1 * 60 * 60 * 1000) + (1 * 60 * 1000) + (1 * 1000); // 1 hour 1 minute 1 second + long time = (60 * 60 * 1000) + (60 * 1000) + (1000); // 1 hour 1 minute 1 second Assert.assertEquals("1 hour 1 minute 1 second", task.getAnnounceTime(time)); } @@ -377,10 +377,7 @@ public class AnnouncementPeriodicTaskTest { int playEarcon(String earcon, int queueMode, HashMap params); - int playSilence(long durationInMs, int queueMode, - HashMap params); - - int setEngineByPackageName(String enginePackageName); + int playSilence(long durationInMs, int queueMode, HashMap params); int setLanguage(Locale loc); @@ -396,8 +393,7 @@ public class AnnouncementPeriodicTaskTest { int stop(); - int synthesizeToFile(String text, HashMap params, - String filename); + int synthesizeToFile(String text, HashMap params, String filename); } /** diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java index 463afbc63..a911a3c9f 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GpxFileTrackImporter.java @@ -21,12 +21,12 @@ import android.location.Location; import androidx.annotation.VisibleForTesting; -import de.dennisguse.opentracks.content.ContentProviderUtils; -import de.dennisguse.opentracks.content.Waypoint.WaypointType; - import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import de.dennisguse.opentracks.content.ContentProviderUtils; +import de.dennisguse.opentracks.content.Waypoint.WaypointType; + /** * Imports a GPX file. *