Merge "Move testNetworkFailedRollback (2/n)"
diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
index 2c2e828..0393248 100644
--- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
@@ -16,22 +16,98 @@
package com.android.tests.rollback.host;
+import static org.junit.Assert.assertTrue;
+import static org.testng.Assert.assertThrows;
+
+import com.android.tradefed.device.LogcatReceiver;
+import com.android.tradefed.result.InputStreamSource;
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;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Runs the network rollback tests.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class NetworkStagedRollbackTest extends BaseHostJUnit4Test {
/**
+ * Runs the given phase of a test by calling into the device.
+ * Throws an exception if the test phase fails.
+ * <p>
+ * For example, <code>runPhase("testApkOnlyEnableRollback");</code>
+ */
+ private void runPhase(String phase) throws Exception {
+ assertTrue(runDeviceTests("com.android.tests.rollback",
+ "com.android.tests.rollback.NetworkStagedRollbackTest",
+ phase));
+ }
+
+ private static final String REASON_EXPLICIT_HEALTH_CHECK = "REASON_EXPLICIT_HEALTH_CHECK";
+
+ private static final String ROLLBACK_INITIATE = "ROLLBACK_INITIATE";
+ private static final String ROLLBACK_BOOT_TRIGGERED = "ROLLBACK_BOOT_TRIGGERED";
+
+ private LogcatReceiver mReceiver;
+
+ @Before
+ public void setUp() throws Exception {
+ mReceiver = new LogcatReceiver(getDevice(), "logcat -s WatchdogRollbackLogger",
+ getDevice().getOptions().getMaxLogcatDataSize(), 0);
+ mReceiver.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mReceiver.stop();
+ mReceiver.clear();
+ }
+
+ /**
* Tests failed network health check triggers watchdog staged rollbacks.
*/
@Test
public void testNetworkFailedRollback() throws Exception {
+ try {
+ // Disconnect internet so we can test network health triggered rollbacks
+ getDevice().executeShellCommand("svc wifi disable");
+ getDevice().executeShellCommand("svc data disable");
+
+ runPhase("testNetworkFailedRollback_Phase1");
+ // Reboot device to activate staged package
+ getDevice().reboot();
+
+ // Verify rollback was enabled
+ runPhase("testNetworkFailedRollback_Phase2");
+ assertThrows(AssertionError.class, () -> runPhase("testNetworkFailedRollback_Phase3"));
+
+ getDevice().waitForDeviceAvailable();
+ // Verify rollback was executed after health check deadline
+ runPhase("testNetworkFailedRollback_Phase4");
+ InputStreamSource logcatStream = mReceiver.getLogcatData();
+ try {
+ List<String> watchdogEvents = getWatchdogLoggingEvents(logcatStream);
+ assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+ REASON_EXPLICIT_HEALTH_CHECK, null));
+ assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+ null, null));
+ } finally {
+ logcatStream.close();
+ }
+ } finally {
+ // Reconnect internet again so we won't break tests which assume internet available
+ getDevice().executeShellCommand("svc wifi enable");
+ getDevice().executeShellCommand("svc data enable");
+ }
}
/**
@@ -40,4 +116,57 @@
@Test
public void testNetworkPassedDoesNotRollback() throws Exception {
}
+
+ /**
+ * Returns a list of all Watchdog logging events which have occurred.
+ */
+ private List<String> getWatchdogLoggingEvents(InputStreamSource inputStreamSource)
+ throws Exception {
+ List<String> watchdogEvents = new ArrayList<>();
+ InputStream inputStream = inputStreamSource.createInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (line.contains("Watchdog event occurred")) {
+ watchdogEvents.add(line);
+ }
+ }
+ return watchdogEvents;
+ }
+
+ /**
+ * Returns whether a Watchdog event has occurred that matches the given criteria.
+ *
+ * Check the value of all non-null parameters against the list of Watchdog events that have
+ * occurred, and return {@code true} if an event exists which matches all criteria.
+ */
+ private boolean watchdogEventOccurred(List<String> loggingEvents,
+ String type, String logPackage,
+ String rollbackReason, String failedPackageName) throws Exception {
+ List<String> eventCriteria = new ArrayList<>();
+ if (type != null) {
+ eventCriteria.add("type: " + type);
+ }
+ if (logPackage != null) {
+ eventCriteria.add("logPackage: " + logPackage);
+ }
+ if (rollbackReason != null) {
+ eventCriteria.add("rollbackReason: " + rollbackReason);
+ }
+ if (failedPackageName != null) {
+ eventCriteria.add("failedPackageName: " + failedPackageName);
+ }
+ for (String loggingEvent: loggingEvents) {
+ boolean matchesCriteria = true;
+ for (String criterion: eventCriteria) {
+ if (!loggingEvent.contains(criterion)) {
+ matchesCriteria = false;
+ }
+ }
+ if (matchesCriteria) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
index 04004d6..e5c8a68 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/NetworkStagedRollbackTest.java
@@ -16,9 +16,143 @@
package com.android.tests.rollback;
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.rollback.RollbackManager;
+import android.os.ParcelFileDescriptor;
+import android.provider.DeviceConfig;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.rollback.lib.RollbackUtils;
+
+import libcore.io.IoUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.io.File;
+import java.util.concurrent.TimeUnit;
+
@RunWith(JUnit4.class)
public class NetworkStagedRollbackTest {
+ private static final String NETWORK_STACK_CONNECTOR_CLASS =
+ "android.net.INetworkStackConnector";
+ private static final String PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS =
+ "watchdog_request_timeout_millis";
+
+ private static final TestApp NETWORK_STACK = new TestApp("NetworkStack",
+ getNetworkStackPackageName(), -1, false, findNetworkStackApk());
+
+ private static File findNetworkStackApk() {
+ final File apk = new File("/system/priv-app/NetworkStack/NetworkStack.apk");
+ if (apk.isFile()) {
+ return apk;
+ }
+ return new File("/system/priv-app/NetworkStackNext/NetworkStackNext.apk");
+ }
+
+ /**
+ * Adopts common shell permissions needed for rollback tests.
+ */
+ @Before
+ public void adoptShellPermissions() {
+ InstallUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.TEST_MANAGE_ROLLBACKS,
+ Manifest.permission.FORCE_STOP_PACKAGES,
+ Manifest.permission.WRITE_DEVICE_CONFIG);
+ }
+
+ /**
+ * Drops shell permissions needed for rollback tests.
+ */
+ @After
+ public void dropShellPermissions() {
+ InstallUtils.dropShellPermissionIdentity();
+ }
+
+ @Test
+ public void testNetworkFailedRollback_Phase1() throws Exception {
+ // Remove available rollbacks and uninstall NetworkStack on /data/
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ String networkStack = getNetworkStackPackageName();
+
+ rm.expireRollbackForPackage(networkStack);
+ uninstallNetworkStackPackage();
+
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ networkStack)).isNull();
+
+ // Reduce health check deadline
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
+ PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
+ Integer.toString(120000), false);
+ // Simulate re-installation of new NetworkStack with rollbacks enabled
+ installNetworkStackPackage();
+ }
+
+ @Test
+ public void testNetworkFailedRollback_Phase2() throws Exception {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+ getNetworkStackPackageName())).isNotNull();
+
+ // Sleep for < health check deadline
+ Thread.sleep(TimeUnit.SECONDS.toMillis(5));
+ // Verify rollback was not executed before health check deadline
+ assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+ getNetworkStackPackageName())).isNull();
+ }
+
+ @Test
+ public void testNetworkFailedRollback_Phase3() throws Exception {
+ // Sleep for > health check deadline (120s to trigger rollback + 120s to reboot)
+ // The device is expected to reboot during sleeping. This device method will fail and
+ // the host will catch the assertion. If reboot doesn't happen, the host will fail the
+ // assertion.
+ Thread.sleep(TimeUnit.SECONDS.toMillis(240));
+ }
+
+ @Test
+ public void testNetworkFailedRollback_Phase4() throws Exception {
+ RollbackManager rm = RollbackUtils.getRollbackManager();
+ assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+ getNetworkStackPackageName())).isNotNull();
+ }
+
+ private static String getNetworkStackPackageName() {
+ Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
+ ComponentName comp = intent.resolveSystemService(
+ InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(), 0);
+ return comp.getPackageName();
+ }
+
+ private static void installNetworkStackPackage() throws Exception {
+ Install.single(NETWORK_STACK).setStaged().setEnableRollback()
+ .addInstallFlags(PackageManager.INSTALL_REPLACE_EXISTING).commit();
+ }
+
+ private static void uninstallNetworkStackPackage() {
+ // Uninstall the package as a privileged user so we won't fail due to permission.
+ runShellCommand("pm uninstall " + getNetworkStackPackageName());
+ }
+
+ private static void runShellCommand(String cmd) {
+ ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .executeShellCommand(cmd);
+ IoUtils.closeQuietly(pfd);
+ }
}
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 0fdcbc5..bddd93c 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -274,55 +274,6 @@
TestApp.B)).isNotNull();
}
- @Test
- public void testNetworkFailedRollback_Phase1() throws Exception {
- // Remove available rollbacks and uninstall NetworkStack on /data/
- RollbackManager rm = RollbackUtils.getRollbackManager();
- String networkStack = getNetworkStackPackageName();
-
- rm.expireRollbackForPackage(networkStack);
- uninstallNetworkStackPackage();
-
- assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
- networkStack)).isNull();
-
- // Reduce health check deadline
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
- PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
- Integer.toString(120000), false);
- // Simulate re-installation of new NetworkStack with rollbacks enabled
- installNetworkStackPackage();
- }
-
- @Test
- public void testNetworkFailedRollback_Phase2() throws Exception {
- RollbackManager rm = RollbackUtils.getRollbackManager();
- assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
- getNetworkStackPackageName())).isNotNull();
-
- // Sleep for < health check deadline
- Thread.sleep(TimeUnit.SECONDS.toMillis(5));
- // Verify rollback was not executed before health check deadline
- assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
- getNetworkStackPackageName())).isNull();
- }
-
- @Test
- public void testNetworkFailedRollback_Phase3() throws Exception {
- // Sleep for > health check deadline (120s to trigger rollback + 120s to reboot)
- // The device is expected to reboot during sleeping. This device method will fail and
- // the host will catch the assertion. If reboot doesn't happen, the host will fail the
- // assertion.
- Thread.sleep(TimeUnit.SECONDS.toMillis(240));
- }
-
- @Test
- public void testNetworkFailedRollback_Phase4() throws Exception {
- RollbackManager rm = RollbackUtils.getRollbackManager();
- assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
- getNetworkStackPackageName())).isNotNull();
- }
-
private static String getNetworkStackPackageName() {
Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
ComponentName comp = intent.resolveSystemService(
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 032f182..3c5eaef 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
@@ -228,44 +228,6 @@
}
/**
- * Tests failed network health check triggers watchdog staged rollbacks.
- */
- @Test
- public void testNetworkFailedRollback() throws Exception {
- try {
- // Disconnect internet so we can test network health triggered rollbacks
- getDevice().executeShellCommand("svc wifi disable");
- getDevice().executeShellCommand("svc data disable");
-
- runPhase("testNetworkFailedRollback_Phase1");
- // Reboot device to activate staged package
- getDevice().reboot();
-
- // Verify rollback was enabled
- runPhase("testNetworkFailedRollback_Phase2");
- assertThrows(AssertionError.class, () -> runPhase("testNetworkFailedRollback_Phase3"));
-
- getDevice().waitForDeviceAvailable();
- // Verify rollback was executed after health check deadline
- runPhase("testNetworkFailedRollback_Phase4");
- InputStreamSource logcatStream = mReceiver.getLogcatData();
- try {
- List<String> watchdogEvents = getWatchdogLoggingEvents(logcatStream);
- assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
- REASON_EXPLICIT_HEALTH_CHECK, null));
- assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
- null, null));
- } finally {
- logcatStream.close();
- }
- } finally {
- // Reconnect internet again so we won't break tests which assume internet available
- getDevice().executeShellCommand("svc wifi enable");
- getDevice().executeShellCommand("svc data enable");
- }
- }
-
- /**
* Tests passed network health check does not trigger watchdog staged rollbacks.
*/
@Test
diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING
index fefde5b..0f4c460 100644
--- a/tests/RollbackTest/TEST_MAPPING
+++ b/tests/RollbackTest/TEST_MAPPING
@@ -7,6 +7,9 @@
"name": "StagedRollbackTest"
},
{
+ "name": "NetworkStagedRollbackTest"
+ },
+ {
"name": "MultiUserRollbackTest"
}
]