JMeter-SSE响应数据自动化3.0

背景

此次因为多了一些需要过滤排除的错误(数量很少),还需要修改下JMeter的jtl文件输出数据(后续统计数据需要)
所以只涉及到JSR脚本的一些改动(此部分改动并不会影响到JMeter的HTML报告)

改动

主要通过设置JMeter中prev输出数据变量threadName为appName这样的方法,来控制jtl的数据。

prev.setThreadName(vars.get(“xxx”) + “^” + vars.get(“xxx”));

脚本如下:
具体改动可以对比自动化2.0

要注意一些响应信息自带的换行符(\n),可能会影响到后续处理jtl文件的数据,目前用的是将\n更换为"-" 或者 “”

import org.apache.jmeter.samplers.SampleResult;
import org.json.JSONObject;
import org.json.JSONException;// 每次脚本执行前需要重置的变量
private void init(){// 添加APPID信息vars.put("APPID",vars.get("appId"));// 每次重置isExist的值,避免上次结果影响本次vars.put("isExist", "true");// 每次重置断言输出信息vars.put("response_type","");vars.put("error_msg", "");vars.put("actual_msg", "");// 设置threadName为appNameprev.setThreadName(vars.get("appName") + "^" + vars.get("xxx"));}// 判断是否是流式响应
private Boolean isStreamingResponse(String response) {return response.contains("data: {");
}// 非流式响应处理,即HTTP请求错误处理
private void errorResponse(String response) {log.info("进入errorResponse处理!!!");    // 判断是不是json格式的响应,first == { ? 是 : 不是response = response.replace("\n","");String first = response.substring(0,1);if("{".equals(first)) {// json格式的错误响应jsonErrorResponse(response);}else {// 非json格式的错误响应noJsonErrorResponse(response);}
}// json格式的错误响应处理
private void jsonErrorResponse(String response) throws Exception {JSONObject jsonResponse = new JSONObject(response);String msg = jsonResponse.get("msg");if ("智能体不存在".equals(msg)) {setAssertMsg("xxx",msg);} else {setAssertMsg("服务器错误",msg);}
}// 非json格式的错误响应处理
private void noJsonErrorResponse(String response) throws Exception {String mainMag = response.substring(0,response.indexOf("at "));setAssertMsg("服务器/其他错误",mainMag);}// 处理SSE响应数据,以data: 为分隔符,输出结果到String[] 中
private String[] splitResponse(String resp) {try {return resp.split("data: ");}catch(Exception e) {log.error("拆分resp为String数组失败!xxx:" + vars.get("appName"));}
}// 获取event信息
private String getEvent(String resp) {try {String ret = resp.substring(resp.indexOf("\"", 8)+1, resp.indexOf("\"", 12));return ret;}catch(Exception e) {log.error("获取event的字段内容失败!");return "Unknow";}
}// 处理event = error 的响应
private void errorResp(String resp) {try{JSONObject jsonResponse = new JSONObject(resp);String errorMsg = jsonResponse.get("message");setAssertMsg("xxx",errorMsg);}catch(Exception e) {log.error("处理 error 响应信息失败");}
}// 判断有无特定target
private Boolean hasTarget(String resp) {String targetStr = vars.get("target");// 每次执行后重置target,避免影响下次target的值vars.put("target", "");return resp.contains(targetStr);
}// 断言参数设置
private void setAssertMsg(String response_type,String error_msg){vars.put("response_type",response_type);vars.put("error_msg", error_msg);vars.put("isExist", "false");
}
private void setAssertMsg(String resp){//此方法用于无目标值的断言参数设置//获取answer中的信息,实际msgJSONObject jsonResp = new JSONObject(resp);String answer = jsonResp.get("data").get("outputs").optString("answer");vars.put("response_type","输出结果与预期不符");vars.put("actual_msg", answer);vars.put("isExist", "false");
}/**正确响应结果获取正常响应的最终结果,并设置到ResponseMessage,以供后续使用
*/
private void setTrueResp(String resp){//获取answer中的信息,实际msgJSONObject jsonResp = new JSONObject(resp);String answer = jsonResp.get("data").get("outputs").optString("answer");String s = answer.replace("\n","-");prev.setResponseMessage(s);vars.put("isExist", "true");}// 是否需要判断 特定target
private Boolean needCheckTarget(String resp) {if(vars.get("target") != null || !"".equals(vars.get("target"))) {// 有target,需要判断特定targetreturn hasTarget(resp);}else {// 无需判断特定targetreturn true;}
}// 过滤器,过滤白名单
private void filter(String resp) {try {Set<String> whiteSet = vars.getObject("whiteSet");String appId = vars.get("APPID");if(whiteSet.contains(appId)) {vars.put("isExist", "true");}else {// 非白名单errorResp(resp);}} catch (Exception e) {setAssertMsg("过滤器失效!","xxx");log.warn("过滤白名单失败!");}
}/**每次执行后,处理变量避免下次空变量的值 受上次的影响变量:mustParam
*/
private void afterHandle(){vars.put("mustParam","");vars.put("target","");
}SampleResult prev = ctx.getPreviousResult();String response = prev.getResponseDataAsString();// 执行前重置变量
init();// 判断是不是SSE响应
try {if (!isStreamingResponse(response)) {// 非SSE响应errorResponse(response);} else {// SSE响应// 拆分String[] respArray = splitResponse(response);// 获取event,进行判断String event = getEvent(respArray[respArray.length - 1]);if("message_end".equals(event)) {// 没有错误,判断 workflow_finished 响应中含有目标字段if(needCheckTarget(respArray[respArray.length - 2])){setTrueResp(respArray[respArray.length - 2]);}else {// 无目标字段,更新断言信息setAssertMsg(respArray[respArray.length - 2]);}}else if("error".equals(event)) {// 有报错,进入过滤器,过滤白名单filter(respArray[respArray.length - 1]);}else if("Unknow".equals(event)) {// 获取event的字段内容失败!setAssertMsg("xxx","xxx");}else {// 未知错误setAssertMsg("xxx!","xxx");}}
} catch (Exception e) {log.error("处理响应失败!", e);setAssertMsg("xxx!","xxx");prev.setSuccessful(false);
}finally {afterHandle();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88143.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

012 进程状态和优先级

&#x1f984; 个人主页: 小米里的大麦-CSDN博客 &#x1f38f; 所属专栏: Linux_小米里的大麦的博客-CSDN博客 &#x1f381; GitHub主页: 小米里的大麦的 GitHub ⚙️ 操作环境: Visual Studio 2022 文章目录 进程状态和优先级一、进程状态分类特殊状态说明 二、如何查看进程…

React JSX原理

JSX本质 实质上是React.createElement()的语法糖

Java-51 深入浅出 Tomcat 手写 Tomcat 类加载机制 双亲委派机制 生命周期 插件化

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月13日更新到&#xff1a; AI炼丹日志-28 - Aud…

从C++编程入手设计模式——责任链模式

从C编程入手设计模式——责任链模式 ​ 当我们的一个请求需要多个对象去处理&#xff0c;但具体由谁来处理&#xff0c;是根据情况动态决定的。例如&#xff0c;一个日志系统中&#xff0c;可能希望把错误信息写入文件&#xff0c;把提示信息输出到控制台&#xff0c;而不是每…

泛型方法调用需要显示指定泛型类型的场景

泛型类型的推断确定 一般来说&#xff0c;泛型类型的推断可以由以下几个场景确定&#xff1a; 变量定义指定类型 List<String> strList new ArrayList<>();ArrayList的泛型类型是依据变量的类型确定的。 方法返回值确定 Overridepublic Function<List<I…

Deep Research:开启深度研究的智能新时代

在当今信息爆炸的时代&#xff0c;人们面临着海量的信息&#xff0c;无论是专业人士还是普通消费者&#xff0c;都迫切需要一种高效、精准的方式来获取和分析信息。OpenAI 推出的 Deep Research&#xff0c;宛如一颗璀璨的新星&#xff0c;在知识的海洋中为我们导航&#xff0c…

曼昆《经济学原理》第九版 宏观经济学 第二十四章失业与自然失业率

以下是曼昆《经济学原理》第九版宏观经济学第二十四章**“失业与自然失业率”**的详细讲解&#xff0c;从零基础开始构建知识框架&#xff0c;结合中国实际案例与生活化比喻&#xff0c;帮助小白系统理解核心概念&#xff1a; 一、知识框架&#xff1a;失业的“全景图” 1. 核…

【软考高级系统架构论文】论软件系统架构风格

论文真题 请以“软件系统架构风格”为论题,依次从以下三个方面进行论述: 1、概要叙述你参与分析和开发的软件系统开发项目以及你所担任的主要工作。 2、分析软件系统开发中常用的软件系统架构风格有哪些?详细阐述每种风格的具体含义。 3、详细说明在你所参与的软件系统开发项…

LeetCode--35.搜索插入位置

解题思路&#xff1a; 1.获取信息&#xff1a; 给定一个升序排列的数组和一个整数&#xff0c;要求查找该整数应该在数组中插入的位置 限制条件是&#xff0c;要求时间复杂度为O(log N) 2.分析题目&#xff1a; 时间复杂度要求O(log N)&#xff0c;那么就使用二分查找法&#x…

Unix、Linux、POSIX、Minix 区别与联系

一、Unix&#xff1a;现代操作系统的技术原型 诞生&#xff1a;1969年贝尔实验室&#xff0c;用C语言重写后实现跨平台&#xff08;1973年&#xff09;。核心设计&#xff1a; 一切皆文件&#xff08;设备/进程均抽象为文件&#xff09;。管道&#xff08;|&#xff09;和文本…

python计算长方形的周长 2025年3月青少年电子学会等级考试 中小学生python编程等级考试一级真题答案解析

python计算长方形的周长 2025年3月 python编程等级考试一级编程题 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】 1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解 蓝桥杯python省赛真题详解 蓝桥杯python国赛真题详解 2、Python考级 p…

使用 RedisVL 进行复杂查询

一、前置条件 在开始之前&#xff0c;请确保&#xff1a; 已安装 redisvl 并激活相应的 Python 环境。运行 Redis 实例&#xff0c;且 RediSearch 版本 > 2.4。 二、初始化与数据加载 我们将使用一个包含用户信息的数据集&#xff0c;字段包括 user、age、job、credit_s…

「Linux文件及目录管理」vi、vim编辑器

知识点解析 vi/vim编辑器简介 vi:Linux默认的文本编辑器,基于命令行操作,功能强大。vim:vi的增强版,支持语法高亮、多窗口编辑、插件扩展等功能。vi/vim基本模式 命令模式:默认模式,用于移动光标、复制、粘贴、删除等操作。插入模式:按i进入,用于输入文本。末行模式:…

电容器保护测控装置如何选型?

在电力系统的无功补偿环节&#xff0c;​电容器保护测控装置是保障并联电容器组安全稳定运行的核心设备。其选型需综合考量保护需求、系统环境及扩展功能。以下是关键选型要素分析&#xff1a; ​一、明确核心功能需求​ 电容器保护测控装置&#xff0c;选型时需匹配电容器组实…

最近小峰一直在忙国际化项目,确实有点分身乏术... [特殊字符] 不过! 我正紧锣密鼓准备一系列干货文章/深度解析

本人详解 大家晚上好呀&#xff01;&#x1f319; 最近小峰一直在忙国际化项目&#xff0c;确实有点分身乏术... &#x1f605; 不过&#xff01; 我正紧锣密鼓准备一系列干货文章/深度解析&#xff08;选一个更符合你内容的词&#xff09;&#xff0c;很快就会和大家见面啦&am…

OpenCV CUDA模块设备层-----设备端(GPU)线程块级别的一个内存拷贝工具函数blockCopy()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在同一个线程块&#xff08;thread block内&#xff0c;将 [beg, end) 范围内的数据并行地复制到 out 开始的位置。 它使用了 CUDA 线程协作机制…

https没有证书可以访问吗?外网怎么访问内网?

没有SSL证书的网站无法正常通过HTTPS协议访问‌。HTTPS的实现必须依赖有效的SSL证书完成加密握手&#xff0c;否则浏览器会直接阻断连接或显示严重的安全警告。‌‌ 一、技术实现层面‌ ‌HTTPS协议强制要求证书‌。 HTTPS基于SSL/TLS协议实现加密通信&#xff0c;而SSL证书是…

Python pytesseract【OCR引擎库】 简介

想全面了解DeepSeek的看过来 【包邮】DeepSeek全攻略 人人需要的AI通识课 零基础掌握DeepSeek的实用操作手册指南【限量作者亲笔签名版售完即止】 玩转DeepSeek这本就够了 【自营包邮】DeepSeek实战指南 deepseek从入门到精通实用操作指南现代科技科普读物AI普及知识读物人工智…

ubuntu安装postman教程并中文汉化详细教程

一、下载postman安装包 通过网盘分享的文件:Postman-linux-x64-8.7.0.tar.gz 链接: https://pan.baidu.com/s/10WYeguDJlK85cKJ6ptX01w?pwd=xqkh 提取码: xqkh 二、解压到/opt目录 tar -zxvf Postman-linux-x64-8.7.0.tar.gz如果子用户没有/opt权限,可以给子用户赋予/opt的…

《垒球知识科普》垒球世界纪录·垒球1号位

奥运垒球冠军记录 历届冠军榜 1996亚特兰大奥运会 冠军&#xff1a;美国队 ⚡ 首届奥运垒球赛&#xff0c;美国主场3战全胜夺冠&#xff01; 1996 Atlanta Olympics Champion: USA ⚡ Dominated all 3 games in first Olympic softball event 2000悉尼奥运会 冠军&#…