malloc debug root to clean up am: dd415afd33 am: 70bfc2201d am: 9328c744e5 am: 3ab696f0bb am: 06f445cc2d
Original change: https://googleplex-android-review.googlesource.com/c/platform/platform_testing/+/24424185
Change-Id: Id5440bd12d9f9cc4784d3becf9d82795cc23b64e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/libraries/sts-common-util/host-side/src/com/android/sts/common/MallocDebug.java b/libraries/sts-common-util/host-side/src/com/android/sts/common/MallocDebug.java
index 12665b2..214ccc0 100644
--- a/libraries/sts-common-util/host-side/src/com/android/sts/common/MallocDebug.java
+++ b/libraries/sts-common-util/host-side/src/com/android/sts/common/MallocDebug.java
@@ -17,9 +17,6 @@
package com.android.sts.common;
import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeNoException;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
@@ -48,71 +45,89 @@
Pattern.compile("^.*HAS INVALID TAG.*$", Pattern.MULTILINE),
};
- private ITestDevice device;
- private String processName;
- private AutoCloseable setMallocDebugOptionsProperty;
- private AutoCloseable setAttachedProgramProperty;
- private AutoCloseable killProcess;
+ private ITestDevice mDevice;
+ private String mProcessName;
+ private boolean mWasAdbRoot;
+ private AutoCloseable mSetMallocDebugOptionsProperty;
+ private AutoCloseable mSetAttachedProgramProperty;
+ private AutoCloseable mProcessKill;
private MallocDebug(
ITestDevice device, String mallocDebugOption, String processName, boolean isService)
throws DeviceNotAvailableException, TimeoutException, ProcessUtil.KillException {
- this.device = device;
- this.processName = processName;
+ mDevice = device;
+ mProcessName = processName;
+ mWasAdbRoot = device.isAdbRoot();
- // It's an error if this is called while something else is also doing malloc debug.
- assertNull(
- MALLOC_DEBUG_OPTIONS_PROP + " is already set!",
- device.getProperty(MALLOC_DEBUG_OPTIONS_PROP));
- CommandUtil.runAndCheck(device, "logcat -c");
+ String previousProperty = device.getProperty(MALLOC_DEBUG_OPTIONS_PROP);
+ if (previousProperty != null) {
+ // log if this is called while something else is also doing malloc debug.
+ CLog.w("%s is already set! <%s>", MALLOC_DEBUG_OPTIONS_PROP, previousProperty);
+ }
try {
- this.setMallocDebugOptionsProperty =
+ mSetMallocDebugOptionsProperty =
SystemUtil.withProperty(device, MALLOC_DEBUG_OPTIONS_PROP, mallocDebugOption);
- this.setAttachedProgramProperty =
+ mSetAttachedProgramProperty =
SystemUtil.withProperty(device, MALLOC_DEBUG_PROGRAM_PROP, processName);
+ CommandUtil.runAndCheck(device, "logcat -c");
+
// Kill and wait for the process to come back if we're attaching to a service
- this.killProcess = null;
+ mProcessKill = null;
if (isService) {
- this.killProcess = ProcessUtil.withProcessKill(device, processName, null);
+ mProcessKill = ProcessUtil.withProcessKill(device, processName, null);
ProcessUtil.waitProcessRunning(device, processName);
}
} catch (Throwable e1) {
try {
- if (setMallocDebugOptionsProperty != null) {
- setMallocDebugOptionsProperty.close();
+ if (mSetMallocDebugOptionsProperty != null) {
+ mSetMallocDebugOptionsProperty.close();
}
- if (setAttachedProgramProperty != null) {
- setAttachedProgramProperty.close();
+ if (mSetAttachedProgramProperty != null) {
+ mSetAttachedProgramProperty.close();
}
} catch (Exception e2) {
CLog.e(e2);
- fail(
+ throw new IllegalStateException(
"Could not enable malloc debug. Additionally, there was an"
+ " exception while trying to reset device state. Tests after"
- + " this may not work as expected!\n"
- + e2);
+ + " this may not work as expected!",
+ e2);
}
- assumeNoException("Could not enable malloc debug", e1);
+ throw new IllegalStateException("Could not enable malloc debug", e1);
}
}
@Override
public void close() throws Exception {
- device.waitForDeviceAvailable();
- setMallocDebugOptionsProperty.close();
- setAttachedProgramProperty.close();
- if (killProcess != null) {
+ mDevice.waitForDeviceAvailable();
+ boolean isAdbRoot = mDevice.isAdbRoot();
+ if (mWasAdbRoot) {
+ // regain root permissions to teardown
+ mDevice.enableAdbRoot();
+ }
+ try {
+ mSetMallocDebugOptionsProperty.close();
+ mSetAttachedProgramProperty.close();
+ } catch (Exception e) {
+ throw new IllegalStateException("Could not disable malloc debug", e);
+ }
+ if (mProcessKill != null) {
try {
- killProcess.close();
- ProcessUtil.waitProcessRunning(device, processName);
+ mProcessKill.close();
+ ProcessUtil.waitProcessRunning(mDevice, mProcessName);
} catch (TimeoutException e) {
- assumeNoException(
- "Could not restart '" + processName + "' after disabling malloc debug", e);
+ throw new IllegalStateException(
+ "Could not restart '" + mProcessName + "' after disabling malloc debug", e);
}
}
- String logcat = CommandUtil.runAndCheck(device, "logcat -d *:S malloc_debug:V").getStdout();
+ String logcat =
+ CommandUtil.runAndCheck(mDevice, "logcat -d *:S malloc_debug:V").getStdout();
+ if (!isAdbRoot) {
+ // restore nonroot status if the try-with-resources body unrooted
+ mDevice.disableAdbRoot();
+ }
assertNoMallocDebugErrors(logcat);
}
@@ -129,7 +144,7 @@
public static AutoCloseable withLibcMallocDebugOnService(
ITestDevice device, String mallocDebugOptions, String processName)
throws DeviceNotAvailableException, IllegalArgumentException, TimeoutException,
- ProcessUtil.KillException {
+ ProcessUtil.KillException {
if (processName == null || processName.isEmpty()) {
throw new IllegalArgumentException("Service processName can't be empty");
}
@@ -149,7 +164,7 @@
public static AutoCloseable withLibcMallocDebugOnNewProcess(
ITestDevice device, String mallocDebugOptions, String processName)
throws DeviceNotAvailableException, IllegalArgumentException, TimeoutException,
- ProcessUtil.KillException {
+ ProcessUtil.KillException {
if (processName == null || processName.isEmpty()) {
throw new IllegalArgumentException("processName can't be empty");
}
diff --git a/libraries/sts-common-util/host-side/tests/src/com/android/sts/common/MallocDebugTest.java b/libraries/sts-common-util/host-side/tests/src/com/android/sts/common/MallocDebugTest.java
index 03b1934..99faf82 100644
--- a/libraries/sts-common-util/host-side/tests/src/com/android/sts/common/MallocDebugTest.java
+++ b/libraries/sts-common-util/host-side/tests/src/com/android/sts/common/MallocDebugTest.java
@@ -16,6 +16,11 @@
package com.android.sts.common;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
@@ -54,4 +59,59 @@
public void testMallocDebugWithErrors() throws Exception {
MallocDebug.assertNoMallocDebugErrors(logcatWithErrors);
}
+
+ @Test(expected = IllegalStateException.class)
+ public void testMallocDebugAutocloseableNonRoot() throws Exception {
+ assertTrue(getDevice().disableAdbRoot());
+ try (AutoCloseable mallocDebug =
+ MallocDebug.withLibcMallocDebugOnNewProcess(
+ getDevice(), "backtrace guard", "native-poc")) {
+ // empty
+ }
+ }
+
+ @Test
+ public void testMallocDebugAutocloseableRoot() throws Exception {
+ assertTrue("must test with rootable device", getDevice().enableAdbRoot());
+ try (AutoCloseable mallocDebug =
+ MallocDebug.withLibcMallocDebugOnNewProcess(
+ getDevice(), "backtrace guard", "native-poc")) {
+ // empty
+ }
+ }
+
+ @Test
+ public void testMallocDebugAutocloseableNonRootCleanup() throws Exception {
+ assertTrue("must test with rootable device", getDevice().enableAdbRoot());
+ try (AutoCloseable mallocDebug =
+ MallocDebug.withLibcMallocDebugOnNewProcess(
+ getDevice(), "backtrace guard", "native-poc")) {
+ assertTrue("could not disable root", getDevice().disableAdbRoot());
+ }
+ assertFalse(
+ "device should not be root after autoclose if the body unrooted",
+ getDevice().isAdbRoot());
+ }
+
+ @Test
+ public void testMallocDebugAutoseablePriorValueNoException() throws Exception {
+ assertTrue("must test with rootable device", getDevice().enableAdbRoot());
+ final String oldValue = "TEST_VALUE_OLD";
+ final String newValue = "TEST_VALUE_NEW";
+ assertTrue(
+ "could not set property",
+ getDevice().setProperty("libc.debug.malloc.options", oldValue));
+ assertWithMessage("test property was not properly set on device")
+ .that(getDevice().getProperty("libc.debug.malloc.options"))
+ .isEqualTo(oldValue);
+ try (AutoCloseable mallocDebug =
+ MallocDebug.withLibcMallocDebugOnNewProcess(getDevice(), newValue, "native-poc")) {
+ assertWithMessage("new property was not set during malloc debug body")
+ .that(getDevice().getProperty("libc.debug.malloc.options"))
+ .isEqualTo(newValue);
+ }
+ assertWithMessage("prior property was not restored after test")
+ .that(getDevice().getProperty("libc.debug.malloc.options"))
+ .isEqualTo(oldValue);
+ }
}