-
Notifications
You must be signed in to change notification settings - Fork 0
/
schedule.js
151 lines (135 loc) · 4.79 KB
/
schedule.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
const schedule = require('node-schedule');
const planModel = require('./models/plan');
const resultModel = require('./models/result');
const yapi = require('yapi.js');
const axios = require('axios');
const jobMap = new Map();
const retryMap = new Map();
/**
* 定时执行测试计划
*/
class testSchedule {
constructor(ctx) {
this.ctx = ctx;
this.planModel = yapi.getInst(planModel);
this.resultModel = yapi.getInst(resultModel);
this.init()
}
//初始化定时任务
async init() {
let allPlan = await this.planModel.listAll();
for (let i = 0, len = allPlan.length; i < len; i++) {
let plan = allPlan[i];
if (plan.is_plan_open) {
this.addTestJob(plan._id, plan);
}
}
}
/**
* 添加一个测试计划
* @param {测试计划id} planId
* @param {测试计划} plan
*/
async addTestJob(planId, plan) {
var url = plan.plan_url;
// 自动测试不支持下载
url = url.replace("download=true", "download=false");
url = url.replace("mode=html", "mode=json");
// 清空url中带的plan_id
url = url.replace(/&plan_id=\d+&/, "&")
// 替换API
url = url.replace("/api/open/run_auto_test", "/api/open/plugin/test/run");
url += "&plan_id=" + planId;
let handlerPlan = async (planId, plan, retry) => {
try {
let result = await axios.get(url);
let data = result.data || { message: {} };
this.saveTestLog(plan.plan_name, data.message.msg, plan.uid, plan.project_id);
if (plan.plan_result_size >= 0) {
let results = await this.resultModel.findByPlan(planId);
let ids = results.map((val) => val._id).slice(plan.plan_result_size);
await this.resultModel.deleteByIds(ids);
}
let job = jobMap.get(planId);
if (data.message.failedNum !== 0 && plan.plan_fail_retries && plan.plan_fail_retries > retry) {
job && job.cancel();
let retryDate = new Date();
let seconds = retryDate.getSeconds();
retryDate.setSeconds(seconds + 60 * (retry + 1));
// 延迟60 * 次数s执行重试
let retryItem = schedule.scheduleJob(retryDate, async () => {
yapi.commons.log(`项目ID为【${plan.project_id}】下测试计划【${plan.plan_name}】失败后自动重试第${retry+1}次`);
this.deleteRetryJob(planId); // 开始执行就取消重试的任务防止重复执行
await handlerPlan(planId, plan, retry + 1);
});
this.addRetryJob(planId, retryItem)
} else if (retry > 0) {
// 重试过的任务不再重试就需要恢复
job && job.reschedule(plan.plan_cron);
}
} catch (e) {
yapi.commons.log(`项目ID为【${plan.project_id}】下测试计划【${plan.plan_name}】配置有误,请检查后重新配置。`);
}
}
let scheduleItem = schedule.scheduleJob(plan.plan_cron, async () => {
handlerPlan(planId, plan, 0);
});
//判断是否已经存在这个任务
let jobItem = jobMap.get(planId);
if (jobItem) {
jobItem.cancel();
}
jobMap.set(planId, scheduleItem);
}
/**
* 获取测试计划
* @param {测试计划id} planId
*/
getTestJob(planId) {
return jobMap.get(planId);
}
/**
* 删除测试计划
* @param {测试计划id} planId
*/
deleteTestJob(planId) {
let jobItem = jobMap.get(planId);
if (jobItem) {
jobItem.cancel();
}
this.deleteRetryJob(planId);
}
// 动态中添加测试结果
saveTestLog(plan, msg, uid, projectId) {
yapi.commons.saveLog({
content: `成功执行计划名为"${plan}"的自动化测试,${msg}。`,
type: 'project',
uid: uid,
username: "自动化测试",
typeid: projectId
});
}
/**
* 添加重试计划
* @param {*} planId
* @param {*} retryItem
*/
addRetryJob(planId, retryItem) {
let jobItem = retryMap.get(planId);
if (jobItem) {
jobItem.cancel();
}
retryMap.set(planId, retryItem)
}
/**
* 删除重试计划
* @param {测试计划id} planId
*/
deleteRetryJob(planId) {
let jobItem = retryMap.get(planId);
if (jobItem) {
jobItem.cancel();
}
}
}
module.exports = testSchedule;