8000 Feature: Analysis Task - Scan APK file (#633) · microsoft/HydraLab@de01ff7 · GitHub
[go: up one dir, main page]

Skip to content

Commit de01ff7

Browse files
authored
Feature: Analysis Task - Scan APK file (#633)
<!-- Please provide brief information about the PR, what it contains & its purpose, new behaviors after the change. And let us know here if you need any help: https://github.com/microsoft/HydraLab/issues/new --> ## Description <!-- A few words to explain your changes --> ### Linked GitHub issue ID: # ## Pull Request Checklist <!-- Put an x in the boxes that apply. This is simply a reminder of what we are going to look for before merging your code. --> - [ ] Tests for the changes have been added (for bug fixes / features) - [x] Code compiles correctly with all tests are passed. - [x] I've read the [contributing guide](https://github.com/microsoft/HydraLab/blob/main/CONTRIBUTING.md#making-changes-to-the-code) and followed the recommended practices. - [ ] [Wikis](https://github.com/microsoft/HydraLab/wiki) or [README](https://github.com/microsoft/HydraLab/blob/main/README.md) have been reviewed and added / updated if needed (for bug fixes / features) ### Does this introduce a breaking change? *If this introduces a breaking change for Hydra Lab users, please describe the impact and migration path.* - [x] Yes - [ ] No ## How you tested it *Please make sure the change is tested, you can test it by adding UTs, do local test and share the screenshots, etc.* Please check the type of change your PR introduces: - [ ] Bugfix - [x] Feature - [ ] Technical design - [ ] Build related changes - [ ] Refactoring (no functional changes, no api changes) - [ ] Code style update (formatting, renaming) or Documentation content changes - [ ] Other (please describe): ### Feature UI screenshots or Technical design diagrams *If this is a relatively large or complex change, kick it off by drawing the tech design with PlantUML and explaining why you chose the solution you did and what alternatives you considered, etc...* ![image](https://github.com/microsoft/HydraLab/assets/26757995/5200c25f-b3a8-4ca7-b8c7-96d275cd5f79) ![image](https://github.com/microsoft/HydraLab/assets/26757995/54e00981-d639-4295-8a49-427e538e49c1) ![image](https://github.com/microsoft/HydraLab/assets/26757995/62c515d1-d4d9-453d-9216-3949a3ff1cdc)
1 parent d787a31 commit de01ff7

File tree

65 files changed

+2760
-991
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2760
-991
lines changed

agent/src/main/java/com/microsoft/hydralab/agent/command/DeviceScriptCommandLoader.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
package com.microsoft.hydralab.agent.command;
55

66
import com.microsoft.hydralab.common.entity.common.DeviceAction;
7-
import com.microsoft.hydralab.common.entity.common.TestTask;
7+
import com.microsoft.hydralab.common.entity.common.Task;
88
import com.microsoft.hydralab.common.util.Const;
99
import org.springframework.stereotype.Service;
1010
import org.springframework.util.StringUtils;
@@ -24,17 +24,17 @@ public class DeviceScriptCommandLoader {
2424
@Resource(name = "DeviceCommandProperty")
2525
private List<DeviceScriptCommand> commands;
2626

27-
public void loadCommandAction(TestTask testTask) {
28-
if (testTask.getDeviceActions() == null) {
29-
testTask.setDeviceActions(new HashMap<>());
27+
public void loadCommandAction(Task task) {
28+
if (task.getDeviceActions() == null) {
29+
task.setDeviceActions(new HashMap<>());
3030
}
31-
List<DeviceScriptCommand> filteredCommands = filterCommands(testTask.getTestSuite());
31+
List<DeviceScriptCommand> filteredCommands = filterCommands(task.getTaskAlias());
3232
for (DeviceScriptCommand deviceCommand : filteredCommands) {
3333
List<DeviceAction> actions = command2Action(deviceCommand);
3434
List<DeviceAction> originActions =
35-
testTask.getDeviceActions().getOrDefault(deviceCommand.getWhen(), new ArrayList<>());
35+
task.getDeviceActions().getOrDefault(deviceCommand.getWhen(), new ArrayList<>());
3636
originActions.addAll(actions);
37-
testTask.getDeviceActions().put(deviceCommand.getWhen(), originActions);
37+
task.getDeviceActions().put(deviceCommand.getWhen(), originActions);
3838
}
3939
}
4040

agent/src/main/java/com/microsoft/hydralab/agent/config/AppConfiguration.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,7 @@ public AgentManagementService agentManagementService(StorageServiceClientProxy s
143143

144144
// TODO: refactor test runner to remove DependsOn
145145
@Bean
146-
@DependsOn({"espressoRunner",
147-
"appiumRunner",
148-
"appiumCrossRunner",
149-
"smartRunner",
150-
"adbMonkeyRunner",
151-
"appiumMonkeyRunner",
152-
"t2cRunner",
153-
"xctestRunner",
154-
"maestroRunner",
155-
"pythonRunner"})
146+
@DependsOn({"testRunnerManager"})
156147
public AgentWebSocketClient agentWebSocketClient(AgentWebSocketClientService agentWebSocketClientService)
157148
throws Exception {
158149
String wsUrl = String.format("%s://%s/agent/ D868 connect", registrySchema, registryServer);

agent/src/main/java/com/microsoft/hydralab/agent/config/TestRunnerConfig.java

Lines changed: 48 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import com.microsoft.hydralab.agent.command.DeviceScriptCommand;
77
import com.microsoft.hydralab.agent.runner.TestRunDeviceOrchestrator;
8+
import com.microsoft.hydralab.agent.runner.TestRunnerManager;
9+
import com.microsoft.hydralab.agent.runner.analysis.scanner.APKScanner;
810
import com.microsoft.hydralab.agent.runner.appium.AppiumCrossRunner;
911
import com.microsoft.hydralab.agent.runner.appium.AppiumRunner;
1012
import com.microsoft.hydralab.agent.runner.espresso.EspressoRunner;
@@ -18,7 +20,7 @@
1820
import com.microsoft.hydralab.agent.runner.xctest.XCTestRunner;
1921
import com.microsoft.hydralab.agent.service.TestTaskEngineService;
2022
import com.microsoft.hydralab.common.entity.agent.LLMProperties;
21-
import com.microsoft.hydralab.common.entity.common.TestTask;
23+
import com.microsoft.hydralab.common.entity.common.Task;
2224
import com.microsoft.hydralab.common.management.AgentManagementService;
2325
import com.microsoft.hydralab.common.util.ADBOperateUtil;
2426
import com.microsoft.hydralab.performance.PerformanceTestManagementService;
@@ -29,121 +31,74 @@
2931

3032
import java.util.ArrayList;
3133
import java.util.List;
32-
import java.util.Map;
3334

3435
@Configuration
3536
public class TestRunnerConfig {
3637
@Value("${app.registry.name}")
3738
String agentName;
38-
@SuppressWarnings("visibilitymodifier")
39-
public static Map<String, String> testRunnerMap = Map.of(
40-
TestTask.TestRunningType.INSTRUMENTATION, "espressoRunner",
41-
TestTask.TestRunningType.APPIUM, "appiumRunner",
42-
TestTask.TestRunningType.APPIUM_CROSS, "appiumCrossRunner",
43-
TestTask.TestRunningType.SMART_TEST, "smartRunner",
44-
TestTask.TestRunningType.MONKEY_TEST, "adbMonkeyRunner",
45-
TestTask.TestRunningType.APPIUM_MONKEY_TEST, "appiumMonkeyRunner",
46-
TestTask.TestRunningType.T2C_JSON_TEST, "t2cRunner",
47-
TestTask.TestRunningType.XCTEST, "xctestRunner",
48-
TestTask.TestRunningType.MAESTRO, "maestroRunner",
49-
TestTask.TestRunningType.PYTHON, "pythonRunner"
50-
);
5139

52-
@Bean
53-
public PerformanceTestManagementService performanceTestManagementService() {
54-
PerformanceTestManagementService performanceTestManagementService = new PerformanceTestManagementService();
55-
performanceTestManagementService.initialize();
56-
return performanceTestManagementService;
57-
}
40+
@Value("${app.runner.analysis.enabled:false}")
41+
boolean isAnalysisEnabled;
5842

5943
@Bean
60-
public EspressoRunner espressoRunner(AgentManagementService agentManagementService,
61-
TestTaskEngineService testTaskEngineService,
62-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
63-
PerformanceTestManagementService performanceTestManagementService,
64-
ADBOperateUtil adbOperateUtil) {
65-
return new EspressoRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
66-
adbOperateUtil);
67-
}
44+
public TestRunnerManager testRunnerManager(AgentManagementService agentManagementService,
45+
TestTaskEngineService testTaskEngineService,
46+
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
47+
PerformanceTestManagementService performanceTestManagementService,
48+
ADBOperateUtil adbOperateUtil,
49+
SmartTestUtil smartTestUtil,
50+
LLMProperties llmProperties) {
6851

69-
@Bean
70-
public AdbMonkeyRunner adbMonkeyRunner(AgentManagementService agentManagementService,
71-
TestTaskEngineService testTaskEngineService,
72-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
73-
PerformanceTestManagementService performanceTestManagementService,
74-
ADBOperateUtil adbOperateUtil) {
75-
return new AdbMonkeyRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
76-
adbOperateUtil);
77-
}
52+
TestRunnerManager testRunnerManager = new TestRunnerManager();
7853

79-
@Bean
80-
public AppiumMonkeyRunner appiumMonkeyRunner(AgentManagementService agentManagementService,
81-
TestTaskEngineService testTaskEngineService,
82-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
83-
PerformanceTestManagementService performanceTestManagementService) {
84-
return new AppiumMonkeyRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator,
85-
performanceTestManagementService);
86-
}
54+
EspressoRunner espressoRunner = new EspressoRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
55+
adbOperateUtil);
56+
testRunnerManager.addRunEngine(Task.RunnerType.INSTRUMENTATION, espressoRunner);
8757

88-
@Bean
89-
public AppiumRunner appiumRunner(AgentManagementService agentManagementService,
90-
TestTaskEngineService testTaskEngineService,
91-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
92-
PerformanceTestManagementService performanceTestManagementService) {
93-
return new AppiumRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
94-
}
58+
AppiumRunner appiumRunner = new AppiumRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
59+
testRunnerManager.addRunEngine(Task.RunnerType.APPIUM, appiumRunner);
9560

96-
@Bean
97-
public AppiumCrossRunner appiumCrossRunner(AgentManagementService agentManagementService,
98-
TestTaskEngineService testTaskEngineService,
99-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
100-
PerformanceTestManagementService performanceTestManagementService) {
101-
return new AppiumCrossRunner(agentManagementService, testTaskEngineService,
61+
AppiumCrossRunner appiumCrossRunner = new AppiumCrossRunner(agentManagementService, testTaskEngineService,
10262
testRunDeviceOrchestrator, performanceTestManagementService,
10363
agentName);
104-
}
64+
testRunnerManager.addRunEngine(Task.RunnerType.APPIUM_CROSS, appiumCrossRunner);
10565

106-
@Bean
107-
public SmartRunner smartRunner(AgentManagementService agentManagementService,
108-
TestTaskEngineService testTaskEngineService,
109-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
110-
PerformanceTestManagementService performanceTestManagementService,
111-
SmartTestUtil smartTestUtil, LLMProperties llmProperties) {
112-
return new SmartRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
66+
SmartRunner smartRunner = new SmartRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
11367
smartTestUtil, llmProperties);
114-
}
68+
testRunnerManager.addRunEngine(Task.RunnerType.SMART, smartRunner);
11569

116-
@Bean
117-
public T2CRunner t2cRunner(AgentManagementService agentManagementService,
118-
TestTaskEngineService testTaskEngineService,
119-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
120-
PerformanceTestManagementService performanceTestManagementService) {
121-
return new T2CRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
70+
AdbMonkeyRunner adbMonkeyRunner = new AdbMonkeyRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
71+
adbOperateUtil);
72+
testRunnerManager.addRunEngine(Task.RunnerType.MONKEY, adbMonkeyRunner);
73+
74+
AppiumMonkeyRunner appiumMonkeyRunner = new AppiumMonkeyRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator,
75+
performanceTestManagementService);
76+
testRunnerManager.addRunEngine(Task.RunnerType.APPIUM_MONKEY, appiumMonkeyRunner);
77+
78+
T2CRunner t2cRunner = new T2CRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService,
12279
agentName);
123-
}
80+
testRunnerManager.addRunEngine(Task.RunnerType.T2C_JSON, t2cRunner);
12481

125-
@Bean
126-
public XCTestRunner xctestRunner(AgentManagementService agentManagementService,
127-
TestTaskEngineService testTaskEngineService,
128-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
129-
PerformanceTestManagementService performanceTestManagementService) {
130-
return new XCTestRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
131-
}
82+
XCTestRunner 8E66 xctestRunner = new XCTestRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
83+
testRunnerManager.addRunEngine(Task.RunnerType.XCTEST, xctestRunner);
13284

133-
@Bean
134-
public MaestroRunner maestroRunner(AgentManagementService agentManagementService,
135-
TestTaskEngineService testTaskEngineService,
136-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
137-
PerformanceTestManagementService performanceTestManagementService) {
138-
return new MaestroRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
85+
MaestroRunner maestroRunner = new MaestroRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
86+
testRunnerManager.addRunEngine(Task.RunnerType.MAESTRO, maestroRunner);
87+
88+
PythonRunner pythonRunner = new PythonRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
89+
testRunnerManager.addRunEngine(Task.RunnerType.PYTHON, pythonRunner);
90+
91+
APKScanner apkScanner = new APKScanner(agentManagementService, testTaskEngineService, isAnalysisEnabled);
92+
testRunnerManager.addRunEngine(Task.RunnerType.APK_SCANNER, apkScanner);
93+
94+
return testRunnerManager;
13995
}
14096

14197
@Bean
142-
public PythonRunner pythonRunner(AgentManagementService agentManagementService,
143-
TestTaskEngineService testTaskEngineService,
144-
TestRunDeviceOrchestrator testRunDeviceOrchestrator,
145-
PerformanceTestManagementService performanceTestManagementService) {
146-
return new PythonRunner(agentManagementService, testTaskEngineService, testRunDeviceOrchestrator, performanceTestManagementService);
98+
public PerformanceTestManagementService performanceTestManagementService() {
99+
PerformanceTestManagementService performanceTestManagementService = new PerformanceTestManagementService();
100+
performanceTestManagementService.initialize();
101+
return performanceTestManagementService;
147102
}
148103

149104
@ConfigurationProperties(prefix = "app.device-script.commands")

agent/src/main/java/com/microsoft/hydralab/agent/environment/EnvCapabilityScanner.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ void extractAndParseVersionOutput(EnvCapability capability) throws IOException {
115115
Matcher matcher = versionPattern.matcher(versionOutput);
116116
if (matcher.find()) {
117117
capability.setVersion(matcher.group());
118+
} else if (capability.getKeyword() == EnvCapability.CapabilityKeyword.apkanalyzer && versionOutput.contains("--human-readable")) {
119+
capability.setVersion("1.0.0");
118120
} else {
119121
LOGGER.warn("Failed to get version of " + capability.getKeyword().name() + " in " + versionOutput);
120122
}

agent/src/main/java/com/microsoft/hydralab/agent/runner/DeviceTaskControlExecutor.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,36 @@ public class DeviceTaskControlExecutor {
2626

2727
@Nullable
2828
public DeviceTaskControl runForAllDeviceAsync(Collection<TestRunDevice> allDevices, DeviceTask task,
29-
TaskCompletion taskCompletion) {
29+
TaskCompletion taskCompletion, boolean isAgentTask) {
3030
//the status of device will be controlled by master, so the task will run no matter what the status saved in agent is
31-
return runForAllDeviceAsync(allDevices, task, taskCompletion, true, true);
31+
return runForAllDeviceAsync(allDevices, task, taskCompletion, true, true, isAgentTask);
3232
}
3333

3434
public DeviceTaskControl runForAllDeviceAsync(Collection<TestRunDevice> allDevices, DeviceTask task,
3535
TaskCompletion taskCompletion, boolean logging,
36-
boolean forceForTesting) {
36+
boolean forceForTesting, boolean isAgentTask) {
37+
if (isAgentTask) {
38+
CountDownLatch count = new CountDownLatch(1);
39+
TestRunDevice fakeDevice = allDevices.iterator().next();
40+
Runnable run = () -> {
41+
try {
42+
if (logging) {
43+
DeviceTaskControlExecutor.log.info("start do task on a fake device");
44+
}
45+
task.doTask(fakeDevice);
46+
} catch (Exception e) {
47+
DeviceTaskControlExecutor.log.error(e.getMessage(), e);
48+
} finally {
49+
count.countDown();
50+
if (count.getCount() <= 0 && taskCompletion != null) {
51+
taskCompletion.onComplete();
52+
}
53+
}
54+
};
55+
ThreadPoolUtil.TEST_EXECUTOR.execute(run);
56+
57+
return new DeviceTaskControl(count, Set.of(fakeDevice));
58+
}
3759
int activeDevice = 0;
3860
log.warn("All device count {}", allDevices.size());
3961
for (TestRunDevice device : allDevices) {

0 commit comments

Comments
 (0)
0