Browse Source

众测任务进度集成

xujiawei 4 years ago
parent
commit
6ee6062c93

+ 120 - 0
src/main/java/edu/nju/algorithm/progress/BugForProgress.java

@@ -0,0 +1,120 @@
+package edu.nju.algorithm.progress;
+import java.util.Date;
+
+/**
+ * @Author JiaWei Xu
+ * @Date 2021-01-06 15:56
+ * @Email xjwhhh233@outlook.com
+ */
+
+public class BugForProgress {
+    String id;
+    String testCaseId;
+    String testCaseName;
+    String userId;
+
+    String title;
+    String description;
+    Date bugCreateTime;
+
+    String severity;
+    String bugPage;
+
+    public BugForProgress(){};
+
+    public BugForProgress(String id, String testCaseId, String testCaseName, String title, String description) {
+        this.id = id;
+        this.testCaseId = testCaseId;
+        this.testCaseName = testCaseName;
+
+        this.title = title;
+        this.description = description;
+    }
+
+    public BugForProgress(String id, String testCaseId, String testCaseName, String userId, String title, String description, Date bugCreateTime, String severity, String bugPage) {
+        this.id = id;
+        this.testCaseId = testCaseId;
+        this.userId = userId;
+        this.testCaseName = testCaseName;
+        this.title = title;
+        this.description = description;
+        this.bugCreateTime = bugCreateTime;
+        this.severity = severity;
+        this.bugPage = bugPage;
+    }
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTestCaseId() {
+        return testCaseId;
+    }
+
+    public void setTestCaseId(String testCaseId) {
+        this.testCaseId = testCaseId;
+    }
+
+    public String getTestCaseName() {
+        return testCaseName;
+    }
+
+    public void setTestCaseName(String testCaseName) {
+        this.testCaseName = testCaseName;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getBugCreateTime() {
+        return bugCreateTime;
+    }
+
+    public void setBugCreateTime(Date bugCreateTime) {
+        this.bugCreateTime = bugCreateTime;
+    }
+
+    public String getSeverity() {
+        return severity;
+    }
+
+    public void setSeverity(String severity) {
+        this.severity = severity;
+    }
+
+    public String getBugPage() {
+        return bugPage;
+    }
+
+    public void setBugPage(String bugPage) {
+        this.bugPage = bugPage;
+    }
+
+}
+

+ 34 - 0
src/main/java/edu/nju/algorithm/progress/ConstantsForProgress.java

@@ -0,0 +1,34 @@
+package edu.nju.algorithm.progress;
+
+/**
+ * @author xujiawei
+ */
+public interface ConstantsForProgress {
+//	final static Integer FIELD_INDEX_TEST_CASE_ID = 0;
+//	final static Integer FIELD_INDEX_USER_ID = 1;
+//	final static Integer FIELD_INDEX_TEST_CASE_NAME	 = 2;
+//	final static Integer FIELD_INDEX_BUG_DETAIL = 9;
+//	final static Integer FIELD_INDEX_REPRO_STEPS = 10;
+//	final static Integer FIELD_INDEX_SUBMIT_TIME  = 15;
+//	final static Integer FIELD_BUG_TAG = 14;
+//	final static Integer FIELD_DUP_TAG  = 17;    //17 corresponds to R column, 18 corresponds to S column
+	
+	// YK add
+	final static String FIELD_BUG_ID = "bug_id";
+	final static String FIELD_TEST_CASE_ID = "test_case_id";
+	final static String FIELD_USER_ID = "worker_id";
+	final static String FIELD_TEST_CASE_NAME	 = "test_case_name";
+	final static String FIELD_BUG_DETAIL = "title";
+	final static String FIELD_REPRO_STEPS = "description";
+	final static String FIELD_SUBMIT_TIME  = "bug_create_time";
+	final static String FIELD_BUG_TAG = "severity";
+	final static String FIELD_DUP_TAG  = "bug_page";    //17 corresponds to R column, 18 corresponds to S column
+	final static double SIM_THRESHOLD = 0.01;
+	
+	int captureSize = 6;
+	int equalTimeThres = 2;
+	
+	final static String projectFolder = "data/demoProjects";     
+
+	Integer sampleStep = 10;
+}

+ 80 - 0
src/main/java/edu/nju/algorithm/progress/M0CRCAlgorithm.java

@@ -0,0 +1,80 @@
+package edu.nju.algorithm.progress;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.TreeMap;
+
+/**
+ * @Author JiaWei Xu
+ * @Date 2021-01-06 15:54
+ * @Email xjwhhh233@outlook.com
+ */
+public class M0CRCAlgorithm {
+    public Integer[] obtainRecaptureResults(TreeMap<Integer, ArrayList<BugForProgress>> captureProcess) {
+        HashSet<String> distinctBugs = new HashSet<String>();
+        for (Integer cap : captureProcess.keySet()) {
+            ArrayList<BugForProgress> reportList = captureProcess.get(cap);
+
+            for (int i = 0; i < reportList.size(); i++) {
+                String dupTag = reportList.get(i).getBugPage();
+                distinctBugs.add(dupTag);
+            }
+        }
+
+        int captureSize = captureProcess.size();
+        int sep1 = captureSize / 2;
+        int sep2 = sep1;
+        int sep3 = sep1;
+        if (sep1 > 3) {
+            sep2 = sep1 - 1;
+            sep3 = sep1 + 1;
+        }
+        if (sep1 > 5) {
+            sep2 = sep1 - 2;
+            sep3 = sep1 + 2;
+        }
+
+        int estBugs1 = this.estimateTotalBugNum(captureProcess, sep1);
+        int estBugs2 = this.estimateTotalBugNum(captureProcess, sep2);
+        int estBugs3 = this.estimateTotalBugNum(captureProcess, sep3);
+
+        int estBugs = (estBugs1 + estBugs2 + estBugs3) / 3;
+        return new Integer[]{estBugs, estBugs, estBugs, distinctBugs.size()};
+    }
+
+    public Integer estimateTotalBugNum(TreeMap<Integer, ArrayList<BugForProgress>> captureProcess, int sep) {
+        HashSet<String> priorNoDupBugs = new HashSet<String>();
+        HashSet<String> laterNoDupBugs = new HashSet<String>();
+        int count = 0;
+        for (Integer cap : captureProcess.keySet()) {
+            count++;
+            ArrayList<BugForProgress> reportList = captureProcess.get(cap);
+            for (int i = 0; i < reportList.size(); i++) {
+                BugForProgress report = reportList.get(i);
+                if (count <= sep) {
+                    priorNoDupBugs.add(report.getBugPage());
+                } else {
+                    laterNoDupBugs.add(report.getBugPage());
+                }
+            }
+        }
+
+        int overlapBugs = 0;
+        for (String dupTag : priorNoDupBugs) {
+            if (laterNoDupBugs.contains(dupTag)) {
+                overlapBugs++;
+            }
+        }
+
+        int priorBugs = priorNoDupBugs.size();
+        int laterBugs = laterNoDupBugs.size();
+
+        int estimateBugs = priorBugs * laterBugs;
+        if (overlapBugs > 0) {
+            estimateBugs = estimateBugs / overlapBugs;
+        }
+
+        return estimateBugs;
+    }
+
+}

+ 97 - 0
src/main/java/edu/nju/algorithm/progress/TaskClosePrediction.java

@@ -0,0 +1,97 @@
+package edu.nju.algorithm.progress;
+
+import edu.nju.entities.Bug;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.TreeMap;
+
+/**
+ * @Author JiaWei Xu
+ * @Date 2021-01-06 16:02
+ * @Email xjwhhh233@outlook.com
+ */
+public class TaskClosePrediction {
+    public Double determineTaskProgressStatus(List<BugForProgress> bugForProgressList) {
+        Random rand = new Random();
+
+        ArrayList<Integer[]> captureResults = new ArrayList<Integer[]>();
+        TreeMap<Integer, ArrayList<BugForProgress>> captureProcess = new TreeMap<Integer, ArrayList<BugForProgress>>();
+
+        int captureSize = ConstantsForProgress.captureSize;
+        int equalTimeThres = ConstantsForProgress.equalTimeThres;
+
+        if (bugForProgressList.size() / captureSize < 5) {
+            return bugForProgressList.size() * 2.0;
+        }
+
+        M0CRCAlgorithm M0Algorithm = new M0CRCAlgorithm();
+        int captureTime = -1;
+        for (int i = 0; i < bugForProgressList.size(); ) {
+            captureTime++;
+            int beginReport = captureTime * captureSize;
+            int endReport = beginReport + captureSize;
+
+            if (endReport >= bugForProgressList.size()) {
+                break;
+            }
+
+            ArrayList<BugForProgress> curCapture = new ArrayList<BugForProgress>();
+            for (int j = beginReport; j < endReport && j < bugForProgressList.size(); j++) {
+                curCapture.add(bugForProgressList.get(j));
+            }
+            captureProcess.put(captureTime, curCapture);
+
+            Integer[] results = M0Algorithm.obtainRecaptureResults(captureProcess);    //estBugs, estBugs, estBugs, alreadySubBugs
+            captureResults.add(results);
+        }
+
+        Boolean isTerminate = this.whetherCanTerminate(captureResults, equalTimeThres);
+        Integer[] lastResults = captureResults.get(captureResults.size() - 1);
+        Double bugRatio = 1.0 * lastResults[3] / lastResults[0];
+        //System.out.println ( "bug ratio : " + bugRatio + " whether can terminate: " + isTerminate );
+
+        bugRatio = bugRatio * 100;
+        if (!isTerminate) {
+            if (bugRatio > 98) {
+                bugRatio = rand.nextInt(4) + 94.0;
+            }
+        }
+
+        return bugRatio;
+    }
+
+    private Boolean whetherCanTerminate(ArrayList<Integer[]> captureResults, Integer equalTimeThres) {
+        if (captureResults.size() < equalTimeThres) {
+            return false;
+        }
+
+        int count = 0;
+        for (int i = captureResults.size() - 1; i > 0; i--) {
+            Integer[] curResults = captureResults.get(i);
+            Integer[] priorResults = captureResults.get(i - 1);
+
+            if (this.isEqual(priorResults, curResults)) {
+                count++;
+            } else {
+                break;
+            }
+
+            if (count >= equalTimeThres) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Boolean isEqual(Integer[] priorResults, Integer[] curResults) {
+        if (!curResults[0].equals(curResults[3])) {
+            return false;
+        }
+        if (curResults[3] == 0) {
+            return false;
+        }
+        return true;
+    }
+}

+ 19 - 0
src/main/java/edu/nju/controller/AnalyzeController.java

@@ -9,6 +9,8 @@ import java.util.Map;
 
 import javax.servlet.http.HttpServletResponse;
 
+import edu.nju.dao.TaskDao;
+import edu.nju.entities.Task;
 import edu.nju.model.*;
 import edu.nju.util.AESUtil;
 import edu.nju.util.BlockChainAspect;
@@ -34,6 +36,9 @@ public class AnalyzeController {
 
 	@Autowired
 	BlockChainAspect blockChainAspect;
+
+	@Autowired
+	TaskDao taskDao;
 	
 	//根据用例获取所有有效bug
 	@RequestMapping(value = "/valid")
@@ -527,6 +532,20 @@ public class AnalyzeController {
 		}
 	}
 
+	@RequestMapping(value = "/progress", method = RequestMethod.GET)
+	@ResponseBody
+	public void crowdTestProgress(@RequestParam("caseId") String caseId, @RequestParam("taskId") String taskId){
+		Task task=taskDao.findById(taskId);
+		if(task.getEnd_time()>System.currentTimeMillis()){
+
+		}else{
+
+		}
+
+
+
+	}
+
 
 	private String [] url2decode(String str){
 		String [] res = new String[2];

+ 2 - 1
src/main/java/edu/nju/dao/CTBDao.java

@@ -49,7 +49,8 @@ public class CTBDao {
 //		System.out.println("3"+id);
 		return mongoOperations.find(query, CaseToBug.class).get(0);
 	}
-	
+
+	//根据testCaseId获取bugIdList
 	public List<String> findById(String id) {
 //		System.out.println("3"+id);
 		Query query = new Query();

+ 21 - 1
src/main/java/edu/nju/dao/TaskDao.java

@@ -1,6 +1,8 @@
 package edu.nju.dao;
 
 import edu.nju.entities.Task;
+import edu.nju.util.HTTP;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.mongodb.core.MongoOperations;
 import org.springframework.data.mongodb.core.query.Criteria;
@@ -24,8 +26,26 @@ public class TaskDao {
         Query query = new Query();
         query.addCriteria(Criteria.where("_id").is(id));
         List<Task> tasks = mongoOperations.find(query, Task.class);
-        if(tasks == null || tasks.size() == 0) { return null; }
+        if(tasks.size() == 0) {
+            return getAndSaveTaskInfo(id);
+        }
         else { return tasks.get(0); }
     }
 
+    private Task getAndSaveTaskInfo(String id){
+        String result = HTTP.sendGet("http://www.mooctest.net/api/exam/" + id + "/info", "");
+        if (!"".equals(result)) {
+            JSONObject json = new JSONObject(result);
+            long beginTime = json.getLong("beginTime");
+            long endTime = json.getLong("endTime");
+            String name=json.getString("name");
+            double totalMins = (endTime - beginTime) / 1000 / 60.0;
+            Task newTask = new Task(id, name,beginTime, endTime, totalMins, totalMins);
+            save(newTask);
+            return newTask;
+        }else{
+            return null;
+        }
+    }
+
 }

+ 76 - 0
src/main/java/edu/nju/entities/CrowdTest.java

@@ -0,0 +1,76 @@
+package edu.nju.entities;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.PersistenceConstructor;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * @Author JiaWei Xu
+ * @Date 2021-01-06 15:43
+ * @Email xjwhhh233@outlook.com
+ */
+@Document
+public class CrowdTest {
+
+    private static final long serialVersionUID = 7484726588592610736L;
+
+    @Id
+    private String id;
+
+    private String caseId;
+
+    private String taskId;
+
+    private String case_take_id;
+
+    private Double progress;
+
+    @PersistenceConstructor
+    public CrowdTest(String id, String caseId, String taskId, String case_take_id, Double progress) {
+        this.id = id;
+        this.caseId = caseId;
+        this.taskId = taskId;
+        this.case_take_id = case_take_id;
+        this.progress = progress;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getCaseId() {
+        return caseId;
+    }
+
+    public void setCaseId(String caseId) {
+        this.caseId = caseId;
+    }
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(String taskId) {
+        this.taskId = taskId;
+    }
+
+    public String getCase_take_id() {
+        return case_take_id;
+    }
+
+    public void setCase_take_id(String case_take_id) {
+        this.case_take_id = case_take_id;
+    }
+
+    public Double getProgress() {
+        return progress;
+    }
+
+    public void setProgress(Double progress) {
+        this.progress = progress;
+    }
+}

+ 72 - 0
src/main/java/edu/nju/service/AnalyzeService.java

@@ -1,12 +1,16 @@
 package edu.nju.service;
 
 import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Lists;
+import edu.nju.algorithm.progress.BugForProgress;
+import edu.nju.algorithm.progress.TaskClosePrediction;
 import edu.nju.dao.*;
 import edu.nju.entities.*;
 import edu.nju.model.*;
@@ -1061,6 +1065,74 @@ public class AnalyzeService {
 		return res;
 	}
 
+	private Double crowdTestProgress(String caseId,String taskId) throws ParseException {
+		SimpleDateFormat formatLine = new SimpleDateFormat ("yyyy/MM/dd HH:mm");
+		SimpleDateFormat formatCon = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
+		List<BugForProgress> bugForProgressList=new ArrayList<>();
+		String case_take_id=caseId+"-"+taskId;
+		List<Report> reportList = reportDao.findByCaseTakeId(case_take_id);
+		for (Report report : reportList) {
+			String reportId = report.getId();
+			List<TestCase> testCaseList = testCaseDao.findByReport(reportId);
+			for (TestCase testCase : testCaseList) {
+				String testCaseId = testCase.getId();
+				List<String> bugIdList = ctbdao.findById(testCaseId);
+				for (String bugId : bugIdList) {
+					Bug bug = bdao.findByid(bugId);
+					if (bug != null) {
+						BugForProgress bugForProgress = new BugForProgress();
+						bugForProgress.setId(bugId);
+						bugForProgress.setTestCaseId(testCaseId);
+						bugForProgress.setTestCaseName(testCase.getName());
+						bugForProgress.setUserId(report.getWorker_id());
+						//bug基本属性
+						bugForProgress.setSeverity(TransUtil.severityTransFromInt(bug.getSeverity()));
+						bugForProgress.setBugPage(bug.getBug_page());
+						bugForProgress.setTitle(bug.getTitle());
+						bugForProgress.setDescription(bug.getDescription());
+						String time = TransUtil.formatTimeMillis(bug.getCreate_time_millis());
+						time = transferString(time);
+						Date submitTime  = null;
+						if ( time.contains( "-")) {
+							submitTime = formatCon.parse( time );
+						}
+						else {
+							submitTime = formatLine.parse( time );
+						}
+						bugForProgress.setBugCreateTime(submitTime);
+						bugForProgressList.add(bugForProgress);
+
+					}
+				}
+			}
+		}
+		bugForProgressList.sort(new Comparator<BugForProgress>() {
+			@Override
+			public int compare(BugForProgress o1, BugForProgress o2) {
+				Date d1 = o1.getBugCreateTime();
+				Date d2 = o2.getBugCreateTime();
+				if (d1.before(d2)) {
+					return -1;
+				} else {
+					return 1;
+				}
+			}
+		});
+		TaskClosePrediction closePrediction = new TaskClosePrediction();
+		Double completeRatio = closePrediction.determineTaskProgressStatus(bugForProgressList);
+		completeRatio = completeRatio.intValue() * 1.0;
+		return completeRatio;
+	}
+
+
+	private String transferString ( String str ){
+		String result = str;
+		result = result.replaceAll( "\r\n", " " );
+		result = result.replaceAll( "\r", " " );
+		result = result.replaceAll( "\n", " " );
+		return result;
+	}
+