Skip to content

Commit

Permalink
[Refactor] Rename DeviceTestTask to TestRun (#223)
Browse files Browse the repository at this point in the history
* Rename DeviceTestTask to TestRun

* Rename all

Co-authored-by: shbu <[email protected]>
  • Loading branch information
hydraxman and shbu authored Jan 11, 2023
1 parent 4c3c7f9 commit 05069f6
Show file tree
Hide file tree
Showing 33 changed files with 373 additions and 376 deletions.
2 changes: 1 addition & 1 deletion TrickyDesign.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ com.microsoft.hydralab.agent.runner.smart.SmartTestLog
We'd better create a new POJO to wrap the info.
Related references:
- com.microsoft.hydralab.agent.runner.espresso.testStarted
- com.microsoft.hydralab.common.entity.common.DeviceTestTask.addNewTimeTag
- com.microsoft.hydralab.common.entity.common.TestRun.addNewTimeTag
- com.microsoft.hydralab.center.controller.TestDetailController.deviceTaskInfo
- react/src/component/VideoNavView.jsx:110
6 changes: 3 additions & 3 deletions agent/doc/UML/logger_file_design.puml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ note top of DeviceLogger
deviceLogBaseDir/device.getName()/device_control.log
end note

object DeviceTestTaskLogger
note bottom of DeviceTestTaskLogger
object TestRunLogger
note bottom of TestRunLogger
DeviceTestResultFolder/loggerNamePrefix_dateInfo.log
end note

DeviceTestTaskLogger -u-|> DeviceLogger
TestRunLogger -u-|> DeviceLogger
@enduml

@startuml loggers
Expand Down
8 changes: 4 additions & 4 deletions agent/doc/UML/test_runner_design.puml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@startuml test_runners_classes
abstract class TestRunner {
#buildDeviceTestTask(...)
#createTestRun(...)
#setUp(TestTask)
#run(TestTaskSpec)
#tearDown(...)
Expand Down Expand Up @@ -132,13 +132,13 @@ Runner *--> TestRunnerListener

entity (TestTaskSpec)
entity (TestTask)
entity (DeviceTestTask)
entity (TestRun)
entity (AndroidTestUnit)


TestTaskSpec -- TestTask: is mapped to
TestTask *--> DeviceTestTask: contain a list of
DeviceTestTask *--> AndroidTestUnit: contain a list of
TestTask *--> TestRun: contain a list of
TestRun *--> AndroidTestUnit: contain a list of
@enduml

@startuml test_objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import cn.hutool.core.lang.Assert;
import com.microsoft.hydralab.common.entity.common.DeviceAction;
import com.microsoft.hydralab.common.entity.common.DeviceInfo;
import com.microsoft.hydralab.common.entity.common.DeviceTestTask;
import com.microsoft.hydralab.common.entity.common.TestRun;
import com.microsoft.hydralab.common.entity.common.TestTask;
import com.microsoft.hydralab.common.management.DeviceManager;
import com.microsoft.hydralab.common.management.impl.IOSDeviceManager;
Expand Down Expand Up @@ -40,24 +40,24 @@ public void runTestOnDevice(TestTask testTask, DeviceInfo deviceInfo, Logger log
checkTestTaskCancel(testTask);
logger.info("Start running tests {}, timeout {}s", testTask.getTestSuite(), testTask.getTimeOutSecond());

DeviceTestTask deviceTestTask = buildDeviceTestTask(deviceInfo, testTask, logger);
TestRun testRun = createTestRun(deviceInfo, testTask, logger);
checkTestTaskCancel(testTask);

setUp(deviceInfo, testTask, deviceTestTask);
setUp(deviceInfo, testTask, testRun);
checkTestTaskCancel(testTask);
try {
runByFutureTask(deviceInfo, testTask, deviceTestTask);
runByFutureTask(deviceInfo, testTask, testRun);
} catch (Exception e) {
deviceTestTask.getLogger().error(deviceInfo.getSerialNum() + ": " + e.getMessage(), e);
saveErrorSummary(deviceTestTask, e);
testRun.getLogger().error(deviceInfo.getSerialNum() + ": " + e.getMessage(), e);
saveErrorSummary(testRun, e);
} finally {
tearDown(deviceInfo, testTask, deviceTestTask);
tearDown(deviceInfo, testTask, testRun);
}
}

private void runByFutureTask(DeviceInfo deviceInfo, TestTask testTask, DeviceTestTask deviceTestTask) throws Exception {
private void runByFutureTask(DeviceInfo deviceInfo, TestTask testTask, TestRun testRun) throws Exception {
FutureTask<String> futureTask = new FutureTask<>(() -> {
run(deviceInfo, testTask, deviceTestTask);
run(deviceInfo, testTask, testRun);
return null;
});
ThreadPoolUtil.TEST_EXECUTOR.execute(futureTask);
Expand All @@ -74,90 +74,90 @@ private void runByFutureTask(DeviceInfo deviceInfo, TestTask testTask, DeviceTes
}
}

private static void saveErrorSummary(DeviceTestTask deviceTestTask, Exception e) {
private static void saveErrorSummary(TestRun testRun, Exception e) {
String errorStr = e.getClass().getName() + ": " + e.getMessage();
if (errorStr.length() > 255) {
errorStr = errorStr.substring(0, 254);
}
deviceTestTask.setErrorInProcess(errorStr);
testRun.setErrorInProcess(errorStr);
}

protected void checkTestTaskCancel(TestTask testTask) {
Assert.isFalse(testTask.isCanceled(), "Task {} is canceled", testTask.getId());
}

protected DeviceTestTask buildDeviceTestTask(DeviceInfo deviceInfo, TestTask testTask, Logger parentLogger) {
DeviceTestTask deviceTestTask = new DeviceTestTask(deviceInfo.getSerialNum(), deviceInfo.getName(), testTask.getId());
File deviceTestResultFolder = new File(testTask.getResourceDir(), deviceInfo.getSerialNum());
parentLogger.info("DeviceTestResultFolder {}", deviceTestResultFolder);
if (!deviceTestResultFolder.exists()) {
if (!deviceTestResultFolder.mkdirs()) {
throw new RuntimeException("deviceTestResultFolder.mkdirs() failed: " + deviceTestResultFolder);
protected TestRun createTestRun(DeviceInfo deviceInfo, TestTask testTask, Logger parentLogger) {
TestRun testRun = new TestRun(deviceInfo.getSerialNum(), deviceInfo.getName(), testTask.getId());
File testRunResultFolder = new File(testTask.getResourceDir(), deviceInfo.getSerialNum());
parentLogger.info("DeviceTestResultFolder {}", testRunResultFolder);
if (!testRunResultFolder.exists()) {
if (!testRunResultFolder.mkdirs()) {
throw new RuntimeException("testRunResultFolder.mkdirs() failed: " + testRunResultFolder);
}
}

deviceTestTask.setDeviceTestResultFolder(deviceTestResultFolder);
Logger loggerForDeviceTestTask = createLoggerForDeviceTestTask(deviceTestTask, testTask.getTestSuite(), parentLogger);
deviceTestTask.setLogger(loggerForDeviceTestTask);
testTask.addTestedDeviceResult(deviceTestTask);
return deviceTestTask;
testRun.setResultFolder(testRunResultFolder);
Logger loggerForTestRun = createLoggerForTestRun(testRun, testTask.getTestSuite(), parentLogger);
testRun.setLogger(loggerForTestRun);
testTask.addTestedDeviceResult(testRun);
return testRun;
}

protected void setUp(DeviceInfo deviceInfo, TestTask testTask, DeviceTestTask deviceTestTask) throws Exception {
protected void setUp(DeviceInfo deviceInfo, TestTask testTask, TestRun testRun) throws Exception {
deviceInfo.killAll();
// this key will be used to recover device status when lost the connection between agent and master
deviceInfo.addCurrentTask(testTask);

/* set up device */
deviceTestTask.getLogger().info("Start setup device");
deviceManager.testDeviceSetup(deviceInfo, deviceTestTask.getLogger());
deviceManager.wakeUpDevice(deviceInfo, deviceTestTask.getLogger());
testRun.getLogger().info("Start setup device");
deviceManager.testDeviceSetup(deviceInfo, testRun.getLogger());
deviceManager.wakeUpDevice(deviceInfo, testRun.getLogger());
ThreadUtils.safeSleep(1000);
checkTestTaskCancel(testTask);
reInstallApp(deviceInfo, testTask, deviceTestTask.getLogger());
reInstallTestApp(deviceInfo, testTask, deviceTestTask.getLogger());
reInstallApp(deviceInfo, testTask, testRun.getLogger());
reInstallTestApp(deviceInfo, testTask, testRun.getLogger());

if (testTask.isThisForMicrosoftLauncher()) {
presetForMicrosoftLauncherApp(deviceInfo, testTask, deviceTestTask.getLogger());
presetForMicrosoftLauncherApp(deviceInfo, testTask, testRun.getLogger());
}
//execute actions
if (testTask.getDeviceActions() != null) {
deviceTestTask.getLogger().info("Start executing setUp actions.");
actionExecutor.doActions(deviceManager, deviceInfo, deviceTestTask.getLogger(), testTask.getDeviceActions(), DeviceAction.When.SET_UP);
testRun.getLogger().info("Start executing setUp actions.");
actionExecutor.doActions(deviceManager, deviceInfo, testRun.getLogger(), testTask.getDeviceActions(), DeviceAction.When.SET_UP);
}

deviceTestTask.getLogger().info("Start granting all package needed permissions device");
deviceManager.grantAllTaskNeededPermissions(deviceInfo, testTask, deviceTestTask.getLogger());
testRun.getLogger().info("Start granting all package needed permissions device");
deviceManager.grantAllTaskNeededPermissions(deviceInfo, testTask, testRun.getLogger());

checkTestTaskCancel(testTask);
deviceManager.getScreenShot(deviceInfo, deviceTestTask.getLogger());
deviceManager.getScreenShot(deviceInfo, testRun.getLogger());
}

protected abstract void run(DeviceInfo deviceInfo, TestTask testTask, DeviceTestTask deviceTestTask) throws Exception;
protected abstract void run(DeviceInfo deviceInfo, TestTask testTask, TestRun testRun) throws Exception;

protected void tearDown(DeviceInfo deviceInfo, TestTask testTask, DeviceTestTask deviceTestTask) {
protected void tearDown(DeviceInfo deviceInfo, TestTask testTask, TestRun testRun) {
try {
String absoluteReportPath = xmlBuilder.buildTestResultXml(testTask, deviceTestTask);
deviceTestTask.setTestXmlReportPath(deviceManager.getTestBaseRelPathInUrl(new File(absoluteReportPath)));
String absoluteReportPath = xmlBuilder.buildTestResultXml(testTask, testRun);
testRun.setTestXmlReportPath(deviceManager.getTestBaseRelPathInUrl(new File(absoluteReportPath)));
} catch (Exception e) {
deviceTestTask.getLogger().error("Error in buildTestResultXml", e);
testRun.getLogger().error("Error in buildTestResultXml", e);
}
if (testTaskRunCallback != null) {
try {
testTaskRunCallback.onOneDeviceComplete(testTask, deviceInfo, deviceTestTask.getLogger(), deviceTestTask);
testTaskRunCallback.onOneDeviceComplete(testTask, deviceInfo, testRun.getLogger(), testRun);
} catch (Exception e) {
deviceTestTask.getLogger().error("Error in onOneDeviceComplete", e);
testRun.getLogger().error("Error in onOneDeviceComplete", e);
}
}
deviceManager.testDeviceUnset(deviceInfo, deviceTestTask.getLogger());
deviceManager.testDeviceUnset(deviceInfo, testRun.getLogger());
//execute actions
if (testTask.getDeviceActions() != null) {
deviceTestTask.getLogger().info("Start executing tearDown actions.");
actionExecutor.doActions(deviceManager, deviceInfo, deviceTestTask.getLogger(), testTask.getDeviceActions(), DeviceAction.When.TEAR_DOWN);
testRun.getLogger().info("Start executing tearDown actions.");
actionExecutor.doActions(deviceManager, deviceInfo, testRun.getLogger(), testTask.getDeviceActions(), DeviceAction.When.TEAR_DOWN);
}

deviceTestTask.getLogger().info("Start Close/finish resource");
LogUtils.releaseLogger(deviceTestTask.getLogger());
testRun.getLogger().info("Start Close/finish resource");
LogUtils.releaseLogger(testRun.getLogger());
}

private void presetForMicrosoftLauncherApp(DeviceInfo deviceInfo, TestTask testTask, Logger reportLogger) {
Expand Down Expand Up @@ -216,15 +216,15 @@ protected boolean shouldInstallTestPackageAsApp() {
return false;
}

private Logger createLoggerForDeviceTestTask(DeviceTestTask deviceTestTask, String loggerNamePrefix, Logger parentLogger) {
private Logger createLoggerForTestRun(TestRun testRun, String loggerNamePrefix, Logger parentLogger) {
parentLogger.info("Start setup report child parentLogger");
String dateInfo = DateUtil.fileNameDateFormat.format(new Date());
File instrumentLogFile = new File(deviceTestTask.getDeviceTestResultFolder(), loggerNamePrefix + "_" + dateInfo + ".log");
File instrumentLogFile = new File(testRun.getResultFolder(), loggerNamePrefix + "_" + dateInfo + ".log");
// make sure it's a child logger of the parentLogger
String loggerName = parentLogger.getName() + ".test." + dateInfo;
Logger reportLogger = LogUtils.getLoggerWithRollingFileAppender(loggerName, instrumentLogFile.getAbsolutePath(), "%d %p -- %m%n");
// TODO the getTestBaseRelPathInUrl method shouldn't be in deviceManager, testBaseDir should be managed by agent
deviceTestTask.setInstrumentReportPath(deviceManager.getTestBaseRelPathInUrl(instrumentLogFile));
testRun.setInstrumentReportPath(deviceManager.getTestBaseRelPathInUrl(instrumentLogFile));

return reportLogger;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
package com.microsoft.hydralab.agent.runner;

import com.microsoft.hydralab.common.entity.common.DeviceInfo;
import com.microsoft.hydralab.common.entity.common.DeviceTestTask;
import com.microsoft.hydralab.common.entity.common.TestRun;
import com.microsoft.hydralab.common.entity.common.TestTask;
import org.slf4j.Logger;

public interface TestTaskRunCallback {
void onTaskStart(TestTask testTask);
void onTaskComplete(TestTask testTask);

void onOneDeviceComplete(TestTask testTask, DeviceInfo deviceControl, Logger logger, DeviceTestTask result);
void onOneDeviceComplete(TestTask testTask, DeviceInfo deviceControl, Logger logger, TestRun result);

void onDeviceOffline(TestTask testTask);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package com.microsoft.hydralab.agent.runner;

import com.microsoft.hydralab.common.entity.common.AndroidTestUnit;
import com.microsoft.hydralab.common.entity.common.DeviceTestTask;
import com.microsoft.hydralab.common.entity.common.TestRun;
import com.microsoft.hydralab.common.entity.common.TestTask;
import com.microsoft.hydralab.common.util.DateUtil;
import org.w3c.dom.Document;
Expand Down Expand Up @@ -45,35 +45,35 @@ public class XmlBuilder {
private static final String TIMESTAMP = "timestamp";
private static final String HOSTNAME = "hostname";

public String buildTestResultXml(TestTask testTask, DeviceTestTask deviceTestTask) throws Exception {
public String buildTestResultXml(TestTask testTask, TestRun testRun) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document document = db.newDocument();
Element testSuite = buildTestSuite(document, testTask, deviceTestTask);
Element testSuite = buildTestSuite(document, testTask, testRun);
document.appendChild(testSuite);

File xmlFile = File.createTempFile(TEST_RESULT_FILE_PREFIX, TEST_RESULT_FILE_SUFFIX, deviceTestTask.getDeviceTestResultFolder());
File xmlFile = File.createTempFile(TEST_RESULT_FILE_PREFIX, TEST_RESULT_FILE_SUFFIX, testRun.getResultFolder());
transferToFile(document, xmlFile);
return xmlFile.getAbsolutePath();
}

private Element buildTestSuite(Document document, TestTask testTask, DeviceTestTask deviceTestTask) throws UnknownHostException {
private Element buildTestSuite(Document document, TestTask testTask, TestRun testRun) throws UnknownHostException {
Element testSuite = document.createElement(TESTSUITE);

testSuite.setAttribute(ATTR_NAME, testTask.getTestSuite());
testSuite.setAttribute(ATTR_TESTS, String.valueOf(deviceTestTask.getTotalCount()));
testSuite.setAttribute(ATTR_FAILURES, String.valueOf(deviceTestTask.getFailCount()));
testSuite.setAttribute(ATTR_TIME, Double.toString((double) (deviceTestTask.getTestEndTimeMillis() - deviceTestTask.getTestStartTimeMillis()) / 1000.f));
testSuite.setAttribute(TIMESTAMP, DateUtil.appCenterFormat2.format(DateUtil.localToUTC(new Date(deviceTestTask.getTestStartTimeMillis()))));
testSuite.setAttribute(ATTR_TESTS, String.valueOf(testRun.getTotalCount()));
testSuite.setAttribute(ATTR_FAILURES, String.valueOf(testRun.getFailCount()));
testSuite.setAttribute(ATTR_TIME, Double.toString((double) (testRun.getTestEndTimeMillis() - testRun.getTestStartTimeMillis()) / 1000.f));
testSuite.setAttribute(TIMESTAMP, DateUtil.appCenterFormat2.format(DateUtil.localToUTC(new Date(testRun.getTestStartTimeMillis()))));
testSuite.setAttribute(HOSTNAME, InetAddress.getLocalHost().getHostName());
if (deviceTestTask.getTestUnitList() != null) {
testSuite.setAttribute(ATTR_SKIPPED, String.valueOf(deviceTestTask.getTotalCount() - deviceTestTask.getTestUnitList().size()));
for (AndroidTestUnit unitTest : deviceTestTask.getTestUnitList()) {
if (testRun.getTestUnitList() != null) {
testSuite.setAttribute(ATTR_SKIPPED, String.valueOf(testRun.getTotalCount() - testRun.getTestUnitList().size()));
for (AndroidTestUnit unitTest : testRun.getTestUnitList()) {
Element testCase = buildTestCase(document, unitTest);
testSuite.appendChild(testCase);
}
} else {
testSuite.setAttribute(ATTR_SKIPPED, String.valueOf(deviceTestTask.getTotalCount() - deviceTestTask.getFailCount()));
testSuite.setAttribute(ATTR_SKIPPED, String.valueOf(testRun.getTotalCount() - testRun.getFailCount()));
}
return testSuite;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import com.microsoft.hydralab.agent.runner.TestTaskRunCallback;
import com.microsoft.hydralab.common.entity.common.DeviceInfo;
import com.microsoft.hydralab.common.entity.common.DeviceTestTask;
import com.microsoft.hydralab.common.entity.common.TestRun;
import com.microsoft.hydralab.common.entity.common.TestTask;
import com.microsoft.hydralab.common.management.DeviceManager;
import org.slf4j.Logger;
Expand All @@ -18,10 +18,10 @@ public AppiumCrossRunner(DeviceManager deviceManager, TestTaskRunCallback testTa
}

@Override
protected DeviceTestTask buildDeviceTestTask(DeviceInfo deviceInfo, TestTask testTask, Logger parentLogger) {
DeviceTestTask deviceTestTask = super.buildDeviceTestTask(deviceInfo, testTask, parentLogger);
protected TestRun createTestRun(DeviceInfo deviceInfo, TestTask testTask, Logger parentLogger) {
TestRun testRun = super.createTestRun(deviceInfo, testTask, parentLogger);
String deviceName = System.getProperties().getProperty("os.name") + "-" + agentName + "-" + deviceInfo.getName();
deviceTestTask.setDeviceName(deviceName);
return deviceTestTask;
testRun.setDeviceName(deviceName);
return testRun;
}
}
Loading

0 comments on commit 05069f6

Please sign in to comment.