JobStoreTest.java revision 7060b04f6d92351b67222e636ab378a0273bf3e7
13d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamspackage com.android.server.task; 23d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 33d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 43d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.content.ComponentName; 53d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.content.Context; 67060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport android.app.job.JobInfo; 77060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport android.app.job.JobInfo.Builder; 83d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.os.PersistableBundle; 93d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.test.AndroidTestCase; 103d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.test.RenamingDelegatingContext; 113d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.util.Log; 123d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 137060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport com.android.server.job.JobMapReadFinishedListener; 147060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport com.android.server.job.JobStore; 157060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport com.android.server.job.controllers.JobStatus; 163d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 173d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport java.util.List; 183d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 197060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tateimport static com.android.server.job.JobStore.initAndGet; 203d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams/** 213d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * Test reading and writing correctly from file. 223d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams */ 233d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamspublic class TaskStoreTest extends AndroidTestCase { 243d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private static final String TAG = "TaskStoreTest"; 253d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private static final String TEST_PREFIX = "_test_"; 263d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams // private static final int USER_NON_0 = 3; 273d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private static final int SOME_UID = 34234; 283d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private ComponentName mComponent; 293d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private static final long IO_WAIT = 600L; 303d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 317060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStore mTaskStoreUnderTest; 323d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams Context mTestContext; 337060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobMapReadFinishedListener mTaskMapReadFinishedListenerStub = 347060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate new JobMapReadFinishedListener() { 353d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 367060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate public void onJobMapReadFinished(List<JobStatus> tasks) { 373d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams // do nothing. 383d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 393d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams }; 403d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 413d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 423d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams public void setUp() throws Exception { 433d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTestContext = new RenamingDelegatingContext(getContext(), TEST_PREFIX); 443d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams Log.d(TAG, "Saving tasks to '" + mTestContext.getFilesDir() + "'"); 457060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate mTaskStoreUnderTest = JobStore.initAndGetForTesting(mTestContext, 463d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTestContext.getFilesDir(), mTaskMapReadFinishedListenerStub); 473d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mComponent = new ComponentName(getContext().getPackageName(), StubClass.class.getName()); 483d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 493d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 503d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 513d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams public void tearDown() throws Exception { 523d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTaskStoreUnderTest.clear(); 533d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 543d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 553d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams public void testMaybeWriteStatusToDisk() throws Exception { 563d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams int taskId = 5; 573d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams long runByMillis = 20000L; // 20s 583d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams long runFromMillis = 2000L; // 2s 593d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams long initialBackoff = 10000L; // 10s 603d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 617060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobInfo task = new Builder(taskId, mComponent) 623d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setRequiresCharging(true) 637060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate .setRequiredNetworkCapabilities(JobInfo.NetworkType.ANY) 647060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate .setBackoffCriteria(initialBackoff, JobInfo.BackoffPolicy.EXPONENTIAL) 653d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setOverrideDeadline(runByMillis) 663d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setMinimumLatency(runFromMillis) 673d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .build(); 687060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobStatus ts = new JobStatus(task, SOME_UID, true /* persisted */); 693d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTaskStoreUnderTest.add(ts); 703d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams Thread.sleep(IO_WAIT); 713d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams // Manually load tasks from xml file. 727060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() { 733d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 747060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate public void onJobMapReadFinished(List<JobStatus> tasks) { 753d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Didn't get expected number of persisted tasks.", 1, tasks.size()); 767060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStatus loadedTaskStatus = tasks.get(0); 777060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate assertTasksEqual(task, loadedTaskStatus.getJob()); 783d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different uids.", SOME_UID, tasks.get(0).getUid()); 793d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Early run-times not the same after read.", 803d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams ts.getEarliestRunTime(), loadedTaskStatus.getEarliestRunTime()); 813d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Late run-times not the same after read.", 823d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams ts.getLatestRunTimeElapsed(), loadedTaskStatus.getLatestRunTimeElapsed()); 833d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 843d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams }); 853d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 863d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 873d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 883d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams public void testWritingTwoFilesToDisk() throws Exception { 897060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobInfo task1 = new Builder(8, mComponent) 903d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setRequiresDeviceIdle(true) 913d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setPeriodic(10000L) 923d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setRequiresCharging(true) 933d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .build(); 947060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobInfo task2 = new Builder(12, mComponent) 953d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setMinimumLatency(5000L) 967060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate .setBackoffCriteria(15000L, JobInfo.BackoffPolicy.LINEAR) 973d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setOverrideDeadline(30000L) 987060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate .setRequiredNetworkCapabilities(JobInfo.NetworkType.UNMETERED) 993d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .build(); 1007060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, true /* persisted */); 1017060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, true /* persisted */); 1023d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTaskStoreUnderTest.add(taskStatus1); 1033d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTaskStoreUnderTest.add(taskStatus2); 1043d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams Thread.sleep(IO_WAIT); 1057060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() { 1063d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 1077060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate public void onJobMapReadFinished(List<JobStatus> tasks) { 1083d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Incorrect # of persisted tasks.", 2, tasks.size()); 1097060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStatus loaded1 = tasks.get(0); 1107060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStatus loaded2 = tasks.get(1); 1117060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate assertTasksEqual(task1, loaded1.getJob()); 1127060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate assertTasksEqual(task2, loaded2.getJob()); 1133d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1143d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams // Check that the loaded task has the correct runtimes. 1153d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Early run-times not the same after read.", 1163d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams taskStatus1.getEarliestRunTime(), loaded1.getEarliestRunTime()); 1173d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Late run-times not the same after read.", 1183d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams taskStatus1.getLatestRunTimeElapsed(), loaded1.getLatestRunTimeElapsed()); 1193d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Early run-times not the same after read.", 1203d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams taskStatus2.getEarliestRunTime(), loaded2.getEarliestRunTime()); 1213d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams compareTimestampsSubjectToIoLatency("Late run-times not the same after read.", 1223d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams taskStatus2.getLatestRunTimeElapsed(), loaded2.getLatestRunTimeElapsed()); 1233d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1243d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams }); 1253d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1263d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1273d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1283d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams public void testWritingTaskWithExtras() throws Exception { 1297060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobInfo.Builder b = new Builder(8, mComponent) 1303d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setRequiresDeviceIdle(true) 1313d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setPeriodic(10000L) 1323d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams .setRequiresCharging(true); 1333d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1343d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams PersistableBundle extras = new PersistableBundle(); 1353d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams extras.putDouble("hello", 3.2); 1363d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams extras.putString("hi", "there"); 1373d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams extras.putInt("into", 3); 1383d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams b.setExtras(extras); 1397060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate final JobInfo task = b.build(); 1407060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStatus taskStatus = new JobStatus(task, SOME_UID, true /* persisted */); 1413d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1423d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams mTaskStoreUnderTest.add(taskStatus); 1433d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams Thread.sleep(IO_WAIT); 1447060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate mTaskStoreUnderTest.readJobMapFromDisk(new JobMapReadFinishedListener() { 1453d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams @Override 1467060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate public void onJobMapReadFinished(List<JobStatus> tasks) { 1473d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Incorrect # of persisted tasks.", 1, tasks.size()); 1487060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate JobStatus loaded = tasks.get(0); 1497060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate assertTasksEqual(task, loaded.getJob()); 1503d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1513d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams }); 1523d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1533d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1543d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1553d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams /** 1563d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * Helper function to throw an error if the provided task and TaskStatus objects are not equal. 1573d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams */ 1587060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate private void assertTasksEqual(JobInfo first, JobInfo second) { 1593d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different task ids.", first.getId(), second.getId()); 1603d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different components.", first.getService(), second.getService()); 1613d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different periodic status.", first.isPeriodic(), second.isPeriodic()); 1623d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different period.", first.getIntervalMillis(), second.getIntervalMillis()); 1633d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different inital backoff.", first.getInitialBackoffMillis(), 1643d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.getInitialBackoffMillis()); 1653d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Different backoff policy.", first.getBackoffPolicy(), 1663d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.getBackoffPolicy()); 1673d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1683d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid charging constraint.", first.isRequireCharging(), 1693d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.isRequireCharging()); 1703d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid idle constraint.", first.isRequireDeviceIdle(), 1713d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.isRequireDeviceIdle()); 1723d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid unmetered constraint.", 1737060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate first.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED, 1747060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate second.getNetworkCapabilities() == JobInfo.NetworkType.UNMETERED); 1753d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid connectivity constraint.", 1767060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate first.getNetworkCapabilities() == JobInfo.NetworkType.ANY, 1777060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate second.getNetworkCapabilities() == JobInfo.NetworkType.ANY); 1783d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid deadline constraint.", 1793d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams first.hasLateConstraint(), 1803d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.hasLateConstraint()); 1813d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Invalid delay constraint.", 1823d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams first.hasEarlyConstraint(), 1833d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams second.hasEarlyConstraint()); 1843d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertEquals("Extras don't match", 1853d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams first.getExtras().toString(), second.getExtras().toString()); 1863d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1873d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1883d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams /** 1893d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * When comparing timestamps before and after DB read/writes (to make sure we're saving/loading 1903d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * the correct values), there is some latency involved that terrorises a naive assertEquals(). 1913d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * We define a <code>DELTA_MILLIS</code> as a function variable here to make this comparision 1923d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams * more reasonable. 1933d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams */ 1943d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private void compareTimestampsSubjectToIoLatency(String error, long ts1, long ts2) { 1953d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams final long DELTA_MILLIS = 700L; // We allow up to 700ms of latency for IO read/writes. 1963d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams assertTrue(error, Math.abs(ts1 - ts2) < DELTA_MILLIS + IO_WAIT); 1973d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams } 1983d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 1993d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams private static class StubClass {} 2003d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams 2013d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams}