diff options
author | JW Wang <wangchun@google.com> | 2020-02-11 02:48:58 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-02-11 02:48:58 +0000 |
commit | 5feeb53e762c928b0a5e80e7bbefc58498ee2d6e (patch) | |
tree | 4df3abcaade931dafd143011a1932bfe3a63306e | |
parent | ed1e5bb8759c05819195f92efeeafa6ae69e9866 (diff) | |
parent | 82228f22d491bee3549349f312a20e5aa162bf39 (diff) |
Merge "Move testNetworkFailedRollback (2/n)"
5 files changed, 266 insertions, 87 deletions
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 2c2e8282ff51..0393248c34d2 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 @@ public class NetworkStagedRollbackTest extends BaseHostJUnit4Test { @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 04004d6abb5a..e5c8a685813f 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 0fdcbc52bffa..bddd93c6de36 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 @@ public class StagedRollbackTest { 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 032f18240a55..3c5eaef86bcc 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 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { } /** - * 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 fefde5b4be12..0f4c4603f9b4 100644 --- a/tests/RollbackTest/TEST_MAPPING +++ b/tests/RollbackTest/TEST_MAPPING @@ -7,6 +7,9 @@ "name": "StagedRollbackTest" }, { + "name": "NetworkStagedRollbackTest" + }, + { "name": "MultiUserRollbackTest" } ] |