From e6e09ec25d398d954fe93865b681f711a1c22322 Mon Sep 17 00:00:00 2001 From: wnwen Date: Wed, 16 Dec 2015 11:20:11 -0800 Subject: [PATCH] Show more stack trace in instrumentation tests. When unknown exceptions are raised during instrumentation tests, catch the exception and output its stack trace as part of the log rather than just displaying 'CRASHED' or 'UNKNOWN' statuses. This should also show up in buildbot logs. BUG=567841 Review URL: https://codereview.chromium.org/1514453007 Cr-Commit-Position: refs/heads/master@{#365586} --- .../instrumentation_test_instance_test.py | 19 ++++++++++++++ .../chrome/browser/ChromeStrictMode.java | 3 +++ .../test/ChromeActivityTestCaseBase.java | 25 ++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance_test.py b/build/android/pylib/instrumentation/instrumentation_test_instance_test.py index 752e4d3d0e4fee..b6787b24655316 100755 --- a/build/android/pylib/instrumentation/instrumentation_test_instance_test.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance_test.py @@ -104,6 +104,25 @@ def testGenerateTestResults_testFailed(self): self.assertEqual(1, len(results)) self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType()) + def testGenerateTestResults_testUnknownException(self): + stacktrace = 'long\nstacktrace' + statuses = [ + (1, { + 'class': 'test.package.TestClass', + 'test': 'testMethod', + }), + (-1, { + 'class': 'test.package.TestClass', + 'test': 'testMethod', + 'stack': stacktrace, + }), + ] + results = instrumentation_test_instance.GenerateTestResults( + None, None, statuses, 0, 1000) + self.assertEqual(1, len(results)) + self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType()) + self.assertEqual(stacktrace, results[0].GetLog()) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeStrictMode.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeStrictMode.java index bf07298721815e..516504e5040782 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeStrictMode.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeStrictMode.java @@ -44,6 +44,9 @@ public static void configureStrictMode() { if ("death".equals(commandLine.getSwitchValue(ChromeSwitches.STRICT_MODE))) { threadPolicy = threadPolicy.penaltyDeath(); vmPolicy = vmPolicy.penaltyDeath(); + } else if ("testing".equals(commandLine.getSwitchValue(ChromeSwitches.STRICT_MODE))) { + threadPolicy = threadPolicy.penaltyDeath(); + // Currently VmDeathPolicy kills the process, and is not visible on bot test output. } StrictMode.setThreadPolicy(threadPolicy.build()); StrictMode.setVmPolicy(vmPolicy.build()); diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java index 16a6b3a26bf69d..770bda125a29c3 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java @@ -11,7 +11,9 @@ import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; +import android.os.Bundle; import android.provider.Browser; +import android.test.InstrumentationTestRunner; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -118,12 +120,32 @@ public ChromeActivityTestCaseBase(Class activityClass) { protected boolean mSkipClearAppData = false; protected boolean mSkipCheckHttpServer = false; + private Thread.UncaughtExceptionHandler mDefaultUncaughtExceptionHandler; + + private class ChromeUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { + @Override + public void uncaughtException(Thread t, Throwable e) { + String stackTrace = Log.getStackTraceString(e); + if (e.getClass().getName().endsWith("StrictModeViolation")) { + stackTrace += "\nSearch logcat for \"StrictMode policy violation\" for full stack."; + } + Bundle resultsBundle = new Bundle(); + resultsBundle.putString(InstrumentationTestRunner.REPORT_KEY_NAME_CLASS, + getClass().getName()); + resultsBundle.putString(InstrumentationTestRunner.REPORT_KEY_NAME_TEST, getName()); + resultsBundle.putString(InstrumentationTestRunner.REPORT_KEY_STACK, stackTrace); + getInstrumentation().sendStatus(-1, resultsBundle); + mDefaultUncaughtExceptionHandler.uncaughtException(t, e); + } + } + @Override protected void setUp() throws Exception { super.setUp(); + mDefaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(new ChromeUncaughtExceptionHandler()); ApplicationTestUtils.setUp( getInstrumentation().getTargetContext(), !mSkipClearAppData, !mSkipCheckHttpServer); - setActivityInitialTouchMode(false); startMainActivity(); } @@ -131,6 +153,7 @@ protected void setUp() throws Exception { @Override protected void tearDown() throws Exception { ApplicationTestUtils.tearDown(getInstrumentation().getTargetContext()); + Thread.setDefaultUncaughtExceptionHandler(mDefaultUncaughtExceptionHandler); super.tearDown(); }