mirror of
https://gitee.com/270580156/weiyu.git
synced 2026-05-17 12:48:08 +00:00
Sync from bytedesk-private: update
This commit is contained in:
@@ -22,7 +22,7 @@ import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import com.bytedesk.core.message.MessageProtobuf;
|
||||
import com.bytedesk.core.utils.JsonResult;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -41,103 +41,97 @@ public class VisitorAnonymousControllerTest {
|
||||
@MockBean
|
||||
private VisitorRestService visitorRestService;
|
||||
|
||||
// orgUid=df_org_uid
|
||||
// type=0 or 1
|
||||
// sid=df_ag_uid or df_wg_uid
|
||||
private List<String> visitorUids;
|
||||
private static final String ORG_UID = "df_org_uid";
|
||||
private static final String AGENT_UID = "df_ag_uid"; // df_ag_uid or df_wg_uid
|
||||
private static final String TYPE = "0";// 0: agent, 1: workgroup
|
||||
private static final int VISITOR_COUNT = 100;
|
||||
private static final int REQUEST_PER_VISITOR = 100;
|
||||
|
||||
private List<VisitorResponse> visitors;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
// 初始化访客ID列表
|
||||
visitorUids = new ArrayList<>();
|
||||
// 初始化访客列表
|
||||
visitors = new ArrayList<>();
|
||||
for (int i = 0; i < VISITOR_COUNT; i++) {
|
||||
visitorUids.add("visitor_" + i);
|
||||
VisitorResponse visitor = VisitorResponse.builder()
|
||||
.nickname("Visitor " + i)
|
||||
.avatar("https://example.com/avatar/" + i + ".jpg")
|
||||
.build();
|
||||
visitor.setUid("visitor_" + i);
|
||||
visitors.add(visitor);
|
||||
}
|
||||
|
||||
// Mock visitorService的响应
|
||||
when(visitorRestService.create(any())).thenReturn(VisitorResponse.builder().build());
|
||||
when(visitorRestService.requestThread(any())).thenReturn(MessageProtobuf.builder().build());
|
||||
when(visitorRestService.create(any())).thenAnswer(invocation -> {
|
||||
int index = (int)(Math.random() * VISITOR_COUNT);
|
||||
return visitors.get(index);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMassVisitorRequests() throws Exception {
|
||||
// 1. 首先创建100个访客
|
||||
log.info("开始创建{}个访客", VISITOR_COUNT);
|
||||
createVisitors();
|
||||
|
||||
// 2. 每个访客发起100次请求
|
||||
log.info("开始模拟每个访客发起{}次请求", REQUEST_PER_VISITOR);
|
||||
simulateVisitorRequests();
|
||||
|
||||
// 3. 验证调用次数
|
||||
verify(visitorRestService, times(VISITOR_COUNT)).create(any());
|
||||
verify(visitorRestService, times(VISITOR_COUNT * REQUEST_PER_VISITOR)).requestThread(any());
|
||||
}
|
||||
|
||||
private void createVisitors() throws Exception {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
for (String visitorUid : visitorUids) {
|
||||
// 创建访客
|
||||
for (int i = 0; i < VISITOR_COUNT; i++) {
|
||||
final int visitorIndex = i;
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
VisitorRequest request = new VisitorRequest();
|
||||
request.setUid(visitorUid);
|
||||
request.setNickname("Visitor " + visitorUid);
|
||||
request.setAvatar("https://example.com/avatar.png");
|
||||
// 1. 初始化访客
|
||||
VisitorRequest initRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.build();
|
||||
initRequest.setType(TYPE);
|
||||
initRequest.setOrgUid(ORG_UID);
|
||||
|
||||
mockMvc.perform(post("/visitor/anonymous/init")
|
||||
String initResult = mockMvc.perform(post("/visitor/api/v1/init")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request)))
|
||||
.andExpect(status().isOk());
|
||||
.content(objectMapper.writeValueAsString(initRequest)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
// 解析返回的访客信息
|
||||
JsonResult<?> initResponse = objectMapper.readValue(initResult, JsonResult.class);
|
||||
VisitorResponse visitor = objectMapper.convertValue(initResponse.getData(), VisitorResponse.class);
|
||||
|
||||
// 2. 请求会话
|
||||
for (int j = 0; j < REQUEST_PER_VISITOR; j++) {
|
||||
VisitorRequest threadRequest = VisitorRequest.builder()
|
||||
.sid(AGENT_UID)
|
||||
.nickname(visitor.getNickname())
|
||||
.avatar(visitor.getAvatar())
|
||||
.build();
|
||||
threadRequest.setOrgUid(ORG_UID);
|
||||
threadRequest.setType(TYPE);
|
||||
threadRequest.setUid(visitor.getUid());
|
||||
|
||||
mockMvc.perform(post("/visitor/api/v1/request")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(threadRequest)))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建访客失败: {}", visitorUid, e);
|
||||
log.error("访客请求失败: {}", visitorIndex, e);
|
||||
}
|
||||
}, executor);
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
// 等待所有访客创建完成
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
private void simulateVisitorRequests() throws Exception {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(20);
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
for (String visitorUid : visitorUids) {
|
||||
for (int i = 0; i < REQUEST_PER_VISITOR; i++) {
|
||||
final int requestNum = i;
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
VisitorRequest request = new VisitorRequest();
|
||||
request.setUid(visitorUid);
|
||||
// request.setWorkGroupWid("workgroup_1");
|
||||
// request.setRequestNo("request_" + visitorUid + "_" + requestNum);
|
||||
|
||||
mockMvc.perform(post("/visitor/anonymous/requestThread")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request)))
|
||||
.andExpect(status().isOk());
|
||||
} catch (Exception e) {
|
||||
log.error("访客请求失败: {} - 请求 {}", visitorUid, requestNum, e);
|
||||
}
|
||||
}, executor);
|
||||
futures.add(future);
|
||||
}
|
||||
}
|
||||
|
||||
// 等待所有请求完成
|
||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
|
||||
executor.shutdown();
|
||||
|
||||
// 验证调用次数
|
||||
verify(visitorRestService, times(VISITOR_COUNT)).create(any());
|
||||
verify(visitorRestService, times(VISITOR_COUNT * REQUEST_PER_VISITOR)).requestThread(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConcurrentVisitorRequests() throws Exception {
|
||||
// 创建10个访客同时发起10次请求的并发测试
|
||||
int concurrentVisitors = 10;
|
||||
int concurrentRequests = 10;
|
||||
|
||||
@@ -145,38 +139,46 @@ public class VisitorAnonymousControllerTest {
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < concurrentVisitors; i++) {
|
||||
final String visitorUid = "concurrent_visitor_" + i;
|
||||
|
||||
// 先创建访客
|
||||
VisitorRequest initRequest = new VisitorRequest();
|
||||
initRequest.setUid(visitorUid);
|
||||
initRequest.setNickname("Concurrent Visitor " + i);
|
||||
|
||||
mockMvc.perform(post("/visitor/anonymous/init")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(initRequest)))
|
||||
.andExpect(status().isOk());
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
// 1. 初始化访客
|
||||
VisitorRequest initRequest = new VisitorRequest();
|
||||
initRequest.setOrgUid(ORG_UID);
|
||||
initRequest.setType(TYPE);
|
||||
initRequest.setSid(AGENT_UID);
|
||||
|
||||
// 然后并发发起请求
|
||||
for (int j = 0; j < concurrentRequests; j++) {
|
||||
final int requestNum = j;
|
||||
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
VisitorRequest request = new VisitorRequest();
|
||||
request.setUid(visitorUid);
|
||||
// request.setWorkGroupWid("workgroup_1");
|
||||
// request.setRequestNo("concurrent_request_" + visitorUid + "_" + requestNum);
|
||||
String initResult = mockMvc.perform(post("/visitor/anonymous/init")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(initRequest)))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
// 解析返回的访客信息
|
||||
JsonResult initResponse = objectMapper.readValue(initResult, JsonResult.class);
|
||||
VisitorResponse visitor = objectMapper.convertValue(initResponse.getData(), VisitorResponse.class);
|
||||
|
||||
// 2. 并发请求会话
|
||||
for (int j = 0; j < concurrentRequests; j++) {
|
||||
VisitorRequest threadRequest = new VisitorRequest();
|
||||
threadRequest.setOrgUid(ORG_UID);
|
||||
threadRequest.setType(TYPE);
|
||||
threadRequest.setSid(AGENT_UID);
|
||||
threadRequest.setUid(visitor.getUid());
|
||||
threadRequest.setNickname(visitor.getNickname());
|
||||
threadRequest.setAvatar(visitor.getAvatar());
|
||||
|
||||
mockMvc.perform(post("/visitor/anonymous/requestThread")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request)))
|
||||
.content(objectMapper.writeValueAsString(threadRequest)))
|
||||
.andExpect(status().isOk());
|
||||
} catch (Exception e) {
|
||||
log.error("并发请求失败: {} - 请求 {}", visitorUid, requestNum, e);
|
||||
}
|
||||
}, executor);
|
||||
futures.add(future);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("并发请求失败", e);
|
||||
}
|
||||
}, executor);
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
// 等待所有并发请求完成
|
||||
|
||||
Reference in New Issue
Block a user