Merge "Add network health check watchdog triggered rollback tests" into qt-dev
am: 80b53bd68b
Change-Id: I760b8f0d948702a51b96c3aaffa6ccb268b891fe
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 1cf3d36..aec4055 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -95,7 +95,7 @@
":RollbackTestAppASplitV2",
],
test_config: "RollbackTest.xml",
- sdk_version: "test_current",
+ // TODO: sdk_version: "test_current" when Intent#resolveSystemservice is TestApi
}
java_test_host {
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
index 81629aa..a9e20cd 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
@@ -28,6 +28,7 @@
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 @@
* 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 @@
* @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;
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 1ddfa6e..1a29c4c 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -21,7 +21,9 @@
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 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 @@
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 @@
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();
+ }
}
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 75a95ad..bad2947 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -23,6 +23,8 @@
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 @@
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 @@
}
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");
+ }
}