blob: e7217080f67fd20b6f0a7e7539348ab03fc79686 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tradefed.device.metric;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.android.ddmlib.IDevice;
import com.android.tradefed.config.ConfigurationDef;
import com.android.tradefed.device.ILogcatReceiver;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.device.NullDevice;
import com.android.tradefed.device.TestDeviceState;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.InvocationContext;
import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
import com.android.tradefed.result.ByteArrayInputStreamSource;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.result.LogDataType;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.util.IRunUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.HashMap;
/** Unit tests for {@link LogcatOnFailureCollector}. */
@RunWith(JUnit4.class)
public class LogcatOnFailureCollectorTest {
private TestableLogcatOnFailureCollector mCollector;
@Mock ITestInvocationListener mMockListener;
@Mock ITestDevice mMockDevice;
@Mock ITestDevice mNullMockDevice;
private ITestInvocationListener mTestListener;
private IInvocationContext mContext;
@Mock ILogcatReceiver mMockReceiver;
@Mock IRunUtil mMockRunUtil;
private class TestableLogcatOnFailureCollector extends LogcatOnFailureCollector {
public boolean mOnTestStartCalled = false;
public boolean mOnTestFailCalled = false;
@Override
public void onTestStart(DeviceMetricData testData) {
super.onTestStart(testData);
mOnTestStartCalled = true;
}
@Override
public void onTestFail(DeviceMetricData testData, TestDescription test) {
super.onTestFail(testData, test);
mOnTestFailCalled = true;
}
@Override
ILogcatReceiver createLogcatReceiver(ITestDevice device) {
return mMockReceiver;
}
@Override
IRunUtil getRunUtil() {
return mMockRunUtil;
}
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mCollector = new TestableLogcatOnFailureCollector();
mContext = new InvocationContext();
mContext.addAllocatedDevice(ConfigurationDef.DEFAULT_DEVICE_NAME, mMockDevice);
mContext.addAllocatedDevice("second_null_device", mNullMockDevice);
when(mMockDevice.getSerialNumber()).thenReturn("serial");
when(mMockDevice.getIDevice()).thenReturn(mock(IDevice.class));
when(mMockDevice.getDeviceState()).thenReturn(TestDeviceState.ONLINE);
when(mNullMockDevice.getIDevice()).thenReturn(new NullDevice("null-dev"));
}
@Test
public void testCollect() throws Exception {
when(mMockDevice.getApiLevel()).thenReturn(20);
TestDescription test = new TestDescription("class", "test");
// Buffer at testRunStarted
when(mMockReceiver.getLogcatData())
.thenReturn(new ByteArrayInputStreamSource("aaa".getBytes()));
// Buffer to be logged
when(mMockReceiver.getLogcatData(Mockito.anyInt(), Mockito.eq(3)))
.thenReturn(new ByteArrayInputStreamSource("aaabbb".getBytes()));
mTestListener = mCollector.init(mContext, mMockListener);
mTestListener.testRunStarted("runName", 1);
mTestListener.testStarted(test);
mTestListener.testFailed(test, "I failed");
mTestListener.testEnded(test, new HashMap<String, Metric>());
mTestListener.testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockReceiver).start();
verify(mMockReceiver).clear();
verify(mMockReceiver).stop();
verify(mMockListener)
.testRunStarted(
Mockito.eq("runName"), Mockito.eq(1), Mockito.eq(0), Mockito.anyLong());
verify(mMockListener).testStarted(Mockito.eq(test), Mockito.anyLong());
verify(mMockListener).testFailed(Mockito.eq(test), (String) Mockito.any());
verify(mMockListener)
.testEnded(
Mockito.eq(test),
Mockito.anyLong(),
Mockito.<HashMap<String, Metric>>any());
verify(mMockListener).testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockListener)
.testLog(
Mockito.eq("class#test-serial-logcat-on-failure"),
Mockito.eq(LogDataType.LOGCAT),
Mockito.any());
// Ensure the callback went through
assertTrue(mCollector.mOnTestStartCalled);
assertTrue(mCollector.mOnTestFailCalled);
}
/**
* If the API level support of the device is lower than a threshold we fall back to a different
* collection for the logcat.
*/
@Test
public void testCollect_legacy() throws Exception {
when(mMockDevice.getApiLevel()).thenReturn(18);
TestDescription test = new TestDescription("class", "test");
mTestListener = mCollector.init(mContext, mMockListener);
mTestListener.testRunStarted("runName", 1);
mTestListener.testStarted(test);
mTestListener.testFailed(test, "I failed");
mTestListener.testEnded(test, new HashMap<String, Metric>());
mTestListener.testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockListener)
.testRunStarted(
Mockito.eq("runName"), Mockito.eq(1), Mockito.eq(0), Mockito.anyLong());
verify(mMockListener).testStarted(Mockito.eq(test), Mockito.anyLong());
verify(mMockListener).testFailed(Mockito.eq(test), (String) Mockito.any());
verify(mMockListener)
.testEnded(
Mockito.eq(test),
Mockito.anyLong(),
Mockito.<HashMap<String, Metric>>any());
verify(mMockListener).testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockDevice).executeShellCommand(Mockito.eq("logcat -t 5000"), Mockito.any());
verify(mMockListener)
.testLog(
Mockito.eq("class#test-serial-logcat-on-failure"),
Mockito.eq(LogDataType.LOGCAT),
Mockito.any());
// Ensure the callback went through
assertTrue(mCollector.mOnTestStartCalled);
assertTrue(mCollector.mOnTestFailCalled);
}
@Test
public void testCollect_noRuns() throws Exception {
// If there was no runs, nothing should be done.
mTestListener = mCollector.init(mContext, mMockListener);
assertFalse(mCollector.mOnTestStartCalled);
assertFalse(mCollector.mOnTestFailCalled);
}
@Test
public void testCollect_multiRun() throws Exception {
when(mMockDevice.getApiLevel()).thenReturn(20);
TestDescription test = new TestDescription("class", "test");
TestDescription test2 = new TestDescription("class2", "test2");
// Buffer at testRunStarted
when(mMockReceiver.getLogcatData())
.thenReturn(new ByteArrayInputStreamSource("aaa".getBytes()));
// Buffer to be logged
when(mMockReceiver.getLogcatData(Mockito.anyInt(), Mockito.eq(3)))
.thenReturn(new ByteArrayInputStreamSource("aaabbb".getBytes()));
// Buffer at testRunStarted
when(mMockReceiver.getLogcatData())
.thenReturn(new ByteArrayInputStreamSource("aaa".getBytes()));
// Buffer to be logged
when(mMockReceiver.getLogcatData(Mockito.anyInt(), Mockito.eq(3)))
.thenReturn(new ByteArrayInputStreamSource("aaabbb".getBytes()));
mTestListener = mCollector.init(mContext, mMockListener);
mTestListener.testRunStarted("runName", 1);
mTestListener.testStarted(test);
mTestListener.testFailed(test, "I failed");
mTestListener.testEnded(test, new HashMap<String, Metric>());
mTestListener.testRunEnded(0L, new HashMap<String, Metric>());
// Second run
mTestListener.testRunStarted("runName2", 1);
mTestListener.testStarted(test2);
mTestListener.testFailed(test2, "I failed");
mTestListener.testEnded(test2, new HashMap<String, Metric>());
mTestListener.testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockReceiver, times(2)).start();
verify(mMockReceiver, times(2)).clear();
verify(mMockReceiver, times(2)).stop();
verify(mMockListener)
.testRunStarted(
Mockito.eq("runName"), Mockito.eq(1), Mockito.eq(0), Mockito.anyLong());
verify(mMockListener).testStarted(Mockito.eq(test), Mockito.anyLong());
verify(mMockListener).testFailed(Mockito.eq(test), (String) Mockito.any());
verify(mMockListener)
.testEnded(
Mockito.eq(test),
Mockito.anyLong(),
Mockito.<HashMap<String, Metric>>any());
// verify testRunEnded for both runs with times(2)
verify(mMockListener, times(2)).testRunEnded(0L, new HashMap<String, Metric>());
verify(mMockListener)
.testLog(
Mockito.eq("class#test-serial-logcat-on-failure"),
Mockito.eq(LogDataType.LOGCAT),
Mockito.any());
verify(mMockListener)
.testRunStarted(
Mockito.eq("runName2"), Mockito.eq(1), Mockito.eq(0), Mockito.anyLong());
verify(mMockListener).testStarted(Mockito.eq(test2), Mockito.anyLong());
verify(mMockListener).testFailed(Mockito.eq(test2), (String) Mockito.any());
verify(mMockListener)
.testEnded(
Mockito.eq(test2),
Mockito.anyLong(),
Mockito.<HashMap<String, Metric>>any());
verify(mMockListener)
.testLog(
Mockito.eq("class2#test2-serial-logcat-on-failure"),
Mockito.eq(LogDataType.LOGCAT),
Mockito.any());
// Ensure the callback went through
assertTrue(mCollector.mOnTestStartCalled);
assertTrue(mCollector.mOnTestFailCalled);
}
}