Commit 20d381eb by 吴博

feat: [none] ws_auto_test

parent 124f8e6f
......@@ -281,7 +281,40 @@
<version>3.1.1-RELEASE</version>
</dependency>
<dependency>
<groupId>CGLIB</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version> <!-- 确保版本适合您的项目 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.6.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.14</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.6.9</version> <!-- 使用正确定义的版本 -->
</dependency>
</dependencies>
......
......@@ -13,6 +13,7 @@ import com.lemon.utils.HttpUtils;
import io.qameta.allure.Step;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
......@@ -227,9 +228,7 @@ public class BaseCase {
@Step("结束")
public void finish() {
//所有的接口都执行完毕后再执行批量回写
log.info("===================批量回写===================");
ExcelUtils.batchWrite();
log.info("===================项目结束===================");
}
......
......@@ -3,24 +3,18 @@ package com.lemon.cases;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lemon.constants.Constants;
import com.lemon.pojo.API;
import com.lemon.pojo.Case;
import com.lemon.pojo.TestRecord;
import com.lemon.testng.WebSocketManager;
import com.lemon.utils.ExcelUtils;
import com.lemon.utils.SqlUtils;
import com.pcloud.llm.cockpit.api.domain.dto.request.DifyRequestFile;
import com.pcloud.llm.cockpit.api.domain.dto.request.WorkflowRequestBody;
import com.pcloud.llm.cockpit.api.domain.dto.response.CompletionResponse;
import com.pcloud.llm.cockpit.client.DifyClient;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
......@@ -38,14 +32,11 @@ import java.util.concurrent.TimeUnit;
import static com.lemon.utils.Robot.sendAlarm;
@Component
public class changjiangzuoyeserveCase extends BaseCase {
private WebSocketManager webSocketManager;
@Autowired
private DifyClient difyClient;
//excel用例路径
public static final String EXCEL_PATH = "src/test/resources/changjiangcase.xls";
......@@ -57,6 +48,12 @@ public class changjiangzuoyeserveCase extends BaseCase {
public void setup() throws URISyntaxException {
webSocketManager = new WebSocketManager();
webSocketManager.connect();
// 清空所有共享变量
ExcelUtils.wbdList.clear();
ExcelUtils.caseList.clear();
ExcelUtils.parameterList.clear();
ExcelUtils.apiList.clear();
}
......@@ -101,12 +98,10 @@ public class changjiangzuoyeserveCase extends BaseCase {
Assert.assertTrue(event5Received, "未在规定时间内收到 event-5 响应");
// 验证 event-5 消息的内容
log.info(caseTraceId + "event5 收到的消息是: " + JSONUtil.toJsonStr(webSocketManager.event5Messages));
/*
addWBD(Integer.parseInt(cas.getId()), Constants.ASSERT_RESULT_CELL_NUM, "");
*/
Assert.assertNotNull(webSocketManager.event5Messages, "event-5 消息不应为空");
addWBD(Integer.parseInt(cas.getId()), 6, JSONUtil.toJsonStr(webSocketManager.event5Messages));
cas.setActualValue(JSONUtil.toJsonStr(webSocketManager.event5Messages));
cas.setPassState(cas.getExpectValue().equals(cas.getActualValue()) ? 1 : 0);
cas.setPass(cas.getExpectValue().equals(cas.getActualValue()) ? 1 : 0);
} catch (Exception e) {
log.info(caseTraceId + "testReceiveEvent5Responses,WebSocket出错: " + e.getMessage());
} finally {
......@@ -118,14 +113,14 @@ public class changjiangzuoyeserveCase extends BaseCase {
testRecord.setExpectContent(cas.getExpectValue());
testRecord.setInputContent(cas.getParams());
testRecord.setOutputContent(JSONUtil.toJsonStr(webSocketManager.event5Messages));
testRecord.setState(cas.getPassState());
testRecord.setState(cas.getPass());
testRecord.setTestVersion(DateUtils.formatDate(new Date(), "yyyyMMdd HH:mm"));
testRecord.setCreateTime(new Date());
testRecord.setUpdateTime(new Date());
testRecord.setIsDelete(0);
// SqlUtils.insertTestRecord(testRecord);
// 如果失败则发送消息提醒
if (cas.getPassState() == null || cas.getPassState() == 0)
if (cas.getPass() == null || cas.getPass() == 0)
sendAlarm(cas.getParams());
}
}
......@@ -155,26 +150,23 @@ public class changjiangzuoyeserveCase extends BaseCase {
inputs.put("inquery", jsonStr);
WorkflowRequestBody requestBody = WorkflowRequestBody.builder().user(ramdonUserId).inputs(inputs).build();
log.info(caseTraceId + "调用dify请求参数:" + JSONUtil.toJsonStr(requestBody));
int count = 0;
String res = "";
try {
do {
CompletionResponse aiTopicScience = difyClient.workflowsRunBlocking("ai_autotest", requestBody);
CompletionResponse aiTopicScience = webSocketManager.workflowsRunBlocking("ai_autotest", requestBody);
Map<String, Object> outputs = aiTopicScience.getData().getOutputs();
res = (String) outputs.get("result");
if (count > 3) {
log.info(caseTraceId + "没有返回指定内容,dify调用开始重试" + com.alibaba.fastjson.JSONObject.toJSONString(requestBody));
break;
res = res.replace("```json", "").replace("```", "");
List<Case> resultList = JSONUtil.toList(res,Case.class);
for (Case item : resultList) {
addWBD(Integer.parseInt(item.getId()), 7, Optional.ofNullable(item.getPass()).map(String::valueOf).orElse(""));
}
int finalCount = count;
ThreadUtil.safeSleep(1 + finalCount * 2L);
count++;
} while (!StrUtil.containsAny(res, "考查知识", "解题思路", "分步骤讲解"));
} catch (Exception e) {
log.warn("请求dify异常:{}" + e.getMessage());
}
log.info(caseTraceId + "dify返回的内容======>{}" + res);
log.info("===================批量回写===================");
ExcelUtils.batchWrite(EXCEL_PATH);
log.info("===================项目结束===================");
}
@DataProvider(name = "data1")
......
package com.lemon.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@ComponentScan({"com.lemon","com.pcloud"})
@EnableScheduling
public class AppContext {
}
package com.lemon.config;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
/**
* @description: 启动类
*
* @author: huwei
* @dateTime: 2023/5/24 14:12
*/
@SpringBootApplication
public class AskBooksApplication {
public static void main(String[] args) {
// 定义Nacos相关目录,即当前项目运行所在目录,会自动建nacos目录
System.setProperty("JM.LOG.PATH", ".");
System.setProperty("JM.SNAPSHOT.PATH", ".");
new SpringApplicationBuilder(AskBooksApplication.class).build(args).run(args);
}
}
package com.lemon.config;
import com.pcloud.llm.cockpit.client.DifyClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DifyClientConfig {
@Bean
public DifyClient difyClient() {
System.out.println("开始创建DifyClient");
// 在这里创建 DifyClient 的实例,并进行所需的配置
return new DifyClient(/* 参数配置 */);
}
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ public class Case {
@Excel(name = "消息条数")
private Integer messageCount;
@Excel(name = "是否验证通过")
private Integer passState;
private Integer pass;
@Excel(name = "实际响应数据")
private String actualValue;
......@@ -41,7 +41,7 @@ public class Case {
}
public Case(String id, String desc, String params, String apiID, String expectValue, String checkSQL, String aExpectValue,
String checkBSQL, String bExpectValue,Boolean stream, Integer messageCount,Integer passState,String actualValue) {
String checkBSQL, String bExpectValue,Boolean stream, Integer messageCount,Integer pass,String actualValue) {
this.id = id;
this.desc = desc;
this.params = params;
......@@ -53,7 +53,7 @@ public class Case {
this.bExpectValue = bExpectValue;
this.stream = stream;
this.messageCount = messageCount;
this.passState = passState;
this.pass = pass;
this.actualValue = actualValue;
}
......@@ -145,12 +145,12 @@ public class Case {
this.messageCount = messageCount;
}
public Integer getPassState() {
return passState;
public Integer getPass() {
return pass;
}
public void setPassState(Integer passState) {
this.passState = passState;
public void setPass(Integer pass) {
this.pass = pass;
}
public String getActualValue() {
......@@ -175,7 +175,7 @@ public class Case {
", bExpectValue='" + bExpectValue + '\'' +
", stream=" + stream +
", messageCount=" + messageCount +
", passState=" + passState +
", pass=" + pass +
", actualValue='" + actualValue + '\'' +
'}';
}
......
package com.lemon.testng;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.lemon.utils.AuthorizationUtils;
import com.pcloud.llm.cockpit.api.constants.Constants;
import com.pcloud.llm.cockpit.api.domain.dto.request.WorkflowRequestBody;
import com.pcloud.llm.cockpit.api.domain.dto.response.CompletionResponse;
import com.pcloud.llm.cockpit.api.domain.dto.response.CompletionResponseData;
import org.apache.log4j.Logger;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
......@@ -116,4 +129,34 @@ public class WebSocketManager {
public void close() {
webSocketClient.close();
}
/**
* 工作流同步接口
* @param callCode Dify调用code
* @param dto 参数
* @return 同步返回
*/
public CompletionResponse workflowsRunBlocking(String callCode, WorkflowRequestBody dto) {
dto.setResponse_mode(Constants.RESPONSE_MODE_BLOCKING);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
headers.add(Constants.CALL_CODE_HEADER, callCode);
try {
String server = "http://192.168.92.235:8313";
HttpRequest post= HttpUtil.createPost(server + "/v1/workflows/run");
post.addHeaders(headers.toSingleValueMap());
post.body(JSONUtil.toJsonStr(dto));
HttpResponse httpResponse = post.execute();
CompletionResponse result = JSONUtil.toBean(httpResponse.body(), CompletionResponse.class);
log.info("workflow:" + callCode + "->" + JSON.toJSONString(dto) + "=>" + JSON.toJSONString(result) + ",server=" + server);
return result;
} catch (Throwable t) {
log.error("workflow:" + callCode + "->" + JSON.toJSONString(dto), t);
CompletionResponse result = new CompletionResponse();
CompletionResponseData data = new CompletionResponseData();
data.setStatus("failed");
data.setError(t.getMessage());
return result;
}
}
}
\ No newline at end of file
......@@ -54,7 +54,7 @@ public class ExcelUtils {
} finally {
close(fis);
}
return null;
return new ArrayList<>();
}
public static <E> List<E> read(String filePath,int startSheetIndex, Class<E> clazz) {
......@@ -132,6 +132,38 @@ public class ExcelUtils {
}
}
// 不用传参,因为集合为静态方法,修改Excel需要用到原生的poi
public static void batchWrite(String filePath) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(filePath);
Workbook workbook = WorkbookFactory.create(fis);
Sheet sheet = workbook.getSheetAt(0);
//回写操作行和列
//1、遍历wbdList集合
for (WriteBackData wbd : wbdList) {
//2、获取行号,根据行号获取row对象
int rowNum = wbd.getRowNum();
Row row = sheet.getRow(rowNum);
//3、获取列号,根据列号获取cell对象
int cellNum = wbd.getCellNum();
Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
//4、获取回写内容,设置到cell中
cell.setCellType(CellType.STRING);
String content = wbd.getContent();
// 5、将数据设置到Excel对应行和列中
cell.setCellValue(content);
}
fos = new FileOutputStream(filePath);
workbook.write(fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
close(fis);
close(fos);
}
}
/*
* 从已经读取很多所有list<API>和所有list<Case>
......
......@@ -20,8 +20,9 @@
<!-- </test>-->
<test name="RAYS7服务"> <!-- 模块-->
<parameter name="excelPath" value="src/test/resources/changjiangcase.xls"/> <!-- 示例参数 -->
<classes>
<class name="com.lemon.cases.ServerCase"/> <!-- 测试类/用例类-->
<class name="com.lemon.cases.changjiangzuoyeserveCase"/> <!-- 测试类/用例类-->
</classes>
</test>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment