feat(接口自动化): 完成需求16 部分功能 #1002331
--story=1002331 --user=赵勇 16.景执行增加停止操作... https://www.tapd.cn/55049933/s/1032826
This commit is contained in:
parent
ff607a2d48
commit
afb2198ea5
|
@ -6,6 +6,7 @@ import io.metersphere.api.dto.*;
|
|||
import io.metersphere.api.dto.automation.*;
|
||||
import io.metersphere.api.dto.automation.parse.ScenarioImport;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.jmeter.LocalRunner;
|
||||
import io.metersphere.api.service.ApiAutomationService;
|
||||
import io.metersphere.base.domain.ApiScenario;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
|
@ -183,7 +184,7 @@ public class ApiAutomationController {
|
|||
@PostMapping(value = "/run")
|
||||
@MsAuditLog(module = "api_automation", type = OperLogConstants.EXECUTE, content = "#msClass.getLogDetails(#request.ids)", msClass = ApiAutomationService.class)
|
||||
public String run(@RequestBody RunScenarioRequest request) {
|
||||
if(!StringUtils.equals(request.getExecuteType(),ExecuteType.Saved.name())){
|
||||
if (!StringUtils.equals(request.getExecuteType(), ExecuteType.Saved.name())) {
|
||||
request.setExecuteType(ExecuteType.Completed.name());
|
||||
}
|
||||
request.setTriggerMode(TriggerMode.MANUAL.name());
|
||||
|
@ -300,5 +301,10 @@ public class ApiAutomationController {
|
|||
public List<ApiScenrioExportJmx> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
|
||||
return apiAutomationService.exportJmx(request);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/stop/{reportId}")
|
||||
public void stop(@PathVariable String reportId) {
|
||||
new LocalRunner().stop(reportId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
|||
public void teardownTest(BackendListenerContext context) throws Exception {
|
||||
TestResult testResult = new TestResult();
|
||||
testResult.setTestId(testId);
|
||||
MessageCache.runningEngine.remove(testId);
|
||||
testResult.setTotal(0);
|
||||
// 一个脚本里可能包含多个场景(ThreadGroup),所以要区分开,key: 场景Id
|
||||
final Map<String, ScenarioResult> scenarios = new LinkedHashMap<>();
|
||||
|
|
|
@ -69,7 +69,7 @@ public class JMeterService {
|
|||
String runMode = StringUtils.isBlank(debugReportId) ? ApiRunMode.RUN.name() : ApiRunMode.DEBUG.name();
|
||||
addBackendListener(testId, debugReportId, runMode, testPlan);
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
runner.run(testId);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("api_load_script_error"));
|
||||
|
@ -130,7 +130,7 @@ public class JMeterService {
|
|||
addResultCollector(testId, testPlan);
|
||||
}
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
runner.run(testId);
|
||||
}
|
||||
|
||||
public void runTest(String testId, String reportId, String runMode, String testPlanScenarioId, RunModeConfig config) {
|
||||
|
|
|
@ -1,24 +1,41 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.jmeter.engine.JMeterEngine;
|
||||
import org.apache.jmeter.engine.JMeterEngineException;
|
||||
import org.apache.jmeter.engine.StandardJMeterEngine;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
|
||||
public class LocalRunner {
|
||||
private final HashTree jmxTree;
|
||||
private HashTree jmxTree;
|
||||
|
||||
public LocalRunner(HashTree jmxTree) {
|
||||
this.jmxTree = jmxTree;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
public LocalRunner() {
|
||||
}
|
||||
|
||||
public void run(String report) {
|
||||
JMeterEngine engine = new StandardJMeterEngine();
|
||||
engine.configure(jmxTree);
|
||||
try {
|
||||
engine.runTest();
|
||||
MessageCache.runningEngine.put(report, engine);
|
||||
} catch (JMeterEngineException e) {
|
||||
engine.stopTest(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(String report) {
|
||||
try {
|
||||
JMeterEngine engine = MessageCache.runningEngine.get(report);
|
||||
if (engine != null) {
|
||||
engine.stopTest();
|
||||
MessageCache.runningEngine.remove(report);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package io.metersphere.api.jmeter;
|
||||
|
||||
import org.apache.jmeter.engine.JMeterEngine;
|
||||
|
||||
import javax.websocket.Session;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -10,4 +12,6 @@ public class MessageCache {
|
|||
|
||||
public static ConcurrentHashMap<String, Session> reportCache = new ConcurrentHashMap<>();
|
||||
|
||||
public static ConcurrentHashMap<String, JMeterEngine> runningEngine = new ConcurrentHashMap<>();
|
||||
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-tooltip>
|
||||
<el-button icon="el-icon-loading" size="mini" type="primary" :disabled="debug" v-else>执行中</el-button>
|
||||
<el-button size="mini" type="primary" v-else @click="stop">{{ $t('report.stop_btn') }}</el-button>
|
||||
<el-tooltip class="item" effect="dark" :content="$t('commons.refresh')" placement="top-start">
|
||||
<el-button :disabled="scenarioDefinition.length < 1" size="mini" icon="el-icon-refresh"
|
||||
v-prevent-re-click @click="getApiScenario"></el-button>
|
||||
|
@ -292,6 +292,7 @@
|
|||
@showScenarioParameters="showScenarioParameters"
|
||||
@setCookieShare="setCookieShare"
|
||||
@setSampleError="setSampleError"
|
||||
@stop="stop"
|
||||
ref="maximizeHeader"/>
|
||||
</template>
|
||||
|
||||
|
@ -308,14 +309,14 @@
|
|||
:debug="debug"
|
||||
:reloadDebug="reloadDebug"
|
||||
:stepReEnable="stepEnable"
|
||||
:message="message"
|
||||
@openScenario="openScenario"
|
||||
ref="maximizeScenario"/>
|
||||
</ms-drawer>
|
||||
<ms-change-history ref="changeHistory"/>
|
||||
|
||||
<el-backtop target=".card-content" :visibility-height="100" :right="50"></el-backtop>
|
||||
</div>
|
||||
<ms-task-center ref="taskCenter"/>
|
||||
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
@ -488,6 +489,22 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
stop() {
|
||||
let url = "/api/automation/stop/" + this.reportId;
|
||||
this.$get(url, response => {
|
||||
this.debugLoading = false;
|
||||
if (this.websocket) {
|
||||
this.websocket.close();
|
||||
}
|
||||
if (this.messageWebSocket) {
|
||||
this.messageWebSocket.close();
|
||||
}
|
||||
this.clearNodeStatus(this.$refs.stepTree.root.childNodes);
|
||||
this.clearDebug();
|
||||
this.$success(this.$t('report.test_stop_success'));
|
||||
this.reload();
|
||||
});
|
||||
},
|
||||
clearDebug() {
|
||||
this.reqError = 0;
|
||||
this.reqTotalTime = 0;
|
||||
|
@ -1452,6 +1469,7 @@ export default {
|
|||
|
||||
#fab {
|
||||
right: 90px;
|
||||
bottom: 120px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
:node="node"
|
||||
:project-list="projectList"
|
||||
:env-map="projectEnvMap"
|
||||
:message="message"
|
||||
@remove="remove" @copyRow="copyRow"
|
||||
@suggestClick="suggestClick"
|
||||
@refReload="refReload" @openScenario="openScenario"/>
|
||||
|
@ -140,6 +141,8 @@
|
|||
class="ms-sc-variable-header"/>
|
||||
<!--外部导入-->
|
||||
<api-import v-if="type!=='detail'" ref="apiImport" :saved="false" @refresh="apiImport"/>
|
||||
<el-backtop target=".el-main .ms-main-container" :visibility-height="10" :right="50" :bottom="20"></el-backtop>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -184,6 +187,7 @@ export default {
|
|||
reqSuccess: Number,
|
||||
reqError: Number,
|
||||
reqTotalTime: Number,
|
||||
message: String,
|
||||
},
|
||||
components: {
|
||||
MsVariableList,
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
<el-dropdown-item>{{ $t('api_test.automation.generate_report') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button icon="el-icon-loading" size="mini" type="primary" :disabled="debug" v-else>执行中</el-button>
|
||||
<el-button size="mini" type="primary" v-else @click="stop">{{ $t('report.stop_btn') }}</el-button>
|
||||
|
||||
<font-awesome-icon class="ms-alt-ico" :icon="['fa', 'compress-alt']" size="lg" @click="unFullScreen"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -100,6 +101,11 @@ export default {
|
|||
}, 1000);
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
this.debug = false;
|
||||
this.debugLoading = false;
|
||||
this.$emit('stop');
|
||||
},
|
||||
showAll() {
|
||||
this.$emit('showAllBtn');
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue