Making data hub tests run considerably faster.

This commit is contained in:
Rodrigo Damazio
2011-05-19 21:42:40 -03:00
parent f657c2f1d1
commit da928fb549
2 changed files with 30 additions and 23 deletions
@@ -15,11 +15,13 @@
*/ */
package com.google.android.apps.mytracks.content; package com.google.android.apps.mytracks.content;
import static com.google.android.apps.mytracks.Constants.DEFAULT_MIN_REQUIRED_ACCURACY;
import static com.google.android.apps.mytracks.Constants.MAX_DISPLAYED_WAYPOINTS_POINTS;
import static com.google.android.apps.mytracks.Constants.TARGET_DISPLAYED_TRACK_POINTS;
import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS; import static com.google.android.apps.mytracks.Constants.MAX_LOCATION_AGE_MS;
import static com.google.android.apps.mytracks.Constants.MAX_NETWORK_AGE_MS; import static com.google.android.apps.mytracks.Constants.MAX_NETWORK_AGE_MS;
import static com.google.android.apps.mytracks.Constants.TAG; import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.DataSourceManager.DataSourceListener; import com.google.android.apps.mytracks.content.DataSourceManager.DataSourceListener;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.DoubleBufferedLocationFactory; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.DoubleBufferedLocationFactory;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator; import com.google.android.apps.mytracks.content.MyTracksProviderUtils.LocationIterator;
@@ -63,6 +65,9 @@ public class TrackDataHub {
private final String METRIC_UNITS_KEY; private final String METRIC_UNITS_KEY;
private final String SPEED_REPORTING_KEY; private final String SPEED_REPORTING_KEY;
// Overridable constants
private final int targetNumPoints;
/** Types of data that we can expose. */ /** Types of data that we can expose. */
public static enum ListenerDataType { public static enum ListenerDataType {
/** Listen to when the selected track changes. */ /** Listen to when the selected track changes. */
@@ -193,7 +198,7 @@ public class TrackDataHub {
public TrackDataHub(Context ctx, SharedPreferences preferences, public TrackDataHub(Context ctx, SharedPreferences preferences,
MyTracksProviderUtils providerUtils) { MyTracksProviderUtils providerUtils) {
this(ctx, new DataSourcesWrapperImpl(ctx, preferences), new TrackDataListeners(), this(ctx, new DataSourcesWrapperImpl(ctx, preferences), new TrackDataListeners(),
preferences, providerUtils); preferences, providerUtils, TARGET_DISPLAYED_TRACK_POINTS);
} }
/** /**
@@ -201,12 +206,13 @@ public class TrackDataHub {
*/ */
// @VisibleForTesting // @VisibleForTesting
TrackDataHub(Context ctx, DataSourcesWrapper dataSources, TrackDataListeners listeners, TrackDataHub(Context ctx, DataSourcesWrapper dataSources, TrackDataListeners listeners,
SharedPreferences preferences, MyTracksProviderUtils providerUtils) { SharedPreferences preferences, MyTracksProviderUtils providerUtils, int targetNumPoints) {
this.context = ctx; this.context = ctx;
this.listeners = listeners; this.listeners = listeners;
this.preferences = preferences; this.preferences = preferences;
this.providerUtils = providerUtils; this.providerUtils = providerUtils;
this.dataSources = dataSources; this.dataSources = dataSources;
this.targetNumPoints = targetNumPoints;
this.dataSourceManager = new DataSourceManager(dataSourceListener, dataSources); this.dataSourceManager = new DataSourceManager(dataSourceListener, dataSources);
this.locationFactory = new DoubleBufferedLocationFactory(); this.locationFactory = new DoubleBufferedLocationFactory();
@@ -249,7 +255,7 @@ public class TrackDataHub {
useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true); useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true);
reportSpeed = preferences.getBoolean(SPEED_REPORTING_KEY, true); reportSpeed = preferences.getBoolean(SPEED_REPORTING_KEY, true);
minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY, minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
Constants.DEFAULT_MIN_REQUIRED_ACCURACY); DEFAULT_MIN_REQUIRED_ACCURACY);
} }
/** /**
@@ -566,7 +572,7 @@ public class TrackDataHub {
notifyPointsUpdated(true, 0, 0, pointListeners, sampledOutPointListeners); notifyPointsUpdated(true, 0, 0, pointListeners, sampledOutPointListeners);
notifyWaypointUpdated(getListenersFor(ListenerDataType.WAYPOINT_UPDATES)); notifyWaypointUpdated(getListenersFor(ListenerDataType.WAYPOINT_UPDATES));
if (lastSeenLocation != null) { if (lastSeenLocation != null) {
notifyLocationChanged(lastSeenLocation, true, notifyLocationChanged(lastSeenLocation, true,
getListenersFor(ListenerDataType.LOCATION_UPDATES)); getListenersFor(ListenerDataType.LOCATION_UPDATES));
@@ -587,7 +593,7 @@ public class TrackDataHub {
private void notifyPreferenceChanged(String key) { private void notifyPreferenceChanged(String key) {
if (MIN_REQUIRED_ACCURACY_KEY.equals(key)) { if (MIN_REQUIRED_ACCURACY_KEY.equals(key)) {
minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY, minRequiredAccuracy = preferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
Constants.DEFAULT_MIN_REQUIRED_ACCURACY); DEFAULT_MIN_REQUIRED_ACCURACY);
} else if (METRIC_UNITS_KEY.equals(key)) { } else if (METRIC_UNITS_KEY.equals(key)) {
useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true); useMetricUnits = preferences.getBoolean(METRIC_UNITS_KEY, true);
notifyUnitsChanged(); notifyUnitsChanged();
@@ -824,7 +830,7 @@ public class TrackDataHub {
// Always reload all the waypoints. // Always reload all the waypoints.
final Cursor cursor = providerUtils.getWaypointsCursor( final Cursor cursor = providerUtils.getWaypointsCursor(
selectedTrackId, 0L, Constants.MAX_DISPLAYED_WAYPOINTS_POINTS); selectedTrackId, 0L, MAX_DISPLAYED_WAYPOINTS_POINTS);
runInListenerThread(new Runnable() { runInListenerThread(new Runnable() {
@Override @Override
@@ -919,7 +925,7 @@ public class TrackDataHub {
long maxPointId = keepState ? -1 : lastSeenLocationId; long maxPointId = keepState ? -1 : lastSeenLocationId;
// TODO: Move (re)sampling to a separate class. // TODO: Move (re)sampling to a separate class.
if (numLoadedPoints >= Constants.TARGET_DISPLAYED_TRACK_POINTS) { if (numLoadedPoints >= targetNumPoints) {
// We're about to exceed the maximum desired number of points, so reload // We're about to exceed the maximum desired number of points, so reload
// the whole track with fewer points (the sampling frequency will be // the whole track with fewer points (the sampling frequency will be
// lower). We do this for every listener even if we were loading just for // lower). We do this for every listener even if we were loading just for
@@ -987,8 +993,7 @@ public class TrackDataHub {
// no matter how many points we get in the newest batch, we'll never exceed // no matter how many points we get in the newest batch, we'll never exceed
// MAX_DISPLAYED_TRACK_POINTS = 2 * TARGET_DISPLAYED_TRACK_POINTS before resampling. // MAX_DISPLAYED_TRACK_POINTS = 2 * TARGET_DISPLAYED_TRACK_POINTS before resampling.
long numTotalPoints = lastStoredLocationId - localFirstSeenLocationId; long numTotalPoints = lastStoredLocationId - localFirstSeenLocationId;
pointSamplingFrequency = pointSamplingFrequency = (int) (1 + numTotalPoints / targetNumPoints);
(int) (1 + numTotalPoints / Constants.TARGET_DISPLAYED_TRACK_POINTS);
} }
notifyNewPoint(location, locationId, lastStoredLocationId, notifyNewPoint(location, locationId, lastStoredLocationId,
@@ -63,6 +63,8 @@ import org.easymock.IAnswer;
public class TrackDataHubTest extends AndroidTestCase { public class TrackDataHubTest extends AndroidTestCase {
private static final long TRACK_ID = 42L; private static final long TRACK_ID = 42L;
private static final int TARGET_POINTS = 50;
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
private TrackDataHub hub; private TrackDataHub hub;
private TrackDataListeners listeners; private TrackDataListeners listeners;
@@ -89,7 +91,7 @@ public class TrackDataHubTest extends AndroidTestCase {
dataSources = AndroidMock.createNiceMock("dataSources", DataSourcesWrapper.class); dataSources = AndroidMock.createNiceMock("dataSources", DataSourcesWrapper.class);
listeners = new TrackDataListeners(); listeners = new TrackDataListeners();
hub = new TrackDataHub(context, dataSources, listeners, prefs, providerUtils) { hub = new TrackDataHub(context, dataSources, listeners, prefs, providerUtils, TARGET_POINTS) {
@Override @Override
protected void runInListenerThread(Runnable runnable) { protected void runInListenerThread(Runnable runnable) {
// Run everything in the same thread. // Run everything in the same thread.
@@ -627,11 +629,11 @@ public class TrackDataHubTest extends AndroidTestCase {
dataSources.registerContentObserver( dataSources.registerContentObserver(
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture)); eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 20000, 4, 253, 700, 712); FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 200, 4, 25, 71, 120);
expect(providerUtils.getLocationIterator( expect(providerUtils.getLocationIterator(
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class))) eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
.andReturn(locationIterator); .andReturn(locationIterator);
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(20000L); expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(200L);
listener1.clearTrackPoints(); listener1.clearTrackPoints();
listener2.clearTrackPoints(); listener2.clearTrackPoints();
@@ -660,12 +662,12 @@ public class TrackDataHubTest extends AndroidTestCase {
dataSources.registerContentObserver( dataSources.registerContentObserver(
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture)); eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
// Deliver 3000 points (no sampling happens) // Deliver 30 points (no sampling happens)
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 3000, 5); FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 30, 5);
expect(providerUtils.getLocationIterator( expect(providerUtils.getLocationIterator(
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class))) eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
.andReturn(locationIterator); .andReturn(locationIterator);
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(3000L); expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(30L);
listener1.clearTrackPoints(); listener1.clearTrackPoints();
locationIterator.expectLocationsDelivered(listener1); locationIterator.expectLocationsDelivered(listener1);
@@ -678,13 +680,13 @@ public class TrackDataHubTest extends AndroidTestCase {
verifyAndReset(); verifyAndReset();
// Now deliver 3000 more (incrementally sampled) // Now deliver 30 more (incrementally sampled)
ContentObserver observer = observerCapture.getValue(); ContentObserver observer = observerCapture.getValue();
locationIterator = new FixedSizeLocationIterator(3001, 3000); locationIterator = new FixedSizeLocationIterator(31, 30);
expect(providerUtils.getLocationIterator( expect(providerUtils.getLocationIterator(
eq(TRACK_ID), eq(3001L), eq(false), isA(LocationFactory.class))) eq(TRACK_ID), eq(31L), eq(false), isA(LocationFactory.class)))
.andReturn(locationIterator); .andReturn(locationIterator);
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(6000L); expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(60L);
locationIterator.expectSampledLocationsDelivered(listener1, 2, false); locationIterator.expectSampledLocationsDelivered(listener1, 2, false);
listener1.onNewTrackPointsDone(); listener1.onNewTrackPointsDone();
@@ -695,12 +697,12 @@ public class TrackDataHubTest extends AndroidTestCase {
verifyAndReset(); verifyAndReset();
// Now another 3000 (triggers resampling) // Now another 30 (triggers resampling)
locationIterator = new FixedSizeLocationIterator(1, 9000); locationIterator = new FixedSizeLocationIterator(1, 90);
expect(providerUtils.getLocationIterator( expect(providerUtils.getLocationIterator(
eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class))) eq(TRACK_ID), eq(0L), eq(false), isA(LocationFactory.class)))
.andReturn(locationIterator); .andReturn(locationIterator);
expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(9000L); expect(providerUtils.getLastLocationId(TRACK_ID)).andReturn(90L);
listener1.clearTrackPoints(); listener1.clearTrackPoints();
locationIterator.expectSampledLocationsDelivered(listener1, 2, false); locationIterator.expectSampledLocationsDelivered(listener1, 2, false);