diff options
author | Julien Desprez <jdesprez@google.com> | 2017-09-14 21:43:49 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-09-14 21:43:49 +0000 |
commit | 74278d4b1333e05a2377d74c96bdb636e2dbafcc (patch) | |
tree | fd54210b0e6272b2561d83ea1b3829c76f8e7ab7 | |
parent | cc53aaf552184f73a1ce70717fed0b1327771aca (diff) | |
parent | dfb337ffec5313cc57690a5010b4c53473574b51 (diff) | |
download | tradefederation-74278d4b1333e05a2377d74c96bdb636e2dbafcc.tar.gz |
Merge "Allow TestFailureListener for multi devices" into oc-dev
3 files changed, 89 insertions, 40 deletions
diff --git a/src/com/android/tradefed/testtype/suite/ITestSuite.java b/src/com/android/tradefed/testtype/suite/ITestSuite.java index 0b4f3f6a7..cdef58310 100644 --- a/src/com/android/tradefed/testtype/suite/ITestSuite.java +++ b/src/com/android/tradefed/testtype/suite/ITestSuite.java @@ -205,7 +205,7 @@ public abstract class ITestSuite TestFailureListener failureListener = new TestFailureListener( listener, - getDevice(), + mContext.getDevices(), mBugReportOnFailure, mLogcatOnFailure, mScreenshotOnFailure, diff --git a/src/com/android/tradefed/testtype/suite/TestFailureListener.java b/src/com/android/tradefed/testtype/suite/TestFailureListener.java index 71187d72e..84035d3ef 100644 --- a/src/com/android/tradefed/testtype/suite/TestFailureListener.java +++ b/src/com/android/tradefed/testtype/suite/TestFailureListener.java @@ -44,7 +44,7 @@ public class TestFailureListener implements ITestInvocationListener { private static final String LOGCAT_ON_FAILURE_SIZE_OPTION = "logcat-on-failure-size"; private static final long LOGCAT_CAPTURE_TIMEOUT = 2 * 60 * 1000; - private ITestDevice mDevice; + private List<ITestDevice> mListDevice; private ITestInvocationListener mListener; private boolean mBugReportOnFailure; private boolean mLogcatOnFailure; @@ -54,11 +54,16 @@ public class TestFailureListener implements ITestInvocationListener { private Map<TestIdentifier, Long> mTrackStartTime = new HashMap<>(); private List<Thread> mLogcatThreads = new ArrayList<>(); - public TestFailureListener(ITestInvocationListener listener, ITestDevice device, - boolean bugReportOnFailure, boolean logcatOnFailure, boolean screenshotOnFailure, - boolean rebootOnFailure, int maxLogcatBytes) { + public TestFailureListener( + ITestInvocationListener listener, + List<ITestDevice> devices, + boolean bugReportOnFailure, + boolean logcatOnFailure, + boolean screenshotOnFailure, + boolean rebootOnFailure, + int maxLogcatBytes) { mListener = listener; - mDevice = device; + mListDevice = devices; mBugReportOnFailure = bugReportOnFailure; mLogcatOnFailure = logcatOnFailure; mScreenshotOnFailure = screenshotOnFailure; @@ -84,7 +89,7 @@ public class TestFailureListener implements ITestInvocationListener { public void testStarted(TestIdentifier test) { if (mLogcatOnFailure) { try { - mTrackStartTime.put(test, mDevice.getDeviceDate()); + mTrackStartTime.put(test, mListDevice.get(0).getDeviceDate()); } catch (DeviceNotAvailableException e) { CLog.e(e); // we fall back to logcat dump on null. @@ -110,25 +115,32 @@ public class TestFailureListener implements ITestInvocationListener { public void testFailed(TestIdentifier test, String trace) { CLog.i("FailureListener.testFailed %s %b %b %b", test.toString(), mBugReportOnFailure, mLogcatOnFailure, mScreenshotOnFailure); + for (ITestDevice device : mListDevice) { + captureFailure(device, test); + } + } + + /** Capture the appropriate logs for one device for one test failure. */ + private void captureFailure(ITestDevice device, TestIdentifier test) { + String serial = device.getSerialNumber(); if (mScreenshotOnFailure) { try { - try (InputStreamSource screenSource = mDevice.getScreenshot()) { + try (InputStreamSource screenSource = device.getScreenshot()) { testLog( - String.format("%s-screenshot", test.toString()), + String.format("%s-%s-screenshot", test.toString(), serial), LogDataType.PNG, screenSource); } } catch (DeviceNotAvailableException e) { CLog.e(e); - CLog.e("Device %s became unavailable while capturing screenshot", - mDevice.getSerialNumber()); + CLog.e("Device %s became unavailable while capturing screenshot", serial); } } if (mBugReportOnFailure) { - try (InputStreamSource bugSource = mDevice.getBugreportz()) { + try (InputStreamSource bugSource = device.getBugreportz()) { testLog( - String.format("%s-bugreport", test.toString()), - LogDataType.BUGREPORT, + String.format("%s-%s-bugreport", test.toString(), serial), + LogDataType.BUGREPORTZ, bugSource); } } @@ -140,15 +152,15 @@ public class TestFailureListener implements ITestInvocationListener { InputStreamSource logSource = null; Long startTime = mTrackStartTime.remove(test); if (startTime != null) { - logSource = mDevice.getLogcatSince(startTime); + logSource = device.getLogcatSince(startTime); } else { // sleep 2s to ensure test failure stack trace makes it into the // logcat capture getRunUtil().sleep(2 * 1000); - logSource = mDevice.getLogcat(mMaxLogcatBytes); + logSource = device.getLogcat(mMaxLogcatBytes); } testLog( - String.format("%s-logcat", test.toString()), + String.format("%s-%s-logcat", test.toString(), serial), LogDataType.LOGCAT, logSource); logSource.close(); @@ -169,16 +181,15 @@ public class TestFailureListener implements ITestInvocationListener { try { // Rebooting on all failures can hide legitimate issues and platform instabilities, // therefore only allowed on "user-debug" and "eng" builds. - if ("user".equals(mDevice.getProperty("ro.build.type"))) { + if ("user".equals(device.getProperty("ro.build.type"))) { CLog.e("Reboot-on-failure should only be used during development," + " this is a\" user\" build device"); } else { - mDevice.reboot(); + device.reboot(); } } catch (DeviceNotAvailableException e) { CLog.e(e); - CLog.e("Device %s became unavailable while rebooting", - mDevice.getSerialNumber()); + CLog.e("Device %s became unavailable while rebooting", serial); } } } diff --git a/tests/src/com/android/tradefed/testtype/suite/TestFailureListenerTest.java b/tests/src/com/android/tradefed/testtype/suite/TestFailureListenerTest.java index 0b2cf21cb..3c6fc520a 100644 --- a/tests/src/com/android/tradefed/testtype/suite/TestFailureListenerTest.java +++ b/tests/src/com/android/tradefed/testtype/suite/TestFailureListenerTest.java @@ -30,7 +30,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; /** Unit tests for {@link com.android.tradefed.testtype.suite.TestFailureListener} */ @RunWith(JUnit4.class) @@ -39,15 +41,18 @@ public class TestFailureListenerTest { private TestFailureListener mFailureListener; private ITestInvocationListener mMockListener; private ITestDevice mMockDevice; + private List<ITestDevice> mListDevice; @Before public void setUp() { mMockListener = EasyMock.createMock(ITestInvocationListener.class); mMockDevice = EasyMock.createStrictMock(ITestDevice.class); + mListDevice = new ArrayList<>(); + mListDevice.add(mMockDevice); EasyMock.expect(mMockDevice.getSerialNumber()).andStubReturn("SERIAL"); // Create base failure listener with all option ON and default logcat size. - mFailureListener = new TestFailureListener(mMockListener, mMockDevice, - true, true, true, true, -1); + mFailureListener = + new TestFailureListener(mMockListener, mListDevice, true, true, true, true, -1); } /** @@ -63,16 +68,22 @@ public class TestFailureListenerTest { EasyMock.expect(mMockDevice.getDeviceDate()).andReturn(startDate); // Screenshot routine EasyMock.expect(mMockDevice.getScreenshot()).andReturn(fakeSource); - mMockListener.testLog(EasyMock.eq(testId.toString() + "-screenshot"), - EasyMock.eq(LogDataType.PNG), EasyMock.eq(fakeSource)); + mMockListener.testLog( + EasyMock.eq(testId.toString() + "-SERIAL-screenshot"), + EasyMock.eq(LogDataType.PNG), + EasyMock.eq(fakeSource)); // Bugreport routine EasyMock.expect(mMockDevice.getBugreportz()).andReturn(fakeSource); - mMockListener.testLog(EasyMock.eq(testId.toString() + "-bugreport"), - EasyMock.eq(LogDataType.BUGREPORT), EasyMock.eq(fakeSource)); + mMockListener.testLog( + EasyMock.eq(testId.toString() + "-SERIAL-bugreport"), + EasyMock.eq(LogDataType.BUGREPORTZ), + EasyMock.eq(fakeSource)); // logcat routine EasyMock.expect(mMockDevice.getLogcatSince(EasyMock.eq(startDate))).andReturn(fakeSource); - mMockListener.testLog(EasyMock.eq(testId.toString() + "-logcat"), - EasyMock.eq(LogDataType.LOGCAT), EasyMock.eq(fakeSource)); + mMockListener.testLog( + EasyMock.eq(testId.toString() + "-SERIAL-logcat"), + EasyMock.eq(LogDataType.LOGCAT), + EasyMock.eq(fakeSource)); // Reboot routine EasyMock.expect(mMockDevice.getProperty(EasyMock.eq("ro.build.type"))) .andReturn("userdebug"); @@ -90,13 +101,13 @@ public class TestFailureListenerTest { */ @Test public void testTestFailed_notAvailable() throws Exception { - mFailureListener = new TestFailureListener(mMockListener, mMockDevice, - false, true, true, true, -1) { - @Override - IRunUtil getRunUtil() { - return EasyMock.createMock(IRunUtil.class); - } - }; + mFailureListener = + new TestFailureListener(mMockListener, mListDevice, false, true, true, true, -1) { + @Override + IRunUtil getRunUtil() { + return EasyMock.createMock(IRunUtil.class); + } + }; TestIdentifier testId = new TestIdentifier("com.fake", "methodfake"); final String trace = "oups it failed"; final byte[] fakeData = "fakeData".getBytes(); @@ -107,8 +118,10 @@ public class TestFailureListenerTest { EasyMock.expect(mMockDevice.getScreenshot()).andThrow(dnae); // logcat routine EasyMock.expect(mMockDevice.getLogcat(EasyMock.anyInt())).andReturn(fakeSource); - mMockListener.testLog(EasyMock.eq(testId.toString() + "-logcat"), - EasyMock.eq(LogDataType.LOGCAT), EasyMock.eq(fakeSource)); + mMockListener.testLog( + EasyMock.eq(testId.toString() + "-SERIAL-logcat"), + EasyMock.eq(LogDataType.LOGCAT), + EasyMock.eq(fakeSource)); // Reboot routine EasyMock.expect(mMockDevice.getProperty(EasyMock.eq("ro.build.type"))) .andReturn("userdebug"); @@ -126,8 +139,8 @@ public class TestFailureListenerTest { */ @Test public void testTestFailed_userBuild() throws Exception { - mFailureListener = new TestFailureListener(mMockListener, mMockDevice, - false, false, false, true, -1); + mFailureListener = + new TestFailureListener(mMockListener, mListDevice, false, false, false, true, -1); final String trace = "oups it failed"; TestIdentifier testId = new TestIdentifier("com.fake", "methodfake"); EasyMock.expect(mMockDevice.getProperty(EasyMock.eq("ro.build.type"))).andReturn("user"); @@ -137,4 +150,29 @@ public class TestFailureListenerTest { mFailureListener.testEnded(testId, Collections.emptyMap()); EasyMock.verify(mMockListener, mMockDevice); } + + /** + * Test when a test failure occurs during a multi device run. Each device should capture the + * logs. + */ + @Test + public void testFailed_multiDevice() throws Exception { + ITestDevice device2 = EasyMock.createMock(ITestDevice.class); + mListDevice.add(device2); + mFailureListener = + new TestFailureListener(mMockListener, mListDevice, false, false, false, true, -1); + final String trace = "oups it failed"; + TestIdentifier testId = new TestIdentifier("com.fake", "methodfake"); + EasyMock.expect(mMockDevice.getProperty(EasyMock.eq("ro.build.type"))).andReturn("debug"); + mMockDevice.reboot(); + EasyMock.expect(device2.getSerialNumber()).andStubReturn("SERIAL2"); + EasyMock.expect(device2.getProperty(EasyMock.eq("ro.build.type"))).andReturn("debug"); + device2.reboot(); + + EasyMock.replay(mMockListener, mMockDevice, device2); + mFailureListener.testStarted(testId); + mFailureListener.testFailed(testId, trace); + mFailureListener.testEnded(testId, Collections.emptyMap()); + EasyMock.verify(mMockListener, mMockDevice, device2); + } } |