diff --git a/backend/pom.xml b/backend/pom.xml index 8e38b46fa9..bdd4e17897 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -158,6 +158,12 @@ + + org.apache.jmeter + ApacheJMeter_functions + ${jmeter.version} + + org.apache.dubbo diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java index 89b8e73c53..d587d581ae 100644 --- a/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestReport.java @@ -1,8 +1,9 @@ package io.metersphere.base.domain; -import java.io.Serializable; import lombok.Data; +import java.io.Serializable; + @Data public class LoadTestReport implements Serializable { private String id; @@ -21,7 +22,5 @@ public class LoadTestReport implements Serializable { private String triggerMode; - private String description; - private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/domain/LoadTestReportWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/LoadTestReportWithBLOBs.java new file mode 100644 index 0000000000..1c12e6caaf --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/domain/LoadTestReportWithBLOBs.java @@ -0,0 +1,18 @@ +package io.metersphere.base.domain; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class LoadTestReportWithBLOBs extends LoadTestReport implements Serializable { + private String description; + + private String loadConfiguration; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.java index 8010242ee7..018fc00eaa 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.java @@ -2,9 +2,11 @@ package io.metersphere.base.mapper; import io.metersphere.base.domain.LoadTestReport; import io.metersphere.base.domain.LoadTestReportExample; -import java.util.List; +import io.metersphere.base.domain.LoadTestReportWithBLOBs; import org.apache.ibatis.annotations.Param; +import java.util.List; + public interface LoadTestReportMapper { long countByExample(LoadTestReportExample example); @@ -12,25 +14,25 @@ public interface LoadTestReportMapper { int deleteByPrimaryKey(String id); - int insert(LoadTestReport record); + int insert(LoadTestReportWithBLOBs record); - int insertSelective(LoadTestReport record); + int insertSelective(LoadTestReportWithBLOBs record); - List selectByExampleWithBLOBs(LoadTestReportExample example); + List selectByExampleWithBLOBs(LoadTestReportExample example); List selectByExample(LoadTestReportExample example); - LoadTestReport selectByPrimaryKey(String id); + LoadTestReportWithBLOBs selectByPrimaryKey(String id); - int updateByExampleSelective(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example); + int updateByExampleSelective(@Param("record") LoadTestReportWithBLOBs record, @Param("example") LoadTestReportExample example); - int updateByExampleWithBLOBs(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example); + int updateByExampleWithBLOBs(@Param("record") LoadTestReportWithBLOBs record, @Param("example") LoadTestReportExample example); int updateByExample(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example); - int updateByPrimaryKeySelective(LoadTestReport record); + int updateByPrimaryKeySelective(LoadTestReportWithBLOBs record); - int updateByPrimaryKeyWithBLOBs(LoadTestReport record); + int updateByPrimaryKeyWithBLOBs(LoadTestReportWithBLOBs record); int updateByPrimaryKey(LoadTestReport record); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml index ff6e055f5c..9b1b3543bc 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/LoadTestReportMapper.xml @@ -11,8 +11,9 @@ - + + @@ -76,7 +77,7 @@ id, test_id, `name`, create_time, update_time, `status`, user_id, trigger_mode - description + description, load_configuration @@ -233,6 +240,9 @@ description = #{record.description,jdbcType=LONGVARCHAR}, + + load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR}, + @@ -248,7 +258,8 @@ `status` = #{record.status,jdbcType=VARCHAR}, user_id = #{record.userId,jdbcType=VARCHAR}, trigger_mode = #{record.triggerMode,jdbcType=VARCHAR}, - description = #{record.description,jdbcType=LONGVARCHAR} + description = #{record.description,jdbcType=LONGVARCHAR}, + load_configuration = #{record.loadConfiguration,jdbcType=LONGVARCHAR} @@ -267,7 +278,7 @@ - + update load_test_report @@ -294,10 +305,13 @@ description = #{description,jdbcType=LONGVARCHAR}, + + load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} - + update load_test_report set test_id = #{testId,jdbcType=VARCHAR}, `name` = #{name,jdbcType=VARCHAR}, @@ -306,7 +320,8 @@ `status` = #{status,jdbcType=VARCHAR}, user_id = #{userId,jdbcType=VARCHAR}, trigger_mode = #{triggerMode,jdbcType=VARCHAR}, - description = #{description,jdbcType=LONGVARCHAR} + description = #{description,jdbcType=LONGVARCHAR}, + load_configuration = #{loadConfiguration,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.java index 809ecb88fe..b7c6e588c8 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.java @@ -1,6 +1,5 @@ package io.metersphere.base.mapper.ext; -import io.metersphere.base.domain.LoadTestReport; import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.ReportDTO; import io.metersphere.performance.controller.request.ReportRequest; @@ -14,8 +13,6 @@ public interface ExtLoadTestReportMapper { ReportDTO getReportTestAndProInfo(@Param("id") String id); - LoadTestReport selectByPrimaryKey(String id); - List selectDashboardTests(@Param("workspaceId") String workspaceId, @Param("startTimestamp") long startTimestamp); List selectResourceId(@Param("reportId") String reportId); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.xml index 6ef6c419ad..b4adf632a1 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtLoadTestReportMapper.xml @@ -125,13 +125,6 @@ where ltr.id = #{id} - - diff --git a/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java b/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java index 452f90ef4d..5fd93d32f2 100644 --- a/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java +++ b/backend/src/main/java/io/metersphere/performance/controller/PerformanceReportController.java @@ -2,8 +2,8 @@ package io.metersphere.performance.controller; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; -import io.metersphere.base.domain.LoadTestReport; import io.metersphere.base.domain.LoadTestReportLog; +import io.metersphere.base.domain.LoadTestReportWithBLOBs; import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; @@ -94,7 +94,7 @@ public class PerformanceReportController { } @GetMapping("/{reportId}") - public LoadTestReport getLoadTestReport(@PathVariable String reportId) { + public LoadTestReportWithBLOBs getLoadTestReport(@PathVariable String reportId) { return reportService.getLoadTestReport(reportId); } diff --git a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java index a52187115d..0dda487b2a 100644 --- a/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java +++ b/backend/src/main/java/io/metersphere/performance/service/PerformanceTestService.java @@ -226,8 +226,6 @@ public class PerformanceTestService { startEngine(loadTest, engine, request.getTriggerMode()); - // todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine - return engine.getReportId(); } @@ -257,7 +255,7 @@ public class PerformanceTestService { } private void startEngine(LoadTestWithBLOBs loadTest, Engine engine, String triggerMode) { - LoadTestReport testReport = new LoadTestReport(); + LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs(); testReport.setId(engine.getReportId()); testReport.setCreateTime(engine.getStartTime()); testReport.setUpdateTime(engine.getStartTime()); @@ -277,6 +275,7 @@ public class PerformanceTestService { loadTest.setStatus(PerformanceTestStatus.Starting.name()); loadTestMapper.updateByPrimaryKeySelective(loadTest); // 启动正常插入 report + testReport.setLoadConfiguration(loadTest.getLoadConfiguration()); testReport.setStatus(PerformanceTestStatus.Starting.name()); loadTestReportMapper.insertSelective(testReport); diff --git a/backend/src/main/java/io/metersphere/performance/service/ReportService.java b/backend/src/main/java/io/metersphere/performance/service/ReportService.java index 5c3e366ae8..b3624cdca7 100644 --- a/backend/src/main/java/io/metersphere/performance/service/ReportService.java +++ b/backend/src/main/java/io/metersphere/performance/service/ReportService.java @@ -169,8 +169,8 @@ public class ReportService { } } - public LoadTestReport getLoadTestReport(String id) { - return extLoadTestReportMapper.selectByPrimaryKey(id); + public LoadTestReportWithBLOBs getLoadTestReport(String id) { + return loadTestReportMapper.selectByPrimaryKey(id); } public List getReportLogResource(String reportId) { @@ -241,7 +241,7 @@ public class ReportService { } public void updateStatus(String reportId, String status) { - LoadTestReport report = new LoadTestReport(); + LoadTestReportWithBLOBs report = new LoadTestReportWithBLOBs(); report.setId(reportId); report.setStatus(status); loadTestReportMapper.updateByPrimaryKeySelective(report); diff --git a/backend/src/main/resources/db/migration/V12__modify_load_test_report.sql b/backend/src/main/resources/db/migration/V12__modify_load_test_report.sql new file mode 100644 index 0000000000..bae127a5ba --- /dev/null +++ b/backend/src/main/resources/db/migration/V12__modify_load_test_report.sql @@ -0,0 +1,2 @@ +ALTER TABLE load_test_report + ADD load_configuration LONGTEXT NULL; \ No newline at end of file diff --git a/frontend/src/business/components/api/test/components/ApiKeyValue.vue b/frontend/src/business/components/api/test/components/ApiKeyValue.vue index 4767c331d7..d3632a17d2 100644 --- a/frontend/src/business/components/api/test/components/ApiKeyValue.vue +++ b/frontend/src/business/components/api/test/components/ApiKeyValue.vue @@ -76,6 +76,7 @@

{{ $t('api_test.request.parameters_filter_example') }}:@string(10) | md5 | substr: 1, 3

{{ $t('api_test.request.parameters_filter_example') }}:@integer(1, 5) | concat:_metersphere

+

{{ $t('api_test.request.parameters_filter_tips') }}

@@ -84,7 +85,7 @@ diff --git a/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue b/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue new file mode 100644 index 0000000000..6d4998f88a --- /dev/null +++ b/frontend/src/business/components/performance/report/components/PerformancePressureConfig.vue @@ -0,0 +1,311 @@ + + + + + + diff --git a/frontend/src/business/components/settings/SettingMenu.vue b/frontend/src/business/components/settings/SettingMenu.vue index cc3fd00952..fd8b5b3603 100644 --- a/frontend/src/business/components/settings/SettingMenu.vue +++ b/frontend/src/business/components/settings/SettingMenu.vue @@ -21,6 +21,8 @@ {{$t('commons.workspace')}} + {{$t('organization.service_integration')}} + diff --git a/frontend/src/business/components/settings/organization/DefectManagement.vue b/frontend/src/business/components/settings/organization/DefectManagement.vue new file mode 100644 index 0000000000..ab6ea80e78 --- /dev/null +++ b/frontend/src/business/components/settings/organization/DefectManagement.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/frontend/src/business/components/settings/organization/ServiceIntegration.vue b/frontend/src/business/components/settings/organization/ServiceIntegration.vue new file mode 100644 index 0000000000..911c6c5355 --- /dev/null +++ b/frontend/src/business/components/settings/organization/ServiceIntegration.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseList.vue index ba84c3c3ba..25fa17cb0c 100644 --- a/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/TestPlanTestCaseList.vue @@ -55,6 +55,7 @@ @@ -497,6 +498,10 @@ this.initTableData(); }, sort(column) { + // 每次只对一个字段排序 + if (this.condition.orders) { + this.condition.orders = []; + } _sort(column, this.condition); this.initTableData(); }, diff --git a/frontend/src/common/js/constants.js b/frontend/src/common/js/constants.js index 349daa7119..302477cd60 100644 --- a/frontend/src/common/js/constants.js +++ b/frontend/src/common/js/constants.js @@ -111,3 +111,41 @@ export const MOCKJS_FUNC = [ {name: '@id'}, {name: '@increment'} ] + +export const JMETER_FUNC = [ + {name: "${__threadNum}"}, + {name: "${__samplerName}"}, + {name: "${__machineIP}"}, + {name: "${__machineName}"}, + {name: "${__time}"}, + {name: "${__log}"}, + {name: "${__logn}"}, + {name: "${__StringFromFile}"}, + {name: "${__FileToString}"}, + {name: "${__CSVRead}"}, + {name: "${__XPath}"}, + {name: "${__counter}"}, + {name: "${__intSum}"}, + {name: "${__longSum}"}, + {name: "${__Random}"}, + {name: "${__RandomString}"}, + {name: "${__UUID}"}, + {name: "${__BeanShell}"}, + {name: "${__javaScript}"}, + {name: "${__jexl}"}, + {name: "${__jexl2}"}, + {name: "${__property}"}, + {name: "${__P}"}, + {name: "${__setProperty}"}, + {name: "${__split}"}, + {name: "${__V}"}, + {name: "${__eval}"}, + {name: "${__evalVar}"}, + {name: "${__regexFunction}"}, + {name: "${__escapeOroRegexpChars}"}, + {name: "${__char}"}, + {name: "${__unescape}"}, + {name: "${__unescapeHtml}"}, + {name: "${__escapeHtml}"}, + {name: "${__TestPlanName}"}, +] diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 8bd5db7518..e4713201c7 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -173,8 +173,18 @@ export default { special_characters_are_not_supported: 'Incorrect format (special characters are not supported and cannot end with \'-\')', none: 'None Organization', select: 'Select Organization', - - + service_integration: 'Service integration', + defect_manage: 'Defect management platform', + select_defect_platform: 'Please select the defect management platform to be integrated:', + basic_auth_info: 'Basic Auth account information:', + api_account: 'API account', + api_password: 'API password', + input_api_account: 'please enter account', + input_api_password: 'Please enter password', + use_tip: 'Usage guidelines:', + use_tip_one: 'Basic Auth account information is queried in "Company Management-Security and Integration-Open Platform"', + use_tip_two: 'After saving the Basic Auth account information, you need to manually associate the ID/key in the Metersphere project', + link_the_project_now: 'Link the project now', }, project: { name: 'Project name', @@ -387,6 +397,7 @@ export default { path_description: "etc:/login", parameters: "Query parameters", parameters_filter_example: "Example", + parameters_filter_tips: "Only support MockJs function result preview", parameters_advance: "Advanced parameter settings", parameters_preview: "Preview", parameters_preview_warning: "Please enter the template first", @@ -497,9 +508,9 @@ export default { execution_result: ": Please select the execution result", actual_result: ": The actual result is empty", case: { - input_test_case:'Please enter the associated case name', - test_name:'TestName', - other:'--Other--', + input_test_case: 'Please enter the associated case name', + test_name: 'TestName', + other: '--Other--', test_case: "Case", move: "Move case", case_list: "Test case list", diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index 094949637a..016cdfe8cf 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -174,6 +174,18 @@ export default { none: '无组织', select: '选择组织', delete_warning: '删除该组织将同步删除该组织下所有相关工作空间和相关工作空间下的所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?', + service_integration: '服务集成', + defect_manage: '缺陷管理平台', + select_defect_platform: '请选择要集成的缺陷管理平台:', + basic_auth_info: 'Basic Auth 账号信息:', + api_account: 'API 账号', + api_password: 'API 口令', + input_api_account: '请输入账号', + input_api_password: '请输入口令', + use_tip: '使用指引:', + use_tip_one: 'Basic Auth 账号信息在"公司管理-安全与集成-开放平台"中查询', + use_tip_two: '保存 Basic Auth 账号信息后,需要在 Metersphere 项目中手动关联 ID/key', + link_the_project_now: '马上关联项目', }, project: { recent: '最近的项目', @@ -387,6 +399,7 @@ export default { parameters_filter: "内置函数", parameters_filter_desc: "使用方法", parameters_filter_example: "示例", + parameters_filter_tips: "只支持 MockJs 函数结果预览", parameters_advance: "高级参数设置", parameters_preview: "预览", parameters_preview_warning: "请先输入模版", diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 211873c9f7..3038392d69 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -172,7 +172,18 @@ export default { none: '無組織', select: '選擇組織', delete_warning: '删除该组织将同步删除该组织下所有相关工作空间和相关工作空间下的所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?', - + service_integration: '服務集成', + defect_manage: '缺陷管理平台', + select_defect_platform: '請選擇要集成的缺陷管理平台:', + basic_auth_info: 'Basic Auth 賬號信息:', + api_account: 'API 賬號', + api_password: 'API 口令', + input_api_account: '請輸入賬號', + input_api_password: '請輸入口令', + use_tip: '使用指引:', + use_tip_one: 'Basic Auth 賬號信息在"公司管理-安全與集成-開放平台"中查詢', + use_tip_two: '保存 Basic Auth 賬號信息後,需要在 Metersphere 項目中手動關聯 ID/key', + link_the_project_now: '馬上關聯項目', }, project: { recent: '最近的項目', @@ -386,6 +397,7 @@ export default { url_invalid: "URL無效", parameters: "請求參數", parameters_filter_example: "示例", + parameters_filter_tips: "只支持MockJs函數結果預覽", parameters_advance: "高級參數設置", parameters_preview: "預覽", parameters_preview_warning: "請先輸入模版", @@ -496,9 +508,9 @@ export default { execution_result: ": 請選擇執行結果", actual_result: ": 實際結果為空", case: { - input_test_case:'請輸入關聯用例名稱', - test_name:'測試名稱', - other:'--其他--', + input_test_case: '請輸入關聯用例名稱', + test_name: '測試名稱', + other: '--其他--', test_case: "測試用例", move: "移動用例", case_list: "用例列表",