Merge "Implement ApexManager UnitTest"
This commit is contained in:
committed by
Android (Google) Code Review
commit
fafdcfc6ba
@@ -38,6 +38,7 @@ import android.sysprop.ApexProperties;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
|
||||
@@ -217,7 +218,8 @@ abstract class ApexManager {
|
||||
* An implementation of {@link ApexManager} that should be used in case device supports updating
|
||||
* APEX packages.
|
||||
*/
|
||||
private static class ApexManagerImpl extends ApexManager {
|
||||
@VisibleForTesting
|
||||
static class ApexManagerImpl extends ApexManager {
|
||||
private final IApexService mApexService;
|
||||
private final Context mContext;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
BIN
services/tests/servicestests/res/raw/apex_test.apex
Normal file
BIN
services/tests/servicestests/res/raw/apex_test.apex
Normal file
Binary file not shown.
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.pm;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertThrows;
|
||||
|
||||
import android.apex.ApexInfo;
|
||||
import android.apex.ApexSessionInfo;
|
||||
import android.apex.IApexService;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.FileUtils;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.frameworks.servicestests.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ApexManagerTest {
|
||||
private static final String TEST_APEX_PKG = "com.android.apex.test";
|
||||
private static final int TEST_SESSION_ID = 99999999;
|
||||
private static final int[] TEST_CHILD_SESSION_ID = {8888, 7777};
|
||||
private ApexManager mApexManager;
|
||||
private Context mContext;
|
||||
|
||||
private IApexService mApexService = mock(IApexService.class);
|
||||
|
||||
@Before
|
||||
public void setUp() throws RemoteException {
|
||||
mContext = InstrumentationRegistry.getInstrumentation().getContext();
|
||||
mApexManager = new ApexManager.ApexManagerImpl(mContext, mApexService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPackageInfo_setFlagsMatchActivePackage() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, false));
|
||||
final PackageInfo activePkgPi = mApexManager.getPackageInfo(TEST_APEX_PKG,
|
||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
|
||||
assertThat(activePkgPi).isNotNull();
|
||||
assertThat(activePkgPi.packageName).contains(TEST_APEX_PKG);
|
||||
|
||||
final PackageInfo factoryPkgPi = mApexManager.getPackageInfo(TEST_APEX_PKG,
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
|
||||
assertThat(factoryPkgPi).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPackageInfo_setFlagsMatchFactoryPackage() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
PackageInfo factoryPkgPi = mApexManager.getPackageInfo(TEST_APEX_PKG,
|
||||
ApexManager.MATCH_FACTORY_PACKAGE);
|
||||
|
||||
assertThat(factoryPkgPi).isNotNull();
|
||||
assertThat(factoryPkgPi.packageName).contains(TEST_APEX_PKG);
|
||||
|
||||
final PackageInfo activePkgPi = mApexManager.getPackageInfo(TEST_APEX_PKG,
|
||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||
|
||||
assertThat(activePkgPi).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPackageInfo_setFlagsNone() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
|
||||
assertThat(mApexManager.getPackageInfo(TEST_APEX_PKG, 0)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActivePackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, true));
|
||||
|
||||
assertThat(mApexManager.getActivePackages()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActivePackages_noneActivePackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
|
||||
assertThat(mApexManager.getActivePackages()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFactoryPackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
|
||||
assertThat(mApexManager.getFactoryPackages()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFactoryPackages_noneFactoryPackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, false));
|
||||
|
||||
assertThat(mApexManager.getFactoryPackages()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInactivePackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
|
||||
assertThat(mApexManager.getInactivePackages()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetInactivePackages_noneInactivePackages() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(true, false));
|
||||
|
||||
assertThat(mApexManager.getInactivePackages()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsApexPackage() throws RemoteException {
|
||||
when(mApexService.getAllPackages()).thenReturn(createApexInfo(false, true));
|
||||
|
||||
assertThat(mApexManager.isApexPackage(TEST_APEX_PKG)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsApexSupported() {
|
||||
assertThat(mApexManager.isApexSupported()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStagedSessionInfo() throws RemoteException {
|
||||
when(mApexService.getStagedSessionInfo(anyInt())).thenReturn(
|
||||
getFakeStagedSessionInfo());
|
||||
|
||||
mApexManager.getStagedSessionInfo(TEST_SESSION_ID);
|
||||
verify(mApexService, times(1)).getStagedSessionInfo(TEST_SESSION_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStagedSessionInfo_unKnownStagedSessionId() throws RemoteException {
|
||||
when(mApexService.getStagedSessionInfo(anyInt())).thenReturn(
|
||||
getFakeUnknownSessionInfo());
|
||||
|
||||
assertThat(mApexManager.getStagedSessionInfo(TEST_SESSION_ID)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmitStagedSession_throwPackageManagerException() throws RemoteException {
|
||||
doAnswer(invocation -> {
|
||||
throw new Exception();
|
||||
}).when(mApexService).submitStagedSession(anyInt(), any(), any());
|
||||
|
||||
assertThrows(PackageManagerException.class,
|
||||
() -> mApexManager.submitStagedSession(TEST_SESSION_ID, TEST_CHILD_SESSION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubmitStagedSession_throwRunTimeException() throws RemoteException {
|
||||
doThrow(RemoteException.class).when(mApexService).submitStagedSession(anyInt(), any(),
|
||||
any());
|
||||
|
||||
assertThrows(RuntimeException.class,
|
||||
() -> mApexManager.submitStagedSession(TEST_SESSION_ID, TEST_CHILD_SESSION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkStagedSessionReady_throwPackageManagerException() throws RemoteException {
|
||||
doAnswer(invocation -> {
|
||||
throw new Exception();
|
||||
}).when(mApexService).markStagedSessionReady(anyInt());
|
||||
|
||||
assertThrows(PackageManagerException.class,
|
||||
() -> mApexManager.markStagedSessionReady(TEST_SESSION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkStagedSessionReady_throwRunTimeException() throws RemoteException {
|
||||
doThrow(RemoteException.class).when(mApexService).markStagedSessionReady(anyInt());
|
||||
|
||||
assertThrows(RuntimeException.class,
|
||||
() -> mApexManager.markStagedSessionReady(TEST_SESSION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbortActiveSession_remoteException() throws RemoteException {
|
||||
doThrow(RemoteException.class).when(mApexService).abortActiveSession();
|
||||
|
||||
try {
|
||||
assertThat(mApexManager.abortActiveSession()).isFalse();
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("ApexManager should not raise Exception");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkStagedSessionSuccessful_throwRemoteException() throws RemoteException {
|
||||
doThrow(RemoteException.class).when(mApexService).markStagedSessionSuccessful(anyInt());
|
||||
|
||||
assertThrows(RuntimeException.class,
|
||||
() -> mApexManager.markStagedSessionSuccessful(TEST_SESSION_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUninstallApex_throwException_returnFalse() throws RemoteException {
|
||||
doAnswer(invocation -> {
|
||||
throw new Exception();
|
||||
}).when(mApexService).unstagePackages(any());
|
||||
|
||||
assertThat(mApexManager.uninstallApex(TEST_APEX_PKG)).isFalse();
|
||||
}
|
||||
|
||||
private ApexInfo[] createApexInfo(boolean isActive, boolean isFactory) {
|
||||
File apexFile = copyRawResourceToFile(TEST_APEX_PKG, R.raw.apex_test);
|
||||
ApexInfo apexInfo = new ApexInfo();
|
||||
apexInfo.isActive = isActive;
|
||||
apexInfo.isFactory = isFactory;
|
||||
apexInfo.moduleName = TEST_APEX_PKG;
|
||||
apexInfo.modulePath = apexFile.getPath();
|
||||
apexInfo.versionCode = 191000070;
|
||||
|
||||
return new ApexInfo[]{apexInfo};
|
||||
}
|
||||
|
||||
private ApexSessionInfo getFakeStagedSessionInfo() {
|
||||
ApexSessionInfo stagedSessionInfo = new ApexSessionInfo();
|
||||
stagedSessionInfo.sessionId = TEST_SESSION_ID;
|
||||
stagedSessionInfo.isStaged = true;
|
||||
|
||||
return stagedSessionInfo;
|
||||
}
|
||||
|
||||
private ApexSessionInfo getFakeUnknownSessionInfo() {
|
||||
ApexSessionInfo stagedSessionInfo = new ApexSessionInfo();
|
||||
stagedSessionInfo.sessionId = TEST_SESSION_ID;
|
||||
stagedSessionInfo.isUnknown = true;
|
||||
|
||||
return stagedSessionInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a specified {@code resourceId} to a temp file. Returns a non-null file if the copy
|
||||
* succeeded
|
||||
*/
|
||||
File copyRawResourceToFile(String baseName, int resourceId) {
|
||||
File outFile;
|
||||
try {
|
||||
outFile = File.createTempFile(baseName, ".apex");
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("CreateTempFile IOException" + e);
|
||||
}
|
||||
|
||||
try (InputStream is = mContext.getResources().openRawResource(resourceId);
|
||||
FileOutputStream os = new FileOutputStream(outFile)) {
|
||||
assertThat(FileUtils.copy(is, os)).isGreaterThan(0L);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new AssertionError("File not found exception " + e);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError("IOException" + e);
|
||||
}
|
||||
|
||||
return outFile;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user