blob: a7f4c99474825d2a41ea12757b38b1c0a74b944b [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.timezone;
import org.junit.Before;
import org.junit.Test;
import android.app.timezone.Callback;
import android.app.timezone.DistroRulesVersion;
import android.app.timezone.ICallback;
import android.app.timezone.RulesManager;
import android.app.timezone.RulesState;
import android.os.ParcelFileDescriptor;
import java.io.IOException;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import libcore.tzdata.shared2.DistroVersion;
import libcore.tzdata.shared2.StagedDistroOperation;
import libcore.tzdata.update2.TimeZoneDistroInstaller;
import static com.android.server.timezone.RulesManagerService.REQUIRED_UPDATER_PERMISSION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
/**
* White box interaction / unit testing of the {@link RulesManagerService}.
*/
public class RulesManagerServiceTest {
private RulesManagerService mRulesManagerService;
private FakeExecutor mFakeExecutor;
private PermissionHelper mMockPermissionHelper;
private FileDescriptorHelper mMockFileDescriptorHelper;
private PackageTracker mMockPackageTracker;
private TimeZoneDistroInstaller mMockTimeZoneDistroInstaller;
@Before
public void setUp() {
mFakeExecutor = new FakeExecutor();
mMockFileDescriptorHelper = mock(FileDescriptorHelper.class);
mMockPackageTracker = mock(PackageTracker.class);
mMockPermissionHelper = mock(PermissionHelper.class);
mMockTimeZoneDistroInstaller = mock(TimeZoneDistroInstaller.class);
mRulesManagerService = new RulesManagerService(
mMockPermissionHelper,
mFakeExecutor,
mMockFileDescriptorHelper,
mMockPackageTracker,
mMockTimeZoneDistroInstaller);
}
@Test(expected = SecurityException.class)
public void getRulesState_noCallerPermission() throws Exception {
configureCallerDoesNotHavePermission();
mRulesManagerService.getRulesState();
}
@Test(expected = SecurityException.class)
public void requestInstall_noCallerPermission() throws Exception {
configureCallerDoesNotHavePermission();
mRulesManagerService.requestInstall(null, null, null);
}
@Test(expected = SecurityException.class)
public void requestUninstall_noCallerPermission() throws Exception {
configureCallerDoesNotHavePermission();
mRulesManagerService.requestUninstall(null, null);
}
@Test(expected = SecurityException.class)
public void requestNothing_noCallerPermission() throws Exception {
configureCallerDoesNotHavePermission();
mRulesManagerService.requestNothing(null, true);
}
@Test
public void getRulesState_systemRulesError() throws Exception {
configureDeviceCannotReadSystemRulesVersion();
assertNull(mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_stagedInstall() throws Exception {
configureCallerHasPermission();
configureDeviceSystemRulesVersion("2016a");
DistroVersion stagedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
"2016c",
3);
configureStagedInstall(stagedDistroVersion);
DistroVersion installedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
DistroRulesVersion stagedDistroRulesVersion = new DistroRulesVersion(
stagedDistroVersion.rulesVersion, stagedDistroVersion.revision);
DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
installedDistroVersion.rulesVersion, installedDistroVersion.revision);
RulesState expectedRuleState = new RulesState(
"2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_INSTALL, stagedDistroRulesVersion,
RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_nothingStaged() throws Exception {
configureCallerHasPermission();
configureDeviceSystemRulesVersion("2016a");
configureNoStagedOperation();
DistroVersion installedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
installedDistroVersion.rulesVersion, installedDistroVersion.revision);
RulesState expectedRuleState = new RulesState(
"2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_uninstallStaged() throws Exception {
configureCallerHasPermission();
configureDeviceSystemRulesVersion("2016a");
configureStagedUninstall();
DistroVersion installedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
installedDistroVersion.rulesVersion, installedDistroVersion.revision);
RulesState expectedRuleState = new RulesState(
"2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_installedRulesError() throws Exception {
configureCallerHasPermission();
String systemRulesVersion = "2016a";
configureDeviceSystemRulesVersion(systemRulesVersion);
configureStagedUninstall();
configureDeviceCannotReadInstalledDistroVersion();
RulesState expectedRuleState = new RulesState(
"2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_stagedRulesError() throws Exception {
configureCallerHasPermission();
String systemRulesVersion = "2016a";
configureDeviceSystemRulesVersion(systemRulesVersion);
configureDeviceCannotReadStagedDistroOperation();
DistroVersion installedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
"2016b",
4);
configureInstalledDistroVersion(installedDistroVersion);
DistroRulesVersion installedDistroRulesVersion = new DistroRulesVersion(
installedDistroVersion.rulesVersion, installedDistroVersion.revision);
RulesState expectedRuleState = new RulesState(
"2016a", RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_INSTALLED, installedDistroRulesVersion);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_noInstalledRules() throws Exception {
configureCallerHasPermission();
String systemRulesVersion = "2016a";
configureDeviceSystemRulesVersion(systemRulesVersion);
configureNoStagedOperation();
configureInstalledDistroVersion(null);
RulesState expectedRuleState = new RulesState(
systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
false /* operationInProgress */,
RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void getRulesState_operationInProgress() throws Exception {
configureCallerHasPermission();
String systemRulesVersion = "2016a";
String installedRulesVersion = "2016b";
int revision = 3;
configureDeviceSystemRulesVersion(systemRulesVersion);
DistroVersion installedDistroVersion = new DistroVersion(
DistroVersion.CURRENT_FORMAT_MAJOR_VERSION,
DistroVersion.CURRENT_FORMAT_MINOR_VERSION - 1,
installedRulesVersion,
revision);
configureInstalledDistroVersion(installedDistroVersion);
byte[] expectedContent = createArbitraryBytes(1000);
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
// Start an async operation so there is one in progress. The mFakeExecutor won't actually
// execute it.
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = new StubbedCallback();
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
RulesState expectedRuleState = new RulesState(
systemRulesVersion, RulesManagerService.DISTRO_FORMAT_VERSION_SUPPORTED,
true /* operationInProgress */,
RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
assertEquals(expectedRuleState, mRulesManagerService.getRulesState());
}
@Test
public void requestInstall_operationInProgress() throws Exception {
configureCallerHasPermission();
byte[] expectedContent = createArbitraryBytes(1000);
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = new StubbedCallback();
// First request should succeed.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
// Something async should be enqueued. Clear it but do not execute it so we can detect the
// second request does nothing.
mFakeExecutor.getAndResetLastCommand();
// Second request should fail.
assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestInstall_badToken() throws Exception {
configureCallerHasPermission();
byte[] expectedContent = createArbitraryBytes(1000);
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
byte[] badTokenBytes = new byte[2];
ICallback callback = new StubbedCallback();
try {
mRulesManagerService.requestInstall(parcelFileDescriptor, badTokenBytes, callback);
fail();
} catch (IllegalArgumentException expected) {
}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestInstall_nullParcelFileDescriptor() throws Exception {
configureCallerHasPermission();
ParcelFileDescriptor parcelFileDescriptor = null;
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = new StubbedCallback();
try {
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
fail();
} catch (NullPointerException expected) {}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestInstall_nullCallback() throws Exception {
configureCallerHasPermission();
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = null;
try {
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback);
fail();
} catch (NullPointerException expected) {}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestInstall_asyncSuccess() throws Exception {
configureCallerHasPermission();
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
byte[] expectedContent = createArbitraryBytes(1000);
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
TestCallback callback = new TestCallback();
// Request the install.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
// Assert nothing has happened yet.
callback.assertNoResultReceived();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
// Set up the installer.
configureStageInstallExpectation(expectedContent, TimeZoneDistroInstaller.INSTALL_SUCCESS);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageInstallCalled(expectedContent);
verifyPackageTrackerCalled(token, true /* success */);
// Check the callback was called.
callback.assertResultReceived(Callback.SUCCESS);
}
@Test
public void requestInstall_nullTokenBytes() throws Exception {
configureCallerHasPermission();
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
byte[] expectedContent = createArbitraryBytes(1000);
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
TestCallback callback = new TestCallback();
// Request the install.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestInstall(
parcelFileDescriptor, null /* tokenBytes */, callback));
// Assert nothing has happened yet.
verifyNoInstallerCallsMade();
callback.assertNoResultReceived();
// Set up the installer.
configureStageInstallExpectation(expectedContent, TimeZoneDistroInstaller.INSTALL_SUCCESS);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageInstallCalled(expectedContent);
verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
// Check the callback was received.
callback.assertResultReceived(Callback.SUCCESS);
}
@Test
public void requestInstall_asyncInstallFail() throws Exception {
configureCallerHasPermission();
byte[] expectedContent = createArbitraryBytes(1000);
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
configureParcelFileDescriptorReadSuccess(parcelFileDescriptor, expectedContent);
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
TestCallback callback = new TestCallback();
// Request the install.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
// Assert nothing has happened yet.
verifyNoInstallerCallsMade();
callback.assertNoResultReceived();
// Set up the installer.
configureStageInstallExpectation(
expectedContent, TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageInstallCalled(expectedContent);
// Validation failure is treated like a successful check: repeating it won't improve things.
boolean expectedSuccess = true;
verifyPackageTrackerCalled(token, expectedSuccess);
// Check the callback was received.
callback.assertResultReceived(Callback.ERROR_INSTALL_VALIDATION_ERROR);
}
@Test
public void requestInstall_asyncParcelFileDescriptorReadFail() throws Exception {
configureCallerHasPermission();
ParcelFileDescriptor parcelFileDescriptor = createFakeParcelFileDescriptor();
configureParcelFileDescriptorReadFailure(parcelFileDescriptor);
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
TestCallback callback = new TestCallback();
// Request the install.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestInstall(parcelFileDescriptor, tokenBytes, callback));
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify nothing else happened.
verifyNoInstallerCallsMade();
// A failure to read the ParcelFileDescriptor is treated as a failure. It might be the
// result of a file system error. This is a fairly arbitrary choice.
verifyPackageTrackerCalled(token, false /* success */);
verifyNoPackageTrackerCallsMade();
// Check the callback was received.
callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
}
@Test
public void requestUninstall_operationInProgress() throws Exception {
configureCallerHasPermission();
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = new StubbedCallback();
// First request should succeed.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestUninstall(tokenBytes, callback));
// Something async should be enqueued. Clear it but do not execute it so we can detect the
// second request does nothing.
mFakeExecutor.getAndResetLastCommand();
// Second request should fail.
assertEquals(RulesManager.ERROR_OPERATION_IN_PROGRESS,
mRulesManagerService.requestUninstall(tokenBytes, callback));
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestUninstall_badToken() throws Exception {
configureCallerHasPermission();
byte[] badTokenBytes = new byte[2];
ICallback callback = new StubbedCallback();
try {
mRulesManagerService.requestUninstall(badTokenBytes, callback);
fail();
} catch (IllegalArgumentException expected) {
}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestUninstall_nullCallback() throws Exception {
configureCallerHasPermission();
byte[] tokenBytes = createArbitraryTokenBytes();
ICallback callback = null;
try {
mRulesManagerService.requestUninstall(tokenBytes, callback);
fail();
} catch (NullPointerException expected) {}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestUninstall_asyncSuccess() throws Exception {
configureCallerHasPermission();
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
TestCallback callback = new TestCallback();
// Request the uninstall.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestUninstall(tokenBytes, callback));
// Assert nothing has happened yet.
callback.assertNoResultReceived();
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
// Set up the installer.
configureStageUninstallExpectation(true /* success */);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageUninstallCalled();
verifyPackageTrackerCalled(token, true /* success */);
// Check the callback was called.
callback.assertResultReceived(Callback.SUCCESS);
}
@Test
public void requestUninstall_nullTokenBytes() throws Exception {
configureCallerHasPermission();
TestCallback callback = new TestCallback();
// Request the uninstall.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestUninstall(null /* tokenBytes */, callback));
// Assert nothing has happened yet.
verifyNoInstallerCallsMade();
callback.assertNoResultReceived();
// Set up the installer.
configureStageUninstallExpectation(true /* success */);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageUninstallCalled();
verifyPackageTrackerCalled(null /* expectedToken */, true /* success */);
// Check the callback was received.
callback.assertResultReceived(Callback.SUCCESS);
}
@Test
public void requestUninstall_asyncUninstallFail() throws Exception {
configureCallerHasPermission();
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
TestCallback callback = new TestCallback();
// Request the uninstall.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestUninstall(tokenBytes, callback));
// Assert nothing has happened yet.
verifyNoInstallerCallsMade();
callback.assertNoResultReceived();
// Set up the installer.
configureStageUninstallExpectation(false /* success */);
// Simulate the async execution.
mFakeExecutor.simulateAsyncExecutionOfLastCommand();
// Verify the expected calls were made to other components.
verifyStageUninstallCalled();
verifyPackageTrackerCalled(token, false /* success */);
// Check the callback was received.
callback.assertResultReceived(Callback.ERROR_UNKNOWN_FAILURE);
}
@Test
public void requestNothing_operationInProgressOk() throws Exception {
configureCallerHasPermission();
// Set up a parallel operation.
assertEquals(RulesManager.SUCCESS,
mRulesManagerService.requestUninstall(null, new StubbedCallback()));
// Something async should be enqueued. Clear it but do not execute it to simulate it still
// being in progress.
mFakeExecutor.getAndResetLastCommand();
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
// Make the call.
mRulesManagerService.requestNothing(tokenBytes, true /* success */);
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
// Verify the expected calls were made to other components.
verifyPackageTrackerCalled(token, true /* success */);
verifyNoInstallerCallsMade();
}
@Test
public void requestNothing_badToken() throws Exception {
configureCallerHasPermission();
byte[] badTokenBytes = new byte[2];
try {
mRulesManagerService.requestNothing(badTokenBytes, true /* success */);
fail();
} catch (IllegalArgumentException expected) {
}
// Assert nothing async was enqueued.
mFakeExecutor.assertNothingQueued();
// Assert no other calls were made.
verifyNoInstallerCallsMade();
verifyNoPackageTrackerCallsMade();
}
@Test
public void requestNothing() throws Exception {
configureCallerHasPermission();
CheckToken token = createArbitraryToken();
byte[] tokenBytes = token.toByteArray();
// Make the call.
mRulesManagerService.requestNothing(tokenBytes, false /* success */);
// Assert everything required was done.
verifyNoInstallerCallsMade();
verifyPackageTrackerCalled(token, false /* success */);
}
@Test
public void requestNothing_nullTokenBytes() throws Exception {
configureCallerHasPermission();
// Make the call.
mRulesManagerService.requestNothing(null /* tokenBytes */, true /* success */);
// Assert everything required was done.
verifyNoInstallerCallsMade();
verifyPackageTrackerCalled(null /* token */, true /* success */);
}
private void verifyNoPackageTrackerCallsMade() {
verifyNoMoreInteractions(mMockPackageTracker);
reset(mMockPackageTracker);
}
private void verifyPackageTrackerCalled(
CheckToken expectedCheckToken, boolean expectedSuccess) {
verify(mMockPackageTracker).recordCheckResult(expectedCheckToken, expectedSuccess);
reset(mMockPackageTracker);
}
private void configureCallerHasPermission() throws Exception {
doNothing()
.when(mMockPermissionHelper)
.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
}
private void configureCallerDoesNotHavePermission() {
doThrow(new SecurityException("Simulated permission failure"))
.when(mMockPermissionHelper)
.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
}
private void configureParcelFileDescriptorReadSuccess(ParcelFileDescriptor parcelFileDescriptor,
byte[] content) throws Exception {
when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor)).thenReturn(content);
}
private void configureParcelFileDescriptorReadFailure(ParcelFileDescriptor parcelFileDescriptor)
throws Exception {
when(mMockFileDescriptorHelper.readFully(parcelFileDescriptor))
.thenThrow(new IOException("Simulated failure"));
}
private void configureStageInstallExpectation(byte[] expectedContent, int resultCode)
throws Exception {
when(mMockTimeZoneDistroInstaller.stageInstallWithErrorCode(eq(expectedContent)))
.thenReturn(resultCode);
}
private void configureStageUninstallExpectation(boolean success) throws Exception {
doReturn(success).when(mMockTimeZoneDistroInstaller).stageUninstall();
}
private void verifyStageInstallCalled(byte[] expectedContent) throws Exception {
verify(mMockTimeZoneDistroInstaller).stageInstallWithErrorCode(eq(expectedContent));
verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
reset(mMockTimeZoneDistroInstaller);
}
private void verifyStageUninstallCalled() throws Exception {
verify(mMockTimeZoneDistroInstaller).stageUninstall();
verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
reset(mMockTimeZoneDistroInstaller);
}
private void verifyNoInstallerCallsMade() {
verifyNoMoreInteractions(mMockTimeZoneDistroInstaller);
reset(mMockTimeZoneDistroInstaller);
}
private static byte[] createArbitraryBytes(int length) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = (byte) i;
}
return bytes;
}
private byte[] createArbitraryTokenBytes() {
return createArbitraryToken().toByteArray();
}
private CheckToken createArbitraryToken() {
return new CheckToken(1, new PackageVersions(1, 1));
}
private ParcelFileDescriptor createFakeParcelFileDescriptor() {
return new ParcelFileDescriptor((ParcelFileDescriptor) null);
}
private void configureDeviceSystemRulesVersion(String systemRulesVersion) throws Exception {
when(mMockTimeZoneDistroInstaller.getSystemRulesVersion()).thenReturn(systemRulesVersion);
}
private void configureInstalledDistroVersion(@Nullable DistroVersion installedDistroVersion)
throws Exception {
when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
.thenReturn(installedDistroVersion);
}
private void configureStagedInstall(DistroVersion stagedDistroVersion) throws Exception {
when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
.thenReturn(StagedDistroOperation.install(stagedDistroVersion));
}
private void configureStagedUninstall() throws Exception {
when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
.thenReturn(StagedDistroOperation.uninstall());
}
private void configureNoStagedOperation() throws Exception {
when(mMockTimeZoneDistroInstaller.getStagedDistroOperation()).thenReturn(null);
}
private void configureDeviceCannotReadStagedDistroOperation() throws Exception {
when(mMockTimeZoneDistroInstaller.getStagedDistroOperation())
.thenThrow(new IOException("Simulated failure"));
}
private void configureDeviceCannotReadSystemRulesVersion() throws Exception {
when(mMockTimeZoneDistroInstaller.getSystemRulesVersion())
.thenThrow(new IOException("Simulated failure"));
}
private void configureDeviceCannotReadInstalledDistroVersion() throws Exception {
when(mMockTimeZoneDistroInstaller.getInstalledDistroVersion())
.thenThrow(new IOException("Simulated failure"));
}
private static class FakeExecutor implements Executor {
private Runnable mLastCommand;
@Override
public void execute(Runnable command) {
assertNull(mLastCommand);
assertNotNull(command);
mLastCommand = command;
}
public Runnable getAndResetLastCommand() {
assertNotNull(mLastCommand);
Runnable toReturn = mLastCommand;
mLastCommand = null;
return toReturn;
}
public void simulateAsyncExecutionOfLastCommand() {
Runnable toRun = getAndResetLastCommand();
toRun.run();
}
public void assertNothingQueued() {
assertNull(mLastCommand);
}
}
private static class TestCallback extends ICallback.Stub {
private boolean mOnFinishedCalled;
private int mLastError;
@Override
public void onFinished(int error) {
assertFalse(mOnFinishedCalled);
mOnFinishedCalled = true;
mLastError = error;
}
public void assertResultReceived(int expectedResult) {
assertTrue(mOnFinishedCalled);
assertEquals(expectedResult, mLastError);
}
public void assertNoResultReceived() {
assertFalse(mOnFinishedCalled);
}
}
private static class StubbedCallback extends ICallback.Stub {
@Override
public void onFinished(int error) {
fail("Unexpected call");
}
}
}