package com.zkx.api.common;
import com.alibaba.fastjson.JSONObject;
import com.zkx.api.dao.ApiMapper;
import com.zkx.api.dao.CaseMapper;
import com.zkx.api.dao.DataMapper;
import com.zkx.api.dao.HeaderMapper;
import com.zkx.api.dto.ApiDto;
import com.zkx.api.service.CaseService;
import com.zkx.api.vo.ApiVo;
import com.zkx.api.vo.DataVo;
import com.zkx.api.vo.HeaderVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.jmeter.assertions.ResponseAssertion;
import org.apache.jmeter.assertions.gui.AssertionGui;
import org.apache.jmeter.control.LoopController;
import org.apache.jmeter.control.gui.LoopControlPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.protocol.http.control.Header;
import org.apache.jmeter.protocol.http.control.HeaderManager;
import org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui;
import org.apache.jmeter.protocol.http.gui.HeaderPanel;
import org.apache.jmeter.protocol.http.sampler.HTTPSampler;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
import org.apache.jmeter.reporters.ResultCollector;
import org.apache.jmeter.reporters.Summariser;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.threads.SetupThreadGroup;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.threads.gui.ThreadGroupGui;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.RespTimeGraphVisualizer;
import org.apache.jmeter.visualizers.SummaryReport;
import org.apache.jmeter.visualizers.ViewResultsFullVisualizer;
import org.apache.jorphan.collections.HashTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
@Slf4j
@Component
public class JMeterTest {
@Autowired
ApiMapper apiMapper
;
@Autowired
DataMapper dataMapper
;
@Autowired
HeaderMapper headerMapper
;
@Autowired
CaseService caseService
;
@Autowired
CaseMapper caseMapper
;
@Value("${jmeter.home}")
private String jmeterHome
;
@Value("${jmeter.file}")
private String jmeterFile
;
@Value("${jmeter.properties}")
private String jmeterProperties
;
@Value("${jmeter.nginx}")
private String jmeterNginx
;
public RespBean createJMeterFile(int apiId
) throws IOException {
JMeterUtils.loadJMeterProperties(jmeterProperties
);
JMeterUtils.setJMeterHome(jmeterHome
);
JMeterUtils.initLocale();
ApiVo apiVo
= apiMapper
.findApiById(apiId
);
String apiName
= apiVo
.getName();
String apiUrl
= apiVo
.getUrl();
String apiMethod
= apiVo
.getMethod();
List<DataVo> dataList
= dataMapper
.findDataByApiId(apiId
);
List<HeaderVo> headerVoList
= headerMapper
.findHeaderByApiId(apiId
);
TestPlan testPlan
= createTestPlan(apiName
);
SetupThreadGroup threadGroup
= createThreadGroup();
HeaderVo headerVo
= new HeaderVo();
if (apiVo
.getData_type().equals("json")) {
headerVo
.setKey("Content-Type");
headerVo
.setValue("application/json;charset=UTF-8");
headerVoList
.add(headerVo
);
}
HeaderManager headerManager
= createHeaderManager(headerVoList
);
LoopController loopController
= createLoopController();
threadGroup
.setSamplerController(loopController
);
HashTree subTree
= new HashTree();
HTTPFileArg httpFileArg
= new HTTPFileArg();
HTTPSampler httpSampler
= createHTTPSampler(apiUrl
,apiMethod
);
if (null != apiVo
.getData_type()){
if (apiVo
.getData_type().equals("json")){
HTTPArgument httpArgument
= createHTTPArgument(dataList
);
httpSampler
.getArguments().addArgument(httpArgument
);
}else if (apiVo
.getData_type().equals("form-data")) {
for (DataVo dataVo
: dataList
) {
if (null != dataVo
.getType()) {
if (dataVo
.getType().equals("file")) {
httpFileArg
.setPath(dataVo
.getKey());
httpFileArg
.setParamName(dataVo
.getFile_path());
httpSampler
.setHTTPFiles(new HTTPFileArg[] {httpFileArg
});
}else {
httpSampler
.addArgument(dataVo
.getKey(),dataVo
.getValue());
}
}
}
}else if (apiVo
.getData_type().equals("form-urlencoded")) {
for (DataVo dataVo
: dataList
) {
httpSampler
.addArgument(dataVo
.getKey(),dataVo
.getValue());
}
}
}
threadGroup
.addTestElement(headerManager
);
threadGroup
.addTestElement(httpSampler
);
subTree
.add(threadGroup
,httpSampler
);
Summariser summariser
= new Summariser();
ResultCollector resultCollector
= createResultCollector(summariser
,1,apiName
);
ResultCollector responseTime
= createResultCollector(summariser
,2,apiName
);
ResultCollector resultTree
= createResultCollector(summariser
,3,apiName
);
ResponseAssertion responseAssertion
= createResponseAssertion(caseMapper
.findExpectResultByApiId(apiId
));
testPlan
.addThreadGroup(threadGroup
);
subTree
.add(threadGroup
,headerManager
);
subTree
.add(threadGroup
,resultCollector
);
subTree
.add(threadGroup
,responseTime
);
subTree
.add(threadGroup
,resultTree
);
subTree
.add(threadGroup
,responseAssertion
);
HashTree tree
= new HashTree();
tree
.add(testPlan
,subTree
);
SaveService.saveTree(tree
, new FileOutputStream(jmeterFile
+ apiName
+".jmx"));
ApiDto apiDto
= new ApiDto();
apiDto
.setId(apiId
);
apiDto
.setJmeter_file(jmeterFile
+ apiName
+".jmx");
apiMapper
.updateApi(apiDto
);
log
.info("生成jmeter脚本成功",jmeterFile
+ apiName
+".jmx");
return RespBean.ok("生成jmeter脚本成功",jmeterNginx
+ apiName
+".jmx");
}
private LoopController createLoopController() {
LoopController loopController
= new LoopController();
loopController
.setName("循环控制器");
loopController
.setLoops(10);
loopController
.setFirst(true);
loopController
.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
loopController
.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
return loopController
;
}
private TestPlan createTestPlan(String name
) {
TestPlan testPlan
= new TestPlan(name
);
testPlan
.setFunctionalMode(false);
testPlan
.setTearDownOnShutdown(true);
testPlan
.setComment("");
testPlan
.setSerialized(false);
testPlan
.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan
.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
return testPlan
;
}
private SetupThreadGroup createThreadGroup() {
SetupThreadGroup threadGroup
= new SetupThreadGroup();
threadGroup
.setName("线程组");
threadGroup
.isEnabled();
threadGroup
.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
threadGroup
.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());
threadGroup
.setNumThreads(1);
threadGroup
.setRampUp(0);
return threadGroup
;
}
private HeaderManager createHeaderManager(List<HeaderVo> lists
) {
HeaderManager headerManager
= new HeaderManager();
headerManager
.setName("请求头管理器");
headerManager
.isEnabled();
headerManager
.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
headerManager
.setProperty(TestElement.GUI_CLASS, HeaderPanel.class.getName());
if (lists
.size() > 0) {
for (HeaderVo headerVo
: lists
) {
headerManager
.add(new Header(headerVo
.getKey(), headerVo
.getValue()));
}
}
return headerManager
;
}
private HTTPArgument createHTTPArgument(List<DataVo> lists
) {
HTTPArgument httpArgument
= new HTTPArgument();
HashMap hashMap
= caseService
.convertValue(lists
);
String jsonStr
= JSONObject.toJSONString(hashMap
);
httpArgument
.setValue(jsonStr
);
return httpArgument
;
}
private HTTPSampler createHTTPSampler(String apiUrl
, String apiMethod
) throws MalformedURLException {
URL url
= new URL(apiUrl
);
HTTPSampler httpSampler
= new HTTPSampler();
httpSampler
.setDomain(url
.getHost());
httpSampler
.setPort(url
.getPort());
httpSampler
.setPath(url
.getPath());
httpSampler
.setMethod(apiMethod
);
httpSampler
.setName("HTTP请求");
httpSampler
.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
httpSampler
.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.