blob: c252609b5d88b94b620cdd9a397b82f4f0206ec8 [file] [log] [blame]
Neil Fuller68f66662017-03-16 18:32:21 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.timezone;
18
Neil Fullera6a71d02017-06-13 15:12:17 +010019import com.android.timezone.distro.DistroVersion;
20import com.android.timezone.distro.StagedDistroOperation;
Neil Fuller9c90dc02017-06-22 14:10:29 +010021import com.android.timezone.distro.TimeZoneDistro;
Neil Fuller5ca8b5b2017-06-29 12:39:49 +010022import com.android.timezone.distro.installer.TimeZoneDistroInstaller;
Neil Fullera6a71d02017-06-13 15:12:17 +010023
Neil Fuller68f66662017-03-16 18:32:21 +000024import org.junit.Before;
25import org.junit.Test;
26
27import android.app.timezone.Callback;
28import android.app.timezone.DistroRulesVersion;
29import android.app.timezone.ICallback;
30import android.app.timezone.RulesManager;
31import android.app.timezone.RulesState;
32import android.os.ParcelFileDescriptor;
33
Neil Fuller54525bf2017-06-22 14:10:29 +010034import java.io.File;
Neil Fuller87b11282017-06-23 16:43:45 +010035import java.io.FileDescriptor;
Neil Fuller54525bf2017-06-22 14:10:29 +010036import java.io.FileOutputStream;
Neil Fuller68f66662017-03-16 18:32:21 +000037import java.io.IOException;
Neil Fuller87b11282017-06-23 16:43:45 +010038import java.io.PrintWriter;
Neil Fuller68f66662017-03-16 18:32:21 +000039import java.util.concurrent.Executor;
40import javax.annotation.Nullable;
Neil Fuller68f66662017-03-16 18:32:21 +000041
Neil Fuller87b11282017-06-23 16:43:45 +010042import libcore.io.IoUtils;
43
Neil Fullerb214bc42017-12-18 16:57:22 +000044import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
Neil Fuller68f66662017-03-16 18:32:21 +000045import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
46import static org.junit.Assert.assertEquals;
47import static org.junit.Assert.assertFalse;
48import static org.junit.Assert.assertNotNull;
49import static org.junit.Assert.assertNull;
50import static org.junit.Assert.assertTrue;
51import static org.junit.Assert.fail;
Neil Fuller9c90dc02017-06-22 14:10:29 +010052import static org.mockito.ArgumentMatchers.any;
Neil Fuller68f66662017-03-16 18:32:21 +000053import static org.mockito.Mockito.doNothing;
54import static org.mockito.Mockito.doReturn;
55import static org.mockito.Mockito.doThrow;
56import static org.mockito.Mockito.mock;
57import static org.mockito.Mockito.reset;
58import static org.mockito.Mockito.verify;
59import static org.mockito.Mockito.verifyNoMoreInteractions;
Neil Fuller87b11282017-06-23 16:43:45 +010060import static org.mockito.Mockito.verifyZeroInteractions;
Neil Fuller68f66662017-03-16 18:32:21 +000061import static org.mockito.Mockito.when;
62
63/**
64 * White box interaction / unit testing of the {@link RulesManagerService}.
65 */
66public class RulesManagerServiceTest {
67
68 private RulesManagerService mRulesManagerService;
69
70 private FakeExecutor mFakeExecutor;
71 private PermissionHelper mMockPermissionHelper;
Neil Fullerb1442272017-12-18 15:59:50 +000072 private RulesManagerIntentHelper mMockIntentHelper;
Neil Fuller68f66662017-03-16 18:32:21 +000073 private PackageTracker mMockPackageTracker;
74 private TimeZoneDistroInstaller mMockTimeZoneDistroInstaller;
75
76 @Before
77 public void setUp() {
78 mFakeExecutor = new FakeExecutor();
79
Neil Fuller68f66662017-03-16 18:32:21 +000080 mMockPackageTracker = mock(PackageTracker.class);
81 mMockPermissionHelper = mock(PermissionHelper.class);
Neil Fullerb1442272017-12-18 15:59:50 +000082 mMockIntentHelper = mock(RulesManagerIntentHelper.class);
Neil Fuller68f66662017-03-16 18:32:21 +000083 mMockTimeZoneDistroInstaller = mock(TimeZoneDistroInstaller.class);
84
85 mRulesManagerService = new RulesManagerService(
86 mMockPermissionHelper,
87 mFakeExecutor,
Neil Fullerb1442272017-12-18 15:59:50 +000088 mMockIntentHelper,
Neil Fuller68f66662017-03-16 18:32:21 +000089 mMockPackageTracker,
90 mMockTimeZoneDistroInstaller);
91 }
92
93 @Test(expected = SecurityException.class)
94 public void getRulesState_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +000095 configureCallerDoesNotHaveQueryPermission();
Neil Fuller68f66662017-03-16 18:32:21 +000096 mRulesManagerService.getRulesState();
97 }
98
99 @Test(expected = SecurityException.class)
100 public void requestInstall_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000101 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000102 mRulesManagerService.requestInstall(null, null, null);
103 }
104
105 @Test(expected = SecurityException.class)
106 public void requestUninstall_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000107 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000108 mRulesManagerService.requestUninstall(null, null);
109 }
110
111 @Test(expected = SecurityException.class)
112 public void requestNothing_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000113 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000114 mRulesManagerService.requestNothing(null, true);
115 }
116
117 @Test
118 public void getRulesState_systemRulesError() throws Exception {
119 configureDeviceCannotReadSystemRulesVersion();
120
121 assertNull(mRulesManagerService.getRulesState());
122 }
123
124 @Test
125 public void getRulesState_stagedInstall() throws Exception {
126 configureCallerHasPermission();
127
128 configureDeviceSystemRulesVersion("2016a");
129
130 DistroVersion stagedDistroVersion = new DistroVersion(
131 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
132 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
133 "2016c",
134 3);
135 configureStagedInstall(stagedDistroVersion);
136
137 DistroVersion installedDistroVersion = new DistroVersion(
138 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
139 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
140 "2016b",
141 4);
142 configureInstalledDistroVersion(installedDistroVersion);
143
144 DistroRulesVersion stagedDistroRulesVersion = new DistroRulesVersion(
145 stagedDistroVersion.rulesVersion, stagedDistroVersion.revision);
146 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
147 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
148 RulesState expectedRuleState = new RulesState(
149 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
150 false /* operationInProgress */,
151 RulesState.STAGED_OPERATION_INSTALL, stagedDistroRulesVersion,
152 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
153 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
154 }
155
156 @Test
157 public void getRulesState_nothingStaged() throws Exception {
158 configureCallerHasPermission();
159
160 configureDeviceSystemRulesVersion("2016a");
161
162 configureNoStagedOperation();
163
164 DistroVersion installedDistroVersion = new DistroVersion(
165 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
166 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
167 "2016b",
168 4);
169 configureInstalledDistroVersion(installedDistroVersion);
170
171 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
172 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
173 RulesState expectedRuleState = new RulesState(
174 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
175 false /* operationInProgress */,
176 RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
177 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
178 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
179 }
180
181 @Test
182 public void getRulesState_uninstallStaged() throws Exception {
183 configureCallerHasPermission();
184
185 configureDeviceSystemRulesVersion("2016a");
186
187 configureStagedUninstall();
188
189 DistroVersion installedDistroVersion = new DistroVersion(
190 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
191 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
192 "2016b",
193 4);
194 configureInstalledDistroVersion(installedDistroVersion);
195
196 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
197 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
198 RulesState expectedRuleState = new RulesState(
199 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
200 false /* operationInProgress */,
201 RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
202 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
203 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
204 }
205
206 @Test
207 public void getRulesState_installedRulesError() throws Exception {
208 configureCallerHasPermission();
209
210 String systemRulesVersion = "2016a";
211 configureDeviceSystemRulesVersion(systemRulesVersion);
212
213 configureStagedUninstall();
214 configureDeviceCannotReadInstalledDistroVersion();
215
216 RulesState expectedRuleState = new RulesState(
217 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
218 false /* operationInProgress */,
219 RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
220 RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
221 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
222 }
223
224 @Test
225 public void getRulesState_stagedRulesError() throws Exception {
226 configureCallerHasPermission();
227
228 String systemRulesVersion = "2016a";
229 configureDeviceSystemRulesVersion(systemRulesVersion);
230
231 configureDeviceCannotReadStagedDistroOperation();
232
233 DistroVersion installedDistroVersion = new DistroVersion(
234 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
235 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
236 "2016b",
237 4);
238 configureInstalledDistroVersion(installedDistroVersion);
239
240 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
241 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
242 RulesState expectedRuleState = new RulesState(
243 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
244 false /* operationInProgress */,
245 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
246 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
247 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
248 }
249
250 @Test
251 public void getRulesState_noInstalledRules() throws Exception {
252 configureCallerHasPermission();
253
254 String systemRulesVersion = "2016a";
255 configureDeviceSystemRulesVersion(systemRulesVersion);
256 configureNoStagedOperation();
257 configureInstalledDistroVersion(null);
258
259 RulesState expectedRuleState = new RulesState(
260 systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
261 false /* operationInProgress */,
262 RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
263 RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
264 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
265 }
266
267 @Test
268 public void getRulesState_operationInProgress() throws Exception {
269 configureCallerHasPermission();
270
271 String systemRulesVersion = "2016a";
272 String installedRulesVersion = "2016b";
273 int revision = 3;
274
275 configureDeviceSystemRulesVersion(systemRulesVersion);
276
277 DistroVersion installedDistroVersion = new DistroVersion(
278 DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
279 DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
280 installedRulesVersion,
281 revision);
282 configureInstalledDistroVersion(installedDistroVersion);
283
Neil Fuller54525bf2017-06-22 14:10:29 +0100284 ParcelFileDescriptor parcelFileDescriptor =
285 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000286
287 // Start an async operation so there is one in progress. The mFakeExecutor won't actually
288 // execute it.
289 byte[] tokenBytes = createArbitraryTokenBytes();
290 ICallback callback = new StubbedCallback();
291
292 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
293
Neil Fuller9c90dc02017-06-22 14:10:29 +0100294 // Request the rules state while the async operation is "happening".
295 RulesState actualRulesState = mRulesManagerService.getRulesState();
Neil Fullerad3e1332018-01-22 12:17:14 +0000296 DistroRulesVersion expectedInstalledDistroRulesVersion =
297 new DistroRulesVersion(installedRulesVersion, revision);
Neil Fuller68f66662017-03-16 18:32:21 +0000298 RulesState expectedRuleState = new RulesState(
299 systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
300 true /* operationInProgress */,
301 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
Neil Fullerad3e1332018-01-22 12:17:14 +0000302 RulesState.DISTRO_STATUS_INSTALLED, expectedInstalledDistroRulesVersion);
Neil Fuller9c90dc02017-06-22 14:10:29 +0100303 assertEquals(expectedRuleState, actualRulesState);
Neil Fuller68f66662017-03-16 18:32:21 +0000304 }
305
306 @Test
307 public void requestInstall_operationInProgress() throws Exception {
308 configureCallerHasPermission();
309
Neil Fuller54525bf2017-06-22 14:10:29 +0100310 ParcelFileDescriptor parcelFileDescriptor1 =
311 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000312
313 byte[] tokenBytes = createArbitraryTokenBytes();
314 ICallback callback = new StubbedCallback();
315
316 // First request should succeed.
317 assertEquals(RulesManager.SUCCESS,
Neil Fuller54525bf2017-06-22 14:10:29 +0100318 mRulesManagerService.requestInstall(parcelFileDescriptor1, tokenBytes, callback));
Neil Fuller68f66662017-03-16 18:32:21 +0000319
320 // Something async should be enqueued. Clear it but do not execute it so we can detect the
321 // second request does nothing.
322 mFakeExecutor.getAndResetLastCommand();
323
324 // Second request should fail.
Neil Fuller54525bf2017-06-22 14:10:29 +0100325 ParcelFileDescriptor parcelFileDescriptor2 =
326 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000327 assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
Neil Fuller54525bf2017-06-22 14:10:29 +0100328 mRulesManagerService.requestInstall(parcelFileDescriptor2, tokenBytes, callback));
329
330 assertClosed(parcelFileDescriptor2);
Neil Fuller68f66662017-03-16 18:32:21 +0000331
332 // Assert nothing async was enqueued.
333 mFakeExecutor.assertNothingQueued();
334 verifyNoInstallerCallsMade();
335 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000336 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000337 }
338
339 @Test
340 public void requestInstall_badToken() throws Exception {
341 configureCallerHasPermission();
342
Neil Fuller54525bf2017-06-22 14:10:29 +0100343 ParcelFileDescriptor parcelFileDescriptor =
344 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000345
346 byte[] badTokenBytes = new byte[2];
347 ICallback callback = new StubbedCallback();
348
349 try {
350 mRulesManagerService.requestInstall(parcelFileDescriptor, badTokenBytes, callback);
351 fail();
352 } catch (IllegalArgumentException expected) {
353 }
354
Neil Fuller54525bf2017-06-22 14:10:29 +0100355 assertClosed(parcelFileDescriptor);
356
Neil Fuller68f66662017-03-16 18:32:21 +0000357 // Assert nothing async was enqueued.
358 mFakeExecutor.assertNothingQueued();
359 verifyNoInstallerCallsMade();
360 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000361 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000362 }
363
364 @Test
365 public void requestInstall_nullParcelFileDescriptor() throws Exception {
366 configureCallerHasPermission();
367
368 ParcelFileDescriptor parcelFileDescriptor = null;
369 byte[] tokenBytes = createArbitraryTokenBytes();
370 ICallback callback = new StubbedCallback();
371
372 try {
373 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
374 fail();
375 } catch (NullPointerException expected) {}
376
377 // Assert nothing async was enqueued.
378 mFakeExecutor.assertNothingQueued();
379 verifyNoInstallerCallsMade();
380 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000381 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000382 }
383
384 @Test
385 public void requestInstall_nullCallback() throws Exception {
386 configureCallerHasPermission();
387
Neil Fuller54525bf2017-06-22 14:10:29 +0100388 ParcelFileDescriptor parcelFileDescriptor =
389 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000390 byte[] tokenBytes = createArbitraryTokenBytes();
391 ICallback callback = null;
392
393 try {
394 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
395 fail();
396 } catch (NullPointerException expected) {}
397
Neil Fuller54525bf2017-06-22 14:10:29 +0100398 assertClosed(parcelFileDescriptor);
399
Neil Fuller68f66662017-03-16 18:32:21 +0000400 // Assert nothing async was enqueued.
401 mFakeExecutor.assertNothingQueued();
402 verifyNoInstallerCallsMade();
403 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000404 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000405 }
406
407 @Test
408 public void requestInstall_asyncSuccess() throws Exception {
409 configureCallerHasPermission();
410
Neil Fuller54525bf2017-06-22 14:10:29 +0100411 ParcelFileDescriptor parcelFileDescriptor =
412 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000413
414 CheckToken token = createArbitraryToken();
415 byte[] tokenBytes = token.toByteArray();
416
417 TestCallback callback = new TestCallback();
418
419 // Request the install.
420 assertEquals(RulesManager.SUCCESS,
421 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
422
423 // Assert nothing has happened yet.
424 callback.assertNoResultReceived();
425 verifyNoInstallerCallsMade();
426 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000427 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000428
429 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100430 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000431
432 // Simulate the async execution.
433 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
434
Neil Fuller54525bf2017-06-22 14:10:29 +0100435 assertClosed(parcelFileDescriptor);
436
Neil Fuller68f66662017-03-16 18:32:21 +0000437 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100438 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000439 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000440 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000441
442 // Check the callback was called.
443 callback.assertResultReceived(Callback.SUCCESS);
444 }
445
446 @Test
447 public void requestInstall_nullTokenBytes() throws Exception {
448 configureCallerHasPermission();
449
Neil Fuller54525bf2017-06-22 14:10:29 +0100450 ParcelFileDescriptor parcelFileDescriptor =
451 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000452
453 TestCallback callback = new TestCallback();
454
455 // Request the install.
456 assertEquals(RulesManager.SUCCESS,
457 mRulesManagerService.requestInstall(
458 parcelFileDescriptor, null /* tokenBytes */, callback));
459
460 // Assert nothing has happened yet.
461 verifyNoInstallerCallsMade();
462 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000463 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000464
465 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100466 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000467
468 // Simulate the async execution.
469 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
470
Neil Fuller54525bf2017-06-22 14:10:29 +0100471 assertClosed(parcelFileDescriptor);
472
Neil Fuller68f66662017-03-16 18:32:21 +0000473 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100474 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000475 verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000476 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000477
478 // Check the callback was received.
479 callback.assertResultReceived(Callback.SUCCESS);
480 }
481
482 @Test
483 public void requestInstall_asyncInstallFail() throws Exception {
484 configureCallerHasPermission();
485
Neil Fuller54525bf2017-06-22 14:10:29 +0100486 ParcelFileDescriptor parcelFileDescriptor =
487 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000488
489 CheckToken token = createArbitraryToken();
490 byte[] tokenBytes = token.toByteArray();
491
492 TestCallback callback = new TestCallback();
493
494 // Request the install.
495 assertEquals(RulesManager.SUCCESS,
496 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
497
498 // Assert nothing has happened yet.
499 verifyNoInstallerCallsMade();
500 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000501 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000502
503 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100504 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
Neil Fuller68f66662017-03-16 18:32:21 +0000505
506 // Simulate the async execution.
507 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
508
Neil Fuller54525bf2017-06-22 14:10:29 +0100509 assertClosed(parcelFileDescriptor);
510
Neil Fuller68f66662017-03-16 18:32:21 +0000511 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100512 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000513
514 // Validation failure is treated like a successful check: repeating it won't improve things.
515 boolean expectedSuccess = true;
516 verifyPackageTrackerCalled(token, expectedSuccess);
517
Neil Fullerb1442272017-12-18 15:59:50 +0000518 // Nothing should be staged, so no intents sent.
519 verifyNoIntentsSent();
520
Neil Fuller68f66662017-03-16 18:32:21 +0000521 // Check the callback was received.
522 callback.assertResultReceived(Callback.ERROR_INSTALL_VALIDATION_ERROR);
523 }
524
525 @Test
Neil Fuller68f66662017-03-16 18:32:21 +0000526 public void requestUninstall_operationInProgress() throws Exception {
527 configureCallerHasPermission();
528
529 byte[] tokenBytes = createArbitraryTokenBytes();
530 ICallback callback = new StubbedCallback();
531
532 // First request should succeed.
533 assertEquals(RulesManager.SUCCESS,
534 mRulesManagerService.requestUninstall(tokenBytes, callback));
535
536 // Something async should be enqueued. Clear it but do not execute it so we can detect the
537 // second request does nothing.
538 mFakeExecutor.getAndResetLastCommand();
539
540 // Second request should fail.
541 assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
542 mRulesManagerService.requestUninstall(tokenBytes, callback));
543
544 // Assert nothing async was enqueued.
545 mFakeExecutor.assertNothingQueued();
546 verifyNoInstallerCallsMade();
547 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000548 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000549 }
550
551 @Test
552 public void requestUninstall_badToken() throws Exception {
553 configureCallerHasPermission();
554
555 byte[] badTokenBytes = new byte[2];
556 ICallback callback = new StubbedCallback();
557
558 try {
559 mRulesManagerService.requestUninstall(badTokenBytes, callback);
560 fail();
561 } catch (IllegalArgumentException expected) {
562 }
563
564 // Assert nothing async was enqueued.
565 mFakeExecutor.assertNothingQueued();
566 verifyNoInstallerCallsMade();
567 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000568 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000569 }
570
571 @Test
572 public void requestUninstall_nullCallback() throws Exception {
573 configureCallerHasPermission();
574
575 byte[] tokenBytes = createArbitraryTokenBytes();
576 ICallback callback = null;
577
578 try {
579 mRulesManagerService.requestUninstall(tokenBytes, callback);
580 fail();
581 } catch (NullPointerException expected) {}
582
583 // Assert nothing async was enqueued.
584 mFakeExecutor.assertNothingQueued();
585 verifyNoInstallerCallsMade();
586 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000587 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000588 }
589
590 @Test
591 public void requestUninstall_asyncSuccess() throws Exception {
592 configureCallerHasPermission();
593
594 CheckToken token = createArbitraryToken();
595 byte[] tokenBytes = token.toByteArray();
596
597 TestCallback callback = new TestCallback();
598
599 // Request the uninstall.
600 assertEquals(RulesManager.SUCCESS,
601 mRulesManagerService.requestUninstall(tokenBytes, callback));
602
603 // Assert nothing has happened yet.
604 callback.assertNoResultReceived();
605 verifyNoInstallerCallsMade();
606 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000607 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000608
609 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100610 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
611
612 // Simulate the async execution.
613 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
614
615 // Verify the expected calls were made to other components.
616 verifyStageUninstallCalled();
617 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000618 verifyStagedOperationIntentSent();
Neil Fuller8e27c922017-09-14 09:34:56 +0100619
620 // Check the callback was called.
621 callback.assertResultReceived(Callback.SUCCESS);
622 }
623
624 @Test
625 public void requestUninstall_asyncNothingInstalled() throws Exception {
626 configureCallerHasPermission();
627
628 CheckToken token = createArbitraryToken();
629 byte[] tokenBytes = token.toByteArray();
630
631 TestCallback callback = new TestCallback();
632
633 // Request the uninstall.
634 assertEquals(RulesManager.SUCCESS,
635 mRulesManagerService.requestUninstall(tokenBytes, callback));
636
637 // Assert nothing has happened yet.
638 callback.assertNoResultReceived();
639 verifyNoInstallerCallsMade();
640 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000641 verifyNoIntentsSent();
Neil Fuller8e27c922017-09-14 09:34:56 +0100642
643 // Set up the installer.
644 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED);
Neil Fuller68f66662017-03-16 18:32:21 +0000645
646 // Simulate the async execution.
647 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
648
649 // Verify the expected calls were made to other components.
650 verifyStageUninstallCalled();
651 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000652 verifyUnstagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000653
654 // Check the callback was called.
655 callback.assertResultReceived(Callback.SUCCESS);
656 }
657
658 @Test
659 public void requestUninstall_nullTokenBytes() throws Exception {
660 configureCallerHasPermission();
661
662 TestCallback callback = new TestCallback();
663
664 // Request the uninstall.
665 assertEquals(RulesManager.SUCCESS,
666 mRulesManagerService.requestUninstall(null /* tokenBytes */, callback));
667
668 // Assert nothing has happened yet.
669 verifyNoInstallerCallsMade();
670 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000671 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000672
673 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100674 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000675
676 // Simulate the async execution.
677 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
678
679 // Verify the expected calls were made to other components.
680 verifyStageUninstallCalled();
681 verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000682 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000683
684 // Check the callback was received.
685 callback.assertResultReceived(Callback.SUCCESS);
686 }
687
688 @Test
689 public void requestUninstall_asyncUninstallFail() throws Exception {
690 configureCallerHasPermission();
691
692 CheckToken token = createArbitraryToken();
693 byte[] tokenBytes = token.toByteArray();
694
695 TestCallback callback = new TestCallback();
696
697 // Request the uninstall.
698 assertEquals(RulesManager.SUCCESS,
699 mRulesManagerService.requestUninstall(tokenBytes, callback));
700
701 // Assert nothing has happened yet.
702 verifyNoInstallerCallsMade();
703 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000704 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000705
706 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100707 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_FAIL);
Neil Fuller68f66662017-03-16 18:32:21 +0000708
709 // Simulate the async execution.
710 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
711
712 // Verify the expected calls were made to other components.
713 verifyStageUninstallCalled();
714 verifyPackageTrackerCalled(token, false /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000715 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000716
717 // Check the callback was received.
718 callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
719 }
720
721 @Test
722 public void requestNothing_operationInProgressOk() throws Exception {
723 configureCallerHasPermission();
724
725 // Set up a parallel operation.
726 assertEquals(RulesManager.SUCCESS,
727 mRulesManagerService.requestUninstall(null, new StubbedCallback()));
728 // Something async should be enqueued. Clear it but do not execute it to simulate it still
729 // being in progress.
730 mFakeExecutor.getAndResetLastCommand();
731
732 CheckToken token = createArbitraryToken();
733 byte[] tokenBytes = token.toByteArray();
734
735 // Make the call.
736 mRulesManagerService.requestNothing(tokenBytes, true /* success */);
737
738 // Assert nothing async was enqueued.
739 mFakeExecutor.assertNothingQueued();
740
741 // Verify the expected calls were made to other components.
742 verifyPackageTrackerCalled(token, true /* success */);
743 verifyNoInstallerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000744 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000745 }
746
747 @Test
748 public void requestNothing_badToken() throws Exception {
749 configureCallerHasPermission();
750
751 byte[] badTokenBytes = new byte[2];
752
753 try {
754 mRulesManagerService.requestNothing(badTokenBytes, true /* success */);
755 fail();
756 } catch (IllegalArgumentException expected) {
757 }
758
759 // Assert nothing async was enqueued.
760 mFakeExecutor.assertNothingQueued();
761
762 // Assert no other calls were made.
763 verifyNoInstallerCallsMade();
764 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000765 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000766 }
767
768 @Test
769 public void requestNothing() throws Exception {
770 configureCallerHasPermission();
771
772 CheckToken token = createArbitraryToken();
773 byte[] tokenBytes = token.toByteArray();
774
775 // Make the call.
776 mRulesManagerService.requestNothing(tokenBytes, false /* success */);
777
778 // Assert everything required was done.
779 verifyNoInstallerCallsMade();
780 verifyPackageTrackerCalled(token, false /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000781 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000782 }
783
784 @Test
785 public void requestNothing_nullTokenBytes() throws Exception {
786 configureCallerHasPermission();
787
788 // Make the call.
789 mRulesManagerService.requestNothing(null /* tokenBytes */, true /* success */);
790
791 // Assert everything required was done.
792 verifyNoInstallerCallsMade();
793 verifyPackageTrackerCalled(null /* token */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000794 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000795 }
796
Neil Fuller87b11282017-06-23 16:43:45 +0100797 @Test
798 public void dump_noPermission() throws Exception {
799 when(mMockPermissionHelper.checkDumpPermission(any(String.class), any(PrintWriter.class)))
800 .thenReturn(false);
801
802 doDumpCallAndCapture(mRulesManagerService, null);
803 verifyZeroInteractions(mMockPackageTracker, mMockTimeZoneDistroInstaller);
804 }
805
806 @Test
807 public void dump_emptyArgs() throws Exception {
808 doSuccessfulDumpCall(mRulesManagerService, new String[0]);
809
810 // Verify the package tracker was consulted.
811 verify(mMockPackageTracker).dump(any(PrintWriter.class));
812 }
813
814 @Test
815 public void dump_nullArgs() throws Exception {
816 doSuccessfulDumpCall(mRulesManagerService, null);
817 // Verify the package tracker was consulted.
818 verify(mMockPackageTracker).dump(any(PrintWriter.class));
819 }
820
821 @Test
822 public void dump_unknownArgs() throws Exception {
823 String dumpedTextUnknownArgs = doSuccessfulDumpCall(
824 mRulesManagerService, new String[] { "foo", "bar"});
825
826 // Verify the package tracker was consulted.
827 verify(mMockPackageTracker).dump(any(PrintWriter.class));
828
829 String dumpedTextZeroArgs = doSuccessfulDumpCall(mRulesManagerService, null);
830 assertEquals(dumpedTextZeroArgs, dumpedTextUnknownArgs);
831 }
832
833 @Test
834 public void dump_formatState() throws Exception {
835 // Just expect these to not throw exceptions, not return nothing, and not interact with the
836 // package tracker.
837 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("p"));
838 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("s"));
839 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("c"));
840 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("i"));
841 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("o"));
842 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("t"));
843 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("a"));
844 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("z" /* Unknown */));
845 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("piscotz"));
846
847 verifyZeroInteractions(mMockPackageTracker);
848 }
849
850 private static String[] dumpFormatArgs(String argsString) {
851 return new String[] { "-format_state", argsString};
852 }
853
854 private String doSuccessfulDumpCall(RulesManagerService rulesManagerService, String[] args)
855 throws Exception {
856 when(mMockPermissionHelper.checkDumpPermission(any(String.class), any(PrintWriter.class)))
857 .thenReturn(true);
858
859 // Set up the mocks to return (arbitrary) information about the current device state.
860 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn("2017a");
861 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion()).thenReturn(
862 new DistroVersion(2, 3, "2017b", 4));
863 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(
864 StagedDistroOperation.install(new DistroVersion(5, 6, "2017c", 7)));
865
866 // Do the dump call.
867 String dumpedOutput = doDumpCallAndCapture(rulesManagerService, args);
868
869 assertFalse(dumpedOutput.isEmpty());
870
871 return dumpedOutput;
872 }
873
874 private static String doDumpCallAndCapture(
875 RulesManagerService rulesManagerService, String[] args) throws IOException {
876 File file = File.createTempFile("dump", null);
877 try {
878 try (FileOutputStream fos = new FileOutputStream(file)) {
879 FileDescriptor fd = fos.getFD();
880 rulesManagerService.dump(fd, args);
881 }
882 return IoUtils.readFileAsString(file.getAbsolutePath());
883 } finally {
884 file.delete();
885 }
886 }
887
Neil Fuller68f66662017-03-16 18:32:21 +0000888 private void verifyNoPackageTrackerCallsMade() {
889 verifyNoMoreInteractions(mMockPackageTracker);
890 reset(mMockPackageTracker);
891 }
892
893 private void verifyPackageTrackerCalled(
894 CheckToken expectedCheckToken, boolean expectedSuccess) {
895 verify(mMockPackageTracker).recordCheckResult(expectedCheckToken, expectedSuccess);
896 reset(mMockPackageTracker);
897 }
898
Neil Fullerb1442272017-12-18 15:59:50 +0000899 private void verifyNoIntentsSent() {
900 verifyNoMoreInteractions(mMockIntentHelper);
901 reset(mMockIntentHelper);
902 }
903
904 private void verifyStagedOperationIntentSent() {
905 verify(mMockIntentHelper).sendTimeZoneOperationStaged();
906 reset(mMockIntentHelper);
907 }
908
909 private void verifyUnstagedOperationIntentSent() {
910 verify(mMockIntentHelper).sendTimeZoneOperationUnstaged();
911 reset(mMockIntentHelper);
912 }
913
Neil Fuller68f66662017-03-16 18:32:21 +0000914 private void configureCallerHasPermission() throws Exception {
915 doNothing()
916 .when(mMockPermissionHelper)
917 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
918 }
919
Neil Fullerb214bc42017-12-18 16:57:22 +0000920 private void configureCallerDoesNotHaveUpdatePermission() {
Neil Fuller68f66662017-03-16 18:32:21 +0000921 doThrow(new SecurityException("Simulated permission failure"))
922 .when(mMockPermissionHelper)
923 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
924 }
925
Neil Fullerb214bc42017-12-18 16:57:22 +0000926 private void configureCallerDoesNotHaveQueryPermission() {
927 doThrow(new SecurityException("Simulated permission failure"))
928 .when(mMockPermissionHelper)
929 .enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);
930 }
931
Neil Fuller9c90dc02017-06-22 14:10:29 +0100932 private void configureStageInstallExpectation(int resultCode)
Neil Fuller68f66662017-03-16 18:32:21 +0000933 throws Exception {
Neil Fuller9c90dc02017-06-22 14:10:29 +0100934 when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(any(TimeZoneDistro.class)))
Neil Fuller68f66662017-03-16 18:32:21 +0000935 .thenReturn(resultCode);
936 }
937
Neil Fuller8e27c922017-09-14 09:34:56 +0100938 private void configureStageUninstallExpectation(int resultCode) throws Exception {
939 doReturn(resultCode).when(mMockTimeZoneDistroInstaller).stageUninstall();
Neil Fuller68f66662017-03-16 18:32:21 +0000940 }
941
Neil Fuller9c90dc02017-06-22 14:10:29 +0100942 private void verifyStageInstallCalled() throws Exception {
943 verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(any(TimeZoneDistro.class));
Neil Fuller68f66662017-03-16 18:32:21 +0000944 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
945 reset(mMockTimeZoneDistroInstaller);
946 }
947
948 private void verifyStageUninstallCalled() throws Exception {
949 verify(mMockTimeZoneDistroInstaller).stageUninstall();
950 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
951 reset(mMockTimeZoneDistroInstaller);
952 }
953
954 private void verifyNoInstallerCallsMade() {
955 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
956 reset(mMockTimeZoneDistroInstaller);
957 }
958
959 private static byte[] createArbitraryBytes(int length) {
960 byte[] bytes = new byte[length];
961 for (int i = 0; i < length; i++) {
962 bytes[i] = (byte) i;
963 }
964 return bytes;
965 }
966
967 private byte[] createArbitraryTokenBytes() {
968 return createArbitraryToken().toByteArray();
969 }
970
971 private CheckToken createArbitraryToken() {
972 return new CheckToken(1, new PackageVersions(1, 1));
973 }
974
Neil Fuller68f66662017-03-16 18:32:21 +0000975 private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
976 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
977 }
978
979 private void configureInstalledDistroVersion(@Nullable DistroVersion installedDistroVersion)
980 throws Exception {
981 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
982 .thenReturn(installedDistroVersion);
983 }
984
985 private void configureStagedInstall(DistroVersion stagedDistroVersion) throws Exception {
986 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
987 .thenReturn(StagedDistroOperation.install(stagedDistroVersion));
988 }
989
990 private void configureStagedUninstall() throws Exception {
991 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
992 .thenReturn(StagedDistroOperation.uninstall());
993 }
994
995 private void configureNoStagedOperation() throws Exception {
996 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(null);
997 }
998
999 private void configureDeviceCannotReadStagedDistroOperation() throws Exception {
1000 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
1001 .thenThrow(new IOException("Simulated failure"));
1002 }
1003
1004 private void configureDeviceCannotReadSystemRulesVersion() throws Exception {
1005 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion())
1006 .thenThrow(new IOException("Simulated failure"));
1007 }
1008
1009 private void configureDeviceCannotReadInstalledDistroVersion() throws Exception {
1010 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
1011 .thenThrow(new IOException("Simulated failure"));
1012 }
1013
Neil Fuller54525bf2017-06-22 14:10:29 +01001014 private static void assertClosed(ParcelFileDescriptor parcelFileDescriptor) {
1015 assertFalse(parcelFileDescriptor.getFileDescriptor().valid());
1016 }
1017
Neil Fuller68f66662017-03-16 18:32:21 +00001018 private static class FakeExecutor implements Executor {
1019
1020 private Runnable mLastCommand;
1021
1022 @Override
1023 public void execute(Runnable command) {
1024 assertNull(mLastCommand);
1025 assertNotNull(command);
1026 mLastCommand = command;
1027 }
1028
1029 public Runnable getAndResetLastCommand() {
1030 assertNotNull(mLastCommand);
1031 Runnable toReturn = mLastCommand;
1032 mLastCommand = null;
1033 return toReturn;
1034 }
1035
1036 public void simulateAsyncExecutionOfLastCommand() {
1037 Runnable toRun = getAndResetLastCommand();
1038 toRun.run();
1039 }
1040
1041 public void assertNothingQueued() {
1042 assertNull(mLastCommand);
1043 }
1044 }
1045
1046 private static class TestCallback extends ICallback.Stub {
1047
1048 private boolean mOnFinishedCalled;
1049 private int mLastError;
1050
1051 @Override
1052 public void onFinished(int error) {
1053 assertFalse(mOnFinishedCalled);
1054 mOnFinishedCalled = true;
1055 mLastError = error;
1056 }
1057
1058 public void assertResultReceived(int expectedResult) {
1059 assertTrue(mOnFinishedCalled);
1060 assertEquals(expectedResult, mLastError);
1061 }
1062
1063 public void assertNoResultReceived() {
1064 assertFalse(mOnFinishedCalled);
1065 }
1066 }
1067
1068 private static class StubbedCallback extends ICallback.Stub {
1069 @Override
1070 public void onFinished(int error) {
1071 fail("Unexpected call");
1072 }
1073 }
Neil Fuller54525bf2017-06-22 14:10:29 +01001074
1075 private static ParcelFileDescriptor createParcelFileDescriptor(byte[] bytes)
1076 throws IOException {
1077 File file = File.createTempFile("pfd", null);
1078 try (FileOutputStream fos = new FileOutputStream(file)) {
1079 fos.write(bytes);
1080 }
1081 ParcelFileDescriptor pfd =
1082 ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
1083 // This should now be safe to delete. The ParcelFileDescriptor has an open fd.
1084 file.delete();
1085 return pfd;
1086 }
Neil Fuller68f66662017-03-16 18:32:21 +00001087}