diff --git a/pom.xml b/pom.xml
index 796a6ce..43e59c4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,6 +68,13 @@
0.12.35
+
+
+ net.lingala.zip4j
+ zip4j
+ 2.11.5
+
+
diff --git a/src/main/java/net/geedge/api/controller/APIController.java b/src/main/java/net/geedge/api/controller/APIController.java
index 8d04d32..cad62e5 100644
--- a/src/main/java/net/geedge/api/controller/APIController.java
+++ b/src/main/java/net/geedge/api/controller/APIController.java
@@ -9,15 +9,17 @@ import net.geedge.api.entity.EnvApiYml;
import net.geedge.api.util.AdbUtil;
import net.geedge.api.util.CommandExec;
import net.geedge.common.*;
+import net.lingala.zip4j.ZipFile;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.model.enums.CompressionLevel;
+import net.lingala.zip4j.model.enums.CompressionMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.zip.ZipEntry;
@RestController
@RequestMapping("/api/v1/env")
@@ -298,11 +300,7 @@ public class APIController {
} catch (Exception e) {
log.error(e.getMessage());
- Map resultMap = T.MapUtil.builder()
- .put("status", "error")
- .build();
- Constant.PLAYBOOK_RUN_RESULT.put(id, resultMap);
- return R.ok();
+ throw new APIException(RCode.ERROR);
} finally {
T.FileUtil.del(destination);
}
@@ -316,11 +314,9 @@ public class APIController {
if (T.StrUtil.isEmpty(id)) {
throw new APIException(RCode.BAD_REQUEST);
}
- Map result = Constant.PLAYBOOK_RUN_RESULT.get(id);
- if (T.MapUtil.isNotEmpty(result) && !T.MapUtil.getStr(result, "status").equals("running")){
- Constant.PLAYBOOK_RUN_RESULT.remove(id);
- }
- return R.ok().putData(result);
+ File statusFile = FileUtil.file(Constant.TEMP_PATH, id, "result.json");
+ String status = T.FileUtil.readString(statusFile, "UTF-8");
+ return R.ok().putData(status);
}
@@ -366,9 +362,22 @@ public class APIController {
return name.endsWith(".log") || name.endsWith(".pcap");
}
});
- T.ZipUtil.zip(zipFile, true, files);
- T.ResponseUtil.downloadFile(response,zipFile.getName(), T.FileUtil.readBytes(zipFile));
+ ZipFile zip = null;
+ try {
+ zip = new ZipFile(zipFile);
+ ZipParameters parameters = new ZipParameters();
+ parameters.setCompressionMethod(CompressionMethod.DEFLATE); // 压缩方法
+ parameters.setCompressionLevel(CompressionLevel.FASTEST); // 压缩级别,选项有 FASTEST、ULTRA 等
+
+ // 添加文件到 ZIP
+ for (File file : files) {
+ zip.addFile(file, parameters);
+ }
+ T.ResponseUtil.downloadFile(response, zipFile.getName(), T.FileUtil.readBytes(zipFile.getPath()));
+ } finally {
+ zip.close();
+ }
}
public class PlaybookRunnable extends Thread {
@@ -391,6 +400,9 @@ public class APIController {
@Override
public void run() {
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 {
T.FileUtil.appendString(String.format("Running with %s:%s Android Simulator \n", envApiYml.getAdb().getHost(), envApiYml.getAdb().getPort()), logFile, "UTF-8");
@@ -399,69 +411,94 @@ public class APIController {
Map resultMap = T.MapUtil.builder()
.put("status", "running")
.build();
- Constant.PLAYBOOK_RUN_RESULT.put(tid, resultMap);
+ T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
- // 1. install apk
+ // install apk
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());
}
- // 2. star tcpdump
- AdbUtil.CommandResult startTcpdump = adbUtil.startTcpdump(packageName);
- if (0 != startTcpdump.exitCode()) {
- T.FileUtil.appendString(String.format("ERROR: Start tcpdump failed: exit code %s \n", startTcpdump.exitCode()), logFile, "UTF-8");
- throw new APIException("exec tcpdump error");
+ // clear app data
+ 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, install.exitCode()), logFile, "UTF-8");
+ throw new APIException(clearData.output());
}
- // 3. exec playbook
- AdbUtil.CommandResult execResult = adbUtil.execPlaybook(playbookDir.getPath(), logFile);
- if (0 != execResult.exitCode()) {
- // exec playbook error, stop tcpdump and delete pcap
- T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", execResult.exitCode()), logFile, "UTF-8");
- AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.output());
- adbUtil.execShellCommand(String.format("shell rm -rf %s", stopTcpdump.output()));
- throw new APIException("exec playbook error");
+ // star tcpdump: package name
+ 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));
}
- // 4. stop tcpdump
- AdbUtil.CommandResult stopTcpdump = adbUtil.stopTcpdump(startTcpdump.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());
+ // star tcpdump: all
+ 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");
}
- // 5. pull pcap file
- String filePath = stopTcpdump.output();
- File localPcapFile = T.FileUtil.file(Constant.TEMP_PATH, tid, startTcpdump.output() + ".pcap");
- if (T.StrUtil.isEmpty(filePath)) {
- throw new APIException(RCode.NOT_EXISTS);
+ // exec playbook
+ AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(playbookDir.getPath(), logFile);
+ 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");
}
- 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());
- }
+ // stop package tcpdump
+ stopTcpdump(tcpdumpPackage, logFile, packageName);
- // 6. delete android pcap
- adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath));
+ // stop all tcpdump
+ stopTcpdump(tcpdumpAll, logFile, T.StrUtil.EMPTY);
resultMap = T.MapUtil.builder()
.put("status", "done")
.build();
- Constant.PLAYBOOK_RUN_RESULT.put(tid, resultMap);
+ 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();
- Constant.PLAYBOOK_RUN_RESULT.put(tid, resultMap);
+ T.FileUtil.writeString(T.JSONUtil.toJsonStr(resultMap), statusFile, "UTF-8");
+
+ AdbUtil.CommandResult packageTcpdump = adbUtil.stopTcpdump(tcpdumpPackage.output());
+ adbUtil.execShellCommand(String.format("shell rm -rf %s", packageTcpdump.output()));
+ AdbUtil.CommandResult allTcpdump = adbUtil.stopTcpdump(tcpdumpAll.output());
+ adbUtil.execShellCommand(String.format("shell rm -rf %s", allTcpdump.output()));
} finally {
adbUtil.stopApp(packageName);
T.FileUtil.appendString(String.format("Job succeeded"), logFile, "UTF-8");
}
}
+
+ 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));
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
index 575a809..e0b6b12 100644
--- a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
+++ b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
@@ -218,4 +218,12 @@ public class AdbCommandBuilder {
this.command.add(packageName);
return this;
}
+
+ public AdbCommandBuilder buildClearAppDateCommand(String packageName) {
+ this.command.add("shell");
+ this.command.add("pm");
+ this.command.add("clear");
+ this.command.add(packageName);
+ return this;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/geedge/api/util/AdbUtil.java b/src/main/java/net/geedge/api/util/AdbUtil.java
index 0e09fab..0030261 100644
--- a/src/main/java/net/geedge/api/util/AdbUtil.java
+++ b/src/main/java/net/geedge/api/util/AdbUtil.java
@@ -819,6 +819,15 @@ public class AdbUtil {
log.info("[deleteAcl] [protocol: {}] [ip: {}] [port: {}] [result: {}]", protocol, ip, port, result);
}
+ public CommandResult clearAppData(String packageName) {
+ String result = commandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildClearAppDateCommand(packageName)
+ .build());
+ log.info("[clearAppData] [packageName: {}]", packageName);
+ return new CommandResult(T.StrUtil.containsAny(result, "Success") ? 0 : 1, result);
+ }
+
/**
* flushAcl
* iptables -F ASW_OUTPUT