Merge "Add network health check watchdog triggered rollback tests" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-05-30 15:22:26 +00:00
committed by Android (Google) Code Review
4 changed files with 171 additions and 6 deletions

View File

@@ -95,7 +95,7 @@ android_test {
":RollbackTestAppASplitV2",
],
test_config: "RollbackTest.xml",
sdk_version: "test_current",
// TODO: sdk_version: "test_current" when Intent#resolveSystemservice is TestApi
}
java_test_host {

View File

@@ -28,6 +28,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
@@ -82,13 +83,31 @@ class RollbackTestUtils {
* Returns -1 if the package is not currently installed.
*/
static long getInstalledVersion(String packageName) {
PackageInfo pi = getPackageInfo(packageName);
if (pi == null) {
return -1;
} else {
return pi.getLongVersionCode();
}
}
private static boolean isSystemAppWithoutUpdate(String packageName) {
PackageInfo pi = getPackageInfo(packageName);
if (pi == null) {
return false;
} else {
return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
&& ((pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0);
}
}
private static PackageInfo getPackageInfo(String packageName) {
Context context = InstrumentationRegistry.getContext();
PackageManager pm = context.getPackageManager();
try {
PackageInfo info = pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
return info.getLongVersionCode();
return pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
} catch (PackageManager.NameNotFoundException e) {
return -1;
return null;
}
}
@@ -109,8 +128,8 @@ class RollbackTestUtils {
* @throws AssertionError if package can't be uninstalled.
*/
static void uninstall(String packageName) throws InterruptedException, IOException {
// No need to uninstall if the package isn't installed.
if (getInstalledVersion(packageName) == -1) {
// No need to uninstall if the package isn't installed or is installed on /system.
if (getInstalledVersion(packageName) == -1 || isSystemAppWithoutUpdate(packageName)) {
return;
}

View File

@@ -21,7 +21,9 @@ import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfo
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.VersionedPackage;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
@@ -30,6 +32,8 @@ import androidx.test.InstrumentationRegistry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -54,6 +58,8 @@ public class StagedRollbackTest {
private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
private static final String TEST_APP_A_V1 = "RollbackTestAppAv1.apk";
private static final String TEST_APP_A_CRASHING_V2 = "RollbackTestAppACrashingV2.apk";
private static final String NETWORK_STACK_CONNECTOR_CLASS =
"android.net.INetworkStackConnector";
/**
* Adopts common shell permissions needed for rollback tests.
@@ -157,4 +163,44 @@ public class StagedRollbackTest {
assertTrue(rollback.isStaged());
assertNotEquals(-1, rollback.getCommittedSessionId());
}
@Test
public void resetNetworkStack() throws Exception {
RollbackManager rm = RollbackTestUtils.getRollbackManager();
String networkStack = getNetworkStackPackageName();
rm.expireRollbackForPackage(networkStack);
RollbackTestUtils.uninstall(networkStack);
assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
networkStack));
}
@Test
public void assertNetworkStackRollbackAvailable() throws Exception {
RollbackManager rm = RollbackTestUtils.getRollbackManager();
assertNotNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
getNetworkStackPackageName()));
}
@Test
public void assertNetworkStackRollbackCommitted() throws Exception {
RollbackManager rm = RollbackTestUtils.getRollbackManager();
assertNotNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
getNetworkStackPackageName()));
}
@Test
public void assertNoNetworkStackRollbackCommitted() throws Exception {
RollbackManager rm = RollbackTestUtils.getRollbackManager();
assertNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
getNetworkStackPackageName()));
}
private String getNetworkStackPackageName() {
Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
ComponentName comp = intent.resolveSystemService(
InstrumentationRegistry.getContext().getPackageManager(), 0);
return comp.getPackageName();
}
}

View File

@@ -23,6 +23,8 @@ import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,6 +45,20 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
phase));
}
@Before
public void setUp() throws Exception {
// Disconnect internet so we can test network health triggered rollbacks
getDevice().executeShellCommand("svc wifi disable");
getDevice().executeShellCommand("svc data disable");
}
@After
public void tearDown() throws Exception {
// Reconnect internet after testing network health triggered rollbacks
getDevice().executeShellCommand("svc wifi enable");
getDevice().executeShellCommand("svc data enable");
}
/**
* Tests watchdog triggered staged rollbacks involving only apks.
*/
@@ -63,6 +79,90 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
}
getDevice().waitForDeviceAvailable();
runPhase("testBadApkOnlyConfirmRollback");
}
/**
* Tests failed network health check triggers watchdog staged rollbacks.
*/
@Test
public void testNetworkFailedRollback() throws Exception {
// Remove available rollbacks and uninstall NetworkStack on /data/
runPhase("resetNetworkStack");
// Reduce health check deadline
getDevice().executeShellCommand("device_config put rollback "
+ "watchdog_request_timeout_millis 300000");
// Simulate re-installation of new NetworkStack with rollbacks enabled
getDevice().executeShellCommand("pm install -r --staged --enable-rollback "
+ "/system/priv-app/NetworkStack/NetworkStack.apk");
// Sleep to allow writes to disk before reboot
Thread.sleep(5000);
// Reboot device to activate staged package
getDevice().reboot();
getDevice().waitForDeviceAvailable();
// Verify rollback was enabled
runPhase("assertNetworkStackRollbackAvailable");
// Sleep for < health check deadline
Thread.sleep(5000);
// Verify rollback was not executed before health check deadline
runPhase("assertNoNetworkStackRollbackCommitted");
try {
// This is expected to fail due to the device being rebooted out
// from underneath the test. If this fails for reasons other than
// the device reboot, those failures should result in failure of
// the assertNetworkStackExecutedRollback phase.
CLog.logAndDisplay(LogLevel.INFO, "Sleep and expect to fail while sleeping");
// Sleep for > health check deadline
Thread.sleep(260000);
} catch (AssertionError e) {
// AssertionError is expected.
}
getDevice().waitForDeviceAvailable();
// Verify rollback was executed after health check deadline
runPhase("assertNetworkStackRollbackCommitted");
}
/**
* Tests passed network health check does not trigger watchdog staged rollbacks.
*/
@Test
public void testNetworkPassedDoesNotRollback() throws Exception {
// Remove available rollbacks and uninstall NetworkStack on /data/
runPhase("resetNetworkStack");
// Reduce health check deadline, here unlike the network failed case, we use
// a longer deadline because joining a network can take a much longer time for
// reasons external to the device than 'not joining'
getDevice().executeShellCommand("device_config put rollback "
+ "watchdog_request_timeout_millis 300000");
// Simulate re-installation of new NetworkStack with rollbacks enabled
getDevice().executeShellCommand("pm install -r --staged --enable-rollback "
+ "/system/priv-app/NetworkStack/NetworkStack.apk");
// Sleep to allow writes to disk before reboot
Thread.sleep(5000);
// Reboot device to activate staged package
getDevice().reboot();
getDevice().waitForDeviceAvailable();
// Verify rollback was enabled
runPhase("assertNetworkStackRollbackAvailable");
// Connect to internet so network health check passes
getDevice().executeShellCommand("svc wifi enable");
getDevice().executeShellCommand("svc data enable");
// Wait for device available because emulator device may restart after turning
// on mobile data
getDevice().waitForDeviceAvailable();
// Sleep for > health check deadline
Thread.sleep(310000);
// Verify rollback was not executed after health check deadline
runPhase("assertNoNetworkStackRollbackCommitted");
}
}