blob: 1b106dd371638345dfe484334cf1c36a60091148 [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;
Neil Fuller0ac8df02018-11-16 16:19:26 +000043import libcore.timezone.TzDataSetVersion;
Neil Fuller87b11282017-06-23 16:43:45 +010044
Neil Fullerb214bc42017-12-18 16:57:22 +000045import static com.android.server.timezone.RulesManagerService.REQUIRED_QUERY_PERMISSION;
Neil Fuller68f66662017-03-16 18:32:21 +000046import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
47import static org.junit.Assert.assertEquals;
48import static org.junit.Assert.assertFalse;
49import static org.junit.Assert.assertNotNull;
50import static org.junit.Assert.assertNull;
51import static org.junit.Assert.assertTrue;
52import static org.junit.Assert.fail;
Neil Fuller9c90dc02017-06-22 14:10:29 +010053import static org.mockito.ArgumentMatchers.any;
Neil Fuller68f66662017-03-16 18:32:21 +000054import static org.mockito.Mockito.doNothing;
55import static org.mockito.Mockito.doReturn;
56import static org.mockito.Mockito.doThrow;
57import static org.mockito.Mockito.mock;
58import static org.mockito.Mockito.reset;
59import static org.mockito.Mockito.verify;
60import static org.mockito.Mockito.verifyNoMoreInteractions;
Neil Fuller87b11282017-06-23 16:43:45 +010061import static org.mockito.Mockito.verifyZeroInteractions;
Neil Fuller68f66662017-03-16 18:32:21 +000062import static org.mockito.Mockito.when;
63
64/**
65 * White box interaction / unit testing of the {@link RulesManagerService}.
66 */
67public class RulesManagerServiceTest {
68
69 private RulesManagerService mRulesManagerService;
70
71 private FakeExecutor mFakeExecutor;
72 private PermissionHelper mMockPermissionHelper;
Neil Fullerb1442272017-12-18 15:59:50 +000073 private RulesManagerIntentHelper mMockIntentHelper;
Neil Fuller68f66662017-03-16 18:32:21 +000074 private PackageTracker mMockPackageTracker;
75 private TimeZoneDistroInstaller mMockTimeZoneDistroInstaller;
76
77 @Before
78 public void setUp() {
79 mFakeExecutor = new FakeExecutor();
80
Neil Fuller68f66662017-03-16 18:32:21 +000081 mMockPackageTracker = mock(PackageTracker.class);
82 mMockPermissionHelper = mock(PermissionHelper.class);
Neil Fullerb1442272017-12-18 15:59:50 +000083 mMockIntentHelper = mock(RulesManagerIntentHelper.class);
Neil Fuller68f66662017-03-16 18:32:21 +000084 mMockTimeZoneDistroInstaller = mock(TimeZoneDistroInstaller.class);
85
86 mRulesManagerService = new RulesManagerService(
87 mMockPermissionHelper,
88 mFakeExecutor,
Neil Fullerb1442272017-12-18 15:59:50 +000089 mMockIntentHelper,
Neil Fuller68f66662017-03-16 18:32:21 +000090 mMockPackageTracker,
91 mMockTimeZoneDistroInstaller);
92 }
93
94 @Test(expected = SecurityException.class)
95 public void getRulesState_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +000096 configureCallerDoesNotHaveQueryPermission();
Neil Fuller68f66662017-03-16 18:32:21 +000097 mRulesManagerService.getRulesState();
98 }
99
100 @Test(expected = SecurityException.class)
101 public void requestInstall_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000102 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000103 mRulesManagerService.requestInstall(null, null, null);
104 }
105
106 @Test(expected = SecurityException.class)
107 public void requestUninstall_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000108 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000109 mRulesManagerService.requestUninstall(null, null);
110 }
111
112 @Test(expected = SecurityException.class)
113 public void requestNothing_noCallerPermission() throws Exception {
Neil Fullerb214bc42017-12-18 16:57:22 +0000114 configureCallerDoesNotHaveUpdatePermission();
Neil Fuller68f66662017-03-16 18:32:21 +0000115 mRulesManagerService.requestNothing(null, true);
116 }
117
118 @Test
119 public void getRulesState_systemRulesError() throws Exception {
120 configureDeviceCannotReadSystemRulesVersion();
121
122 assertNull(mRulesManagerService.getRulesState());
123 }
124
125 @Test
126 public void getRulesState_stagedInstall() throws Exception {
127 configureCallerHasPermission();
128
129 configureDeviceSystemRulesVersion("2016a");
130
131 DistroVersion stagedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000132 TzDataSetVersion.currentFormatMajorVersion(),
133 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000134 "2016c",
135 3);
136 configureStagedInstall(stagedDistroVersion);
137
138 DistroVersion installedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000139 TzDataSetVersion.currentFormatMajorVersion(),
140 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000141 "2016b",
142 4);
143 configureInstalledDistroVersion(installedDistroVersion);
144
145 DistroRulesVersion stagedDistroRulesVersion = new DistroRulesVersion(
146 stagedDistroVersion.rulesVersion, stagedDistroVersion.revision);
147 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
148 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
149 RulesState expectedRuleState = new RulesState(
150 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
151 false /* operationInProgress */,
152 RulesState.STAGED_OPERATION_INSTALL, stagedDistroRulesVersion,
153 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
154 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
155 }
156
157 @Test
158 public void getRulesState_nothingStaged() throws Exception {
159 configureCallerHasPermission();
160
161 configureDeviceSystemRulesVersion("2016a");
162
163 configureNoStagedOperation();
164
165 DistroVersion installedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000166 TzDataSetVersion.currentFormatMajorVersion(),
167 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000168 "2016b",
169 4);
170 configureInstalledDistroVersion(installedDistroVersion);
171
172 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
173 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
174 RulesState expectedRuleState = new RulesState(
175 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
176 false /* operationInProgress */,
177 RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
178 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
179 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
180 }
181
182 @Test
183 public void getRulesState_uninstallStaged() throws Exception {
184 configureCallerHasPermission();
185
186 configureDeviceSystemRulesVersion("2016a");
187
188 configureStagedUninstall();
189
190 DistroVersion installedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000191 TzDataSetVersion.currentFormatMajorVersion(),
192 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000193 "2016b",
194 4);
195 configureInstalledDistroVersion(installedDistroVersion);
196
197 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
198 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
199 RulesState expectedRuleState = new RulesState(
200 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
201 false /* operationInProgress */,
202 RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
203 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
204 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
205 }
206
207 @Test
208 public void getRulesState_installedRulesError() throws Exception {
209 configureCallerHasPermission();
210
211 String systemRulesVersion = "2016a";
212 configureDeviceSystemRulesVersion(systemRulesVersion);
213
214 configureStagedUninstall();
215 configureDeviceCannotReadInstalledDistroVersion();
216
217 RulesState expectedRuleState = new RulesState(
218 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
219 false /* operationInProgress */,
220 RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
221 RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
222 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
223 }
224
225 @Test
226 public void getRulesState_stagedRulesError() throws Exception {
227 configureCallerHasPermission();
228
229 String systemRulesVersion = "2016a";
230 configureDeviceSystemRulesVersion(systemRulesVersion);
231
232 configureDeviceCannotReadStagedDistroOperation();
233
234 DistroVersion installedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000235 TzDataSetVersion.currentFormatMajorVersion(),
236 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000237 "2016b",
238 4);
239 configureInstalledDistroVersion(installedDistroVersion);
240
241 DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
242 installedDistroVersion.rulesVersion, installedDistroVersion.revision);
243 RulesState expectedRuleState = new RulesState(
244 "2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
245 false /* operationInProgress */,
246 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
247 RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
248 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
249 }
250
251 @Test
252 public void getRulesState_noInstalledRules() throws Exception {
253 configureCallerHasPermission();
254
255 String systemRulesVersion = "2016a";
256 configureDeviceSystemRulesVersion(systemRulesVersion);
257 configureNoStagedOperation();
258 configureInstalledDistroVersion(null);
259
260 RulesState expectedRuleState = new RulesState(
261 systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
262 false /* operationInProgress */,
263 RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
264 RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
265 assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
266 }
267
268 @Test
269 public void getRulesState_operationInProgress() throws Exception {
270 configureCallerHasPermission();
271
272 String systemRulesVersion = "2016a";
273 String installedRulesVersion = "2016b";
274 int revision = 3;
275
276 configureDeviceSystemRulesVersion(systemRulesVersion);
277
278 DistroVersion installedDistroVersion = new DistroVersion(
Neil Fuller0ac8df02018-11-16 16:19:26 +0000279 TzDataSetVersion.currentFormatMajorVersion(),
280 TzDataSetVersion.currentFormatMinorVersion() - 1,
Neil Fuller68f66662017-03-16 18:32:21 +0000281 installedRulesVersion,
282 revision);
283 configureInstalledDistroVersion(installedDistroVersion);
284
Neil Fuller54525bf2017-06-22 14:10:29 +0100285 ParcelFileDescriptor parcelFileDescriptor =
286 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000287
288 // Start an async operation so there is one in progress. The mFakeExecutor won't actually
289 // execute it.
290 byte[] tokenBytes = createArbitraryTokenBytes();
291 ICallback callback = new StubbedCallback();
292
293 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
294
Neil Fuller9c90dc02017-06-22 14:10:29 +0100295 // Request the rules state while the async operation is "happening".
296 RulesState actualRulesState = mRulesManagerService.getRulesState();
Neil Fullerad3e1332018-01-22 12:17:14 +0000297 DistroRulesVersion expectedInstalledDistroRulesVersion =
298 new DistroRulesVersion(installedRulesVersion, revision);
Neil Fuller68f66662017-03-16 18:32:21 +0000299 RulesState expectedRuleState = new RulesState(
300 systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
301 true /* operationInProgress */,
302 RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
Neil Fullerad3e1332018-01-22 12:17:14 +0000303 RulesState.DISTRO_STATUS_INSTALLED, expectedInstalledDistroRulesVersion);
Neil Fuller9c90dc02017-06-22 14:10:29 +0100304 assertEquals(expectedRuleState, actualRulesState);
Neil Fuller68f66662017-03-16 18:32:21 +0000305 }
306
307 @Test
308 public void requestInstall_operationInProgress() throws Exception {
309 configureCallerHasPermission();
310
Neil Fuller54525bf2017-06-22 14:10:29 +0100311 ParcelFileDescriptor parcelFileDescriptor1 =
312 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000313
314 byte[] tokenBytes = createArbitraryTokenBytes();
315 ICallback callback = new StubbedCallback();
316
317 // First request should succeed.
318 assertEquals(RulesManager.SUCCESS,
Neil Fuller54525bf2017-06-22 14:10:29 +0100319 mRulesManagerService.requestInstall(parcelFileDescriptor1, tokenBytes, callback));
Neil Fuller68f66662017-03-16 18:32:21 +0000320
321 // Something async should be enqueued. Clear it but do not execute it so we can detect the
322 // second request does nothing.
323 mFakeExecutor.getAndResetLastCommand();
324
325 // Second request should fail.
Neil Fuller54525bf2017-06-22 14:10:29 +0100326 ParcelFileDescriptor parcelFileDescriptor2 =
327 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000328 assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
Neil Fuller54525bf2017-06-22 14:10:29 +0100329 mRulesManagerService.requestInstall(parcelFileDescriptor2, tokenBytes, callback));
330
331 assertClosed(parcelFileDescriptor2);
Neil Fuller68f66662017-03-16 18:32:21 +0000332
333 // Assert nothing async was enqueued.
334 mFakeExecutor.assertNothingQueued();
335 verifyNoInstallerCallsMade();
336 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000337 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000338 }
339
340 @Test
341 public void requestInstall_badToken() throws Exception {
342 configureCallerHasPermission();
343
Neil Fuller54525bf2017-06-22 14:10:29 +0100344 ParcelFileDescriptor parcelFileDescriptor =
345 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000346
347 byte[] badTokenBytes = new byte[2];
348 ICallback callback = new StubbedCallback();
349
350 try {
351 mRulesManagerService.requestInstall(parcelFileDescriptor, badTokenBytes, callback);
352 fail();
353 } catch (IllegalArgumentException expected) {
354 }
355
Neil Fuller54525bf2017-06-22 14:10:29 +0100356 assertClosed(parcelFileDescriptor);
357
Neil Fuller68f66662017-03-16 18:32:21 +0000358 // Assert nothing async was enqueued.
359 mFakeExecutor.assertNothingQueued();
360 verifyNoInstallerCallsMade();
361 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000362 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000363 }
364
365 @Test
366 public void requestInstall_nullParcelFileDescriptor() throws Exception {
367 configureCallerHasPermission();
368
369 ParcelFileDescriptor parcelFileDescriptor = null;
370 byte[] tokenBytes = createArbitraryTokenBytes();
371 ICallback callback = new StubbedCallback();
372
373 try {
374 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
375 fail();
376 } catch (NullPointerException expected) {}
377
378 // Assert nothing async was enqueued.
379 mFakeExecutor.assertNothingQueued();
380 verifyNoInstallerCallsMade();
381 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000382 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000383 }
384
385 @Test
386 public void requestInstall_nullCallback() throws Exception {
387 configureCallerHasPermission();
388
Neil Fuller54525bf2017-06-22 14:10:29 +0100389 ParcelFileDescriptor parcelFileDescriptor =
390 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000391 byte[] tokenBytes = createArbitraryTokenBytes();
392 ICallback callback = null;
393
394 try {
395 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
396 fail();
397 } catch (NullPointerException expected) {}
398
Neil Fuller54525bf2017-06-22 14:10:29 +0100399 assertClosed(parcelFileDescriptor);
400
Neil Fuller68f66662017-03-16 18:32:21 +0000401 // Assert nothing async was enqueued.
402 mFakeExecutor.assertNothingQueued();
403 verifyNoInstallerCallsMade();
404 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000405 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000406 }
407
408 @Test
409 public void requestInstall_asyncSuccess() throws Exception {
410 configureCallerHasPermission();
411
Neil Fuller54525bf2017-06-22 14:10:29 +0100412 ParcelFileDescriptor parcelFileDescriptor =
413 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000414
415 CheckToken token = createArbitraryToken();
416 byte[] tokenBytes = token.toByteArray();
417
418 TestCallback callback = new TestCallback();
419
420 // Request the install.
421 assertEquals(RulesManager.SUCCESS,
422 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
423
424 // Assert nothing has happened yet.
425 callback.assertNoResultReceived();
426 verifyNoInstallerCallsMade();
427 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000428 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000429
430 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100431 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000432
433 // Simulate the async execution.
434 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
435
Neil Fuller54525bf2017-06-22 14:10:29 +0100436 assertClosed(parcelFileDescriptor);
437
Neil Fuller68f66662017-03-16 18:32:21 +0000438 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100439 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000440 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000441 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000442
443 // Check the callback was called.
444 callback.assertResultReceived(Callback.SUCCESS);
445 }
446
447 @Test
448 public void requestInstall_nullTokenBytes() throws Exception {
449 configureCallerHasPermission();
450
Neil Fuller54525bf2017-06-22 14:10:29 +0100451 ParcelFileDescriptor parcelFileDescriptor =
452 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000453
454 TestCallback callback = new TestCallback();
455
456 // Request the install.
457 assertEquals(RulesManager.SUCCESS,
458 mRulesManagerService.requestInstall(
459 parcelFileDescriptor, null /* tokenBytes */, callback));
460
461 // Assert nothing has happened yet.
462 verifyNoInstallerCallsMade();
463 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000464 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000465
466 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100467 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000468
469 // Simulate the async execution.
470 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
471
Neil Fuller54525bf2017-06-22 14:10:29 +0100472 assertClosed(parcelFileDescriptor);
473
Neil Fuller68f66662017-03-16 18:32:21 +0000474 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100475 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000476 verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000477 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000478
479 // Check the callback was received.
480 callback.assertResultReceived(Callback.SUCCESS);
481 }
482
483 @Test
484 public void requestInstall_asyncInstallFail() throws Exception {
485 configureCallerHasPermission();
486
Neil Fuller54525bf2017-06-22 14:10:29 +0100487 ParcelFileDescriptor parcelFileDescriptor =
488 createParcelFileDescriptor(createArbitraryBytes(1000));
Neil Fuller68f66662017-03-16 18:32:21 +0000489
490 CheckToken token = createArbitraryToken();
491 byte[] tokenBytes = token.toByteArray();
492
493 TestCallback callback = new TestCallback();
494
495 // Request the install.
496 assertEquals(RulesManager.SUCCESS,
497 mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
498
499 // Assert nothing has happened yet.
500 verifyNoInstallerCallsMade();
501 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000502 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000503
504 // Set up the installer.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100505 configureStageInstallExpectation(TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
Neil Fuller68f66662017-03-16 18:32:21 +0000506
507 // Simulate the async execution.
508 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
509
Neil Fuller54525bf2017-06-22 14:10:29 +0100510 assertClosed(parcelFileDescriptor);
511
Neil Fuller68f66662017-03-16 18:32:21 +0000512 // Verify the expected calls were made to other components.
Neil Fuller9c90dc02017-06-22 14:10:29 +0100513 verifyStageInstallCalled();
Neil Fuller68f66662017-03-16 18:32:21 +0000514
515 // Validation failure is treated like a successful check: repeating it won't improve things.
516 boolean expectedSuccess = true;
517 verifyPackageTrackerCalled(token, expectedSuccess);
518
Neil Fullerb1442272017-12-18 15:59:50 +0000519 // Nothing should be staged, so no intents sent.
520 verifyNoIntentsSent();
521
Neil Fuller68f66662017-03-16 18:32:21 +0000522 // Check the callback was received.
523 callback.assertResultReceived(Callback.ERROR_INSTALL_VALIDATION_ERROR);
524 }
525
526 @Test
Neil Fuller68f66662017-03-16 18:32:21 +0000527 public void requestUninstall_operationInProgress() throws Exception {
528 configureCallerHasPermission();
529
530 byte[] tokenBytes = createArbitraryTokenBytes();
531 ICallback callback = new StubbedCallback();
532
533 // First request should succeed.
534 assertEquals(RulesManager.SUCCESS,
535 mRulesManagerService.requestUninstall(tokenBytes, callback));
536
537 // Something async should be enqueued. Clear it but do not execute it so we can detect the
538 // second request does nothing.
539 mFakeExecutor.getAndResetLastCommand();
540
541 // Second request should fail.
542 assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
543 mRulesManagerService.requestUninstall(tokenBytes, callback));
544
545 // Assert nothing async was enqueued.
546 mFakeExecutor.assertNothingQueued();
547 verifyNoInstallerCallsMade();
548 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000549 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000550 }
551
552 @Test
553 public void requestUninstall_badToken() throws Exception {
554 configureCallerHasPermission();
555
556 byte[] badTokenBytes = new byte[2];
557 ICallback callback = new StubbedCallback();
558
559 try {
560 mRulesManagerService.requestUninstall(badTokenBytes, callback);
561 fail();
562 } catch (IllegalArgumentException expected) {
563 }
564
565 // Assert nothing async was enqueued.
566 mFakeExecutor.assertNothingQueued();
567 verifyNoInstallerCallsMade();
568 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000569 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000570 }
571
572 @Test
573 public void requestUninstall_nullCallback() throws Exception {
574 configureCallerHasPermission();
575
576 byte[] tokenBytes = createArbitraryTokenBytes();
577 ICallback callback = null;
578
579 try {
580 mRulesManagerService.requestUninstall(tokenBytes, callback);
581 fail();
582 } catch (NullPointerException expected) {}
583
584 // Assert nothing async was enqueued.
585 mFakeExecutor.assertNothingQueued();
586 verifyNoInstallerCallsMade();
587 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000588 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000589 }
590
591 @Test
592 public void requestUninstall_asyncSuccess() throws Exception {
593 configureCallerHasPermission();
594
595 CheckToken token = createArbitraryToken();
596 byte[] tokenBytes = token.toByteArray();
597
598 TestCallback callback = new TestCallback();
599
600 // Request the uninstall.
601 assertEquals(RulesManager.SUCCESS,
602 mRulesManagerService.requestUninstall(tokenBytes, callback));
603
604 // Assert nothing has happened yet.
605 callback.assertNoResultReceived();
606 verifyNoInstallerCallsMade();
607 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000608 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000609
610 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100611 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
612
613 // Simulate the async execution.
614 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
615
616 // Verify the expected calls were made to other components.
617 verifyStageUninstallCalled();
618 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000619 verifyStagedOperationIntentSent();
Neil Fuller8e27c922017-09-14 09:34:56 +0100620
621 // Check the callback was called.
622 callback.assertResultReceived(Callback.SUCCESS);
623 }
624
625 @Test
626 public void requestUninstall_asyncNothingInstalled() throws Exception {
627 configureCallerHasPermission();
628
629 CheckToken token = createArbitraryToken();
630 byte[] tokenBytes = token.toByteArray();
631
632 TestCallback callback = new TestCallback();
633
634 // Request the uninstall.
635 assertEquals(RulesManager.SUCCESS,
636 mRulesManagerService.requestUninstall(tokenBytes, callback));
637
638 // Assert nothing has happened yet.
639 callback.assertNoResultReceived();
640 verifyNoInstallerCallsMade();
641 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000642 verifyNoIntentsSent();
Neil Fuller8e27c922017-09-14 09:34:56 +0100643
644 // Set up the installer.
645 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED);
Neil Fuller68f66662017-03-16 18:32:21 +0000646
647 // Simulate the async execution.
648 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
649
650 // Verify the expected calls were made to other components.
651 verifyStageUninstallCalled();
652 verifyPackageTrackerCalled(token, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000653 verifyUnstagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000654
655 // Check the callback was called.
656 callback.assertResultReceived(Callback.SUCCESS);
657 }
658
659 @Test
660 public void requestUninstall_nullTokenBytes() throws Exception {
661 configureCallerHasPermission();
662
663 TestCallback callback = new TestCallback();
664
665 // Request the uninstall.
666 assertEquals(RulesManager.SUCCESS,
667 mRulesManagerService.requestUninstall(null /* tokenBytes */, callback));
668
669 // Assert nothing has happened yet.
670 verifyNoInstallerCallsMade();
671 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000672 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000673
674 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100675 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_SUCCESS);
Neil Fuller68f66662017-03-16 18:32:21 +0000676
677 // Simulate the async execution.
678 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
679
680 // Verify the expected calls were made to other components.
681 verifyStageUninstallCalled();
682 verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000683 verifyStagedOperationIntentSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000684
685 // Check the callback was received.
686 callback.assertResultReceived(Callback.SUCCESS);
687 }
688
689 @Test
690 public void requestUninstall_asyncUninstallFail() throws Exception {
691 configureCallerHasPermission();
692
693 CheckToken token = createArbitraryToken();
694 byte[] tokenBytes = token.toByteArray();
695
696 TestCallback callback = new TestCallback();
697
698 // Request the uninstall.
699 assertEquals(RulesManager.SUCCESS,
700 mRulesManagerService.requestUninstall(tokenBytes, callback));
701
702 // Assert nothing has happened yet.
703 verifyNoInstallerCallsMade();
704 callback.assertNoResultReceived();
Neil Fullerb1442272017-12-18 15:59:50 +0000705 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000706
707 // Set up the installer.
Neil Fuller8e27c922017-09-14 09:34:56 +0100708 configureStageUninstallExpectation(TimeZoneDistroInstaller.UNINSTALL_FAIL);
Neil Fuller68f66662017-03-16 18:32:21 +0000709
710 // Simulate the async execution.
711 mFakeExecutor.simulateAsyncExecutionOfLastCommand();
712
713 // Verify the expected calls were made to other components.
714 verifyStageUninstallCalled();
715 verifyPackageTrackerCalled(token, false /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000716 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000717
718 // Check the callback was received.
719 callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
720 }
721
722 @Test
723 public void requestNothing_operationInProgressOk() throws Exception {
724 configureCallerHasPermission();
725
726 // Set up a parallel operation.
727 assertEquals(RulesManager.SUCCESS,
728 mRulesManagerService.requestUninstall(null, new StubbedCallback()));
729 // Something async should be enqueued. Clear it but do not execute it to simulate it still
730 // being in progress.
731 mFakeExecutor.getAndResetLastCommand();
732
733 CheckToken token = createArbitraryToken();
734 byte[] tokenBytes = token.toByteArray();
735
736 // Make the call.
737 mRulesManagerService.requestNothing(tokenBytes, true /* success */);
738
739 // Assert nothing async was enqueued.
740 mFakeExecutor.assertNothingQueued();
741
742 // Verify the expected calls were made to other components.
743 verifyPackageTrackerCalled(token, true /* success */);
744 verifyNoInstallerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000745 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000746 }
747
748 @Test
749 public void requestNothing_badToken() throws Exception {
750 configureCallerHasPermission();
751
752 byte[] badTokenBytes = new byte[2];
753
754 try {
755 mRulesManagerService.requestNothing(badTokenBytes, true /* success */);
756 fail();
757 } catch (IllegalArgumentException expected) {
758 }
759
760 // Assert nothing async was enqueued.
761 mFakeExecutor.assertNothingQueued();
762
763 // Assert no other calls were made.
764 verifyNoInstallerCallsMade();
765 verifyNoPackageTrackerCallsMade();
Neil Fullerb1442272017-12-18 15:59:50 +0000766 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000767 }
768
769 @Test
770 public void requestNothing() throws Exception {
771 configureCallerHasPermission();
772
773 CheckToken token = createArbitraryToken();
774 byte[] tokenBytes = token.toByteArray();
775
776 // Make the call.
777 mRulesManagerService.requestNothing(tokenBytes, false /* success */);
778
779 // Assert everything required was done.
780 verifyNoInstallerCallsMade();
781 verifyPackageTrackerCalled(token, false /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000782 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000783 }
784
785 @Test
786 public void requestNothing_nullTokenBytes() throws Exception {
787 configureCallerHasPermission();
788
789 // Make the call.
790 mRulesManagerService.requestNothing(null /* tokenBytes */, true /* success */);
791
792 // Assert everything required was done.
793 verifyNoInstallerCallsMade();
794 verifyPackageTrackerCalled(null /* token */, true /* success */);
Neil Fullerb1442272017-12-18 15:59:50 +0000795 verifyNoIntentsSent();
Neil Fuller68f66662017-03-16 18:32:21 +0000796 }
797
Neil Fuller87b11282017-06-23 16:43:45 +0100798 @Test
799 public void dump_noPermission() throws Exception {
800 when(mMockPermissionHelper.checkDumpPermission(any(String.class), any(PrintWriter.class)))
801 .thenReturn(false);
802
803 doDumpCallAndCapture(mRulesManagerService, null);
804 verifyZeroInteractions(mMockPackageTracker, mMockTimeZoneDistroInstaller);
805 }
806
807 @Test
808 public void dump_emptyArgs() throws Exception {
809 doSuccessfulDumpCall(mRulesManagerService, new String[0]);
810
811 // Verify the package tracker was consulted.
812 verify(mMockPackageTracker).dump(any(PrintWriter.class));
813 }
814
815 @Test
816 public void dump_nullArgs() throws Exception {
817 doSuccessfulDumpCall(mRulesManagerService, null);
818 // Verify the package tracker was consulted.
819 verify(mMockPackageTracker).dump(any(PrintWriter.class));
820 }
821
822 @Test
823 public void dump_unknownArgs() throws Exception {
824 String dumpedTextUnknownArgs = doSuccessfulDumpCall(
825 mRulesManagerService, new String[] { "foo", "bar"});
826
827 // Verify the package tracker was consulted.
828 verify(mMockPackageTracker).dump(any(PrintWriter.class));
829
830 String dumpedTextZeroArgs = doSuccessfulDumpCall(mRulesManagerService, null);
831 assertEquals(dumpedTextZeroArgs, dumpedTextUnknownArgs);
832 }
833
834 @Test
835 public void dump_formatState() throws Exception {
836 // Just expect these to not throw exceptions, not return nothing, and not interact with the
837 // package tracker.
838 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("p"));
839 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("s"));
840 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("c"));
841 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("i"));
842 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("o"));
843 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("t"));
844 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("a"));
845 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("z" /* Unknown */));
846 doSuccessfulDumpCall(mRulesManagerService, dumpFormatArgs("piscotz"));
847
848 verifyZeroInteractions(mMockPackageTracker);
849 }
850
851 private static String[] dumpFormatArgs(String argsString) {
852 return new String[] { "-format_state", argsString};
853 }
854
855 private String doSuccessfulDumpCall(RulesManagerService rulesManagerService, String[] args)
856 throws Exception {
857 when(mMockPermissionHelper.checkDumpPermission(any(String.class), any(PrintWriter.class)))
858 .thenReturn(true);
859
860 // Set up the mocks to return (arbitrary) information about the current device state.
861 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn("2017a");
862 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion()).thenReturn(
863 new DistroVersion(2, 3, "2017b", 4));
864 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(
865 StagedDistroOperation.install(new DistroVersion(5, 6, "2017c", 7)));
866
867 // Do the dump call.
868 String dumpedOutput = doDumpCallAndCapture(rulesManagerService, args);
869
870 assertFalse(dumpedOutput.isEmpty());
871
872 return dumpedOutput;
873 }
874
875 private static String doDumpCallAndCapture(
876 RulesManagerService rulesManagerService, String[] args) throws IOException {
877 File file = File.createTempFile("dump", null);
878 try {
879 try (FileOutputStream fos = new FileOutputStream(file)) {
880 FileDescriptor fd = fos.getFD();
881 rulesManagerService.dump(fd, args);
882 }
883 return IoUtils.readFileAsString(file.getAbsolutePath());
884 } finally {
885 file.delete();
886 }
887 }
888
Neil Fuller68f66662017-03-16 18:32:21 +0000889 private void verifyNoPackageTrackerCallsMade() {
890 verifyNoMoreInteractions(mMockPackageTracker);
891 reset(mMockPackageTracker);
892 }
893
894 private void verifyPackageTrackerCalled(
895 CheckToken expectedCheckToken, boolean expectedSuccess) {
896 verify(mMockPackageTracker).recordCheckResult(expectedCheckToken, expectedSuccess);
897 reset(mMockPackageTracker);
898 }
899
Neil Fullerb1442272017-12-18 15:59:50 +0000900 private void verifyNoIntentsSent() {
901 verifyNoMoreInteractions(mMockIntentHelper);
902 reset(mMockIntentHelper);
903 }
904
905 private void verifyStagedOperationIntentSent() {
906 verify(mMockIntentHelper).sendTimeZoneOperationStaged();
907 reset(mMockIntentHelper);
908 }
909
910 private void verifyUnstagedOperationIntentSent() {
911 verify(mMockIntentHelper).sendTimeZoneOperationUnstaged();
912 reset(mMockIntentHelper);
913 }
914
Neil Fuller68f66662017-03-16 18:32:21 +0000915 private void configureCallerHasPermission() throws Exception {
916 doNothing()
917 .when(mMockPermissionHelper)
918 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
919 }
920
Neil Fullerb214bc42017-12-18 16:57:22 +0000921 private void configureCallerDoesNotHaveUpdatePermission() {
Neil Fuller68f66662017-03-16 18:32:21 +0000922 doThrow(new SecurityException("Simulated permission failure"))
923 .when(mMockPermissionHelper)
924 .enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
925 }
926
Neil Fullerb214bc42017-12-18 16:57:22 +0000927 private void configureCallerDoesNotHaveQueryPermission() {
928 doThrow(new SecurityException("Simulated permission failure"))
929 .when(mMockPermissionHelper)
930 .enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);
931 }
932
Neil Fuller9c90dc02017-06-22 14:10:29 +0100933 private void configureStageInstallExpectation(int resultCode)
Neil Fuller68f66662017-03-16 18:32:21 +0000934 throws Exception {
Neil Fuller9c90dc02017-06-22 14:10:29 +0100935 when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(any(TimeZoneDistro.class)))
Neil Fuller68f66662017-03-16 18:32:21 +0000936 .thenReturn(resultCode);
937 }
938
Neil Fuller8e27c922017-09-14 09:34:56 +0100939 private void configureStageUninstallExpectation(int resultCode) throws Exception {
940 doReturn(resultCode).when(mMockTimeZoneDistroInstaller).stageUninstall();
Neil Fuller68f66662017-03-16 18:32:21 +0000941 }
942
Neil Fuller9c90dc02017-06-22 14:10:29 +0100943 private void verifyStageInstallCalled() throws Exception {
944 verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(any(TimeZoneDistro.class));
Neil Fuller68f66662017-03-16 18:32:21 +0000945 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
946 reset(mMockTimeZoneDistroInstaller);
947 }
948
949 private void verifyStageUninstallCalled() throws Exception {
950 verify(mMockTimeZoneDistroInstaller).stageUninstall();
951 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
952 reset(mMockTimeZoneDistroInstaller);
953 }
954
955 private void verifyNoInstallerCallsMade() {
956 verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
957 reset(mMockTimeZoneDistroInstaller);
958 }
959
960 private static byte[] createArbitraryBytes(int length) {
961 byte[] bytes = new byte[length];
962 for (int i = 0; i < length; i++) {
963 bytes[i] = (byte) i;
964 }
965 return bytes;
966 }
967
968 private byte[] createArbitraryTokenBytes() {
969 return createArbitraryToken().toByteArray();
970 }
971
972 private CheckToken createArbitraryToken() {
973 return new CheckToken(1, new PackageVersions(1, 1));
974 }
975
Neil Fuller68f66662017-03-16 18:32:21 +0000976 private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
977 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
978 }
979
980 private void configureInstalledDistroVersion(@Nullable DistroVersion installedDistroVersion)
981 throws Exception {
982 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
983 .thenReturn(installedDistroVersion);
984 }
985
986 private void configureStagedInstall(DistroVersion stagedDistroVersion) throws Exception {
987 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
988 .thenReturn(StagedDistroOperation.install(stagedDistroVersion));
989 }
990
991 private void configureStagedUninstall() throws Exception {
992 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
993 .thenReturn(StagedDistroOperation.uninstall());
994 }
995
996 private void configureNoStagedOperation() throws Exception {
997 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(null);
998 }
999
1000 private void configureDeviceCannotReadStagedDistroOperation() throws Exception {
1001 when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
1002 .thenThrow(new IOException("Simulated failure"));
1003 }
1004
1005 private void configureDeviceCannotReadSystemRulesVersion() throws Exception {
1006 when(mMockTimeZoneDistroInstaller.getSystemRulesVersion())
1007 .thenThrow(new IOException("Simulated failure"));
1008 }
1009
1010 private void configureDeviceCannotReadInstalledDistroVersion() throws Exception {
1011 when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
1012 .thenThrow(new IOException("Simulated failure"));
1013 }
1014
Neil Fuller54525bf2017-06-22 14:10:29 +01001015 private static void assertClosed(ParcelFileDescriptor parcelFileDescriptor) {
1016 assertFalse(parcelFileDescriptor.getFileDescriptor().valid());
1017 }
1018
Neil Fuller68f66662017-03-16 18:32:21 +00001019 private static class FakeExecutor implements Executor {
1020
1021 private Runnable mLastCommand;
1022
1023 @Override
1024 public void execute(Runnable command) {
1025 assertNull(mLastCommand);
1026 assertNotNull(command);
1027 mLastCommand = command;
1028 }
1029
1030 public Runnable getAndResetLastCommand() {
1031 assertNotNull(mLastCommand);
1032 Runnable toReturn = mLastCommand;
1033 mLastCommand = null;
1034 return toReturn;
1035 }
1036
1037 public void simulateAsyncExecutionOfLastCommand() {
1038 Runnable toRun = getAndResetLastCommand();
1039 toRun.run();
1040 }
1041
1042 public void assertNothingQueued() {
1043 assertNull(mLastCommand);
1044 }
1045 }
1046
1047 private static class TestCallback extends ICallback.Stub {
1048
1049 private boolean mOnFinishedCalled;
1050 private int mLastError;
1051
1052 @Override
1053 public void onFinished(int error) {
1054 assertFalse(mOnFinishedCalled);
1055 mOnFinishedCalled = true;
1056 mLastError = error;
1057 }
1058
1059 public void assertResultReceived(int expectedResult) {
1060 assertTrue(mOnFinishedCalled);
1061 assertEquals(expectedResult, mLastError);
1062 }
1063
1064 public void assertNoResultReceived() {
1065 assertFalse(mOnFinishedCalled);
1066 }
1067 }
1068
1069 private static class StubbedCallback extends ICallback.Stub {
1070 @Override
1071 public void onFinished(int error) {
1072 fail("Unexpected call");
1073 }
1074 }
Neil Fuller54525bf2017-06-22 14:10:29 +01001075
1076 private static ParcelFileDescriptor createParcelFileDescriptor(byte[] bytes)
1077 throws IOException {
1078 File file = File.createTempFile("pfd", null);
1079 try (FileOutputStream fos = new FileOutputStream(file)) {
1080 fos.write(bytes);
1081 }
1082 ParcelFileDescriptor pfd =
1083 ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
1084 // This should now be safe to delete. The ParcelFileDescriptor has an open fd.
1085 file.delete();
1086 return pfd;
1087 }
Neil Fuller68f66662017-03-16 18:32:21 +00001088}