Fix race conditions on SQLiteScoreList

pull/309/head
Alinson S. Xavier 8 years ago
parent e06ace9ea8
commit fe1513bb64

@ -67,6 +67,8 @@ public class BaseAndroidTest
protected ModelFactory modelFactory;
private boolean isDone = false;
@Before
public void setUp()
{
@ -117,6 +119,25 @@ public class BaseAndroidTest
assertTrue(latch.await(60, TimeUnit.SECONDS));
}
protected void runConcurrently(Runnable... runnableList) throws Exception
{
isDone = false;
ExecutorService executor = Executors.newFixedThreadPool(100);
List<Future> futures = new LinkedList<>();
for (Runnable r : runnableList)
futures.add(executor.submit(() ->
{
while (!isDone) r.run();
return null;
}));
Thread.sleep(3000);
isDone = true;
executor.shutdown();
for(Future f : futures) f.get();
while (!executor.isTerminated()) Thread.sleep(50);
}
protected void setTheme(@StyleRes int themeId)
{
targetContext.setTheme(themeId);

@ -61,29 +61,6 @@ public class SQLiteScoreListTest extends BaseAndroidTest
day = DateUtils.millisecondsInOneDay;
}
@Test
public void testGetAll()
{
List<Score> list = scores.toList();
assertThat(list.size(), equalTo(121));
assertThat(list.get(0).getTimestamp(), equalTo(today));
assertThat(list.get(10).getTimestamp(), equalTo(today - 10 * day));
}
@Test
public void testInvalidateNewerThan()
{
scores.getTodayValue(); // force recompute
List<ScoreRecord> records = getAllRecords();
assertThat(records.size(), equalTo(121));
scores.invalidateNewerThan(today - 10 * day);
records = getAllRecords();
assertThat(records.size(), equalTo(110));
assertThat(records.get(0).timestamp, equalTo(today - 11 * day));
}
@Test
public void testAdd()
{
@ -101,6 +78,15 @@ public class SQLiteScoreListTest extends BaseAndroidTest
assertThat(records.get(0).timestamp, equalTo(today));
}
@Test
public void testGetAll()
{
List<Score> list = scores.toList();
assertThat(list.size(), equalTo(121));
assertThat(list.get(0).getTimestamp(), equalTo(today));
assertThat(list.get(10).getTimestamp(), equalTo(today - 10 * day));
}
@Test
public void testGetByInterval()
{
@ -115,6 +101,16 @@ public class SQLiteScoreListTest extends BaseAndroidTest
assertThat(list.get(7).getTimestamp(), equalTo(today - 10 * day));
}
@Test
public void testGetByInterval_concurrent() throws Exception
{
Runnable block1 = () -> scores.invalidateNewerThan(0);
Runnable block2 =
() -> assertThat(scores.getByInterval(today, today).size(),
equalTo(1));
runConcurrently(block1, block2);
}
@Test
public void testGetByInterval_withLongInterval()
{
@ -125,6 +121,30 @@ public class SQLiteScoreListTest extends BaseAndroidTest
assertThat(list.size(), equalTo(201));
}
@Test
public void testGetTodayValue_concurrent() throws Exception
{
Runnable block1 = () -> scores.invalidateNewerThan(0);
Runnable block2 =
() -> assertThat(scores.getTodayValue(), equalTo(18407827));
runConcurrently(block1, block2);
}
@Test
public void testInvalidateNewerThan()
{
scores.getTodayValue(); // force recompute
List<ScoreRecord> records = getAllRecords();
assertThat(records.size(), equalTo(121));
scores.invalidateNewerThan(today - 10 * day);
records = getAllRecords();
assertThat(records.size(), equalTo(110));
assertThat(records.get(0).timestamp, equalTo(today - 11 * day));
}
private List<ScoreRecord> getAllRecords()
{
return new Select()

@ -81,7 +81,7 @@ public abstract class ScoreList implements Iterable<Score>
* @param timestamp the timestamp of a day
* @return score value for that day
*/
public final synchronized int getValue(long timestamp)
public synchronized final int getValue(long timestamp)
{
compute(timestamp, timestamp);
Score s = getComputedByTimestamp(timestamp);

@ -100,7 +100,8 @@ public class SQLiteScoreList extends ScoreList
@NonNull
@Override
public List<Score> getByInterval(long fromTimestamp, long toTimestamp)
public synchronized List<Score> getByInterval(long fromTimestamp,
long toTimestamp)
{
check(habit.getId());
compute(fromTimestamp, toTimestamp);
@ -137,7 +138,7 @@ public class SQLiteScoreList extends ScoreList
}
@Override
public int getTodayValue()
public synchronized int getTodayValue()
{
if (cache == null || cache.expired())
cache = new CachedData(super.getTodayValue());
@ -146,7 +147,7 @@ public class SQLiteScoreList extends ScoreList
}
@Override
public void invalidateNewerThan(long timestamp)
public synchronized void invalidateNewerThan(long timestamp)
{
cache = null;
invalidateStatement.bindLong(1, habit.getId());

Loading…
Cancel
Save