feat(接口自动化): 完成需求16 部分功能 #1002331

--story=1002331 --user=赵勇 16.景执行增加停止操作... https://www.tapd.cn/55049933/s/1032826
This commit is contained in:
fit2-zhao 2021-08-05 19:11:13 +08:00 committed by fit2-zhao
parent ff607a2d48
commit afb2198ea5
8 changed files with 65 additions and 9 deletions

View File

@ -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);
}
}

View File

@ -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<>();

View File

@ -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) {

View File

@ -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());
}
}
}

View File

@ -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<>();
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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');
},