blob: 96bf47908044fc3a181218bebf5f8b0596e80ba2 [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.testtype.mobly;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import com.android.tradefed.build.DeviceBuildInfo;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.InvocationContext;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil;
import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
import com.android.tradefed.result.FailureDescription;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.util.CommandResult;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.IRunUtil;
import com.android.utils.FileUtils;
import com.google.common.truth.Truth;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.InOrder;
import org.mockito.Mockito;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/** Unit tests for {@link MoblyBinaryHostTest}. */
@RunWith(JUnit4.class)
public class MoblyBinaryHostTestTest {
private static final String BINARY_PATH = "/binary/file/path/test.par";
private static final String LOG_PATH = "/log/dir/abs/path";
private static final String DEVICE_SERIAL = "X123SER";
private static final String DEVICE_SERIAL_2 = "Y456SER";
private static final long DEFAULT_TIME_OUT = 30 * 1000L;
private static final String TEST_RESULT_FILE_NAME = "test_summary.yaml";
private MoblyBinaryHostTest mSpyTest;
private ITestDevice mMockDevice;
private ITestDevice mMockDevice2;
private IRunUtil mMockRunUtil;
private MoblyYamlResultParser mMockParser;
private InputStream mMockSummaryInputStream;
private File mMoblyTestDir;
private File mMoblyBinary; // used by mobly-binaries option
private File mMoblyBinary2; // used by mobly-par-file-name option
private File mVenvDir;
private DeviceBuildInfo mMockBuildInfo;
private TestInformation mTestInfo;
private Set<String> mIncludeFilters = new LinkedHashSet<>();
@Before
public void setUp() throws Exception {
mSpyTest = Mockito.spy(new MoblyBinaryHostTest());
mMockDevice = Mockito.mock(ITestDevice.class);
mMockRunUtil = Mockito.mock(IRunUtil.class);
mMockBuildInfo = Mockito.mock(DeviceBuildInfo.class);
IInvocationContext context = new InvocationContext();
context.addAllocatedDevice("device", mMockDevice);
context.addDeviceBuildInfo("device", mMockBuildInfo);
mTestInfo = Mockito.spy(TestInformation.newBuilder().setInvocationContext(context).build());
mSpyTest.setDevice(mMockDevice);
mVenvDir = FileUtil.createTempDir("venv");
new File(mVenvDir, "bin").mkdir();
Mockito.doReturn(Arrays.asList(mMockDevice)).when(mTestInfo).getDevices();
Mockito.doReturn(mTestInfo).when(mSpyTest).getTestInfo();
Mockito.doReturn(mMockRunUtil).when(mSpyTest).getRunUtil();
Mockito.doReturn(DEFAULT_TIME_OUT).when(mSpyTest).getTestTimeout();
Mockito.doReturn("not_adb").when(mSpyTest).getAdbPath();
mMoblyTestDir = FileUtil.createTempDir("mobly_tests");
mMoblyBinary = FileUtil.createTempFile("mobly_binary", ".par", mMoblyTestDir);
mMoblyBinary2 = FileUtil.createTempFile("mobly_binary_2", ".par", mMoblyTestDir);
}
@After
public void tearDown() throws Exception {
FileUtil.recursiveDelete(mMoblyTestDir);
FileUtil.recursiveDelete(mVenvDir);
// Delete log dir.
FileUtil.recursiveDelete(new File(mSpyTest.getLogDirAbsolutePath()));
}
@Test
public void testRun_withPythonBinariesOption() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
// Mimics the behavior of a successful test run.
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
verify(mSpyTest.getRunUtil(), times(2)).runTimedCmd(anyLong(), any());
assertNull(mSpyTest.getLogDirFile());
}
@Test
public void testRun_withPythonBinariesOption_binaryNotFound() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
FileUtil.deleteFile(mMoblyBinary);
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
verify(mSpyTest, never()).reportLogs(any(), any());
}
@Test
public void testRun_withParFileNameOption() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-par-file-name", mMoblyBinary2.getName());
Mockito.doReturn(mMoblyTestDir)
.when(mTestInfo)
.getDependencyFile(eq(mMoblyBinary2.getName()), eq(false));
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
verify(mSpyTest.getRunUtil(), times(2)).runTimedCmd(anyLong(), any());
assertNull(mSpyTest.getLogDirFile());
}
@Test
public void testRun_withParFileNameOption_binaryNotFound() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-par-file-name", mMoblyBinary2.getName());
Mockito.doThrow(new FileNotFoundException())
.when(mTestInfo)
.getDependencyFile(eq(mMoblyBinary2.getName()), eq(false));
FileUtil.deleteFile(mMoblyBinary2);
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mSpyTest, never()).reportLogs(any(), any());
verify(mockListener, times(1)).testRunStarted(eq(mMoblyBinary2.getName()), eq(0));
verify(mockListener, times(1)).testRunFailed(any(FailureDescription.class));
verify(mockListener, times(1)).testRunEnded(eq(0L), eq(new HashMap<String, Metric>()));
}
@Test
public void testRun_withStdLogOption() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-std-log", "true");
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
// Mimics the behavior of a successful test run.
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
});
Mockito.when(
mMockRunUtil.runTimedCmd(
anyLong(), any(OutputStream.class), any(OutputStream.class), any()))
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
}
@Test
public void testRun_testResultIsMissing() throws Exception {
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
// Test result and log files were not created for some reasons during test run.
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
assertFalse(testResult.exists());
}
@Test
public void testRun_shouldActivateVenvAndCleanUp_whenVenvIsSet() throws Exception {
Mockito.when(mMockBuildInfo.getFile(eq("VIRTUAL_ENV"))).thenReturn(mVenvDir);
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult result = new CommandResult(CommandStatus.SUCCESS);
result.setStdout(
"Name: pip\nLocation: "
+ new File(
mVenvDir.getAbsolutePath(),
"lib/python3.8/site-packages"));
return result;
})
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
CommandResult result = new CommandResult(CommandStatus.SUCCESS);
result.setStdout(
"Name: pip\nLocation: "
+ new File(mVenvDir.getAbsolutePath(), "lib/python3.8/site-packages"));
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), anyString(), eq("show"), eq("pip")))
.thenReturn(result);
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
verify(mSpyTest.getRunUtil(), times(3)).runTimedCmd(anyLong(), any());
verify(mSpyTest.getRunUtil(), times(1))
.setEnvVariable(eq("VIRTUAL_ENV"), eq(mVenvDir.getAbsolutePath()));
assertFalse(mVenvDir.exists());
}
@Test
public void testRun_shouldNotActivateVenv_whenVenvIsNotSet() throws Exception {
FileUtil.recursiveDelete(mVenvDir);
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
verify(mSpyTest.getRunUtil(), never())
.setEnvVariable(eq("VIRTUAL_ENV"), eq(mVenvDir.getAbsolutePath()));
}
@Test
public void testBuildCommandLineArrayWithOutConfig() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
List<String> expOptions = Arrays.asList("--option1", "--option2=test_option");
Mockito.doReturn(expOptions).when(mSpyTest).getTestOptions();
String[] cmdArray = mSpyTest.buildCommandLineArray(BINARY_PATH, null);
Truth.assertThat(cmdArray)
.isEqualTo(
new String[] {
BINARY_PATH,
"--",
"--device_serial=" + DEVICE_SERIAL,
"--log_path=" + LOG_PATH,
"--option1",
"--option2=test_option"
});
}
@Test
public void testBuildCommandLineArrayWithOutConfigWithWildcardOn() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-par-file-name", mMoblyBinary2.getName());
setter.setOptionValue("mobly-wildcard-config", "true");
Mockito.doReturn(mMoblyTestDir)
.when(mTestInfo)
.getDependencyFile(eq(mMoblyBinary2.getName()), eq(false));
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
// Verify the command line contains "--config"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="));
}
@Test
public void testRun_withoutTests() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-par-file-name", mMoblyBinary2.getName());
Mockito.doReturn(mMoblyTestDir)
.when(mTestInfo)
.getDependencyFile(eq(mMoblyBinary2.getName()), eq(false));
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout(""); // No tests.
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
// Verify no tests where run.
verify(mSpyTest.getRunUtil()).runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
}
@Test
public void testRun_withoutFilters() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-par-file-name", mMoblyBinary2.getName());
Mockito.doReturn(mMoblyTestDir)
.when(mTestInfo)
.getDependencyFile(eq(mMoblyBinary2.getName()), eq(false));
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
mSpyTest.run(mTestInfo, Mockito.mock(ITestInvocationListener.class));
// Verify the command line contains "--tests"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="));
}
@Test
public void testRun_withInvalidIncludeFilters() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addIncludeFilter("test_bar");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(0));
verify(mockListener, times(1)).testRunFailed(any(FailureDescription.class));
verify(mockListener, times(1)).testRunEnded(eq(0L), eq(new HashMap<String, Metric>()));
}
@Test
public void testRun_withInvalidExcludeFilters() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addExcludeFilter("test_bar");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(0));
}
@Test
public void testRun_withInvalidExcludeFiltersPrefix() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addExcludeFilter("test_f");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(0));
}
@Test
public void testRun_withIncludeFiltersExact() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addIncludeFilter("test_bar");
mSpyTest.addIncludeFilter("test_foo");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo\ntest_baz\ntest_bar");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(2));
// Verify the command line contains "--tests"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="),
eq("--tests"),
eq("test_foo"),
eq("test_bar"));
}
@Test
public void testRun_withPrefixIncludeFiltersPrefix() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addIncludeFilter("test_b");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo\ntest_baz\ntest_bar");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(2));
// Verify the command line contains "--tests"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="),
eq("--tests"),
eq("test_baz"),
eq("test_bar"));
}
@Test
public void testRun_withExcludeFiltersExact() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addExcludeFilter("test_bar");
mSpyTest.addExcludeFilter("test_foo");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo\ntest_baz\ntest_bar");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(1));
// Verify the command line contains "--tests"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="),
eq("--tests"),
eq("test_baz"));
}
@Test
public void testRun_withExcludeFiltersNoTests() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addExcludeFilter("test_bar");
mSpyTest.addExcludeFilter("test_baz");
mSpyTest.addExcludeFilter("test_foo");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo\ntest_baz\ntest_bar");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(0));
}
@Test
public void testRun_withBothIncludeAndExcludeFilters() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
OptionSetter setter = new OptionSetter(mSpyTest);
setter.setOptionValue("mobly-binaries", mMoblyBinary.getAbsolutePath());
File testResult = new File(mSpyTest.getLogDirAbsolutePath(), TEST_RESULT_FILE_NAME);
mSpyTest.addIncludeFilter("test_b");
mSpyTest.addExcludeFilter("test_bar");
Mockito.when(mMockRunUtil.runTimedCmd(anyLong(), any()))
.thenAnswer(
invocation -> {
CommandResult res = new CommandResult(CommandStatus.SUCCESS);
res.setStdout("test_foo\ntest_baz\ntest_bar");
return res;
})
.thenAnswer(
invocation -> {
FileUtils.createFile(testResult, "");
FileUtils.createFile(
new File(mSpyTest.getLogDirAbsolutePath(), "log"),
"log content");
return new CommandResult(CommandStatus.SUCCESS);
});
ITestInvocationListener mockListener = Mockito.mock(ITestInvocationListener.class);
mSpyTest.run(mTestInfo, mockListener);
verify(mockListener, times(1)).testRunStarted(anyString(), eq(1));
// Verify the command line contains "--tests"
InOrder inOrder = inOrder(mSpyTest.getRunUtil());
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(anyLong(), any(), eq("--"), eq("--list_tests"));
inOrder.verify(mSpyTest.getRunUtil())
.runTimedCmd(
anyLong(),
any(),
eq("--"),
contains("--config="),
contains("--device_serial="),
contains("--log_path="),
eq("--tests"),
eq("test_baz"));
}
@Test
public void testBuildCommandLineArrayWithConfig() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
List<String> expOptions = Arrays.asList("--option1", "--option2=test_option");
Mockito.doReturn(expOptions).when(mSpyTest).getTestOptions();
String[] cmdArray = mSpyTest.buildCommandLineArray(BINARY_PATH, "path");
Truth.assertThat(cmdArray)
.isEqualTo(
new String[] {
BINARY_PATH,
"--",
"--config=path",
"--device_serial=" + DEVICE_SERIAL,
"--log_path=" + LOG_PATH,
"--option1",
"--option2=test_option"
});
}
@Test
public void testBuildCommandLineArrayWithIncludeFilter() throws Exception {
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
mIncludeFilters.addAll(
Arrays.asList("ExampleTest#test_print_addresses", "ExampleTest#test_le_connect"));
mSpyTest.addAllIncludeFilters(mIncludeFilters);
String[] cmdArray = mSpyTest.buildCommandLineArray(BINARY_PATH, "path");
Truth.assertThat(cmdArray)
.isEqualTo(
new String[] {
BINARY_PATH,
"--",
"--config=path",
"--device_serial=" + DEVICE_SERIAL,
"--log_path=" + LOG_PATH,
"--tests",
"ExampleTest.test_print_addresses",
"ExampleTest.test_le_connect"
});
}
@Test
public void testProcessYamlTestResultsSuccess() throws Exception {
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
mMockSummaryInputStream = Mockito.mock(InputStream.class);
mMockParser = Mockito.mock(MoblyYamlResultParser.class);
mSpyTest.processYamlTestResults(
mMockSummaryInputStream,
mMockParser,
Mockito.mock(ITestInvocationListener.class),
"runName");
verify(mMockParser, times(1)).parse(mMockSummaryInputStream);
}
@Test
public void testUpdateConfigFile() throws Exception {
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
Mockito.doReturn("testBedName").when(mSpyTest).getTestBed();
String configString =
new StringBuilder()
.append("TestBeds:")
.append("\n")
.append("- TestParams:")
.append("\n")
.append(" dut_name: is_dut")
.append("\n")
.append(" Name: testBedName")
.append("\n")
.append(" Controllers:")
.append("\n")
.append(" AndroidDevice:")
.append("\n")
.append(" - dimensions: {mobile_type: 'dut_rear'}")
.append("\n")
.append(" serial: old123")
.append("\n")
.append("MoblyParams: {{LogPath: {log_path}}}")
.append("\n")
.toString();
InputStream inputStream = new ByteArrayInputStream(configString.getBytes());
Writer writer = new StringWriter();
mSpyTest.updateConfigFile(inputStream, writer);
String updatedConfigString = writer.toString();
LogUtil.CLog.d("Updated config string: %s", updatedConfigString);
// Check if serial injected.
assertThat(updatedConfigString).contains(DEVICE_SERIAL);
// Check if original still exists.
assertThat(updatedConfigString).contains("mobile_type");
// Check if log path is injected.
assertThat(updatedConfigString).contains(LOG_PATH);
}
@Test
public void testUpdateConfigFileMultidevice() throws Exception {
mMockDevice2 = Mockito.mock(ITestDevice.class);
Mockito.doReturn(Arrays.asList(mMockDevice, mMockDevice2)).when(mTestInfo).getDevices();
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(DEVICE_SERIAL_2).when(mMockDevice2).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
Mockito.doReturn("testBedName").when(mSpyTest).getTestBed();
String configString =
new StringBuilder()
.append("TestBeds:")
.append("\n")
.append("- TestParams:")
.append("\n")
.append(" dut_name: is_dut")
.append("\n")
.append(" Name: testBedName")
.append("\n")
.append(" Controllers:")
.append("\n")
.append(" AndroidDevice:")
.append("\n")
.append(" - dimensions: {mobile_type: 'dut_rear'}")
.append("\n")
.append(" serial: old123")
.append("\n")
.append(" - dimensions: {mobile_type: 'dut_rear'}")
.append("\n")
.append(" serial: old456")
.append("\n")
.append("MoblyParams: {{LogPath: {log_path}}}")
.append("\n")
.toString();
InputStream inputStream = new ByteArrayInputStream(configString.getBytes());
Writer writer = new StringWriter();
mSpyTest.updateConfigFile(inputStream, writer);
String updatedConfigString = writer.toString();
LogUtil.CLog.d("Updated config string: %s", updatedConfigString);
// Check if serials are injected.
assertThat(updatedConfigString).contains(DEVICE_SERIAL);
assertThat(updatedConfigString).contains(DEVICE_SERIAL_2);
// Check if original still exists.
assertThat(updatedConfigString).contains("mobile_type");
// Check if log path is injected.
assertThat(updatedConfigString).contains(LOG_PATH);
}
@Test
public void testUpdateConfigFileDetectDevice() throws Exception {
mMockDevice2 = Mockito.mock(ITestDevice.class);
Mockito.doReturn(Arrays.asList(mMockDevice, mMockDevice2)).when(mTestInfo).getDevices();
Mockito.doReturn(DEVICE_SERIAL).when(mMockDevice).getSerialNumber();
Mockito.doReturn(DEVICE_SERIAL_2).when(mMockDevice2).getSerialNumber();
Mockito.doReturn(LOG_PATH).when(mSpyTest).getLogDirAbsolutePath();
Mockito.doNothing().when(mSpyTest).reportLogs(any(), any());
Mockito.doReturn("testBedName").when(mSpyTest).getTestBed();
String configString =
new StringBuilder()
.append("TestBeds:")
.append("\n")
.append("- TestParams:")
.append("\n")
.append(" dut_name: is_dut")
.append("\n")
.append(" Name: testBedName")
.append("\n")
.append(" Controllers:")
.append("\n")
.append(" AndroidDevice: '*'")
.append("\n")
.toString();
InputStream inputStream = new ByteArrayInputStream(configString.getBytes());
Writer writer = new StringWriter();
mSpyTest.updateConfigFile(inputStream, writer);
String updatedConfigString = writer.toString();
LogUtil.CLog.d("Updated config string: %s", updatedConfigString);
// Check if serials are injected.
assertThat(updatedConfigString).contains(DEVICE_SERIAL);
assertThat(updatedConfigString).contains(DEVICE_SERIAL_2);
// Check if original still exists.
assertThat(updatedConfigString).contains(LOG_PATH);
}
}