blob: 31ed8ba7dd234447092c7241df23bd10ffad5bba [file] [log] [blame]
Matthew Williams01ac45b2014-07-22 20:44:12 -07001package com.android.server.job;
Matthew Williams3d86fd22014-05-16 18:02:17 -07002
3
4import android.content.ComponentName;
5import android.content.Context;
Christopher Tate7060b042014-06-09 19:50:00 -07006import android.app.job.JobInfo;
7import android.app.job.JobInfo.Builder;
Matthew Williams3d86fd22014-05-16 18:02:17 -07008import android.os.PersistableBundle;
Matthew Williamsfa8e5082015-10-15 15:59:12 -07009import android.os.SystemClock;
Matthew Williams3d86fd22014-05-16 18:02:17 -070010import android.test.AndroidTestCase;
11import android.test.RenamingDelegatingContext;
12import android.util.Log;
Christopher Tate616541d2017-07-26 14:27:38 -070013import android.util.Pair;
Matthew Williams3d86fd22014-05-16 18:02:17 -070014
Christopher Tate2f36fd62016-02-18 18:36:08 -080015import com.android.server.job.JobStore.JobSet;
Christopher Tate7060b042014-06-09 19:50:00 -070016import com.android.server.job.controllers.JobStatus;
Matthew Williams3d86fd22014-05-16 18:02:17 -070017
Matthew Williams01ac45b2014-07-22 20:44:12 -070018import java.util.Iterator;
Matthew Williams3d86fd22014-05-16 18:02:17 -070019
Matthew Williams3d86fd22014-05-16 18:02:17 -070020/**
21 * Test reading and writing correctly from file.
22 */
Matthew Williams01ac45b2014-07-22 20:44:12 -070023public class JobStoreTest extends AndroidTestCase {
Matthew Williams3d86fd22014-05-16 18:02:17 -070024 private static final String TAG = "TaskStoreTest";
25 private static final String TEST_PREFIX = "_test_";
Matthew Williams01ac45b2014-07-22 20:44:12 -070026
Matthew Williams3d86fd22014-05-16 18:02:17 -070027 private static final int SOME_UID = 34234;
28 private ComponentName mComponent;
Matthew Williams01ac45b2014-07-22 20:44:12 -070029 private static final long IO_WAIT = 1000L;
Matthew Williams3d86fd22014-05-16 18:02:17 -070030
Christopher Tate7060b042014-06-09 19:50:00 -070031 JobStore mTaskStoreUnderTest;
Matthew Williams3d86fd22014-05-16 18:02:17 -070032 Context mTestContext;
Matthew Williams3d86fd22014-05-16 18:02:17 -070033
34 @Override
35 public void setUp() throws Exception {
36 mTestContext = new RenamingDelegatingContext(getContext(), TEST_PREFIX);
37 Log.d(TAG, "Saving tasks to '" + mTestContext.getFilesDir() + "'");
Matthew Williams01ac45b2014-07-22 20:44:12 -070038 mTaskStoreUnderTest =
39 JobStore.initAndGetForTesting(mTestContext, mTestContext.getFilesDir());
Matthew Williams3d86fd22014-05-16 18:02:17 -070040 mComponent = new ComponentName(getContext().getPackageName(), StubClass.class.getName());
41 }
42
43 @Override
44 public void tearDown() throws Exception {
45 mTaskStoreUnderTest.clear();
46 }
47
48 public void testMaybeWriteStatusToDisk() throws Exception {
49 int taskId = 5;
50 long runByMillis = 20000L; // 20s
51 long runFromMillis = 2000L; // 2s
52 long initialBackoff = 10000L; // 10s
53
Christopher Tate7060b042014-06-09 19:50:00 -070054 final JobInfo task = new Builder(taskId, mComponent)
Matthew Williams3d86fd22014-05-16 18:02:17 -070055 .setRequiresCharging(true)
Matthew Williamsd1c06752014-08-22 14:15:28 -070056 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
57 .setBackoffCriteria(initialBackoff, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
Matthew Williams3d86fd22014-05-16 18:02:17 -070058 .setOverrideDeadline(runByMillis)
59 .setMinimumLatency(runFromMillis)
Matthew Williamsd1c06752014-08-22 14:15:28 -070060 .setPersisted(true)
Matthew Williams3d86fd22014-05-16 18:02:17 -070061 .build();
Dianne Hackborn1085ff62016-02-23 17:04:58 -080062 final JobStatus ts = JobStatus.createFromJobInfo(task, SOME_UID, null, -1, null);
Matthew Williams3d86fd22014-05-16 18:02:17 -070063 mTaskStoreUnderTest.add(ts);
64 Thread.sleep(IO_WAIT);
65 // Manually load tasks from xml file.
Christopher Tate2f36fd62016-02-18 18:36:08 -080066 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -070067 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Matthew Williams01ac45b2014-07-22 20:44:12 -070068
69 assertEquals("Didn't get expected number of persisted tasks.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -080070 final JobStatus loadedTaskStatus = jobStatusSet.getAllJobs().get(0);
Matthew Williams01ac45b2014-07-22 20:44:12 -070071 assertTasksEqual(task, loadedTaskStatus.getJob());
Matthew Williams48a30db2014-09-23 13:39:36 -070072 assertTrue("JobStore#contains invalid.", mTaskStoreUnderTest.containsJob(ts));
Matthew Williams01ac45b2014-07-22 20:44:12 -070073 assertEquals("Different uids.", SOME_UID, loadedTaskStatus.getUid());
74 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
75 ts.getEarliestRunTime(), loadedTaskStatus.getEarliestRunTime());
76 compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
77 ts.getLatestRunTimeElapsed(), loadedTaskStatus.getLatestRunTimeElapsed());
Matthew Williams3d86fd22014-05-16 18:02:17 -070078
79 }
80
81 public void testWritingTwoFilesToDisk() throws Exception {
Christopher Tate7060b042014-06-09 19:50:00 -070082 final JobInfo task1 = new Builder(8, mComponent)
Matthew Williams3d86fd22014-05-16 18:02:17 -070083 .setRequiresDeviceIdle(true)
84 .setPeriodic(10000L)
85 .setRequiresCharging(true)
Matthew Williamsd1c06752014-08-22 14:15:28 -070086 .setPersisted(true)
Matthew Williams3d86fd22014-05-16 18:02:17 -070087 .build();
Christopher Tate7060b042014-06-09 19:50:00 -070088 final JobInfo task2 = new Builder(12, mComponent)
Matthew Williams3d86fd22014-05-16 18:02:17 -070089 .setMinimumLatency(5000L)
Matthew Williamsd1c06752014-08-22 14:15:28 -070090 .setBackoffCriteria(15000L, JobInfo.BACKOFF_POLICY_LINEAR)
Matthew Williams3d86fd22014-05-16 18:02:17 -070091 .setOverrideDeadline(30000L)
Matthew Williamsd1c06752014-08-22 14:15:28 -070092 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
93 .setPersisted(true)
Matthew Williams3d86fd22014-05-16 18:02:17 -070094 .build();
Dianne Hackborn1085ff62016-02-23 17:04:58 -080095 final JobStatus taskStatus1 = JobStatus.createFromJobInfo(task1, SOME_UID, null, -1, null);
96 final JobStatus taskStatus2 = JobStatus.createFromJobInfo(task2, SOME_UID, null, -1, null);
Matthew Williams3d86fd22014-05-16 18:02:17 -070097 mTaskStoreUnderTest.add(taskStatus1);
98 mTaskStoreUnderTest.add(taskStatus2);
99 Thread.sleep(IO_WAIT);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700100
Christopher Tate2f36fd62016-02-18 18:36:08 -0800101 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700102 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Matthew Williams01ac45b2014-07-22 20:44:12 -0700103 assertEquals("Incorrect # of persisted tasks.", 2, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800104 Iterator<JobStatus> it = jobStatusSet.getAllJobs().iterator();
Matthew Williams01ac45b2014-07-22 20:44:12 -0700105 JobStatus loaded1 = it.next();
106 JobStatus loaded2 = it.next();
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700107
108 // Reverse them so we know which comparison to make.
109 if (loaded1.getJobId() != 8) {
110 JobStatus tmp = loaded1;
111 loaded1 = loaded2;
112 loaded2 = tmp;
113 }
114
Matthew Williams01ac45b2014-07-22 20:44:12 -0700115 assertTasksEqual(task1, loaded1.getJob());
116 assertTasksEqual(task2, loaded2.getJob());
Matthew Williams48a30db2014-09-23 13:39:36 -0700117 assertTrue("JobStore#contains invalid.", mTaskStoreUnderTest.containsJob(taskStatus1));
118 assertTrue("JobStore#contains invalid.", mTaskStoreUnderTest.containsJob(taskStatus2));
Matthew Williams01ac45b2014-07-22 20:44:12 -0700119 // Check that the loaded task has the correct runtimes.
120 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
121 taskStatus1.getEarliestRunTime(), loaded1.getEarliestRunTime());
122 compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
123 taskStatus1.getLatestRunTimeElapsed(), loaded1.getLatestRunTimeElapsed());
124 compareTimestampsSubjectToIoLatency("Early run-times not the same after read.",
125 taskStatus2.getEarliestRunTime(), loaded2.getEarliestRunTime());
126 compareTimestampsSubjectToIoLatency("Late run-times not the same after read.",
127 taskStatus2.getLatestRunTimeElapsed(), loaded2.getLatestRunTimeElapsed());
Matthew Williams3d86fd22014-05-16 18:02:17 -0700128
129 }
130
131 public void testWritingTaskWithExtras() throws Exception {
Christopher Tate7060b042014-06-09 19:50:00 -0700132 JobInfo.Builder b = new Builder(8, mComponent)
Matthew Williams3d86fd22014-05-16 18:02:17 -0700133 .setRequiresDeviceIdle(true)
134 .setPeriodic(10000L)
Matthew Williams900c67f2014-07-09 12:46:53 -0700135 .setRequiresCharging(true)
Matthew Williamsd1c06752014-08-22 14:15:28 -0700136 .setPersisted(true);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700137
138 PersistableBundle extras = new PersistableBundle();
139 extras.putDouble("hello", 3.2);
140 extras.putString("hi", "there");
141 extras.putInt("into", 3);
142 b.setExtras(extras);
Christopher Tate7060b042014-06-09 19:50:00 -0700143 final JobInfo task = b.build();
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800144 JobStatus taskStatus = JobStatus.createFromJobInfo(task, SOME_UID, null, -1, null);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700145
146 mTaskStoreUnderTest.add(taskStatus);
147 Thread.sleep(IO_WAIT);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700148
Christopher Tate2f36fd62016-02-18 18:36:08 -0800149 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700150 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Matthew Williams01ac45b2014-07-22 20:44:12 -0700151 assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800152 JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
Matthew Williams01ac45b2014-07-22 20:44:12 -0700153 assertTasksEqual(task, loaded.getJob());
Matthew Williams3d86fd22014-05-16 18:02:17 -0700154 }
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000155 public void testWritingTaskWithSourcePackage() throws Exception {
156 JobInfo.Builder b = new Builder(8, mComponent)
157 .setRequiresDeviceIdle(true)
158 .setPeriodic(10000L)
159 .setRequiresCharging(true)
160 .setPersisted(true);
Dianne Hackbornb0001f62016-02-16 10:30:33 -0800161 JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID,
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800162 "com.google.android.gms", 0, null);
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000163
164 mTaskStoreUnderTest.add(taskStatus);
165 Thread.sleep(IO_WAIT);
166
Christopher Tate2f36fd62016-02-18 18:36:08 -0800167 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700168 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000169 assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800170 JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000171 assertEquals("Source package not equal.", loaded.getSourcePackageName(),
172 taskStatus.getSourcePackageName());
173 assertEquals("Source user not equal.", loaded.getSourceUserId(),
174 taskStatus.getSourceUserId());
175 }
176
177 public void testWritingTaskWithFlex() throws Exception {
178 JobInfo.Builder b = new Builder(8, mComponent)
179 .setRequiresDeviceIdle(true)
180 .setPeriodic(5*60*60*1000, 1*60*60*1000)
181 .setRequiresCharging(true)
182 .setPersisted(true);
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800183 JobStatus taskStatus = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000184
185 mTaskStoreUnderTest.add(taskStatus);
186 Thread.sleep(IO_WAIT);
187
Christopher Tate2f36fd62016-02-18 18:36:08 -0800188 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700189 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000190 assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800191 JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000192 assertEquals("Period not equal.", loaded.getJob().getIntervalMillis(),
193 taskStatus.getJob().getIntervalMillis());
194 assertEquals("Flex not equal.", loaded.getJob().getFlexMillis(),
195 taskStatus.getJob().getFlexMillis());
196 }
Matthew Williams3d86fd22014-05-16 18:02:17 -0700197
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700198 public void testMassivePeriodClampedOnRead() throws Exception {
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000199 final long ONE_HOUR = 60*60*1000L; // flex
200 final long TWO_HOURS = 2 * ONE_HOUR; // period
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700201 JobInfo.Builder b = new Builder(8, mComponent)
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000202 .setPeriodic(TWO_HOURS, ONE_HOUR)
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700203 .setPersisted(true);
Christopher Tate616541d2017-07-26 14:27:38 -0700204 final long rtcNow = System.currentTimeMillis();
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700205 final long invalidLateRuntimeElapsedMillis =
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000206 SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS; // > period+flex
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700207 final long invalidEarlyRuntimeElapsedMillis =
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000208 invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period).
Christopher Tate616541d2017-07-26 14:27:38 -0700209 final Pair<Long, Long> persistedExecutionTimesUTC = new Pair<>(rtcNow, rtcNow + ONE_HOUR);
Dianne Hackbornb0001f62016-02-16 10:30:33 -0800210 final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage",
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800211 0 /* sourceUserId */, "someTag",
Makoto Onukiab8a67f2017-06-20 12:20:34 -0700212 invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis,
Christopher Tate616541d2017-07-26 14:27:38 -0700213 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */,
214 persistedExecutionTimesUTC);
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700215
216 mTaskStoreUnderTest.add(js);
217 Thread.sleep(IO_WAIT);
218
Christopher Tate2f36fd62016-02-18 18:36:08 -0800219 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700220 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700221 assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800222 JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700223
224 // Assert early runtime was clamped to be under now + period. We can do <= here b/c we'll
225 // call SystemClock.elapsedRealtime after doing the disk i/o.
226 final long newNowElapsed = SystemClock.elapsedRealtime();
227 assertTrue("Early runtime wasn't correctly clamped.",
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000228 loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS);
229 // Assert late runtime was clamped to be now + period + flex.
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700230 assertTrue("Early runtime wasn't correctly clamped.",
Shreyas Basarge8e64e2e2016-02-12 15:49:31 +0000231 loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS + ONE_HOUR);
Shreyas Basarge5db09082016-01-07 13:38:29 +0000232 }
233
234 public void testPriorityPersisted() throws Exception {
235 JobInfo.Builder b = new Builder(92, mComponent)
236 .setOverrideDeadline(5000)
237 .setPriority(42)
238 .setPersisted(true);
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800239 final JobStatus js = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
Shreyas Basarge5db09082016-01-07 13:38:29 +0000240 mTaskStoreUnderTest.add(js);
241 Thread.sleep(IO_WAIT);
Christopher Tate2f36fd62016-02-18 18:36:08 -0800242 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700243 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Christopher Tate2f36fd62016-02-18 18:36:08 -0800244 JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
Shreyas Basarge5db09082016-01-07 13:38:29 +0000245 assertEquals("Priority not correctly persisted.", 42, loaded.getPriority());
Matthew Williamsfa8e5082015-10-15 15:59:12 -0700246 }
247
Matthew Williams3d86fd22014-05-16 18:02:17 -0700248 /**
Shreyas Basarge7ef490f2015-12-03 16:45:22 +0000249 * Test that non persisted job is not written to disk.
250 */
251 public void testNonPersistedTaskIsNotPersisted() throws Exception {
252 JobInfo.Builder b = new Builder(42, mComponent)
253 .setOverrideDeadline(10000)
254 .setPersisted(false);
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800255 JobStatus jsNonPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
Shreyas Basarge7ef490f2015-12-03 16:45:22 +0000256 mTaskStoreUnderTest.add(jsNonPersisted);
257 b = new Builder(43, mComponent)
258 .setOverrideDeadline(10000)
259 .setPersisted(true);
Dianne Hackborn1085ff62016-02-23 17:04:58 -0800260 JobStatus jsPersisted = JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null);
Shreyas Basarge7ef490f2015-12-03 16:45:22 +0000261 mTaskStoreUnderTest.add(jsPersisted);
262 Thread.sleep(IO_WAIT);
Christopher Tate2f36fd62016-02-18 18:36:08 -0800263 final JobSet jobStatusSet = new JobSet();
Christopher Tate616541d2017-07-26 14:27:38 -0700264 mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
Shreyas Basarge7ef490f2015-12-03 16:45:22 +0000265 assertEquals("Job count is incorrect.", 1, jobStatusSet.size());
Christopher Tate2f36fd62016-02-18 18:36:08 -0800266 JobStatus jobStatus = jobStatusSet.getAllJobs().iterator().next();
Shreyas Basarge7ef490f2015-12-03 16:45:22 +0000267 assertEquals("Wrong job persisted.", 43, jobStatus.getJobId());
268 }
269
270 /**
Matthew Williams3d86fd22014-05-16 18:02:17 -0700271 * Helper function to throw an error if the provided task and TaskStatus objects are not equal.
272 */
Christopher Tate7060b042014-06-09 19:50:00 -0700273 private void assertTasksEqual(JobInfo first, JobInfo second) {
Matthew Williams3d86fd22014-05-16 18:02:17 -0700274 assertEquals("Different task ids.", first.getId(), second.getId());
275 assertEquals("Different components.", first.getService(), second.getService());
276 assertEquals("Different periodic status.", first.isPeriodic(), second.isPeriodic());
277 assertEquals("Different period.", first.getIntervalMillis(), second.getIntervalMillis());
278 assertEquals("Different inital backoff.", first.getInitialBackoffMillis(),
279 second.getInitialBackoffMillis());
280 assertEquals("Different backoff policy.", first.getBackoffPolicy(),
281 second.getBackoffPolicy());
282
283 assertEquals("Invalid charging constraint.", first.isRequireCharging(),
284 second.isRequireCharging());
Dianne Hackborna06ec6a2017-02-13 10:08:42 -0800285 assertEquals("Invalid battery not low constraint.", first.isRequireBatteryNotLow(),
286 second.isRequireBatteryNotLow());
Matthew Williams3d86fd22014-05-16 18:02:17 -0700287 assertEquals("Invalid idle constraint.", first.isRequireDeviceIdle(),
288 second.isRequireDeviceIdle());
289 assertEquals("Invalid unmetered constraint.",
Matthew Williamsd1c06752014-08-22 14:15:28 -0700290 first.getNetworkType() == JobInfo.NETWORK_TYPE_UNMETERED,
291 second.getNetworkType() == JobInfo.NETWORK_TYPE_UNMETERED);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700292 assertEquals("Invalid connectivity constraint.",
Matthew Williamsd1c06752014-08-22 14:15:28 -0700293 first.getNetworkType() == JobInfo.NETWORK_TYPE_ANY,
294 second.getNetworkType() == JobInfo.NETWORK_TYPE_ANY);
Matthew Williams3d86fd22014-05-16 18:02:17 -0700295 assertEquals("Invalid deadline constraint.",
296 first.hasLateConstraint(),
297 second.hasLateConstraint());
298 assertEquals("Invalid delay constraint.",
299 first.hasEarlyConstraint(),
300 second.hasEarlyConstraint());
301 assertEquals("Extras don't match",
302 first.getExtras().toString(), second.getExtras().toString());
Dianne Hackbornba604732016-02-10 17:05:10 -0800303 assertEquals("Transient xtras don't match",
304 first.getTransientExtras().toString(), second.getTransientExtras().toString());
Matthew Williams3d86fd22014-05-16 18:02:17 -0700305 }
306
307 /**
308 * When comparing timestamps before and after DB read/writes (to make sure we're saving/loading
309 * the correct values), there is some latency involved that terrorises a naive assertEquals().
310 * We define a <code>DELTA_MILLIS</code> as a function variable here to make this comparision
311 * more reasonable.
312 */
313 private void compareTimestampsSubjectToIoLatency(String error, long ts1, long ts2) {
314 final long DELTA_MILLIS = 700L; // We allow up to 700ms of latency for IO read/writes.
315 assertTrue(error, Math.abs(ts1 - ts2) < DELTA_MILLIS + IO_WAIT);
316 }
317
318 private static class StubClass {}
319
Matthew Williams01ac45b2014-07-22 20:44:12 -0700320}