Explorar el Código

初步解决因为设备资源有限,设备状态混乱的问题
通过CAS更新设备的空闲-占用-执行状态

LiHaoyu hace 5 años
padre
commit
774e80648b

+ 3 - 1
src/main/java/net/mooctest/www/android_auto_test/common/constant/enums/TraceStatus.java

@@ -35,7 +35,9 @@ public enum TraceStatus {
     BAGGING_FAILED("5", "APK解包失败"),
 
 
-    FAILED("6", "失败");
+    FAILED("6", "失败"),
+
+    NO_DEVICES("7", "无空闲设备");
 
     private String code;
     private String description;

+ 18 - 21
src/main/java/net/mooctest/www/android_auto_test/common/runner/MyApplicationRunner.java

@@ -7,10 +7,7 @@ import net.mooctest.www.android_auto_test.common.constant.enums.DeviceStatus;
 import net.mooctest.www.android_auto_test.models.Device;
 import net.mooctest.www.android_auto_test.services.ApkService;
 import net.mooctest.www.android_auto_test.services.DeviceService;
-import net.mooctest.www.android_auto_test.utils.AddressUtil;
-import net.mooctest.www.android_auto_test.utils.CoverageTest;
-import net.mooctest.www.android_auto_test.utils.PrintUtil;
-import net.mooctest.www.android_auto_test.utils.TraceDaemon;
+import net.mooctest.www.android_auto_test.utils.*;
 import net.mooctest.www.android_auto_test.vo.TraceMetaInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -46,10 +43,6 @@ public class MyApplicationRunner implements ApplicationRunner {
             return;
         }
         System.out.println("轮询获取任务信息");
-        //TODO 先获取当前空闲设备
-        // 然后带着设备信息去发请求,获取任务信息
-        // 获取到任务信息后,起一个线程去跑任务
-        // 如果有一些额外配置,则触发生成报告的操作,然后告诉企业版,报告好了
         runDevicesTasks();
     }
 
