diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index ae68ed8a3..d8bafea82 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -23,7 +23,9 @@ import org.junit.runner.RunWith; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.time.Clock; import java.time.Instant; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -42,6 +44,7 @@ import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.exporter.TrackExporter; import de.dennisguse.opentracks.services.TrackRecordingService; +import de.dennisguse.opentracks.services.handlers.HandlerServer; import de.dennisguse.opentracks.stats.TrackStatistics; import static org.junit.Assert.assertEquals; @@ -51,13 +54,10 @@ import static org.junit.Assert.assertTrue; /** * Export a track to {@link TrackFileFormat} and verify that the import is identical. - *

*/ @RunWith(AndroidJUnit4.class) public class ExportImportTest { - private static final String TAG = ExportImportTest.class.getSimpleName(); - @Rule public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS); @@ -99,32 +99,43 @@ public class ExportImportTest { } @After - public void FileTearDown() { + public void FileTearDown() throws TimeoutException { tmpFile.deleteOnExit(); tmpFileUri = null; + + TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class))) + .getService(); + service.getHandlerServer().setClock(Clock.systemUTC()); } public void setUp(boolean hasSensorDistance) throws TimeoutException { TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class))) .getService(); + HandlerServer handlerServer = service.getHandlerServer(); + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); trackId = service.startNewTrack(); Distance sensorDistance = hasSensorDistance ? Distance.of(5) : null; - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14, 10, 15, 10, 1, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:03Z"), 3, 14, 10, 15, 10, 1, 66, 3, 50, sensorDistance), 0); service.insertMarker("Marker 1", "Marker 1 category", "Marker 1 desc", null); - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.002, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:04Z"), 3, 14.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:05Z"), 3, 14.002, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); service.insertMarker("Marker 2", "Marker 2 category", "Marker 2 desc", null); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:06Z"), ZoneId.of("CET"))); service.pauseCurrentTrack(); + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:20Z"), ZoneId.of("CET"))); service.resumeCurrentTrack(); - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 14.003, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); - service.newTrackPoint(createTrackPoint(System.currentTimeMillis(), 3, 16.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:21Z"), 3, 14.003, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:22Z"), 3, 16, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + service.newTrackPoint(createTrackPoint(Instant.parse("2020-02-02T02:02:23Z"), 3, 16.001, 10, 15, 10, 0, 66, 3, 50, sensorDistance), 0); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:24Z"), ZoneId.of("CET"))); service.endCurrentTrack(); track = contentProviderUtils.getTrack(trackId); @@ -395,8 +406,8 @@ public class ExportImportTest { assertEquals(trackStatistics.getTotalAltitudeLoss(), importedTrackStatistics.getTotalAltitudeLoss(), delta); } - private static TrackPoint createTrackPoint(long time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) { - TrackPoint tp = new TrackPoint(latitude, longitude, Altitude.WGS84.of(altitude), Instant.ofEpochMilli(time)); + private static TrackPoint createTrackPoint(Instant time, double latitude, double longitude, float accuracy, float speed, float altitude, float altitudeGain, float heartRate, float cyclingCadence, float power, Distance distance) { + TrackPoint tp = new TrackPoint(latitude, longitude, Altitude.WGS84.of(altitude), time); tp.setAccuracy(accuracy); tp.setSpeed(Speed.of(speed)); tp.setHeartRate_bpm(heartRate); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java index c74980298..e36f59d4c 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java @@ -90,7 +90,7 @@ public class TrackPointAssert { try { assertEquals(expected.get(i), actual.get(i)); } catch (AssertionError e) { - throw new AssertionError("Expected: " + expected.get(i) + " actual: " + actual.get(i)); + throw new AssertionError("Expected: " + expected.get(i) + " actual: " + actual.get(i), e); } } Assert.assertEquals(expected.size(), actual.size()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java index 28024c2e1..3ac86e766 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java @@ -22,6 +22,7 @@ import android.content.SharedPreferences; import android.os.IBinder; import android.os.Looper; +import androidx.annotation.NonNull; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.MediumTest; @@ -37,7 +38,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import java.time.Clock; import java.time.Instant; +import java.time.ZoneId; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -51,6 +54,9 @@ import de.dennisguse.opentracks.content.data.Track; import de.dennisguse.opentracks.content.data.TrackPoint; import de.dennisguse.opentracks.content.provider.ContentProviderUtils; import de.dennisguse.opentracks.content.provider.CustomContentProvider; +import de.dennisguse.opentracks.io.file.importer.TrackPointAssert; +import de.dennisguse.opentracks.services.handlers.HandlerServer; +import de.dennisguse.opentracks.services.sensors.AltitudeSumManager; import de.dennisguse.opentracks.stats.TrackStatistics; import de.dennisguse.opentracks.util.PreferencesUtils; @@ -99,8 +105,16 @@ public class TrackRecordingServiceTest { return new Intent(context, TrackRecordingService.class); } + private final AltitudeSumManager altitudeSumManager = new AltitudeSumManager() { + @Override + public void fill(@NonNull TrackPoint trackPoint) { + trackPoint.setAltitudeGain(0f); + trackPoint.setAltitudeLoss(0f); + } + }; + @Before - public void setUp() { + public void setUp() throws TimeoutException { // Set up the mock content resolver ContentProvider customContentProvider = new CustomContentProvider() { }; @@ -123,6 +137,7 @@ public class TrackRecordingServiceTest { if (service.isRecording() || service.isPaused()) { service.endCurrentTrack(); } + service.getHandlerServer().setClock(Clock.systemUTC()); // Ensure that the database is empty after every test contentProviderUtils.deleteAllTracks(context); @@ -189,40 +204,34 @@ public class TrackRecordingServiceTest { assertTrue(service.isRecording()); } - @MediumTest - @Test - public void testRecording_start() throws TimeoutException { - // given - TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) - .getService(); - - // when - Track.Id trackId = service.startNewTrack(); - - // then - List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); - - assertEquals(1, trackPoints.size()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType()); - } - @MediumTest @Test public void testRecording_stop() throws TimeoutException { // given TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) .getService(); + + HandlerServer handlerServer = service.getHandlerServer(); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); Track.Id trackId = service.startNewTrack(); + handlerServer.stopGPS(); + handlerServer.setAltitudeSumManager(altitudeSumManager); // when + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:03Z"), ZoneId.of("CET"))); service.endCurrentTrack(); // then List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); - assertEquals(2, trackPoints.size()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType()); - assertEquals(TrackPoint.Type.SEGMENT_END_MANUAL, trackPoints.get(1).getType()); + TrackPointAssert a = new TrackPointAssert(); + a.assertEquals(List.of( + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:02Z")), + new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:02:03Z")) + .setAltitudeGain(0f) + .setAltitudeLoss(0f) + ), trackPoints); } @MediumTest @@ -231,25 +240,37 @@ public class TrackRecordingServiceTest { // given TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) .getService(); + + HandlerServer handlerServer = service.getHandlerServer(); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); Track.Id trackId = service.startNewTrack(); + handlerServer.stopGPS(); + handlerServer.setAltitudeSumManager(altitudeSumManager); // when + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:03Z"), ZoneId.of("CET"))); service.pauseCurrentTrack(); // then assertEquals(2, contentProviderUtils.getTrackPointCursor(trackId, null).getCount()); //when + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:04Z"), ZoneId.of("CET"))); service.resumeTrack(trackId); // then assertTrue(service.isRecording()); List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); - assertEquals(3, trackPoints.size()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType()); - assertEquals(TrackPoint.Type.SEGMENT_END_MANUAL, trackPoints.get(1).getType()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(2).getType()); + TrackPointAssert a = new TrackPointAssert(); + a.assertEquals(List.of( + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:02Z")), + new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:02:03Z")) + .setAltitudeGain(0f) + .setAltitudeLoss(0f), + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:04Z")) + ), trackPoints); } @MediumTest @@ -258,25 +279,40 @@ public class TrackRecordingServiceTest { // given TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) .getService(); + + HandlerServer handlerServer = service.getHandlerServer(); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); Track.Id trackId = service.startNewTrack(); - assertTrue(service.isRecording()); + handlerServer.stopGPS(); + handlerServer.setAltitudeSumManager(altitudeSumManager); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:03Z"), ZoneId.of("CET"))); service.endCurrentTrack(); - assertEquals(2, contentProviderUtils.getTrackPointCursor(trackId, null).getCount()); - // when + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:04Z"), ZoneId.of("CET"))); service.resumeTrack(trackId); - newTrackPoint(service); + handlerServer.stopGPS(); + handlerServer.setAltitudeSumManager(altitudeSumManager); + + handlerServer.onNewTrackPoint(new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:05Z")), 50); // then assertTrue(service.isRecording()); List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); - assertEquals(4, trackPoints.size()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType()); - assertEquals(TrackPoint.Type.SEGMENT_END_MANUAL, trackPoints.get(1).getType()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(2).getType()); - assertEquals(TrackPoint.Type.TRACKPOINT, trackPoints.get(3).getType()); + TrackPointAssert a = new TrackPointAssert(); + a.assertEquals(List.of( + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:02Z")), + new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:02:03Z")) + .setAltitudeGain(0f) + .setAltitudeLoss(0f), + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:04Z")), + new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:05Z")) + .setAltitudeGain(0f) + .setAltitudeLoss(0f) + ), trackPoints); } @MediumTest @@ -285,22 +321,32 @@ public class TrackRecordingServiceTest { // given TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) .getService(); + + HandlerServer handlerServer = service.getHandlerServer(); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); Track.Id trackId = service.startNewTrack(); - assertTrue(service.isRecording()); + handlerServer.stopGPS(); + handlerServer.setAltitudeSumManager(altitudeSumManager); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:03Z"), ZoneId.of("CET"))); service.pauseCurrentTrack(); - assertEquals(2, contentProviderUtils.getTrackPointCursor(trackId, null).getCount()); - // when + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:04Z"), ZoneId.of("CET"))); service.endCurrentTrack(); // then assertFalse(service.isRecording()); List trackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); - assertEquals(2, trackPoints.size()); - assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType()); - assertEquals(TrackPoint.Type.SEGMENT_END_MANUAL, trackPoints.get(1).getType()); + TrackPointAssert a = new TrackPointAssert(); + a.assertEquals(List.of( + new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse("2020-02-02T02:02:02Z")), + new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:02:03Z")) + .setAltitudeGain(0f) + .setAltitudeLoss(0f) + ), trackPoints); } @MediumTest @@ -357,9 +403,19 @@ public class TrackRecordingServiceTest { // given TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(createStartIntent(context))) .getService(); + + HandlerServer handlerServer = service.getHandlerServer(); + handlerServer.stopGPS(); + + handlerServer.setClock(Clock.fixed(Instant.parse("2020-02-02T02:02:02Z"), ZoneId.of("CET"))); Track.Id trackId = service.startNewTrack(); + assertTrue(service.isRecording()); - newTrackPoint(service); + handlerServer.onNewTrackPoint( + new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:03Z")) + .setLatitude(10) + .setLongitude(10) + , 50); // when Marker.Id markerId = service.insertMarker(null, null, null, null); @@ -395,10 +451,6 @@ public class TrackRecordingServiceTest { addTrack(dummyTrack); } - private static void newTrackPoint(TrackRecordingService trackRecordingService) throws InterruptedException { - newTrackPoint(trackRecordingService, 45.0f, 35f, 5, 10, System.currentTimeMillis()); - } - static void newTrackPoint(TrackRecordingService trackRecordingService, double latitude, double longitude, float accuracy, long speed) throws InterruptedException { newTrackPoint(trackRecordingService, latitude, longitude, accuracy, speed, System.currentTimeMillis()); } diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/HandlerServer.java b/src/main/java/de/dennisguse/opentracks/services/handlers/HandlerServer.java index 956f1b0d6..04e08436b 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/HandlerServer.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/HandlerServer.java @@ -28,8 +28,8 @@ public class HandlerServer { // Disabled to simplify testing and implementation of #822 // private ExecutorService serviceExecutor; - @VisibleForTesting - private Clock clock; + @NonNull + private Clock clock = Clock.systemUTC(); private final LocationHandler locationHandler; private final EGM2008CorrectionManager egm2008CorrectionManager = new EGM2008CorrectionManager(); @@ -151,11 +151,7 @@ public class HandlerServer { //TODO Limit visibility public Instant createNow() { - if (clock != null) { - return Instant.now(clock); - } else { - return Instant.now(); - } + return Instant.now(clock); } @Deprecated @@ -170,6 +166,11 @@ public class HandlerServer { this.remoteSensorManager = remoteSensorManager; } + @VisibleForTesting + public void setClock(@NonNull Clock clock) { + this.clock = clock; + } + void sendGpsStatus(GpsStatusValue gpsStatusValue) { service.newGpsStatus(gpsStatusValue); }