chore: 修改生成ID的测试类
This commit is contained in:
parent
d17f729419
commit
4894976eee
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.sdk.constants;
|
||||||
|
|
||||||
|
public enum ApplicationNumScope {
|
||||||
|
API_DEFINITION,
|
||||||
|
API_TEST_CASE,
|
||||||
|
API_SCENARIO,
|
||||||
|
|
||||||
|
UI_SCENARIO,
|
||||||
|
UI_ELEMENT,
|
||||||
|
UI_CUSTOM_COMMAND,
|
||||||
|
|
||||||
|
LOAD_TEST,
|
||||||
|
|
||||||
|
TEST_PLAN,
|
||||||
|
|
||||||
|
BUG_MANAGEMENT,
|
||||||
|
|
||||||
|
CASE_MANAGEMENT
|
||||||
|
}
|
|
@ -20,27 +20,25 @@ public class ProjectApplicationType {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//UI测试
|
//UI测试
|
||||||
public enum UI{
|
public enum UI {
|
||||||
UI_CLEAN_REPORT,
|
UI_CLEAN_REPORT,
|
||||||
UI_SHARE_REPORT,
|
UI_SHARE_REPORT,
|
||||||
UI_RESOURCE_POOL_ID,
|
UI_RESOURCE_POOL_ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//性能测试
|
//性能测试
|
||||||
public enum PERFORMANCE_TEST{
|
public enum LOAD_TEST {
|
||||||
PERFORMANCE_TEST_CLEAN_REPORT,
|
LOAD_TEST_CLEAN_REPORT,
|
||||||
PERFORMANCE_TEST_SHARE_REPORT,
|
LOAD_TEST_SHARE_REPORT,
|
||||||
PERFORMANCE_TEST_SCRIPT_REVIEWER_ENABLE,
|
LOAD_TEST_SCRIPT_REVIEWER_ENABLE,
|
||||||
PERFORMANCE_TEST_SCRIPT_REVIEWER_ID,
|
LOAD_TEST_SCRIPT_REVIEWER_ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//接口测试
|
//接口测试
|
||||||
public enum API{
|
public enum API {
|
||||||
API_URL_REPEATABLE,
|
API_URL_REPEATABLE,
|
||||||
API_CLEAN_REPORT,
|
API_CLEAN_REPORT,
|
||||||
API_SHARE_REPORT,
|
API_SHARE_REPORT,
|
||||||
|
@ -53,40 +51,40 @@ public class ProjectApplicationType {
|
||||||
|
|
||||||
|
|
||||||
//用例管理
|
//用例管理
|
||||||
public enum CASE{
|
public enum CASE {
|
||||||
CASE_PUBLIC,
|
CASE_PUBLIC,
|
||||||
CASE_RE_REVIEW,
|
CASE_RE_REVIEW,
|
||||||
}
|
}
|
||||||
|
|
||||||
//用例管理-关联需求
|
//用例管理-关联需求
|
||||||
public enum CASE_RELATED_CONFIG{
|
public enum CASE_RELATED_CONFIG {
|
||||||
CASE_RELATED,
|
CASE_RELATED,
|
||||||
CASE_ENABLE,
|
CASE_ENABLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//缺陷管理
|
//缺陷管理
|
||||||
public enum BUG{
|
public enum BUG {
|
||||||
BUG_SYNC
|
BUG_SYNC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//缺陷管理-同步配置项
|
//缺陷管理-同步配置项
|
||||||
public enum BUG_SYNC_CONFIG{
|
public enum BUG_SYNC_CONFIG {
|
||||||
CRON_EXPRESSION,
|
CRON_EXPRESSION,
|
||||||
SYNC_ENABLE,
|
SYNC_ENABLE,
|
||||||
MECHANISM,
|
MECHANISM,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 版本管理-配置项
|
// 版本管理-配置项
|
||||||
public enum VERSION{
|
public enum VERSION {
|
||||||
VERSION_ENABLE
|
VERSION_ENABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录项目中配置的默认模板
|
* 记录项目中配置的默认模板
|
||||||
*/
|
*/
|
||||||
public enum DEFAULT_TEMPLATE{
|
public enum DEFAULT_TEMPLATE {
|
||||||
FUNCTIONAL_DEFAULT_TEMPLATE,
|
FUNCTIONAL_DEFAULT_TEMPLATE,
|
||||||
BUG_DEFAULT_TEMPLATE,
|
BUG_DEFAULT_TEMPLATE,
|
||||||
API_DEFAULT_TEMPLATE,
|
API_DEFAULT_TEMPLATE,
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class ProjectApplicationController {
|
||||||
@Operation(summary = "性能测试-获取配置")
|
@Operation(summary = "性能测试-获取配置")
|
||||||
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_PERFORMANCE_TEST_READ)
|
@RequiresPermissions(PermissionConstants.PROJECT_APPLICATION_PERFORMANCE_TEST_READ)
|
||||||
public Map<String, Object> getPerformanceTest(@Validated @RequestBody ProjectApplicationRequest request) {
|
public Map<String, Object> getPerformanceTest(@Validated @RequestBody ProjectApplicationRequest request) {
|
||||||
List<String> types = Arrays.asList(ProjectApplicationType.PERFORMANCE_TEST.values()).stream().map(ProjectApplicationType.PERFORMANCE_TEST::name).collect(Collectors.toList());
|
List<String> types = Arrays.asList(ProjectApplicationType.LOAD_TEST.values()).stream().map(ProjectApplicationType.LOAD_TEST::name).collect(Collectors.toList());
|
||||||
return projectApplicationService.get(request, types);
|
return projectApplicationService.get(request, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class ProjectApplicationService {
|
||||||
String type = application.getType();
|
String type = application.getType();
|
||||||
if (StringUtils.equals(type, ProjectApplicationType.TEST_PLAN.TEST_PLAN_CLEAN_REPORT.name())
|
if (StringUtils.equals(type, ProjectApplicationType.TEST_PLAN.TEST_PLAN_CLEAN_REPORT.name())
|
||||||
|| StringUtils.equals(type, ProjectApplicationType.UI.UI_CLEAN_REPORT.name())
|
|| StringUtils.equals(type, ProjectApplicationType.UI.UI_CLEAN_REPORT.name())
|
||||||
|| StringUtils.equals(type, ProjectApplicationType.PERFORMANCE_TEST.PERFORMANCE_TEST_CLEAN_REPORT.name())
|
|| StringUtils.equals(type, ProjectApplicationType.LOAD_TEST.LOAD_TEST_CLEAN_REPORT.name())
|
||||||
|| StringUtils.equals(type, ProjectApplicationType.API.API_CLEAN_REPORT.name())) {
|
|| StringUtils.equals(type, ProjectApplicationType.API.API_CLEAN_REPORT.name())) {
|
||||||
//清除 测试计划/UI测试/性能测试/接口测试 报告 定时任务
|
//清除 测试计划/UI测试/性能测试/接口测试 报告 定时任务
|
||||||
this.doHandleSchedule(application, currentUser);
|
this.doHandleSchedule(application, currentUser);
|
||||||
|
|
|
@ -177,7 +177,7 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
||||||
@Order(7)
|
@Order(7)
|
||||||
public void testPerformanceClean() throws Exception {
|
public void testPerformanceClean() throws Exception {
|
||||||
//新增
|
//新增
|
||||||
ProjectApplication request = creatRequest(ProjectApplicationType.PERFORMANCE_TEST.PERFORMANCE_TEST_CLEAN_REPORT.name(), TIME_TYPE_VALUE);
|
ProjectApplication request = creatRequest(ProjectApplicationType.LOAD_TEST.LOAD_TEST_CLEAN_REPORT.name(), TIME_TYPE_VALUE);
|
||||||
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
||||||
//更新
|
//更新
|
||||||
request.setTypeValue("4M");
|
request.setTypeValue("4M");
|
||||||
|
@ -192,7 +192,7 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
||||||
@Order(8)
|
@Order(8)
|
||||||
public void testPerformanceShare() throws Exception {
|
public void testPerformanceShare() throws Exception {
|
||||||
//新增
|
//新增
|
||||||
ProjectApplication request = creatRequest(ProjectApplicationType.PERFORMANCE_TEST.PERFORMANCE_TEST_SHARE_REPORT.name(), TIME_TYPE_VALUE);
|
ProjectApplication request = creatRequest(ProjectApplicationType.LOAD_TEST.LOAD_TEST_SHARE_REPORT.name(), TIME_TYPE_VALUE);
|
||||||
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
||||||
//更新
|
//更新
|
||||||
request.setTypeValue("5M");
|
request.setTypeValue("5M");
|
||||||
|
@ -204,7 +204,7 @@ public class ProjectApplicationControllerTests extends BaseTest {
|
||||||
@Order(9)
|
@Order(9)
|
||||||
public void testPerformanceReviewer() throws Exception {
|
public void testPerformanceReviewer() throws Exception {
|
||||||
//新增
|
//新增
|
||||||
ProjectApplication request = creatRequest(ProjectApplicationType.PERFORMANCE_TEST.PERFORMANCE_TEST_SCRIPT_REVIEWER_ENABLE.name(), "admin");
|
ProjectApplication request = creatRequest(ProjectApplicationType.LOAD_TEST.LOAD_TEST_SCRIPT_REVIEWER_ENABLE.name(), "admin");
|
||||||
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
this.requestPost(PERFORMANCE_UPDATE_URL, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package io.metersphere.system.uid;
|
||||||
|
|
||||||
|
import com.fit2cloud.quartz.anno.QuartzScheduled;
|
||||||
|
import io.metersphere.project.domain.Project;
|
||||||
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.redisson.Redisson;
|
||||||
|
import org.redisson.api.RIdGenerator;
|
||||||
|
import org.springframework.data.redis.core.Cursor;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class NumGenerator {
|
||||||
|
private static final long INIT = 100001L; // 代表从100001开始,各种domain的 num
|
||||||
|
private static final long LIMIT = 1;
|
||||||
|
|
||||||
|
private static Redisson redisson;
|
||||||
|
private static StringRedisTemplate stringRedisTemplate;
|
||||||
|
private static ProjectMapper projectMapper;
|
||||||
|
|
||||||
|
public NumGenerator(Redisson redisson, StringRedisTemplate stringRedisTemplate, ProjectMapper projectMapper) {
|
||||||
|
NumGenerator.redisson = redisson;
|
||||||
|
NumGenerator.stringRedisTemplate = stringRedisTemplate;
|
||||||
|
NumGenerator.projectMapper = projectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param prefix 前缀: PROJECT_ID, 或者 PROJECT_ID + "_" + DOMAIN 例如接口用例的前缀为: 100001_12345
|
||||||
|
* @param scope 用例类型
|
||||||
|
*/
|
||||||
|
public static long nextNum(String prefix, ApplicationNumScope scope) {
|
||||||
|
RIdGenerator idGenerator = redisson.getIdGenerator(prefix + "_" + scope.name());
|
||||||
|
// 每次都尝试初始化,容量为1,只有一个线程可以初始化成功
|
||||||
|
if (scope.equals(ApplicationNumScope.API_TEST_CASE)) {
|
||||||
|
// 二级的用例
|
||||||
|
idGenerator.tryInit(Long.parseLong(prefix.split("_")[1] + INIT), LIMIT);
|
||||||
|
} else {
|
||||||
|
idGenerator.tryInit(INIT, LIMIT);
|
||||||
|
}
|
||||||
|
return idGenerator.nextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@QuartzScheduled(cron = "0 1 0 * * ?")
|
||||||
|
public void cleanDeletedProjectResource() {
|
||||||
|
for (ApplicationNumScope value : ApplicationNumScope.values()) {
|
||||||
|
cleanDeletedProjectResource(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanDeletedProjectResource(ApplicationNumScope value) {
|
||||||
|
String suffix = "}:allocation";
|
||||||
|
|
||||||
|
ScanOptions options = ScanOptions.scanOptions().match("*_" + value.name()).count(1000).build();
|
||||||
|
try (
|
||||||
|
Cursor<String> scan = stringRedisTemplate.scan(options)
|
||||||
|
) {
|
||||||
|
while (scan.hasNext()) {
|
||||||
|
String key = scan.next();
|
||||||
|
if (StringUtils.contains(key, suffix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Project project = projectMapper.selectByPrimaryKey(key.split("_")[0]);
|
||||||
|
if (project == null) {
|
||||||
|
LogUtils.info("清理已经删除项目的num数据: " + key);
|
||||||
|
stringRedisTemplate.delete(key);
|
||||||
|
stringRedisTemplate.delete("{" + key + suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,33 +0,0 @@
|
||||||
package io.metersphere.system.controller;
|
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
|
||||||
import org.redisson.Redisson;
|
|
||||||
import org.redisson.api.RIdGenerator;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
||||||
@AutoConfigureMockMvc
|
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
||||||
public class TestRIdGenerator {
|
|
||||||
@Resource
|
|
||||||
private Redisson redisson;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testId1() throws Exception {
|
|
||||||
String projectId = "projectId";
|
|
||||||
RIdGenerator idGenerator = redisson.getIdGenerator(projectId);
|
|
||||||
long capacity = 1000000; // 容量,代表每个项目最多可以生成多少个id
|
|
||||||
long init = 1000000_1000001L; // 代表从100_0000_100_0001开始,项目的num
|
|
||||||
idGenerator.tryInit(init, capacity);
|
|
||||||
long nextId = idGenerator.nextId();
|
|
||||||
Assertions.assertEquals(nextId, init);
|
|
||||||
// for (int i = 0; i < capacity; i++) {
|
|
||||||
// long nextId = idGenerator.nextId();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package io.metersphere.system.rid;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
|
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||||
|
import io.metersphere.system.uid.NumGenerator;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class RIdGeneratorTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void testId1() throws Exception {
|
||||||
|
String projectId = "100001";
|
||||||
|
|
||||||
|
long capacity = 10; // 容量,代表每个项目最多可以生成多少个id
|
||||||
|
long init = 100001L; // 代表从1000001开始,项目的 num
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
AtomicLong atomicLong = new AtomicLong(init);
|
||||||
|
// 使用多线程执行
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(5);
|
||||||
|
for (int i = 0; i < capacity; i++) {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
long nextId = NumGenerator.nextNum(projectId, ApplicationNumScope.API_DEFINITION);
|
||||||
|
System.out.println(nextId);
|
||||||
|
if (atomicLong.get() < nextId) {
|
||||||
|
atomicLong.set(nextId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
executorService.close();
|
||||||
|
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
Assertions.assertEquals(capacity + init, atomicLong.get() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void testId2() throws Exception {
|
||||||
|
String projectId = "100001";
|
||||||
|
|
||||||
|
long capacity = 10; // 容量,代表每个项目最多可以生成多少个id
|
||||||
|
long init = 100001L; // 代表从1000001开始,项目的 num
|
||||||
|
long apiNum = 100005;
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
AtomicLong atomicLong = new AtomicLong(init);
|
||||||
|
// 使用多线程执行
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(5);
|
||||||
|
for (int i = 0; i < capacity; i++) {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
// 接口用例的前缀为: PROJECT_ID_API_DEFINITION 比较特殊
|
||||||
|
long nextId = NumGenerator.nextNum(projectId + "_" + apiNum, ApplicationNumScope.API_TEST_CASE);
|
||||||
|
System.out.println(nextId);
|
||||||
|
if (atomicLong.get() < nextId) {
|
||||||
|
atomicLong.set(nextId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
executorService.close();
|
||||||
|
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
Assertions.assertEquals(capacity + Long.parseLong(apiNum + "" + init), atomicLong.get() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void testClean() {
|
||||||
|
NumGenerator numGenerator = CommonBeanFactory.getBean(NumGenerator.class);
|
||||||
|
numGenerator.cleanDeletedProjectResource();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue