Преглед изворни кода

feat: 接口测试基本完成

zhaoxingrui пре 5 година
родитељ
комит
42b913a45d

+ 9 - 2
web/src/main/java/seecoder/devcloud/web/controller/APITest/APITestController.java

@@ -18,7 +18,7 @@ import java.util.List;
  */
 @Api(tags = "接口测试 API")
 @RestController
-@RequestMapping("/test")
+@RequestMapping("/apitest")
 public class APITestController {
 
     private final APITestService apiTestService;
@@ -28,7 +28,7 @@ public class APITestController {
         this.apiTestService = apiTestService;
     }
 
-    @GetMapping("/create")
+    @PostMapping("/create")
     @ApiOperation(value = "创建一个新的测试任务", httpMethod = "POST")
     public Response createAPITestMission(@RequestBody APITestBodyVO apiTestBodyVO) {
         apiTestService.createAPITest(apiTestBodyVO);
@@ -49,4 +49,11 @@ public class APITestController {
         apiTestService.deleteAPITest(testId);
         return Response.buildSuccess();
     }
+
+    @GetMapping("/execute/{testId}")
+    @ApiOperation(value = "执行制定测试任务", httpMethod = "GET")
+    @ApiImplicitParam(name = "testID", dataType = "int", paramType = "query")
+    public void executeAPITestByTestId(@PathVariable("testId") Integer testId) throws InterruptedException {
+        apiTestService.executeAPITest(testId);
+    }
 }

+ 6 - 0
web/src/main/java/seecoder/devcloud/web/dao/APITest/APITestMapper.java

@@ -21,6 +21,12 @@ public interface APITestMapper {
     @Select("select * from api_test where project_id = #{id}")
     List<APITest> selectByProjectId(Integer id);
 
+    @Select("select * from api_test where test_id = #{id}")
+    APITest selectByTestId(Integer id);
+
     @Delete("delete from api_test where test_id = #{id}")
     boolean delete(Integer id);
+
+    @Update("update api_test set state = #{state}, execute_time = #{executeTime}, success = #{success}, failure = #{failure}, time_list = #{timeList} where test_id = #{id}")
+    boolean update(@Param("state") String state, @Param("executeTime") String executeTime, @Param("success") Integer success, @Param("failure") Integer failure, @Param("timeList") String timeList, @Param("id") Integer id);
 }

+ 3 - 2
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITest.java

@@ -23,13 +23,14 @@ public class APITest {
     private Integer testId;
     private String testName;
     private Integer projectId;
-    private Timestamp createTime;
+    private String createTime;
     private String username;
     private String url;
     private String params;
+    private String method;
     private Integer qps;
     private String state;
-    private Timestamp executeTime;
+    private String executeTime;
     private Integer success;
     private Integer failure;
     private String timeList;

+ 3 - 1
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITestBody.java

@@ -17,9 +17,11 @@ import java.util.Map;
 @AllArgsConstructor
 public class APITestBody {
     private Integer projectId;
-    private Timestamp createTime;
+    private String createTime;
     private String username;
+    private String testName;
     private String url;
     private Map<String, Object> params;
+    private String method;
     private Integer qps;
 }

+ 3 - 2
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITestInfo.java

@@ -22,13 +22,14 @@ public class APITestInfo {
     private Integer testId;
     private String testName;
     private Integer projectId;
-    private Timestamp createTime;
+    private String createTime;
     private String username;
     private String url;
     private Map<String, Object> params;
+    private String method;
     private Integer qps;
     private String state;
-    private Timestamp executeTime;
+    private String executeTime;
     private Integer success;
     private Integer failure;
     private List<Integer> timeList;

+ 4 - 1
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestBodyVO.java

@@ -29,7 +29,7 @@ public class APITestBodyVO {
     private String testName;
 
     @ApiModelProperty("测试创建时间")
-    private Timestamp createTime;
+    private String createTime;
 
     @ApiModelProperty("测试创建者")
     private String username;
@@ -40,6 +40,9 @@ public class APITestBodyVO {
     @ApiModelProperty("测试url中可能携带的参数")
     private Map<String, Object> params;
 
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
     @ApiModelProperty("测试并发数")
     private Integer qps;
 

+ 5 - 2
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestInfoVO.java

@@ -33,7 +33,7 @@ public class APITestInfoVO {
     private Integer projectId;
 
     @ApiModelProperty("创建时间")
-    private Timestamp createTime;
+    private String createTime;
 
     @ApiModelProperty("创建者")
     private String username;
@@ -44,6 +44,9 @@ public class APITestInfoVO {
     @ApiModelProperty("测试可能携带的参数")
     private Map<String, Object> params;
 
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
     @ApiModelProperty("测试并发数")
     private Integer qps;
 
@@ -51,7 +54,7 @@ public class APITestInfoVO {
     private String state;
 
     @ApiModelProperty("测试执行时间")
-    private Timestamp executeTime;
+    private String executeTime;
 
     @ApiModelProperty("测试成功次数")
     private Integer success;

+ 5 - 2
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestVO.java

@@ -29,7 +29,7 @@ public class APITestVO {
     private Integer projectId;
 
     @ApiModelProperty("创建时间")
-    private Timestamp createTime;
+    private String createTime;
 
     @ApiModelProperty("创建者")
     private String username;
@@ -40,6 +40,9 @@ public class APITestVO {
     @ApiModelProperty("测试可能携带的参数")
     private String params;
 
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
     @ApiModelProperty("测试并发数")
     private Integer qps;
 
@@ -47,7 +50,7 @@ public class APITestVO {
     private String state;
 
     @ApiModelProperty("测试执行时间")
-    private Timestamp executeTime;
+    private String executeTime;
 
     @ApiModelProperty("测试成功次数")
     private Integer success;

+ 4 - 5
web/src/main/java/seecoder/devcloud/web/service/APITest/APITestService.java

@@ -26,9 +26,8 @@ public interface APITestService {
      */
     void deleteAPITest(Integer projectId);
 
-//    /**
-//     * 运行指定测试任务
-//     */
-//    APITestBodyVO executeAPITest(Integer projectId);
-//
+    /**
+     * 执行指定测试任务
+     */
+    void executeAPITest(Integer testId) throws InterruptedException;
 }

+ 169 - 1
web/src/main/java/seecoder/devcloud/web/service/impl/APITest/APITestServiceImpl.java

@@ -11,7 +11,15 @@ import seecoder.devcloud.web.model.vo.APITest.APITestBodyVO;
 import seecoder.devcloud.web.model.vo.APITest.APITestInfoVO;
 import seecoder.devcloud.web.service.APITest.APITestService;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.concurrent.CountDownLatch;
 
 @Service
 public class APITestServiceImpl implements APITestService {
@@ -28,7 +36,8 @@ public class APITestServiceImpl implements APITestService {
              .createTime(apiTestBodyVO.getCreateTime())
              .username(apiTestBodyVO.getUsername())
              .url(apiTestBodyVO.getUrl())
-             .params("{}")
+             .params(JSONObject.fromObject(apiTestBodyVO.getParams()).toString())
+             .method(apiTestBodyVO.getMethod())
              .qps(apiTestBodyVO.getQps())
              .state("进行中")
              .success(0)
@@ -42,6 +51,7 @@ public class APITestServiceImpl implements APITestService {
     public void deleteAPITest(Integer projectId) {
         apiTestMapper.delete(projectId);
     }
+
     @Override
     public List<APITestInfoVO> getAPITestsByProjectId(Integer projectId) {
         List<APITest> apiTestInfoVOs = apiTestMapper.selectByProjectId(projectId);
@@ -52,6 +62,20 @@ public class APITestServiceImpl implements APITestService {
         return apiTestInfoVOList;
     }
 
+    @Override
+    public void executeAPITest(Integer testId) throws InterruptedException {
+        APITest apiTest = apiTestMapper.selectByTestId(testId);
+        String url = apiTest.getUrl();
+        Map<String, Object> params = parseJson2Map(apiTest.getParams());
+        int qps = apiTest.getQps();
+        String method = apiTest.getMethod();
+
+        System.out.println(method);
+        if (method.equals("GET")) { // GET方法
+            simulateHttpGet(url, params, qps, testId);
+        }
+    }
+
     // 将数据库中读取的 APITestInfoMysql 转为 APITestInfo
     public APITestInfo transform(APITest apiTest) {
         APITestInfo apiTestInfo = new APITestInfo();
@@ -62,6 +86,7 @@ public class APITestServiceImpl implements APITestService {
         apiTestInfo.setUsername(apiTest.getUsername());
         apiTestInfo.setUrl(apiTest.getUrl());
         apiTestInfo.setParams(parseJson2Map(apiTest.getParams()));
+        apiTestInfo.setMethod(apiTest.getMethod());
         apiTestInfo.setQps(apiTest.getQps());
         apiTestInfo.setState(apiTest.getState());
         apiTestInfo.setExecuteTime(apiTest.getExecuteTime());
@@ -104,4 +129,147 @@ public class APITestServiceImpl implements APITestService {
         }
         return timeList;
     }
+
+    // 处理GET方法
+    public void simulateHttpGet(String url, Map<String, Object> params, int qps, int testId) throws InterruptedException {
+        ArrayList<Integer> timeList = new ArrayList<>();
+        final int[] success = {0};
+        final int[] failure = {0};
+        Runnable task = new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < qps / 10; i++) {
+                    int[] arr = doGet(url, params);
+                    timeList.add(arr[1]);
+                    if (arr[0] == 1) success[0]++;
+                    else failure[0]++;
+                    try{
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        };
+        APITestServiceImpl apiTestService = new APITestServiceImpl();
+        apiTestService.startTaskAllInOnce(10, task);
+        String tl = "";
+        for (int j = 0; j < timeList.size(); j++) {
+            if (j != timeList.size() - 1) tl += timeList.get(j).toString() + ",";
+            else tl += timeList.get(j).toString();
+        }
+        Date d = new Date();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String executeTime = sdf.format(d);
+        System.out.println(success[0]);
+        apiTestMapper.update("完成", executeTime, success[0], failure[0], tl, testId);
+    }
+
+    //
+    public int[] doGet(String url, Map<String, Object> params) {
+        HttpURLConnection connection = null;
+        BufferedReader br = null;
+        StringBuffer sb = new StringBuffer();
+        String result = "";
+        String path = "";
+        int[] arr = new int[2];
+        int flag = 0;
+        long start = System.currentTimeMillis();
+        try {
+            if (params.size() == 1) {
+                for (String name:params.keySet()) {
+                    sb.append(name).append("=").append(URLEncoder.encode((String) params.get(name), "UTF-8"));
+                }
+                path = sb.toString();
+            } else if (params.size() >= 2) {
+                for (String name:params.keySet()) {
+                    sb.append(name).append("=").append(URLEncoder.encode((String) params.get(name), "UTF-8")).append("&");
+                }
+                String temp_path = sb.toString();
+                path = temp_path.substring(0, temp_path.length() - 1);
+            }
+            String full_url = "";
+            if (path != "") {
+                full_url = url + "?" + path;
+            } else {
+                full_url = url;
+            }
+
+//            System.out.println(full_url);
+            URL connURL = new URL(full_url);
+
+            connection = (HttpURLConnection) connURL.openConnection();
+            // 设置一些属性
+//            connection.setRequestMethod("GET");
+            connection.setRequestProperty("Accept", "*/*");
+            connection.setRequestProperty("Connection", "Keep-Alive");
+            connection.setRequestProperty("User-Agent",
+                    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
+            connection.setConnectTimeout(15000);
+            connection.setReadTimeout(60000);
+
+            // 建立连接
+            connection.connect();
+            if (connection.getResponseCode() == 200) {
+                flag = 1;
+            } else {
+                flag = 0;
+            }
+//            Map<String, List<String>> headers = connection.getHeaderFields();
+//            for (String key:headers.keySet()) {
+//                System.out.println(key + "\t: \t" + headers.get(key));
+//            }
+            br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+            String line;
+            while ((line = br.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (br != null)
+                    br.close();
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+        long end = System.currentTimeMillis();
+//        System.out.println(result);
+        int time = Long.valueOf(end - start).intValue();
+        arr[0] = flag;
+        arr[1] = time;
+        return arr;
+    }
+
+    public long startTaskAllInOnce(int threadNums, final Runnable task) throws InterruptedException {
+        final CountDownLatch startGate = new CountDownLatch(1);
+        final CountDownLatch endGate = new CountDownLatch(threadNums);
+        for (int i = 0; i < threadNums; i++) {
+            Thread t = new Thread() {
+                public void run() {
+                    try {
+                        startGate.await();
+                        try {
+                            task.run();
+                        } finally {
+                            endGate.countDown();
+                        }
+                    } catch (InterruptedException ie) {
+                        ie.printStackTrace();
+                    }
+                }
+            };
+            t.start();
+        }
+        long startTime = System.nanoTime();
+        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
+        // 因开启门只需一个开关,所以立马就开启开始门
+        startGate.countDown();
+        // 等等结束门开启
+        endGate.await();
+        long endTime = System.nanoTime();
+        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
+        return endTime - startTime;
+    }
 }

+ 2 - 0
web/src/main/resources/application-zxr.yml

@@ -25,6 +25,8 @@ mybatis:
     map-underscore-to-camel-case: true
 
 seecoder:
+  jwt:
+    secret: U0VFQy0xOTE5ODEwLU9JREMtMTE0NTE0
   k8s:
     api-server: https://192.168.99.105:8443
     token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjBmSXc4RlRjNUpBYVpGYWc4QzRDY1MzUWJad1JMdFhKcDI1cngzWGtiRlkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZjbG91ZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNicXY4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5NmIxNzU1ZS0zZjE3LTQ1ZTctODFmYi01MTRhODA3NDRhMzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGV2Y2xvdWQ6ZGVmYXVsdCJ9.W0Y1lR6LBi1ZjylBx35YeqYuq2u2AqH-ayK4FD-LDfC26E89DanOwSv9XLrRMnnDBZFS_ZCRBumbnDeMiS5vw2x7-QnrDqj1M5u9FB2fIJsz2LyUkOhATZZmTzj_Uhewvvg09aDKh16ttj6ZX27m-KVk_6MP-VfiuvZnCVxDbqRkRjK-zsor4ty1CEATPyKK-tvugAwS0RFNHUL94DamfZAq_t1PSnH5ZtEHq0uEMZxY2c7j6u9d_aD9lphm_ZpCy_C8OCHfanM21CQPDHlcJTW_aiOO6bAp8qdc1egPO5uIamHl6Zm0N3RkcsRp4DGOHrltTV9y_cGZHXSWmRHfxw