@@ -58,17 +51,22 @@ public class MyApplicationRunner implements ApplicationRunner {
             // 获取目前在线设备且可用的设备
             List<Device> deviceList = deviceService.getOnlineDeviceList();
             for (Device device: deviceList){
-                DeviceStatus deviceStatus = deviceService.getDeviceStatus(device.getUdid());
-                if (deviceStatus != DeviceStatus.FREE){
-                    PrintUtil.print("Device is running, continue.", TAG, device.getUdid());
+                boolean r = deviceService.occupyDevice(device.getUdid());
+                if (!r){
+                    PrintUtil.print("Occupy device failed, continue.", TAG, device.getUdid());
                     continue;
                 }
-                //TODO 这里用CAS去更新device的状态
-                // 或者把接收任务的口子关了。。
-                device = buildDevice(device);
+                device.build();
                 PrintUtil.print("Get TraceInfo.", TAG, device.getUdid());
                 TraceMetaInfo traceMetaInfo = getTraceMetaInfo(device);
-                if (traceMetaInfo == null){
+                if (traceMetaInfo == null
+                        || traceMetaInfo.getDownloadUrl() == null
+                        || traceMetaInfo.getTraceId() == null){
+                    PrintUtil.print("No trace task, free device, continue.", TAG, device.getUdid());
+                    boolean t = deviceService.freeDevice(device.getUdid());
+                    if (!r){
+                        PrintUtil.printErr("释放Device, 这个路径不会被触发。", TAG, device.getUdid());
+                    }
                     continue;
                 }
 
@@ -99,8 +97,11 @@ public class MyApplicationRunner implements ApplicationRunner {
                 CoverageTest coverageTest = new CoverageTest(apkInfo, apkPath, device, traceId);
                 coverageTest.setName(Consts.AUTO_TEST_THREAD_NAME_PREFIX + device.getUdid());
                 oneTraceTasks.add(coverageTest);
-                //TODO 这里需要CAS更新,而不是单纯的更新
-                deviceService.updateDeviceStatus(device.getUdid(), DeviceStatus.RUNNING);
+                // CAS更新Device状态,OCCUPY -> RUNNING
+                deviceService.startRunDevice(device.getUdid());
+                if (!r){
+                    PrintUtil.printErr("开始Device任务, 这个路径不会被触发。", TAG, device.getUdid());
+                }
                 coverageTest.start();
 
                 //启动守护线程
@@ -121,10 +122,6 @@ public class MyApplicationRunner implements ApplicationRunner {
         }
     }
 
-    private Device buildDevice(Device device){
-        return device;
-    }
-
     private TraceMetaInfo getTraceMetaInfo(Device device){
         // TODO 发送请求,获取Trace信息,这里Mock一下发给自己这个项目
         RestTemplate rt = new RestTemplate();

+ 15 - 0
src/main/java/net/mooctest/www/android_auto_test/models/Device.java

@@ -1,6 +1,7 @@
 package net.mooctest.www.android_auto_test.models;
 
 import lombok.Data;
+import net.mooctest.www.android_auto_test.utils.DeviceUtil;
 import net.mooctest.www.android_auto_test.utils.OsUtil;
 
 import java.io.Serializable;
@@ -12,4 +13,18 @@ import java.io.Serializable;
 public class Device{
     private String id;
     private String udid;
+    private String os;
+    private String deviceModel;
+    private String brand;
+    private String deviceName;
+    private String resolution;
+
+    public void build(){
+        this.setOs(DeviceUtil.getPlatformVersion(udid));
+        this.setDeviceModel(DeviceUtil.getMobileModel(udid));
+        this.setBrand(DeviceUtil.getMobileBrand(udid));
+        this.setDeviceName(DeviceUtil.getMobileName(udid));
+        this.setResolution(DeviceUtil.getMobileResolution(udid));
+    }
+
 }

+ 8 - 0
src/main/java/net/mooctest/www/android_auto_test/services/DeviceService.java

@@ -40,4 +40,12 @@ public interface DeviceService {
      * @return 设备状态
      */
     DeviceStatus getDeviceStatus(String udid);
+
+    boolean occupyDevice(String udid);
+
+    boolean freeDevice(String udid);
+
+    boolean startRunDevice(String udid);
+
+    boolean endRunDevice(String udid);
 }

+ 21 - 8
src/main/java/net/mooctest/www/android_auto_test/services/Impl/AutoTestServiceImpl.java

@@ -90,19 +90,32 @@ public class AutoTestServiceImpl implements AutoTestService {
             }
             // 获取目前在线设备
             List<Device> deviceList = deviceService.getOnlineDeviceList();
-            // 获取空闲设备
+            // 筛选用户选择设备
             List<Device> selectedDevices = deviceService.selectDeviceByApp(apkInfo, deviceList, selectDevices);
-            if (selectedDevices == null || selectedDevices.size() == 0){
-                traceService.updateTraceStatue(traceId, TraceStatus.FAILED);
+            // 尝试更改设备状态的OCCUPY,失败则忽略该设备
+            List<Device> finalDevices = new ArrayList<>();
+            for (Device d: selectedDevices) {
+                if (deviceService.occupyDevice(d.getUdid())){
+                    finalDevices.add(d);
+                }
+            }
+            if (finalDevices.size() == 0){
+                traceService.updateTraceStatue(traceId, TraceStatus.NO_DEVICES);
                 throw new NoFreeDeviceException("暂无空闲设备");
             }
-            traceService.setTraceDevices(traceId, selectedDevices);
+            // 保存任务和设备的关系
+            traceService.setTraceDevices(traceId, finalDevices);
+            // 更新任务状态为Running
             traceService.updateTraceStatue(traceId, TraceStatus.RUNNING);
+            // 更新任务开始时间
             apkService.updateTraceStartTime(traceId);
-            List<CoverageTest> oneTraceTasks = new ArrayList<>(selectedDevices.size());
-            for (Device device: selectedDevices){
-                //TODO 这里需要CAS更新,而不是单纯的更新
-                deviceService.updateDeviceStatus(device.getUdid(), DeviceStatus.RUNNING);
+            // 开启所有任务线程
+            List<CoverageTest> oneTraceTasks = new ArrayList<>(finalDevices.size());
+            for (Device device: finalDevices){
+                boolean r = deviceService.startRunDevice(device.getUdid());
+                if (!r){
+                    PrintUtil.printErr("开始Device任务, 这个路径不会被触发。", TAG, device.getUdid());
+                }
                 CoverageTest coverageTest = new CoverageTest(apkInfo, filePath, device, traceId);
                 coverageTest.setName(Consts.AUTO_TEST_THREAD_NAME_PREFIX + device.getUdid());
                 coverageTest.start();

+ 22 - 9
src/main/java/net/mooctest/www/android_auto_test/services/Impl/DeviceServiceImpl.java

@@ -53,18 +53,11 @@ public class DeviceServiceImpl implements DeviceService {
 
     @Override
     public List<Device> selectDeviceByApp(ApkInfo apkInfo, List<Device> devices, List<String> selectDevices) {
-        List<Device> freeDevices = new ArrayList<>();
-        for (Device d: devices){
-            DeviceStatus ds = deviceStatusMap.get(d.getUdid());
-            if (ds == null || ds == DeviceStatus.FREE){
-                freeDevices.add(d);
-            }
-        }
         if (selectDevices == null || selectDevices.size() == 0){
-            return freeDevices;
+            return devices;
         }
         List<Device> selected = new ArrayList<>();
-        for (Device d: freeDevices){
+        for (Device d: devices){
             String udid = d.getUdid();
             if (selectDevices.contains(udid)){
                 selected.add(d);
@@ -92,4 +85,24 @@ public class DeviceServiceImpl implements DeviceService {
     public DeviceStatus getDeviceStatus(String udid) {
         return deviceStatusMap.get(udid);
     }
+
+    @Override
+    public boolean occupyDevice(String udid) {
+        return deviceStatusMap.compareAndSet(udid, DeviceStatus.FREE, DeviceStatus.OCCUPY);
+    }
+
+    @Override
+    public boolean freeDevice(String udid) {
+        return deviceStatusMap.compareAndSet(udid, DeviceStatus.OCCUPY, DeviceStatus.FREE);
+    }
+
+    @Override
+    public boolean startRunDevice(String udid) {
+        return deviceStatusMap.compareAndSet(udid, DeviceStatus.OCCUPY, DeviceStatus.RUNNING);
+    }
+
+    @Override
+    public boolean endRunDevice(String udid) {
+        return deviceStatusMap.compareAndSet(udid, DeviceStatus.RUNNING, DeviceStatus.FREE);
+    }
 }

+ 4 - 1
src/main/java/net/mooctest/www/android_auto_test/utils/CoverageTest.java

@@ -151,7 +151,10 @@ public class CoverageTest extends Thread{
             // 停止appium server
             stopAppiumServer(this.port);
             PrintUtil.print("Device " + udid + ", test has finished", TAG, udid);
-            deviceService.updateDeviceStatus(udid, DeviceStatus.FREE);
+            boolean r = deviceService.endRunDevice(udid);
+            if (!r){
+                PrintUtil.printErr("释放Device, 这个路径不会被触发。", TAG, device.getUdid());
+            }
             deviceService.updateDeviceRunningStatus(traceId, udid, DeviceRunningStatus.FINISH);
             finalEnd = true;
         }