mirror of
https://gitee.com/270580156/weiyu.git
synced 2025-12-30 02:42:25 +00:00
Sync from bytedesk-private: update
This commit is contained in:
15
jmeter/readme.md
Normal file
15
jmeter/readme.md
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2024-07-09 16:47:04
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2024-12-24 13:59:35
|
||||
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||
* 仅支持企业内部员工自用,严禁私自用于销售、二次销售或者部署SaaS方式销售
|
||||
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
|
||||
* contact: 270580156@qq.com
|
||||
* 联系:270580156@qq.com
|
||||
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
|
||||
-->
|
||||
# jmeter
|
||||
308
jmeter/requestThread接口测试.jmx
Normal file
308
jmeter/requestThread接口测试.jmx
Normal file
@@ -0,0 +1,308 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
|
||||
<hashTree>
|
||||
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="requestThread接口测试">
|
||||
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量">
|
||||
<collectionProp name="Arguments.arguments"/>
|
||||
</elementProp>
|
||||
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||
</TestPlan>
|
||||
<hashTree>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="线程组">
|
||||
<intProp name="ThreadGroup.num_threads">10</intProp>
|
||||
<intProp name="ThreadGroup.ramp_time">10</intProp>
|
||||
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器">
|
||||
<stringProp name="LoopController.loops">10</stringProp>
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
</elementProp>
|
||||
</ThreadGroup>
|
||||
<hashTree>
|
||||
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP请求" enabled="true">
|
||||
<stringProp name="HTTPSampler.domain">127.0.0.1</stringProp>
|
||||
<stringProp name="HTTPSampler.port">9003</stringProp>
|
||||
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||
<stringProp name="HTTPSampler.path">/visitor/api/v1/thread</stringProp>
|
||||
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||
<boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
|
||||
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="用户定义的变量">
|
||||
<collectionProp name="Arguments.arguments">
|
||||
<elementProp name="type" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">0</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
<stringProp name="Argument.name">type</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="sid" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">default_agent_uid</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
<stringProp name="Argument.name">sid</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="uid" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">1395890719817857</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
<stringProp name="Argument.name">uid</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="nickname" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">LOCAL9686</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
<stringProp name="Argument.name">nickname</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="avatar" elementType="HTTPArgument">
|
||||
<boolProp name="HTTPArgument.always_encode">false</boolProp>
|
||||
<stringProp name="Argument.value">https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/visitor_default_avatar.png</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
<boolProp name="HTTPArgument.use_equals">true</boolProp>
|
||||
<stringProp name="Argument.name">avatar</stringProp>
|
||||
</elementProp>
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
</HTTPSamplerProxy>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="查看结果树" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="汇总报告" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="聚合报告" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultSaver guiclass="ResultSaverGui" testclass="ResultSaver" testname="保存响应到文件" enabled="true">
|
||||
<stringProp name="FileSaver.filename"></stringProp>
|
||||
<boolProp name="FileSaver.errorsonly">false</boolProp>
|
||||
<boolProp name="FileSaver.successonly">false</boolProp>
|
||||
<boolProp name="FileSaver.skipsuffix">false</boolProp>
|
||||
<boolProp name="FileSaver.skipautonumber">false</boolProp>
|
||||
</ResultSaver>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="RespTimeGraphVisualizer" testclass="ResultCollector" testname="响应时间图" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="StatGraphVisualizer" testclass="ResultCollector" testname="汇总图" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
<Summariser guiclass="SummariserGui" testclass="Summariser" testname="生成概要结果" enabled="true"/>
|
||||
<hashTree/>
|
||||
<ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="用表格查看结果" enabled="true">
|
||||
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||
<objProp>
|
||||
<name>saveConfig</name>
|
||||
<value class="SampleSaveConfiguration">
|
||||
<time>true</time>
|
||||
<latency>true</latency>
|
||||
<timestamp>true</timestamp>
|
||||
<success>true</success>
|
||||
<label>true</label>
|
||||
<code>true</code>
|
||||
<message>true</message>
|
||||
<threadName>true</threadName>
|
||||
<dataType>true</dataType>
|
||||
<encoding>false</encoding>
|
||||
<assertions>true</assertions>
|
||||
<subresults>true</subresults>
|
||||
<responseData>false</responseData>
|
||||
<samplerData>false</samplerData>
|
||||
<xml>false</xml>
|
||||
<fieldNames>true</fieldNames>
|
||||
<responseHeaders>false</responseHeaders>
|
||||
<requestHeaders>false</requestHeaders>
|
||||
<responseDataOnError>false</responseDataOnError>
|
||||
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||
<bytes>true</bytes>
|
||||
<sentBytes>true</sentBytes>
|
||||
<url>true</url>
|
||||
<threadCounts>true</threadCounts>
|
||||
<idleTime>true</idleTime>
|
||||
<connectTime>true</connectTime>
|
||||
</value>
|
||||
</objProp>
|
||||
<stringProp name="filename"></stringProp>
|
||||
</ResultCollector>
|
||||
<hashTree/>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</hashTree>
|
||||
</jmeterTestPlan>
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2024-05-25 13:07:20
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2024-12-19 15:52:30
|
||||
* @LastEditTime: 2024-12-24 12:49:28
|
||||
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||
@@ -109,6 +109,8 @@ public enum ClientEnum {
|
||||
SHOPIFY, // Shopify
|
||||
LAZADA, // 来赞达
|
||||
SHOPEE, // 虾皮
|
||||
//
|
||||
TEST,
|
||||
;
|
||||
|
||||
// 根据字符串查找对应的枚举常量
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2024-01-29 16:21:24
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2024-12-24 10:55:34
|
||||
* @LastEditTime: 2024-12-24 13:04:17
|
||||
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2024-04-04 17:05:48
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2024-12-24 09:46:10
|
||||
* @LastEditTime: 2024-12-24 13:01:36
|
||||
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
|
||||
* Please be aware of the BSL license restrictions before installing Bytedesk IM –
|
||||
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
|
||||
@@ -47,9 +47,11 @@ public class VisitorRequest extends BaseRequest {
|
||||
private String lang = LanguageEnum.ZH_CN.name();
|
||||
|
||||
// location info
|
||||
private String ip;
|
||||
@Builder.Default
|
||||
private String ip = "127.0.0.1";
|
||||
|
||||
private String ipLocation;
|
||||
@Builder.Default
|
||||
private String ipLocation = "localhost";
|
||||
|
||||
// device info
|
||||
private String browser;
|
||||
|
||||
@@ -4,11 +4,13 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import com.bytedesk.core.enums.ClientEnum;
|
||||
import com.bytedesk.service.visitor.VisitorRequest;
|
||||
import com.bytedesk.service.visitor.VisitorResponse;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -17,11 +19,11 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Collections;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = {
|
||||
"bytedesk.socket.enabled=false", // 禁用MQTT服务器
|
||||
"server.port=0" // 使用随机端口
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
|
||||
"bytedesk.socket.enabled=false", // 禁用MQTT服务器
|
||||
"server.port=0" // 使用随机端口
|
||||
})
|
||||
public class VisitorAnonymousControllerIntegrationTest {
|
||||
|
||||
@@ -36,38 +38,60 @@ public class VisitorAnonymousControllerIntegrationTest {
|
||||
public void testVisitorFlowWithRealServer() {
|
||||
// Step 1: Create visitor
|
||||
VisitorRequest initRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
.sid(AGENT_UID)
|
||||
.nickname("Test Visitor")
|
||||
.build();
|
||||
initRequest.setUid("visitor_test_uid");
|
||||
initRequest.setOrgUid(ORG_UID);
|
||||
initRequest.setType(TYPE);
|
||||
initRequest.setClient(ClientEnum.TEST.name());
|
||||
|
||||
ResponseEntity<VisitorResponse> visitorResponse = restTemplate.postForEntity(
|
||||
"/visitor/api/v1/init",
|
||||
initRequest,
|
||||
VisitorResponse.class
|
||||
);
|
||||
// 创建HTTP Headers并添加必要的信息
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("User-Agent", "Mozilla/5.0 (Test Browser)");
|
||||
headers.set("X-Real-IP", "127.0.0.1");
|
||||
headers.set("X-Forwarded-For", "127.0.0.1");
|
||||
headers.set("Referer", "https://test.bytedesk.com");
|
||||
headers.setContentType(MediaType.APPLICATION_JSON); // 添加Content-Type
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); // 添加Accept
|
||||
|
||||
// 使用HttpEntity包装请求
|
||||
HttpEntity<VisitorRequest> requestEntity = new HttpEntity<>(initRequest, headers);
|
||||
|
||||
// 然后再进行实际的测试请求
|
||||
ResponseEntity<VisitorResponse> visitorResponse = restTemplate.exchange(
|
||||
"/visitor/api/v1/init",
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
VisitorResponse.class);
|
||||
|
||||
// 打印原始响应内容
|
||||
System.out.println("Response Status: " + visitorResponse.getStatusCode());
|
||||
System.out.println("Response Headers: " + visitorResponse.getHeaders());
|
||||
System.out.println("Response Body: " + visitorResponse.getBody());
|
||||
|
||||
// Verify visitor creation response
|
||||
assertThat(visitorResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(visitorResponse.getBody()).isNotNull();
|
||||
assertThat(visitorResponse.getBody()).as("Response body should not be null").isNotNull();
|
||||
assertThat(visitorResponse.getBody().getUid()).isNotNull();
|
||||
assertThat(visitorResponse.getBody().getNickname()).isNotNull();
|
||||
assertThat(visitorResponse.getBody().getAvatar()).isNotNull();
|
||||
|
||||
// Step 2: Request thread with visitor info
|
||||
VisitorRequest threadRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.nickname(visitorResponse.getBody().getNickname())
|
||||
.avatar(visitorResponse.getBody().getAvatar())
|
||||
.build();
|
||||
.sid(AGENT_UID)
|
||||
.nickname(visitorResponse.getBody().getNickname())
|
||||
.avatar(visitorResponse.getBody().getAvatar())
|
||||
.build();
|
||||
threadRequest.setUid(visitorResponse.getBody().getUid());
|
||||
threadRequest.setOrgUid(ORG_UID);
|
||||
threadRequest.setType(TYPE);
|
||||
threadRequest.setClient(ClientEnum.TEST.name());
|
||||
|
||||
ResponseEntity<String> threadResponse = restTemplate.postForEntity(
|
||||
"/visitor/api/v1/request",
|
||||
threadRequest,
|
||||
String.class
|
||||
);
|
||||
"/visitor/api/v1/request",
|
||||
threadRequest,
|
||||
String.class);
|
||||
|
||||
// Verify thread request response
|
||||
assertThat(threadResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@@ -78,24 +102,37 @@ public class VisitorAnonymousControllerIntegrationTest {
|
||||
public void testConcurrentVisitorRequests() throws InterruptedException {
|
||||
int concurrentRequests = 10;
|
||||
Thread[] threads = new Thread[concurrentRequests];
|
||||
|
||||
|
||||
for (int i = 0; i < concurrentRequests; i++) {
|
||||
final int index = i;
|
||||
threads[i] = new Thread(() -> {
|
||||
VisitorRequest initRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
initRequest.setUid("visitor_test_uid_" + index);
|
||||
initRequest.setOrgUid(ORG_UID);
|
||||
initRequest.setType(TYPE);
|
||||
initRequest.setClient(ClientEnum.TEST.name());
|
||||
|
||||
ResponseEntity<VisitorResponse> response = restTemplate.postForEntity(
|
||||
"/visitor/api/v1/init",
|
||||
initRequest,
|
||||
VisitorResponse.class
|
||||
);
|
||||
// 创建HTTP Headers并添加必要的信息
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("User-Agent", "Mozilla/5.0 (Test Browser)");
|
||||
headers.set("X-Real-IP", "127.0.0.1");
|
||||
headers.set("X-Forwarded-For", "127.0.0.1");
|
||||
headers.set("Referer", "https://test.bytedesk.com");
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getUid()).isNotNull();
|
||||
// 使用HttpEntity包装请求
|
||||
HttpEntity<VisitorRequest> requestEntity = new HttpEntity<>(initRequest, headers);
|
||||
|
||||
ResponseEntity<VisitorResponse> visitorResponse = restTemplate.exchange(
|
||||
"/visitor/api/v1/init",
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
VisitorResponse.class);
|
||||
|
||||
assertThat(visitorResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(visitorResponse.getBody()).isNotNull();
|
||||
assertThat(visitorResponse.getBody().getUid()).isNotNull();
|
||||
});
|
||||
threads[i].start();
|
||||
}
|
||||
@@ -106,46 +143,44 @@ public class VisitorAnonymousControllerIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVisitorInitWithInvalidParams() {
|
||||
// Test with missing required parameters
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
|
||||
params.add("type", TYPE); // Missing orgUid and sid
|
||||
|
||||
ResponseEntity<VisitorResponse> response = restTemplate.postForEntity(
|
||||
"/visible/api/v1/init",
|
||||
params,
|
||||
VisitorResponse.class
|
||||
);
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleVisitorsWithMultipleRequests() throws InterruptedException {
|
||||
int visitorCount = 100;
|
||||
int requestsPerVisitor = 100;
|
||||
|
||||
|
||||
// Create a thread pool for managing concurrent visitors
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(20);
|
||||
CountDownLatch completionLatch = new CountDownLatch(visitorCount);
|
||||
|
||||
|
||||
// Create visitors and their requests
|
||||
for (int i = 0; i < visitorCount; i++) {
|
||||
final int index = i;
|
||||
executorService.submit(() -> {
|
||||
try {
|
||||
// Step 1: Create visitor
|
||||
VisitorRequest initRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
initRequest.setUid("visitor_test_uid_" + index);
|
||||
initRequest.setOrgUid(ORG_UID);
|
||||
initRequest.setType(TYPE);
|
||||
initRequest.setClient(ClientEnum.TEST.name());
|
||||
|
||||
ResponseEntity<VisitorResponse> visitorResponse = restTemplate.postForEntity(
|
||||
"/visitor/api/v1/init",
|
||||
initRequest,
|
||||
VisitorResponse.class
|
||||
);
|
||||
// 创建HTTP Headers并添加必要的信息
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("User-Agent", "Mozilla/5.0 (Test Browser)");
|
||||
headers.set("X-Real-IP", "127.0.0.1");
|
||||
headers.set("X-Forwarded-For", "127.0.0.1");
|
||||
headers.set("Referer", "https://test.bytedesk.com");
|
||||
|
||||
// 使用HttpEntity包装请求
|
||||
HttpEntity<VisitorRequest> requestEntity = new HttpEntity<>(initRequest, headers);
|
||||
|
||||
ResponseEntity<VisitorResponse> visitorResponse = restTemplate.exchange(
|
||||
"/visitor/api/v1/init",
|
||||
HttpMethod.GET,
|
||||
requestEntity,
|
||||
VisitorResponse.class);
|
||||
|
||||
assertThat(visitorResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(visitorResponse.getBody()).isNotNull();
|
||||
@@ -154,19 +189,19 @@ public class VisitorAnonymousControllerIntegrationTest {
|
||||
// Step 2: Make multiple thread requests for this visitor
|
||||
for (int j = 0; j < requestsPerVisitor; j++) {
|
||||
VisitorRequest threadRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.nickname(visitor.getNickname())
|
||||
.avatar(visitor.getAvatar())
|
||||
.build();
|
||||
.sid(AGENT_UID)
|
||||
.nickname(visitor.getNickname())
|
||||
.avatar(visitor.getAvatar())
|
||||
.build();
|
||||
threadRequest.setUid(visitor.getUid());
|
||||
threadRequest.setOrgUid(ORG_UID);
|
||||
threadRequest.setType(TYPE);
|
||||
threadRequest.setClient(ClientEnum.TEST.name());
|
||||
|
||||
ResponseEntity<String> threadResponse = restTemplate.postForEntity(
|
||||
"/visitor/api/v1/request",
|
||||
threadRequest,
|
||||
String.class
|
||||
);
|
||||
"/visitor/api/v1/request",
|
||||
threadRequest,
|
||||
String.class);
|
||||
|
||||
assertThat(threadResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(threadResponse.getBody()).isNotNull();
|
||||
@@ -180,9 +215,9 @@ public class VisitorAnonymousControllerIntegrationTest {
|
||||
// Wait for all visitors to complete their requests
|
||||
boolean completed = completionLatch.await(5, TimeUnit.MINUTES);
|
||||
executorService.shutdown();
|
||||
|
||||
|
||||
assertThat(completed).isTrue()
|
||||
.withFailMessage("Not all visitors completed their requests within the timeout period");
|
||||
.withFailMessage("Not all visitors completed their requests within the timeout period");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user