2024-11-25 15:01:43 +08:00
|
|
|
package net.geedge.api.util;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.hutool.core.collection.ListUtil;
|
|
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
|
|
import cn.hutool.log.Log;
|
|
|
|
|
import net.geedge.api.entity.EnvApiYml;
|
|
|
|
|
import net.geedge.common.APIException;
|
|
|
|
|
import net.geedge.common.Constant;
|
|
|
|
|
import net.geedge.common.RCode;
|
|
|
|
|
import net.geedge.common.T;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
public class PlaybookRunnable implements Runnable {
|
|
|
|
|
private final static Log log = Log.get();
|
|
|
|
|
|
|
|
|
|
private AdbUtil adbUtil;
|
|
|
|
|
private EnvApiYml envApiYml;
|
|
|
|
|
private String tid;
|
|
|
|
|
private File apkFile;
|
|
|
|
|
private String packageName;
|
2024-11-26 10:08:24 +08:00
|
|
|
private File scriptPath;
|
|
|
|
|
private String type;
|
2024-11-25 15:01:43 +08:00
|
|
|
private boolean reInstall;
|
|
|
|
|
private boolean clearCache;
|
|
|
|
|
private boolean unInstall;
|
|
|
|
|
private boolean interrupt;
|
|
|
|
|
|
2024-11-26 10:08:24 +08:00
|
|
|
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File scriptPath, String tid, String packageName, String type, Boolean reInstall, Boolean clearCache, Boolean unInstall) {
|
2024-11-25 15:01:43 +08:00
|
|
|
this.envApiYml = envApiYml;
|
|
|
|
|
this.tid = tid;
|
|
|
|
|
this.apkFile = apkFile;
|
|
|
|
|
this.packageName = packageName;
|
2024-11-26 10:08:24 +08:00
|
|
|
this.scriptPath = scriptPath;
|
|
|
|
|
this.type = type;
|
2024-11-25 15:01:43 +08:00
|
|
|
this.reInstall = reInstall;
|
|
|
|
|
this.clearCache = clearCache;
|
|
|
|
|
this.unInstall = unInstall;
|
|
|
|
|
this.interrupt = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
Thread.currentThread().setName("exec-playbook-thread-" + tid);
|
|
|
|
|
Constant.ACTIVE_TASKS.add(this);
|
|
|
|
|
File logFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.log");
|
|
|
|
|
File statusFile = FileUtil.file(Constant.TEMP_PATH, tid, "result.json");
|
|
|
|
|
AdbUtil.CommandResult tcpdumpPackage = null;
|
|
|
|
|
AdbUtil.CommandResult tcpdumpAll = null;
|
|
|
|
|
try {
|
|
|
|
|
Map resultMap = T.MapUtil.builder()
|
|
|
|
|
.put("status", "running")
|
|
|
|
|
.build();
|
|
|
|
|
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
|
|
|
|
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
T.FileUtil.appendString(String.format("Running with %s:%s Android Simulator \n", envApiYml.getAdb().getHost(), envApiYml.getAdb().getPort()), logFile, "UTF-8");
|
|
|
|
|
adbUtil = new AdbUtil(envApiYml.getAdb(), new CommandExec(logFile));
|
|
|
|
|
|
|
|
|
|
// Check if the package is installed
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
boolean packageIsInstall = adbUtil.findPackageInstall(packageName);
|
|
|
|
|
if (packageIsInstall) {
|
|
|
|
|
if (!reInstall) {
|
|
|
|
|
// install apk
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true);
|
|
|
|
|
if (0 != install.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(install.output());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// install apk
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
AdbUtil.CommandResult install = adbUtil.install(apkFile.getAbsolutePath(), true, true);
|
|
|
|
|
if (0 != install.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Install apk failed: exit code %s \n", install.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(install.output());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Close other apps
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
List<String> packageNameList = adbUtil.findPackageNameList();
|
|
|
|
|
this.closeApp(packageNameList, packageName);
|
|
|
|
|
|
|
|
|
|
// clear app data
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
if (clearCache) {
|
|
|
|
|
AdbUtil.CommandResult clearData = adbUtil.clearAppData(packageName);
|
|
|
|
|
if (0 != clearData.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Clear %s data error: exit code %s \n", packageName, clearData.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(clearData.output());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Launch the app
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
adbUtil.startApp(packageName);
|
|
|
|
|
|
|
|
|
|
// star tcpdump: package name
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
tcpdumpPackage = adbUtil.startTcpdump(packageName);
|
|
|
|
|
if (0 != tcpdumpPackage.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Start tcpdump %s failed: exit code %s \n", packageName, tcpdumpPackage.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(String.format("tcpdump %s error", packageName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// star tcpdump: all
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
tcpdumpAll = adbUtil.startTcpdump(T.StrUtil.EMPTY);
|
|
|
|
|
if (0 != tcpdumpAll.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Start tcpdump all failed: exit code %s \n", tcpdumpAll.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException("tcpdump all error");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// exec playbook
|
|
|
|
|
if (interrupt) return;
|
2024-11-26 10:08:24 +08:00
|
|
|
AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(scriptPath.getPath(), tid, packageName, type, logFile);
|
2024-11-25 15:01:43 +08:00
|
|
|
if (0 != airtestResult.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", airtestResult.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException("playbook exec error");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// stop package tcpdump
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
stopTcpdump(tcpdumpPackage, logFile, packageName);
|
|
|
|
|
|
|
|
|
|
// stop all tcpdump
|
|
|
|
|
if (interrupt) return;
|
|
|
|
|
stopTcpdump(tcpdumpAll, logFile, T.StrUtil.EMPTY);
|
|
|
|
|
|
|
|
|
|
resultMap = T.MapUtil.builder()
|
|
|
|
|
.put("status", "done")
|
|
|
|
|
.build();
|
|
|
|
|
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error(e);
|
|
|
|
|
Map resultMap = T.MapUtil.builder()
|
|
|
|
|
.put("status", "error")
|
|
|
|
|
.build();
|
|
|
|
|
T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
|
|
|
|
|
} finally {
|
|
|
|
|
if (T.StrUtil.isNotEmpty(tcpdumpPackage.output())) {
|
|
|
|
|
AdbUtil.CommandResult packageTcpdump = adbUtil.stopTcpdump(tcpdumpPackage.output());
|
|
|
|
|
adbUtil.execShellCommand(String.format("shell rm -rf %s", packageTcpdump.output()));
|
|
|
|
|
}
|
|
|
|
|
if (T.StrUtil.isNotEmpty(tcpdumpAll.output())) {
|
|
|
|
|
AdbUtil.CommandResult allTcpdump = adbUtil.stopTcpdump(tcpdumpAll.output());
|
|
|
|
|
adbUtil.execShellCommand(String.format("shell rm -rf %s", allTcpdump.output()));
|
|
|
|
|
}
|
|
|
|
|
this.closeApp(ListUtil.empty(), packageName);
|
|
|
|
|
if (unInstall) {
|
|
|
|
|
adbUtil.uninstall(packageName);
|
|
|
|
|
}
|
|
|
|
|
T.FileUtil.appendString(String.format("Job execution ends"), logFile, "UTF-8");
|
|
|
|
|
Constant.ACTIVE_TASKS.remove(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void interrupt() {
|
|
|
|
|
this.interrupt = true;
|
|
|
|
|
adbUtil.setInterrupt(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void closeApp(List<String> packageNameList, String packageName) {
|
|
|
|
|
if (CollUtil.isNotEmpty(packageNameList)) {
|
|
|
|
|
for (String name : packageNameList) {
|
|
|
|
|
adbUtil.stopApp(name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
adbUtil.stopApp(packageName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void stopTcpdump(AdbUtil.CommandResult tcpdump, File logFile, String packageName) {
|
|
|
|
|
// stop tcpdump
|
|
|
|
|
AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(tcpdump.output());
|
|
|
|
|
if (0 != stopTcpdump.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Stop tcpdump failed: exit code %s \n", stopTcpdump.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(stopTcpdump.output());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pull pcap file
|
|
|
|
|
String filePath = stopTcpdump.output();
|
|
|
|
|
packageName = T.StrUtil.isEmpty(packageName) ? "all" : packageName;
|
|
|
|
|
File localPcapFile = T.FileUtil.file(Constant.TEMP_PATH, tid, String.format("%s-%s%s", tcpdump.output(), packageName, ".pcap"));
|
|
|
|
|
if (T.StrUtil.isEmpty(filePath)) {
|
|
|
|
|
throw new APIException(RCode.NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AdbUtil.CommandResult pull = adbUtil.pull(filePath, localPcapFile.getAbsolutePath());
|
|
|
|
|
if (0 != pull.exitCode()) {
|
|
|
|
|
T.FileUtil.appendString(String.format("ERROR: Pull pcap file failed: exit code %s \n", pull.exitCode()), logFile, "UTF-8");
|
|
|
|
|
throw new APIException(pull.output());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// delete android pcap
|
|
|
|
|
adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath));
|
|
|
|
|
}
|
|
|
|
|
}
|