aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Desprez <jdesprez@google.com>2017-09-14 21:43:49 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-09-14 21:43:49 +0000
commit74278d4b1333e05a2377d74c96bdb636e2dbafcc (patch)
treefd54210b0e6272b2561d83ea1b3829c76f8e7ab7
parentcc53aaf552184f73a1ce70717fed0b1327771aca (diff)
parentdfb337ffec5313cc57690a5010b4c53473574b51 (diff)
downloadtradefederation-74278d4b1333e05a2377d74c96bdb636e2dbafcc.tar.gz
Merge "Allow TestFailureListener for multi devices" into oc-dev
-rw-r--r--src/com/android/tradefed/testtype/suite/ITestSuite.java2
-rw-r--r--src/com/android/tradefed/testtype/suite/TestFailureListener.java51
-rw-r--r--tests/src/com/android/tradefed/testtype/suite/TestFailureListenerTest.java76
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);
+ }
}