Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
6b8c059f
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 大约 3 年
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6b8c059f
编写于
3月 24, 2020
作者:
C
chenjianxing
浏览文件
操作
浏览文件
下载
差异文件
merge
上级
a9845bf8
fdb6d690
变更
40
展开全部
隐藏空白更改
内联
并排
Showing
40 changed file
with
1372 addition
and
304 deletion
+1372
-304
backend/pom.xml
backend/pom.xml
+4
-16
backend/src/main/java/io/metersphere/Application.java
backend/src/main/java/io/metersphere/Application.java
+7
-0
backend/src/main/java/io/metersphere/base/domain/FileMetadata.java
...rc/main/java/io/metersphere/base/domain/FileMetadata.java
+0
-10
backend/src/main/java/io/metersphere/base/domain/FileMetadataExample.java
.../java/io/metersphere/base/domain/FileMetadataExample.java
+0
-70
backend/src/main/java/io/metersphere/base/mapper/FileMetadataMapper.xml
...in/java/io/metersphere/base/mapper/FileMetadataMapper.xml
+5
-20
backend/src/main/java/io/metersphere/commons/constants/EngineType.java
...ain/java/io/metersphere/commons/constants/EngineType.java
+0
-5
backend/src/main/java/io/metersphere/commons/constants/ResourcePoolTypeEnum.java
...o/metersphere/commons/constants/ResourcePoolTypeEnum.java
+1
-1
backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java
...io/metersphere/controller/TestResourcePoolController.java
+9
-0
backend/src/main/java/io/metersphere/dto/KubernetesDTO.java
backend/src/main/java/io/metersphere/dto/KubernetesDTO.java
+41
-0
backend/src/main/java/io/metersphere/dto/NodeDTO.java
backend/src/main/java/io/metersphere/dto/NodeDTO.java
+40
-0
backend/src/main/java/io/metersphere/engine/EngineContext.java
...nd/src/main/java/io/metersphere/engine/EngineContext.java
+0
-9
backend/src/main/java/io/metersphere/engine/EngineFactory.java
...nd/src/main/java/io/metersphere/engine/EngineFactory.java
+33
-6
backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java
...n/java/io/metersphere/engine/docker/DockerTestEngine.java
+11
-6
backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java
...o/metersphere/engine/kubernetes/KubernetesTestEngine.java
+4
-0
backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java
...etersphere/parse/xml/reader/jmx/JmeterDocumentParser.java
+3
-1
backend/src/main/java/io/metersphere/report/JtlResolver.java
backend/src/main/java/io/metersphere/report/JtlResolver.java
+113
-0
backend/src/main/java/io/metersphere/report/base/Metric.java
backend/src/main/java/io/metersphere/report/base/Metric.java
+180
-0
backend/src/main/java/io/metersphere/report/base/RequestStatistics.java
...in/java/io/metersphere/report/base/RequestStatistics.java
+125
-0
backend/src/main/java/io/metersphere/service/FuctionalTestService.java
...ain/java/io/metersphere/service/FuctionalTestService.java
+0
-5
backend/src/main/java/io/metersphere/service/LoadTestService.java
...src/main/java/io/metersphere/service/LoadTestService.java
+4
-6
backend/src/main/java/io/metersphere/service/ReportService.java
...d/src/main/java/io/metersphere/service/ReportService.java
+4
-0
backend/src/main/java/io/metersphere/service/TestResourcePoolService.java
.../java/io/metersphere/service/TestResourcePoolService.java
+70
-0
backend/src/main/resources/db/migration/V2__metersphere_ddl.sql
...d/src/main/resources/db/migration/V2__metersphere_ddl.sql
+0
-1
backend/src/main/resources/generatorConfig.xml
backend/src/main/resources/generatorConfig.xml
+14
-4
backend/src/test/java/io/metersphere/GenerateGraphTest.java
backend/src/test/java/io/metersphere/GenerateGraphTest.java
+35
-31
backend/src/test/java/io/metersphere/JtlTest.java
backend/src/test/java/io/metersphere/JtlTest.java
+271
-0
backend/src/test/java/io/metersphere/Metric.java
backend/src/test/java/io/metersphere/Metric.java
+180
-0
frontend/src/business/components/performance/plan/EditPerformanceTestPlan.vue
...s/components/performance/plan/EditPerformanceTestPlan.vue
+4
-0
frontend/src/business/components/performance/plan/components/PerformancePressureConfig.vue
...performance/plan/components/PerformancePressureConfig.vue
+42
-2
frontend/src/business/components/project/MsProject.vue
frontend/src/business/components/project/MsProject.vue
+1
-1
frontend/src/business/components/settings/organization/OrganizationMember.vue
...s/components/settings/organization/OrganizationMember.vue
+2
-2
frontend/src/business/components/settings/organization/OrganizationWorkspace.vue
...omponents/settings/organization/OrganizationWorkspace.vue
+3
-3
frontend/src/business/components/settings/personal/PersonSetting.vue
...c/business/components/settings/personal/PersonSetting.vue
+1
-1
frontend/src/business/components/settings/system/Organization.vue
.../src/business/components/settings/system/Organization.vue
+4
-4
frontend/src/business/components/settings/system/SystemWorkspace.vue
...c/business/components/settings/system/SystemWorkspace.vue
+4
-4
frontend/src/business/components/settings/system/TestResourcePool.vue
.../business/components/settings/system/TestResourcePool.vue
+149
-92
frontend/src/business/components/settings/system/User.vue
frontend/src/business/components/settings/system/User.vue
+2
-2
frontend/src/business/components/settings/workspace/WorkspaceMember.vue
...usiness/components/settings/workspace/WorkspaceMember.vue
+2
-2
frontend/src/i18n/en-US.js
frontend/src/i18n/en-US.js
+2
-0
frontend/src/i18n/zh-CN.js
frontend/src/i18n/zh-CN.js
+2
-0
未找到文件。
backend/pom.xml
浏览文件 @
6b8c059f
...
@@ -152,25 +152,13 @@
...
@@ -152,25 +152,13 @@
<artifactId>
jmeter-plugins-casutg
</artifactId>
<artifactId>
jmeter-plugins-casutg
</artifactId>
<version>
2.9
</version>
<version>
2.9
</version>
</dependency>
</dependency>
<!-- jmeter graph -->
<dependency>
<groupId>
kg.apc
</groupId>
<artifactId>
jmeter-plugins-cmd
</artifactId>
<version>
2.2
</version>
</dependency>
<dependency>
<groupId>
kg.apc
</groupId>
<artifactId>
jmeter-plugins-synthesis
</artifactId>
<version>
2.2
</version>
</dependency>
<!-- https://mvnrepository.com/artifact/kg.apc/jmeter-plugins-standard -->
<dependency>
<dependency>
<groupId>
kg.apc
</groupId>
<groupId>
com.opencsv
</groupId>
<artifactId>
jmeter-plugins-standard
</artifactId>
<artifactId>
opencsv
</artifactId>
<version>
1.4.0
</version>
<version>
5.1
</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpclient
</artifactId>
<artifactId>
httpclient
</artifactId>
...
...
backend/src/main/java/io/metersphere/Application.java
浏览文件 @
6b8c059f
...
@@ -6,6 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
...
@@ -6,6 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration
;
import
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.boot.web.servlet.ServletComponentScan
;
import
org.springframework.boot.web.servlet.ServletComponentScan
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.web.client.RestTemplate
;
@SpringBootApplication
(
exclude
=
{
QuartzAutoConfiguration
.
class
})
@SpringBootApplication
(
exclude
=
{
QuartzAutoConfiguration
.
class
})
@ServletComponentScan
@ServletComponentScan
...
@@ -14,4 +16,9 @@ public class Application {
...
@@ -14,4 +16,9 @@ public class Application {
public
static
void
main
(
String
[]
args
)
{
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
Application
.
class
,
args
);
SpringApplication
.
run
(
Application
.
class
,
args
);
}
}
@Bean
public
RestTemplate
restTemplate
()
{
return
new
RestTemplate
();
}
}
}
backend/src/main/java/io/metersphere/base/domain/FileMetadata.java
浏览文件 @
6b8c059f
...
@@ -9,8 +9,6 @@ public class FileMetadata implements Serializable {
...
@@ -9,8 +9,6 @@ public class FileMetadata implements Serializable {
private
String
type
;
private
String
type
;
private
String
engine
;
private
Long
createTime
;
private
Long
createTime
;
private
Long
updateTime
;
private
Long
updateTime
;
...
@@ -43,14 +41,6 @@ public class FileMetadata implements Serializable {
...
@@ -43,14 +41,6 @@ public class FileMetadata implements Serializable {
this
.
type
=
type
==
null
?
null
:
type
.
trim
();
this
.
type
=
type
==
null
?
null
:
type
.
trim
();
}
}
public
String
getEngine
()
{
return
engine
;
}
public
void
setEngine
(
String
engine
)
{
this
.
engine
=
engine
==
null
?
null
:
engine
.
trim
();
}
public
Long
getCreateTime
()
{
public
Long
getCreateTime
()
{
return
createTime
;
return
createTime
;
}
}
...
...
backend/src/main/java/io/metersphere/base/domain/FileMetadataExample.java
浏览文件 @
6b8c059f
...
@@ -314,76 +314,6 @@ public class FileMetadataExample {
...
@@ -314,76 +314,6 @@ public class FileMetadataExample {
return
(
Criteria
)
this
;
return
(
Criteria
)
this
;
}
}
public
Criteria
andEngineIsNull
()
{
addCriterion
(
"engine is null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineIsNotNull
()
{
addCriterion
(
"engine is not null"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineEqualTo
(
String
value
)
{
addCriterion
(
"engine ="
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineNotEqualTo
(
String
value
)
{
addCriterion
(
"engine <>"
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineGreaterThan
(
String
value
)
{
addCriterion
(
"engine >"
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineGreaterThanOrEqualTo
(
String
value
)
{
addCriterion
(
"engine >="
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineLessThan
(
String
value
)
{
addCriterion
(
"engine <"
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineLessThanOrEqualTo
(
String
value
)
{
addCriterion
(
"engine <="
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineLike
(
String
value
)
{
addCriterion
(
"engine like"
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineNotLike
(
String
value
)
{
addCriterion
(
"engine not like"
,
value
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineIn
(
List
<
String
>
values
)
{
addCriterion
(
"engine in"
,
values
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineNotIn
(
List
<
String
>
values
)
{
addCriterion
(
"engine not in"
,
values
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"engine between"
,
value1
,
value2
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andEngineNotBetween
(
String
value1
,
String
value2
)
{
addCriterion
(
"engine not between"
,
value1
,
value2
,
"engine"
);
return
(
Criteria
)
this
;
}
public
Criteria
andCreateTimeIsNull
()
{
public
Criteria
andCreateTimeIsNull
()
{
addCriterion
(
"create_time is null"
);
addCriterion
(
"create_time is null"
);
return
(
Criteria
)
this
;
return
(
Criteria
)
this
;
...
...
backend/src/main/java/io/metersphere/base/mapper/FileMetadataMapper.xml
浏览文件 @
6b8c059f
...
@@ -5,7 +5,6 @@
...
@@ -5,7 +5,6 @@
<id
column=
"id"
jdbcType=
"VARCHAR"
property=
"id"
/>
<id
column=
"id"
jdbcType=
"VARCHAR"
property=
"id"
/>
<result
column=
"name"
jdbcType=
"VARCHAR"
property=
"name"
/>
<result
column=
"name"
jdbcType=
"VARCHAR"
property=
"name"
/>
<result
column=
"type"
jdbcType=
"VARCHAR"
property=
"type"
/>
<result
column=
"type"
jdbcType=
"VARCHAR"
property=
"type"
/>
<result
column=
"engine"
jdbcType=
"VARCHAR"
property=
"engine"
/>
<result
column=
"create_time"
jdbcType=
"BIGINT"
property=
"createTime"
/>
<result
column=
"create_time"
jdbcType=
"BIGINT"
property=
"createTime"
/>
<result
column=
"update_time"
jdbcType=
"BIGINT"
property=
"updateTime"
/>
<result
column=
"update_time"
jdbcType=
"BIGINT"
property=
"updateTime"
/>
<result
column=
"size"
jdbcType=
"BIGINT"
property=
"size"
/>
<result
column=
"size"
jdbcType=
"BIGINT"
property=
"size"
/>
...
@@ -69,7 +68,7 @@
...
@@ -69,7 +68,7 @@
</where>
</where>
</sql>
</sql>
<sql
id=
"Base_Column_List"
>
<sql
id=
"Base_Column_List"
>
id, name, type,
engine,
create_time, update_time, size
id, name, type, create_time, update_time, size
</sql>
</sql>
<select
id=
"selectByExample"
parameterType=
"io.metersphere.base.domain.FileMetadataExample"
resultMap=
"BaseResultMap"
>
<select
id=
"selectByExample"
parameterType=
"io.metersphere.base.domain.FileMetadataExample"
resultMap=
"BaseResultMap"
>
select
select
...
@@ -103,11 +102,11 @@
...
@@ -103,11 +102,11 @@
</delete>
</delete>
<insert
id=
"insert"
parameterType=
"io.metersphere.base.domain.FileMetadata"
>
<insert
id=
"insert"
parameterType=
"io.metersphere.base.domain.FileMetadata"
>
insert into file_metadata (id, name, type,
insert into file_metadata (id, name, type,
engine, create_time, update_time,
create_time, update_time, size
size
)
)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
#{
engine,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{
createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{size,jdbcType=BIGINT}
#{size,jdbcType=BIGINT}
)
)
</insert>
</insert>
<insert
id=
"insertSelective"
parameterType=
"io.metersphere.base.domain.FileMetadata"
>
<insert
id=
"insertSelective"
parameterType=
"io.metersphere.base.domain.FileMetadata"
>
insert into file_metadata
insert into file_metadata
...
@@ -121,9 +120,6 @@
...
@@ -121,9 +120,6 @@
<if
test=
"type != null"
>
<if
test=
"type != null"
>
type,
type,
</if>
</if>
<if
test=
"engine != null"
>
engine,
</if>
<if
test=
"createTime != null"
>
<if
test=
"createTime != null"
>
create_time,
create_time,
</if>
</if>
...
@@ -144,9 +140,6 @@
...
@@ -144,9 +140,6 @@
<if
test=
"type != null"
>
<if
test=
"type != null"
>
#{type,jdbcType=VARCHAR},
#{type,jdbcType=VARCHAR},
</if>
</if>
<if
test=
"engine != null"
>
#{engine,jdbcType=VARCHAR},
</if>
<if
test=
"createTime != null"
>
<if
test=
"createTime != null"
>
#{createTime,jdbcType=BIGINT},
#{createTime,jdbcType=BIGINT},
</if>
</if>
...
@@ -176,9 +169,6 @@
...
@@ -176,9 +169,6 @@
<if
test=
"record.type != null"
>
<if
test=
"record.type != null"
>
type = #{record.type,jdbcType=VARCHAR},
type = #{record.type,jdbcType=VARCHAR},
</if>
</if>
<if
test=
"record.engine != null"
>
engine = #{record.engine,jdbcType=VARCHAR},
</if>
<if
test=
"record.createTime != null"
>
<if
test=
"record.createTime != null"
>
create_time = #{record.createTime,jdbcType=BIGINT},
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
</if>
...
@@ -198,7 +188,6 @@
...
@@ -198,7 +188,6 @@
set id = #{record.id,jdbcType=VARCHAR},
set id = #{record.id,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
type = #{record.type,jdbcType=VARCHAR},
type = #{record.type,jdbcType=VARCHAR},
engine = #{record.engine,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
size = #{record.size,jdbcType=BIGINT}
size = #{record.size,jdbcType=BIGINT}
...
@@ -215,9 +204,6 @@
...
@@ -215,9 +204,6 @@
<if
test=
"type != null"
>
<if
test=
"type != null"
>
type = #{type,jdbcType=VARCHAR},
type = #{type,jdbcType=VARCHAR},
</if>
</if>
<if
test=
"engine != null"
>
engine = #{engine,jdbcType=VARCHAR},
</if>
<if
test=
"createTime != null"
>
<if
test=
"createTime != null"
>
create_time = #{createTime,jdbcType=BIGINT},
create_time = #{createTime,jdbcType=BIGINT},
</if>
</if>
...
@@ -234,7 +220,6 @@
...
@@ -234,7 +220,6 @@
update file_metadata
update file_metadata
set name = #{name,jdbcType=VARCHAR},
set name = #{name,jdbcType=VARCHAR},
type = #{type,jdbcType=VARCHAR},
type = #{type,jdbcType=VARCHAR},
engine = #{engine,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
size = #{size,jdbcType=BIGINT}
size = #{size,jdbcType=BIGINT}
...
...
backend/src/main/java/io/metersphere/commons/constants/EngineType.java
已删除
100644 → 0
浏览文件 @
a9845bf8
package
io.metersphere.commons.constants
;
public
enum
EngineType
{
DOCKER
,
KUBERNETES
}
backend/src/main/java/io/metersphere/commons/constants/ResourceTypeEnum.java
→
backend/src/main/java/io/metersphere/commons/constants/Resource
Pool
TypeEnum.java
浏览文件 @
6b8c059f
package
io.metersphere.commons.constants
;
package
io.metersphere.commons.constants
;
public
enum
ResourceTypeEnum
{
public
enum
Resource
Pool
TypeEnum
{
/**
/**
* k8s 资源池
* k8s 资源池
*/
*/
...
...
backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java
浏览文件 @
6b8c059f
...
@@ -39,4 +39,13 @@ public class TestResourcePoolController {
...
@@ -39,4 +39,13 @@ public class TestResourcePoolController {
Page
<
Object
>
page
=
PageHelper
.
startPage
(
goPage
,
pageSize
,
true
);
Page
<
Object
>
page
=
PageHelper
.
startPage
(
goPage
,
pageSize
,
true
);
return
PageUtils
.
setPageInfo
(
page
,
testResourcePoolService
.
listResourcePools
(
request
));
return
PageUtils
.
setPageInfo
(
page
,
testResourcePoolService
.
listResourcePools
(
request
));
}
}
@GetMapping
(
"list/all"
)
public
List
<
TestResourcePool
>
listResourcePools
()
{
PageHelper
.
startPage
(
1
,
10000
,
true
);
QueryResourcePoolRequest
request
=
new
QueryResourcePoolRequest
();
return
testResourcePoolService
.
listResourcePools
(
request
);
}
}
}
backend/src/main/java/io/metersphere/dto/KubernetesDTO.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere.dto
;
public
class
KubernetesDTO
{
private
String
masterUrl
;
private
String
token
;
private
Integer
maxConcurrency
;
private
Boolean
validate
;
public
String
getMasterUrl
()
{
return
masterUrl
;
}
public
void
setMasterUrl
(
String
masterUrl
)
{
this
.
masterUrl
=
masterUrl
;
}
public
String
getToken
()
{
return
token
;
}
public
void
setToken
(
String
token
)
{
this
.
token
=
token
;
}
public
Integer
getMaxConcurrency
()
{
return
maxConcurrency
;
}
public
void
setMaxConcurrency
(
Integer
maxConcurrency
)
{
this
.
maxConcurrency
=
maxConcurrency
;
}
public
Boolean
getValidate
()
{
return
validate
;
}
public
void
setValidate
(
Boolean
validate
)
{
this
.
validate
=
validate
;
}
}
backend/src/main/java/io/metersphere/dto/NodeDTO.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere.dto
;
public
class
NodeDTO
{
private
String
ip
;
private
Integer
port
;
private
Integer
maxConcurrency
;
private
Boolean
validate
;
public
String
getIp
()
{
return
ip
;
}
public
void
setIp
(
String
ip
)
{
this
.
ip
=
ip
;
}
public
Integer
getPort
()
{
return
port
;
}
public
void
setPort
(
Integer
port
)
{
this
.
port
=
port
;
}
public
Integer
getMaxConcurrency
()
{
return
maxConcurrency
;
}
public
void
setMaxConcurrency
(
Integer
maxConcurrency
)
{
this
.
maxConcurrency
=
maxConcurrency
;
}
public
Boolean
getValidate
()
{
return
validate
;
}
public
void
setValidate
(
Boolean
validate
)
{
this
.
validate
=
validate
;
}
}
backend/src/main/java/io/metersphere/engine/EngineContext.java
浏览文件 @
6b8c059f
...
@@ -7,7 +7,6 @@ public class EngineContext {
...
@@ -7,7 +7,6 @@ public class EngineContext {
private
String
testId
;
private
String
testId
;
private
String
testName
;
private
String
testName
;
private
String
namespace
;
private
String
namespace
;
private
String
engineType
;
private
String
fileType
;
private
String
fileType
;
private
String
content
;
private
String
content
;
private
Map
<
String
,
Object
>
properties
=
new
HashMap
<>();
private
Map
<
String
,
Object
>
properties
=
new
HashMap
<>();
...
@@ -37,14 +36,6 @@ public class EngineContext {
...
@@ -37,14 +36,6 @@ public class EngineContext {
this
.
namespace
=
namespace
;
this
.
namespace
=
namespace
;
}
}
public
String
getEngineType
()
{
return
engineType
;
}
public
void
setEngineType
(
String
engineType
)
{
this
.
engineType
=
engineType
;
}
public
void
addProperty
(
String
key
,
Object
value
)
{
public
void
addProperty
(
String
key
,
Object
value
)
{
this
.
properties
.
put
(
key
,
value
);
this
.
properties
.
put
(
key
,
value
);
}
}
...
...
backend/src/main/java/io/metersphere/engine/EngineFactory.java
浏览文件 @
6b8c059f
...
@@ -5,7 +5,8 @@ import com.alibaba.fastjson.JSONObject;
...
@@ -5,7 +5,8 @@ import com.alibaba.fastjson.JSONObject;
import
io.metersphere.base.domain.FileContent
;
import
io.metersphere.base.domain.FileContent
;
import
io.metersphere.base.domain.FileMetadata
;
import
io.metersphere.base.domain.FileMetadata
;
import
io.metersphere.base.domain.LoadTestWithBLOBs
;
import
io.metersphere.base.domain.LoadTestWithBLOBs
;
import
io.metersphere.commons.constants.EngineType
;
import
io.metersphere.base.domain.TestResourcePool
;
import
io.metersphere.commons.constants.ResourcePoolTypeEnum
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.engine.docker.DockerTestEngine
;
import
io.metersphere.engine.docker.DockerTestEngine
;
import
io.metersphere.engine.kubernetes.KubernetesTestEngine
;
import
io.metersphere.engine.kubernetes.KubernetesTestEngine
;
...
@@ -13,6 +14,7 @@ import io.metersphere.i18n.Translator;
...
@@ -13,6 +14,7 @@ import io.metersphere.i18n.Translator;
import
io.metersphere.parse.EngineSourceParser
;
import
io.metersphere.parse.EngineSourceParser
;
import
io.metersphere.parse.EngineSourceParserFactory
;
import
io.metersphere.parse.EngineSourceParserFactory
;
import
io.metersphere.service.FileService
;
import
io.metersphere.service.FileService
;
import
io.metersphere.service.TestResourcePoolService
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
...
@@ -26,14 +28,35 @@ import java.util.Map;
...
@@ -26,14 +28,35 @@ import java.util.Map;
@Service
@Service
public
class
EngineFactory
{
public
class
EngineFactory
{
private
static
FileService
fileService
;
private
static
FileService
fileService
;
private
static
TestResourcePoolService
testResourcePoolService
;
public
static
Engine
createEngine
(
String
engineType
)
{
public
static
Engine
createEngine
(
LoadTestWithBLOBs
loadTest
)
{
final
EngineType
type
=
EngineType
.
valueOf
(
engineType
);
String
resourcePoolId
=
null
;
if
(!
StringUtils
.
isEmpty
(
loadTest
.
getLoadConfiguration
()))
{
final
JSONArray
jsonArray
=
JSONObject
.
parseArray
(
loadTest
.
getLoadConfiguration
());
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
final
JSONObject
jsonObject
=
jsonArray
.
getJSONObject
(
i
);
if
(
StringUtils
.
equals
(
jsonObject
.
getString
(
"key"
),
"resourcePoolId"
))
{
resourcePoolId
=
jsonObject
.
getString
(
"value"
);
break
;
}
}
}
if
(
StringUtils
.
isBlank
(
resourcePoolId
))
{
MSException
.
throwException
(
"Resource Pool ID is empty."
);
}
TestResourcePool
resourcePool
=
testResourcePoolService
.
getResourcePool
(
resourcePoolId
);
if
(
resourcePool
==
null
)
{
MSException
.
throwException
(
"Resource Pool is empty."
);
}
final
ResourcePoolTypeEnum
type
=
ResourcePoolTypeEnum
.
valueOf
(
resourcePool
.
getType
());
switch
(
type
)
{
switch
(
type
)
{
case
DOCKER
:
case
NODE
:
return
new
DockerTestEngine
();
return
new
DockerTestEngine
();
case
K
UBERNETE
S:
case
K
8
S:
return
new
KubernetesTestEngine
();
return
new
KubernetesTestEngine
();
}
}
return
null
;
return
null
;
...
@@ -48,7 +71,6 @@ public class EngineFactory {
...
@@ -48,7 +71,6 @@ public class EngineFactory {
engineContext
.
setTestId
(
loadTest
.
getId
());
engineContext
.
setTestId
(
loadTest
.
getId
());
engineContext
.
setTestName
(
loadTest
.
getName
());
engineContext
.
setTestName
(
loadTest
.
getName
());
engineContext
.
setNamespace
(
loadTest
.
getProjectId
());
engineContext
.
setNamespace
(
loadTest
.
getProjectId
());
engineContext
.
setEngineType
(
fileMetadata
.
getEngine
());
engineContext
.
setFileType
(
fileMetadata
.
getType
());
engineContext
.
setFileType
(
fileMetadata
.
getType
());
if
(!
StringUtils
.
isEmpty
(
loadTest
.
getLoadConfiguration
()))
{
if
(!
StringUtils
.
isEmpty
(
loadTest
.
getLoadConfiguration
()))
{
...
@@ -86,4 +108,9 @@ public class EngineFactory {
...
@@ -86,4 +108,9 @@ public class EngineFactory {
private
void
setFileService
(
FileService
fileService
)
{
private
void
setFileService
(
FileService
fileService
)
{
EngineFactory
.
fileService
=
fileService
;
EngineFactory
.
fileService
=
fileService
;
}
}
@Resource
public
void
setTestResourcePoolService
(
TestResourcePoolService
testResourcePoolService
)
{
EngineFactory
.
testResourcePoolService
=
testResourcePoolService
;
}
}
}
backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java
浏览文件 @
6b8c059f
package
io.metersphere.engine.docker
;
package
io.metersphere.engine.docker
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.CommonBeanFactory
;
import
io.metersphere.controller.request.TestRequest
;
import
io.metersphere.controller.request.TestRequest
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.EngineContext
;
import
io.metersphere.engine.EngineContext
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.client.RestTemplate
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
public
class
DockerTestEngine
implements
Engine
{
public
class
DockerTestEngine
implements
Engine
{
private
EngineContext
context
;
private
EngineContext
context
;
RestTemplate
restTemplate
;
@Override
@Override
public
boolean
init
(
EngineContext
context
)
{
public
boolean
init
(
EngineContext
context
)
{
this
.
restTemplate
=
CommonBeanFactory
.
getBean
(
RestTemplate
.
class
);
// todo 初始化操作
// todo 初始化操作
this
.
context
=
context
;
this
.
context
=
context
;
return
true
;
return
true
;
...
@@ -22,8 +25,8 @@ public class DockerTestEngine implements Engine {
...
@@ -22,8 +25,8 @@ public class DockerTestEngine implements Engine {
@Override
@Override
public
void
start
()
{
public
void
start
()
{
RestTemplate
restTemplate
=
new
RestTemplate
();
// todo 运行测试
// RestTemplate restTemplate = new RestTemplate();
String
testId
=
context
.
getTestId
();
String
testId
=
context
.
getTestId
();
String
content
=
context
.
getContent
();
String
content
=
context
.
getContent
();
...
@@ -34,6 +37,7 @@ public class DockerTestEngine implements Engine {
...
@@ -34,6 +37,7 @@ public class DockerTestEngine implements Engine {
testRequest
.
setTestId
(
testId
);
testRequest
.
setTestId
(
testId
);
testRequest
.
setFileString
(
content
);
testRequest
.
setFileString
(
content
);
// todo 判断测试状态
String
taskStatusUri
=
"http://localhost:8082/jmeter/task/status/"
+
testId
;
String
taskStatusUri
=
"http://localhost:8082/jmeter/task/status/"
+
testId
;
List
containerList
=
restTemplate
.
getForObject
(
taskStatusUri
,
List
.
class
);
List
containerList
=
restTemplate
.
getForObject
(
taskStatusUri
,
List
.
class
);
for
(
int
i
=
0
;
i
<
containerList
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
containerList
.
size
();
i
++)
{
...
@@ -48,12 +52,13 @@ public class DockerTestEngine implements Engine {
...
@@ -48,12 +52,13 @@ public class DockerTestEngine implements Engine {
@Override
@Override
public
void
stop
()
{
public
void
stop
()
{
RestTemplate
restTemplate
=
new
RestTemplate
();
// TODO 停止运行测试
// RestTemplate restTemplate = new RestTemplate();
String
testId
=
context
.
getTestId
();
String
testId
=
context
.
getTestId
();
String
uri
=
"http://localhost:8082/jmeter/container/stop"
+
testId
;
String
uri
=
"http://localhost:8082/jmeter/container/stop
/
"
+
testId
;
restTemplate
.
getForObject
(
uri
,
String
.
class
);
restTemplate
.
postForObject
(
uri
,
""
,
String
.
class
);
}
}
}
}
backend/src/main/java/io/metersphere/engine/kubernetes/KubernetesTestEngine.java
浏览文件 @
6b8c059f
...
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
...
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import
io.fabric8.kubernetes.api.model.ConfigMap
;
import
io.fabric8.kubernetes.api.model.ConfigMap
;
import
io.fabric8.kubernetes.api.model.ObjectMeta
;
import
io.fabric8.kubernetes.api.model.ObjectMeta
;
import
io.fabric8.kubernetes.client.KubernetesClient
;
import
io.fabric8.kubernetes.client.KubernetesClient
;
import
io.metersphere.commons.utils.CommonBeanFactory
;
import
io.metersphere.commons.utils.LogUtil
;
import
io.metersphere.commons.utils.LogUtil
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.EngineContext
;
import
io.metersphere.engine.EngineContext
;
...
@@ -11,17 +12,20 @@ import io.metersphere.engine.kubernetes.crds.jmeter.Jmeter;
...
@@ -11,17 +12,20 @@ import io.metersphere.engine.kubernetes.crds.jmeter.Jmeter;
import
io.metersphere.engine.kubernetes.crds.jmeter.JmeterSpec
;
import
io.metersphere.engine.kubernetes.crds.jmeter.JmeterSpec
;
import
io.metersphere.engine.kubernetes.provider.ClientCredential
;
import
io.metersphere.engine.kubernetes.provider.ClientCredential
;
import
io.metersphere.engine.kubernetes.provider.KubernetesProvider
;
import
io.metersphere.engine.kubernetes.provider.KubernetesProvider
;
import
io.metersphere.service.TestResourcePoolService
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.collections.MapUtils
;
import
java.util.HashMap
;
import
java.util.HashMap
;
public
class
KubernetesTestEngine
implements
Engine
{
public
class
KubernetesTestEngine
implements
Engine
{
private
EngineContext
context
;
private
EngineContext
context
;
private
TestResourcePoolService
testResourcePoolService
;
@Override
@Override
public
boolean
init
(
EngineContext
context
)
{
public
boolean
init
(
EngineContext
context
)
{
// todo 初始化操作
// todo 初始化操作
this
.
context
=
context
;
this
.
context
=
context
;
this
.
testResourcePoolService
=
CommonBeanFactory
.
getBean
(
TestResourcePoolService
.
class
);
return
true
;
return
true
;
}
}
...
...
backend/src/main/java/io/metersphere/parse/xml/reader/jmx/JmeterDocumentParser.java
浏览文件 @
6b8c059f
...
@@ -233,9 +233,11 @@ public class JmeterDocumentParser implements DocumentParser {
...
@@ -233,9 +233,11 @@ public class JmeterDocumentParser implements DocumentParser {
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.batch.size"
,
kafkaProperties
.
getBatchSize
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.batch.size"
,
kafkaProperties
.
getBatchSize
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.client.id"
,
kafkaProperties
.
getClientId
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.client.id"
,
kafkaProperties
.
getClientId
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.connections.max.idle.ms"
,
kafkaProperties
.
getConnectionsMaxIdleMs
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"kafka.connections.max.idle.ms"
,
kafkaProperties
.
getConnectionsMaxIdleMs
()));
// 添加关联关系 test.id test.name
// 添加关联关系 test.id test.name
test.startTime test.size
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.id"
,
context
.
getTestId
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.id"
,
context
.
getTestId
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.name"
,
context
.
getTestName
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.name"
,
context
.
getTestName
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.startTime"
,
""
+
System
.
currentTimeMillis
()));
collectionProp
.
appendChild
(
createKafkaProp
(
document
,
"test.size"
,
"1"
));
elementProp
.
appendChild
(
collectionProp
);
elementProp
.
appendChild
(
collectionProp
);
// set elementProp
// set elementProp
...
...
backend/src/main/java/io/metersphere/report/JtlResolver.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere.report
;
import
com.alibaba.fastjson.JSONObject
;
import
com.opencsv.bean.CsvToBean
;
import
com.opencsv.bean.CsvToBeanBuilder
;
import
com.opencsv.bean.HeaderColumnNameMappingStrategy
;
import
io.metersphere.report.base.Metric
;
import
io.metersphere.report.base.RequestStatistics
;
import
java.io.Reader
;
import
java.io.StringReader
;
import
java.util.*
;
import
java.util.stream.Collectors
;
public
class
JtlResolver
{
private
List
<
Metric
>
resolver
(
String
jtlString
)
{
HeaderColumnNameMappingStrategy
<
Metric
>
ms
=
new
HeaderColumnNameMappingStrategy
<>();
ms
.
setType
(
Metric
.
class
);
try
(
Reader
reader
=
new
StringReader
(
jtlString
))
{
CsvToBean
<
Metric
>
cb
=
new
CsvToBeanBuilder
<
Metric
>(
reader
)
.
withType
(
Metric
.
class
)
.
withSkipLines
(
0
)
.
withMappingStrategy
(
ms
)
.
withIgnoreLeadingWhiteSpace
(
true
)
.
build
();
return
cb
.
parse
();
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
}
return
null
;
}
private
List
<
RequestStatistics
>
getOneRpsResult
(
Map
<
String
,
List
<
Metric
>>
map
){
List
<
RequestStatistics
>
requestStatisticsList
=
new
ArrayList
<>();
Iterator
<
Map
.
Entry
<
String
,
List
<
Metric
>>>
iterator
=
map
.
entrySet
().
iterator
();
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
String
,
List
<
Metric
>>
entry
=
iterator
.
next
();
String
label
=
entry
.
getKey
();
List
<
Metric
>
list
=
entry
.
getValue
();
List
<
String
>
timestampList
=
list
.
stream
().
map
(
Metric:
:
getTimestamp
).
collect
(
Collectors
.
toList
());
int
index
=
0
;
//总的响应时间
int
sumElapsed
=
0
;
Integer
failSize
=
0
;
Integer
totalBytes
=
0
;
List
<
Integer
>
elapsedList
=
new
ArrayList
<
Integer
>();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
try
{
Metric
row
=
list
.
get
(
i
);
//响应时间
String
elapsed
=
row
.
getElapsed
();
sumElapsed
+=
Integer
.
valueOf
(
elapsed
);
elapsedList
.
add
(
Integer
.
valueOf
(
elapsed
));
//成功与否
String
success
=
row
.
getSuccess
();
if
(!
"true"
.
equals
(
success
)){
failSize
++;
}
//字节
String
bytes
=
row
.
getBytes
();
totalBytes
+=
Integer
.
valueOf
(
bytes
);
index
++;
}
catch
(
Exception
e
){
System
.
out
.
println
(
"exception i:"
+
i
);
}
}
Collections
.
sort
(
elapsedList
,
new
Comparator
<
Integer
>()
{
public
int
compare
(
Integer
o1
,
Integer
o2
)
{
return
o1
-
o2
;
}
});
Integer
tp90
=
elapsedList
.
size
()*
9
/
10
;
Integer
tp95
=
elapsedList
.
size
()*
95
/
100
;
Integer
tp99
=
elapsedList
.
size
()*
99
/
100
;
Long
l
=
Long
.
valueOf
(
timestampList
.
get
(
index
-
1
))
-
Long
.
valueOf
(
timestampList
.
get
(
0
));
RequestStatistics
requestStatistics
=
new
RequestStatistics
();
requestStatistics
.
setRequestLabel
(
label
);
requestStatistics
.
setSamples
(
index
+
""
);
requestStatistics
.
setAverage
(
sumElapsed
/
index
+
""
);
/**
* TP90的计算
* 1,把一段时间内全部的请求的响应时间,从小到大排序,获得序列A
* 2,总的请求数量,乘以90%,获得90%对应的请求个数C
* 3,从序列A中找到第C个请求,它的响应时间,即为TP90的值
* 其余相似的指标还有TP95, TP99
*/
requestStatistics
.
setTp90
(
elapsedList
.
get
(
tp90
)+
""
);
requestStatistics
.
setTp95
(
elapsedList
.
get
(
tp95
)+
""
);
requestStatistics
.
setTp99
(
elapsedList
.
get
(
tp99
)+
""
);
requestStatistics
.
setMin
(
elapsedList
.
get
(
0
)+
""
);
requestStatistics
.
setMax
(
elapsedList
.
get
(
index
-
1
)+
""
);
requestStatistics
.
setErrors
(
String
.
format
(
"%.2f"
,
failSize
*
100.0
/
index
)+
"%"
);
requestStatistics
.
setKbPerSec
(
String
.
format
(
"%.2f"
,
totalBytes
*
1.0
/
1024
/(
l
*
1.0
/
1000
)));
requestStatisticsList
.
add
(
requestStatistics
);
}
return
requestStatisticsList
;
}
public
List
<
RequestStatistics
>
getRequestStatistics
(
String
jtlString
)
{
List
<
Metric
>
totalLines
=
resolver
(
jtlString
);
Map
<
String
,
List
<
Metric
>>
map
=
totalLines
.
stream
().
collect
(
Collectors
.
groupingBy
(
Metric:
:
getLabel
));
return
getOneRpsResult
(
map
);
}
}
\ No newline at end of file
backend/src/main/java/io/metersphere/report/base/Metric.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere.report.base
;
import
com.opencsv.bean.CsvBindByName
;
public
class
Metric
{
// timestamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
@CsvBindByName
(
column
=
"timestamp"
)
// 访问开始时间
private
String
timestamp
;
@CsvBindByName
(
column
=
"elapsed"
)
// 访问开始到结束的用时 - 响应时间
private
String
elapsed
;
@CsvBindByName
(
column
=
"label"
)
// 请求的标签
private
String
label
;
@CsvBindByName
(
column
=
"responseCode"
)
// 响应码
private
String
responseCode
;
@CsvBindByName
(
column
=
"responseMessage"
)
// 响应信息
private
String
responseMessage
;
@CsvBindByName
(
column
=
"threadName"
)
// 请求所属线程
private
String
threadName
;
@CsvBindByName
(
column
=
"dataType"
)
// 数据类型
private
String
dataType
;
@CsvBindByName
(
column
=
"success"
)
// 访问是否成功
private
String
success
;
@CsvBindByName
(
column
=
"failureMessage"
)
// 访问失败信息
private
String
failureMessage
;
@CsvBindByName
(
column
=
"bytes"
)
//
private
String
bytes
;
@CsvBindByName
(
column
=
"sentBytes"
)
//
private
String
sentBytes
;
@CsvBindByName
(
column
=
"grpThreads"
)
// 线程组
private
String
grpThreads
;
@CsvBindByName
(
column
=
"allThreads"
)
//
private
String
allThreads
;
@CsvBindByName
(
column
=
"URL"
)
//
private
String
url
;
@CsvBindByName
(
column
=
"Latency"
)
// 延时
private
String
latency
;
@CsvBindByName
(
column
=
"IdleTime"
)
// 闲置时间
private
String
idleTime
;
@CsvBindByName
(
column
=
"Connect"
)
//
private
String
connect
;
public
String
getTimestamp
()
{
return
timestamp
;
}
public
void
setTimestamp
(
String
timestamp
)
{
this
.
timestamp
=
timestamp
;
}
public
String
getElapsed
()
{
return
elapsed
;
}
public
void
setElapsed
(
String
elapsed
)
{
this
.
elapsed
=
elapsed
;
}
public
String
getLabel
()
{
return
label
;
}
public
void
setLabel
(
String
label
)
{
this
.
label
=
label
;
}
public
String
getResponseCode
()
{
return
responseCode
;
}
public
void
setResponseCode
(
String
responseCode
)
{
this
.
responseCode
=
responseCode
;
}
public
String
getResponseMessage
()
{
return
responseMessage
;
}
public
void
setResponseMessage
(
String
responseMessage
)
{
this
.
responseMessage
=
responseMessage
;
}
public
String
getThreadName
()
{
return
threadName
;
}
public
void
setThreadName
(
String
threadName
)
{
this
.
threadName
=
threadName
;
}
public
String
getDataType
()
{
return
dataType
;
}
public
void
setDataType
(
String
dataType
)
{
this
.
dataType
=
dataType
;
}
public
String
getSuccess
()
{
return
success
;
}
public
void
setSuccess
(
String
success
)
{
this
.
success
=
success
;
}
public
String
getFailureMessage
()
{
return
failureMessage
;
}
public
void
setFailureMessage
(
String
failureMessage
)
{
this
.
failureMessage
=
failureMessage
;
}
public
String
getBytes
()
{
return
bytes
;
}
public
void
setBytes
(
String
bytes
)
{
this
.
bytes
=
bytes
;
}
public
String
getSentBytes
()
{
return
sentBytes
;
}
public
void
setSentBytes
(
String
sentBytes
)
{
this
.
sentBytes
=
sentBytes
;
}
public
String
getGrpThreads
()
{
return
grpThreads
;
}
public
void
setGrpThreads
(
String
grpThreads
)
{
this
.
grpThreads
=
grpThreads
;
}
public
String
getAllThreads
()
{
return
allThreads
;
}
public
void
setAllThreads
(
String
allThreads
)
{
this
.
allThreads
=
allThreads
;
}
public
String
getUrl
()
{
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
String
getLatency
()
{
return
latency
;
}
public
void
setLatency
(
String
latency
)
{
this
.
latency
=
latency
;
}
public
String
getIdleTime
()
{
return
idleTime
;
}
public
void
setIdleTime
(
String
idleTime
)
{
this
.
idleTime
=
idleTime
;
}
public
String
getConnect
()
{
return
connect
;
}
public
void
setConnect
(
String
connect
)
{
this
.
connect
=
connect
;
}
}
backend/src/main/java/io/metersphere/report/base/RequestStatistics.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere.report.base
;
public
class
RequestStatistics
{
/**请求标签*/
private
String
requestLabel
;
/**压测请求数*/
private
String
samples
;
/**平均响应时间*/
private
String
average
;
/**平均点击率*/
private
Double
avgHits
;
/**90% Line*/
private
String
tp90
;
/**95% Line*/
private
String
tp95
;
/**99% Line*/
private
String
tp99
;
/**最小请求时间 Min Response Time /ms */
private
String
min
;
/**最大请求时间 Max Response Time /ms */
private
String
max
;
/**吞吐量 KB/sec*/
private
String
kbPerSec
;
/**错误率 Error Percentage */
private
String
errors
;
public
String
getRequestLabel
()
{
return
requestLabel
;
}
public
void
setRequestLabel
(
String
requestLabel
)
{
this
.
requestLabel
=
requestLabel
;
}
public
String
getSamples
()
{
return
samples
;
}
public
void
setSamples
(
String
samples
)
{
this
.
samples
=
samples
;
}
public
String
getAverage
()
{
return
average
;
}
public
void
setAverage
(
String
average
)
{
this
.
average
=
average
;
}
public
Double
getAvgHits
()
{
return
avgHits
;
}
public
void
setAvgHits
(
Double
avgHits
)
{
this
.
avgHits
=
avgHits
;
}
public
String
getTp90
()
{
return
tp90
;
}
public
void
setTp90
(
String
tp90
)
{
this
.
tp90
=
tp90
;
}
public
String
getTp95
()
{
return
tp95
;
}
public
void
setTp95
(
String
tp95
)
{
this
.
tp95
=
tp95
;
}
public
String
getTp99
()
{
return
tp99
;
}
public
void
setTp99
(
String
tp99
)
{
this
.
tp99
=
tp99
;
}
public
String
getMin
()
{
return
min
;
}
public
void
setMin
(
String
min
)
{
this
.
min
=
min
;
}
public
String
getMax
()
{
return
max
;
}
public
void
setMax
(
String
max
)
{
this
.
max
=
max
;
}
public
String
getKbPerSec
()
{
return
kbPerSec
;
}
public
void
setKbPerSec
(
String
kbPerSec
)
{
this
.
kbPerSec
=
kbPerSec
;
}
public
String
getErrors
()
{
return
errors
;
}
public
void
setErrors
(
String
errors
)
{
this
.
errors
=
errors
;
}
}
backend/src/main/java/io/metersphere/service/FuctionalTestService.java
浏览文件 @
6b8c059f
...
@@ -3,12 +3,9 @@ package io.metersphere.service;
...
@@ -3,12 +3,9 @@ package io.metersphere.service;
import
io.metersphere.base.domain.*
;
import
io.metersphere.base.domain.*
;
import
io.metersphere.base.mapper.*
;
import
io.metersphere.base.mapper.*
;
import
io.metersphere.base.mapper.ext.ExtFunctionalTestMapper
;
import
io.metersphere.base.mapper.ext.ExtFunctionalTestMapper
;
import
io.metersphere.commons.constants.EngineType
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.controller.request.testplan.*
;
import
io.metersphere.controller.request.testplan.*
;
import
io.metersphere.dto.FunctionalTestDTO
;
import
io.metersphere.dto.FunctionalTestDTO
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.EngineFactory
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.i18n.Translator
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
...
@@ -94,8 +91,6 @@ public class FuctionalTestService {
...
@@ -94,8 +91,6 @@ public class FuctionalTestService {
fileMetadata
.
setCreateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setCreateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setUpdateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setUpdateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setType
(
"jmx"
);
fileMetadata
.
setType
(
"jmx"
);
// TODO engine 选择
fileMetadata
.
setEngine
(
EngineType
.
DOCKER
.
name
());
fileMetadataMapper
.
insert
(
fileMetadata
);
fileMetadataMapper
.
insert
(
fileMetadata
);
FileContent
fileContent
=
new
FileContent
();
FileContent
fileContent
=
new
FileContent
();
...
...
backend/src/main/java/io/metersphere/service/LoadTestService.java
浏览文件 @
6b8c059f
...
@@ -6,7 +6,6 @@ import io.metersphere.base.mapper.FileMetadataMapper;
...
@@ -6,7 +6,6 @@ import io.metersphere.base.mapper.FileMetadataMapper;
import
io.metersphere.base.mapper.LoadTestFileMapper
;
import
io.metersphere.base.mapper.LoadTestFileMapper
;
import
io.metersphere.base.mapper.LoadTestMapper
;
import
io.metersphere.base.mapper.LoadTestMapper
;
import
io.metersphere.base.mapper.ext.ExtLoadTestMapper
;
import
io.metersphere.base.mapper.ext.ExtLoadTestMapper
;
import
io.metersphere.commons.constants.EngineType
;
import
io.metersphere.commons.constants.FileType
;
import
io.metersphere.commons.constants.FileType
;
import
io.metersphere.commons.constants.TestStatus
;
import
io.metersphere.commons.constants.TestStatus
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.exception.MSException
;
...
@@ -45,6 +44,8 @@ public class LoadTestService {
...
@@ -45,6 +44,8 @@ public class LoadTestService {
private
LoadTestFileMapper
loadTestFileMapper
;
private
LoadTestFileMapper
loadTestFileMapper
;
@Resource
@Resource
private
FileService
fileService
;
private
FileService
fileService
;
@Resource
private
TestResourcePoolService
testResourcePoolService
;
public
List
<
LoadTestDTO
>
list
(
QueryTestPlanRequest
request
)
{
public
List
<
LoadTestDTO
>
list
(
QueryTestPlanRequest
request
)
{
return
extLoadTestMapper
.
list
(
request
);
return
extLoadTestMapper
.
list
(
request
);
...
@@ -102,8 +103,6 @@ public class LoadTestService {
...
@@ -102,8 +103,6 @@ public class LoadTestService {
fileMetadata
.
setUpdateTime
(
System
.
currentTimeMillis
());
fileMetadata
.
setUpdateTime
(
System
.
currentTimeMillis
());
FileType
fileType
=
getFileType
(
fileMetadata
.
getName
());
FileType
fileType
=
getFileType
(
fileMetadata
.
getName
());
fileMetadata
.
setType
(
fileType
.
name
());
fileMetadata
.
setType
(
fileType
.
name
());
// TODO engine 选择
fileMetadata
.
setEngine
(
EngineType
.
DOCKER
.
name
());
fileMetadataMapper
.
insert
(
fileMetadata
);
fileMetadataMapper
.
insert
(
fileMetadata
);
FileContent
fileContent
=
new
FileContent
();
FileContent
fileContent
=
new
FileContent
();
...
@@ -179,9 +178,8 @@ public class LoadTestService {
...
@@ -179,9 +178,8 @@ public class LoadTestService {
List
<
FileMetadata
>
csvFiles
=
fileMetadataList
.
stream
().
filter
(
f
->
StringUtils
.
equalsIgnoreCase
(
f
.
getType
(),
FileType
.
CSV
.
name
())).
collect
(
Collectors
.
toList
());
List
<
FileMetadata
>
csvFiles
=
fileMetadataList
.
stream
().
filter
(
f
->
StringUtils
.
equalsIgnoreCase
(
f
.
getType
(),
FileType
.
CSV
.
name
())).
collect
(
Collectors
.
toList
());
LogUtil
.
info
(
"Load test started "
+
loadTest
.
getName
());
LogUtil
.
info
(
"Load test started "
+
loadTest
.
getName
());
// engine type (DOCKER|KUBERNETES)
// engine type (NODE|K8S)
// todo set type
final
Engine
engine
=
EngineFactory
.
createEngine
(
loadTest
);
final
Engine
engine
=
EngineFactory
.
createEngine
(
fileMetadata
.
getEngine
());
if
(
engine
==
null
)
{
if
(
engine
==
null
)
{
MSException
.
throwException
(
String
.
format
(
"Test cannot be run,test ID:%s,file type:%s"
,
request
.
getId
(),
fileMetadata
.
getType
()));
MSException
.
throwException
(
String
.
format
(
"Test cannot be run,test ID:%s,file type:%s"
,
request
.
getId
(),
fileMetadata
.
getType
()));
}
}
...
...
backend/src/main/java/io/metersphere/service/ReportService.java
浏览文件 @
6b8c059f
...
@@ -41,4 +41,8 @@ public class ReportService {
...
@@ -41,4 +41,8 @@ public class ReportService {
public
ReportDTO
getReportTestAndProInfo
(
String
reportId
)
{
public
ReportDTO
getReportTestAndProInfo
(
String
reportId
)
{
return
extLoadTestReportMapper
.
getReportTestAndProInfo
(
reportId
);
return
extLoadTestReportMapper
.
getReportTestAndProInfo
(
reportId
);
}
}
public
LoadTestReport
getReport
(
String
id
)
{
return
loadTestReportMapper
.
selectByPrimaryKey
(
id
);
}
}
}
backend/src/main/java/io/metersphere/service/TestResourcePoolService.java
浏览文件 @
6b8c059f
package
io.metersphere.service
;
package
io.metersphere.service
;
import
com.alibaba.fastjson.JSON
;
import
io.metersphere.base.domain.TestResourcePool
;
import
io.metersphere.base.domain.TestResourcePool
;
import
io.metersphere.base.domain.TestResourcePoolExample
;
import
io.metersphere.base.domain.TestResourcePoolExample
;
import
io.metersphere.base.mapper.TestResourcePoolMapper
;
import
io.metersphere.base.mapper.TestResourcePoolMapper
;
import
io.metersphere.commons.constants.ResourcePoolTypeEnum
;
import
io.metersphere.commons.utils.BeanUtils
;
import
io.metersphere.controller.request.resourcepool.QueryResourcePoolRequest
;
import
io.metersphere.controller.request.resourcepool.QueryResourcePoolRequest
;
import
io.metersphere.dto.KubernetesDTO
;
import
io.metersphere.dto.NodeDTO
;
import
io.metersphere.engine.kubernetes.provider.ClientCredential
;
import
io.metersphere.engine.kubernetes.provider.KubernetesProvider
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.client.RestTemplate
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.List
;
...
@@ -19,6 +30,8 @@ import java.util.UUID;
...
@@ -19,6 +30,8 @@ import java.util.UUID;
@Transactional
(
rollbackFor
=
Exception
.
class
)
@Transactional
(
rollbackFor
=
Exception
.
class
)
public
class
TestResourcePoolService
{
public
class
TestResourcePoolService
{
private
final
static
String
nodeControllerUrl
=
"%s:%s/status"
;
@Resource
@Resource
private
TestResourcePoolMapper
testResourcePoolMapper
;
private
TestResourcePoolMapper
testResourcePoolMapper
;
...
@@ -27,6 +40,7 @@ public class TestResourcePoolService {
...
@@ -27,6 +40,7 @@ public class TestResourcePoolService {
testResourcePool
.
setCreateTime
(
System
.
currentTimeMillis
());
testResourcePool
.
setCreateTime
(
System
.
currentTimeMillis
());
testResourcePool
.
setUpdateTime
(
System
.
currentTimeMillis
());
testResourcePool
.
setUpdateTime
(
System
.
currentTimeMillis
());
testResourcePool
.
setStatus
(
"1"
);
testResourcePool
.
setStatus
(
"1"
);
validateTestResourcePool
(
testResourcePool
);
testResourcePoolMapper
.
insertSelective
(
testResourcePool
);
testResourcePoolMapper
.
insertSelective
(
testResourcePool
);
return
testResourcePool
;
return
testResourcePool
;
}
}
...
@@ -37,6 +51,7 @@ public class TestResourcePoolService {
...
@@ -37,6 +51,7 @@ public class TestResourcePoolService {
public
void
updateTestResourcePool
(
TestResourcePool
testResourcePool
)
{
public
void
updateTestResourcePool
(
TestResourcePool
testResourcePool
)
{
testResourcePool
.
setUpdateTime
(
System
.
currentTimeMillis
());
testResourcePool
.
setUpdateTime
(
System
.
currentTimeMillis
());
validateTestResourcePool
(
testResourcePool
);
testResourcePoolMapper
.
updateByPrimaryKeySelective
(
testResourcePool
);
testResourcePoolMapper
.
updateByPrimaryKeySelective
(
testResourcePool
);
}
}
...
@@ -47,4 +62,59 @@ public class TestResourcePoolService {
...
@@ -47,4 +62,59 @@ public class TestResourcePoolService {
}
}
return
testResourcePoolMapper
.
selectByExample
(
example
);
return
testResourcePoolMapper
.
selectByExample
(
example
);
}
}
private
void
validateTestResourcePool
(
TestResourcePool
testResourcePool
)
{
if
(
StringUtils
.
equalsIgnoreCase
(
testResourcePool
.
getType
(),
ResourcePoolTypeEnum
.
K8S
.
name
()))
{
validateK8s
(
testResourcePool
);
return
;
}
validateNodes
(
testResourcePool
);
}
private
void
validateNodes
(
TestResourcePool
testResourcePool
)
{
List
<
NodeDTO
>
nodes
=
JSON
.
parseArray
(
testResourcePool
.
getInfo
(),
NodeDTO
.
class
);
if
(
CollectionUtils
.
isEmpty
(
nodes
))
{
throw
new
RuntimeException
(
"没有节点信息"
);
}
for
(
NodeDTO
node
:
nodes
)
{
boolean
isValidate
=
validateNode
(
node
);
if
(!
isValidate
)
{
testResourcePool
.
setStatus
(
"0"
);
}
node
.
setValidate
(
isValidate
);
}
testResourcePool
.
setInfo
(
JSON
.
toJSONString
(
nodes
));
}
private
boolean
validateNode
(
NodeDTO
dto
)
{
RestTemplate
restTemplate
=
new
RestTemplate
();
ResponseEntity
<
String
>
entity
=
restTemplate
.
getForEntity
(
String
.
format
(
nodeControllerUrl
,
dto
.
getIp
(),
dto
.
getPort
()),
String
.
class
);
return
entity
.
getStatusCode
().
value
()
==
HttpStatus
.
SC_OK
;
}
private
void
validateK8s
(
TestResourcePool
testResourcePool
)
{
List
<
KubernetesDTO
>
dtos
=
JSON
.
parseArray
(
testResourcePool
.
getInfo
(),
KubernetesDTO
.
class
);
if
(
CollectionUtils
.
isEmpty
(
dtos
)
||
dtos
.
size
()
!=
1
)
{
throw
new
RuntimeException
(
"只能添加一个 K8s"
);
}
ClientCredential
clientCredential
=
new
ClientCredential
();
BeanUtils
.
copyBean
(
clientCredential
,
dtos
.
get
(
0
));
try
{
KubernetesProvider
provider
=
new
KubernetesProvider
(
JSON
.
toJSONString
(
clientCredential
));
provider
.
validateCredential
();
dtos
.
get
(
0
).
setValidate
(
true
);
}
catch
(
Exception
e
)
{
dtos
.
get
(
0
).
setValidate
(
false
);
testResourcePool
.
setStatus
(
"0"
);
}
testResourcePool
.
setInfo
(
JSON
.
toJSONString
(
dtos
));
}
public
TestResourcePool
getResourcePool
(
String
resourcePoolId
)
{
return
testResourcePoolMapper
.
selectByPrimaryKey
(
resourcePoolId
);
}
}
}
backend/src/main/resources/db/migration/V2__metersphere_ddl.sql
浏览文件 @
6b8c059f
...
@@ -11,7 +11,6 @@ CREATE TABLE IF NOT EXISTS `file_metadata` (
...
@@ -11,7 +11,6 @@ CREATE TABLE IF NOT EXISTS `file_metadata` (
`id`
varchar
(
64
)
NOT
NULL
COMMENT
'File ID'
,
`id`
varchar
(
64
)
NOT
NULL
COMMENT
'File ID'
,
`name`
varchar
(
64
)
NOT
NULL
COMMENT
'File name'
,
`name`
varchar
(
64
)
NOT
NULL
COMMENT
'File name'
,
`type`
varchar
(
64
)
DEFAULT
NULL
COMMENT
'File type'
,
`type`
varchar
(
64
)
DEFAULT
NULL
COMMENT
'File type'
,
`engine`
varchar
(
64
)
DEFAULT
'DOCKER'
COMMENT
'engine type'
,
`size`
bigint
(
13
)
NOT
NULL
COMMENT
'File size'
,
`size`
bigint
(
13
)
NOT
NULL
COMMENT
'File size'
,
`create_time`
bigint
(
13
)
NOT
NULL
COMMENT
'Create timestamp'
,
`create_time`
bigint
(
13
)
NOT
NULL
COMMENT
'Create timestamp'
,
`update_time`
bigint
(
13
)
NOT
NULL
COMMENT
'Update timestamp'
,
`update_time`
bigint
(
13
)
NOT
NULL
COMMENT
'Update timestamp'
,
...
...
backend/src/main/resources/generatorConfig.xml
浏览文件 @
6b8c059f
...
@@ -45,10 +45,20 @@
...
@@ -45,10 +45,20 @@
</javaClientGenerator>
</javaClientGenerator>
<!--要生成的数据库表 -->
<!--要生成的数据库表 -->
<table
tableName=
"test_plan"
/>
<table
tableName=
"test_case_node"
/>
<table
tableName=
"test_case"
/>
<table
tableName=
"test_plan_test_case"
/>
<!-- <table tableName="user"/>-->
<!-- <table tableName="user_role"/>-->
<!-- <table tableName="workspace"/>-->
<!-- <table tableName="test_resource_pool"/>-->
<!-- <table tableName="test_resource"/>-->
<!-- <table tableName="system_parameter"/>-->
<!-- <table tableName="role"/>-->
<!-- <table tableName="project"/>-->
<!-- <table tableName="organization"/>-->
<!-- <table tableName="load_test_report"/>-->
<!-- <table tableName="load_test"/>-->
<!-- <table tableName="file_content"/>-->
<table
tableName=
"file_metadata"
/>
<!-- <table tableName="load_test_file"/>-->
</context>
</context>
</generatorConfiguration>
</generatorConfiguration>
\ No newline at end of file
backend/src/test/java/io/metersphere/GenerateGraphTest.java
浏览文件 @
6b8c059f
package
io.metersphere
;
package
io.metersphere
;
import
io.metersphere.commons.constants.JmeterReportType
;
import
com.opencsv.bean.CsvToBean
;
import
kg.apc.jmeter.PluginsCMDWorker
;
import
com.opencsv.bean.CsvToBeanBuilder
;
import
org.apache.jmeter.util.JMeterUtils
;
import
com.opencsv.bean.HeaderColumnNameMappingStrategy
;
import
com.opencsv.bean.MappingStrategy
;
import
org.junit.Test
;
import
org.junit.Test
;
import
java.io.File
;
import
java.io.Reader
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.util.List
;
public
class
GenerateGraphTest
{
public
class
GenerateGraphTest
{
/*
AggregateReport = JMeter's native Aggregate Report, can be saved only as CSV
SynthesisReport = mix between JMeter's native Summary Report and Aggregate Report, can be saved only as CSV
ThreadsStateOverTime = Active Threads Over Time
BytesThroughputOverTime
HitsPerSecond
LatenciesOverTime
PerfMon = PerfMon Metrics Collector
DbMon = DbMon Metrics Collector, DataBase, get performance counters via sql
JMXMon = JMXMon Metrics Collector, Java Management Extensions counters
ResponseCodesPerSecond
ResponseTimesDistribution
ResponseTimesOverTime
ResponseTimesPercentiles
ThroughputVsThreads
TimesVsThreads = Response Times VS Threads
TransactionsPerSecond
PageDataExtractorOverTime
MergeResults = MergeResults Command Line Merge Tool to simplify the comparison of two or more load tests, need properties file (like merge-results.properties)
*/
@Test
@Test
public
void
test1
()
{
public
void
test1
()
{
JMeterUtils
.
setJMeterHome
(
"/opt/fit2cloud/apache-jmeter-5.2.1"
);
File
csvFile
=
new
File
(
"/Users/liuruibin/Desktop/0316.jtl"
);
JMeterUtils
.
loadJMeterProperties
(
"/opt/fit2cloud/apache-jmeter-5.2.1/bin/jmeter.properties"
);
HeaderColumnNameMappingStrategy
<
Metric
>
ms
=
new
HeaderColumnNameMappingStrategy
<>();
PluginsCMDWorker
worker
=
new
PluginsCMDWorker
();
ms
.
setType
(
Metric
.
class
);
worker
.
setPluginType
(
JmeterReportType
.
AggregateReport
.
name
());
List
<
Metric
>
metrics
=
beanBuilderExample
(
csvFile
.
toPath
(),
ms
);
worker
.
addExportMode
(
2
);
metrics
.
forEach
(
c
->
{
worker
.
setOutputCSVFile
(
"/tmp/test0320.csv"
);
System
.
out
.
println
(
c
.
getTimestamp
());
worker
.
setInputFile
(
"/Users/liuruibin/Desktop/0316.jtl"
);
});
worker
.
doJob
();
}
public
static
List
<
Metric
>
beanBuilderExample
(
Path
path
,
MappingStrategy
<
Metric
>
ms
)
{
try
(
Reader
reader
=
Files
.
newBufferedReader
(
path
))
{
CsvToBean
<
Metric
>
cb
=
new
CsvToBeanBuilder
<
Metric
>(
reader
)
.
withType
(
Metric
.
class
)
.
withSkipLines
(
0
)
.
withMappingStrategy
(
ms
)
.
withIgnoreLeadingWhiteSpace
(
true
)
.
build
();
return
cb
.
parse
();
}
catch
(
Exception
ex
)
{
ex
.
printStackTrace
();
}
return
null
;
}
}
}
}
backend/src/test/java/io/metersphere/JtlTest.java
0 → 100644
浏览文件 @
6b8c059f
此差异已折叠。
点击以展开。
backend/src/test/java/io/metersphere/Metric.java
0 → 100644
浏览文件 @
6b8c059f
package
io.metersphere
;
import
com.opencsv.bean.CsvBindByName
;
public
class
Metric
{
// timestamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
@CsvBindByName
(
column
=
"timestamp"
)
private
String
timestamp
;
@CsvBindByName
(
column
=
"elapsed"
)
private
String
elapsed
;
@CsvBindByName
(
column
=
"label"
)
private
String
label
;
@CsvBindByName
(
column
=
"responseCode"
)
private
String
responseCode
;
@CsvBindByName
(
column
=
"responseMessage"
)
private
String
responseMessage
;
@CsvBindByName
(
column
=
"threadName"
)
private
String
threadName
;
@CsvBindByName
(
column
=
"dataType"
)
private
String
dataType
;
@CsvBindByName
(
column
=
"success"
)
private
String
success
;
@CsvBindByName
(
column
=
"failureMessage"
)
private
String
failureMessage
;
@CsvBindByName
(
column
=
"bytes"
)
private
String
bytes
;
@CsvBindByName
(
column
=
"sentBytes"
)
private
String
sentBytes
;
@CsvBindByName
(
column
=
"grpThreads"
)
private
String
grpThreads
;
@CsvBindByName
(
column
=
"allThreads"
)
private
String
allThreads
;
@CsvBindByName
(
column
=
"URL"
)
private
String
url
;
@CsvBindByName
(
column
=
"Latency"
)
private
String
latency
;
@CsvBindByName
(
column
=
"IdleTime"
)
private
String
idleTime
;
@CsvBindByName
(
column
=
"Connect"
)
private
String
connect
;
public
String
getTimestamp
()
{
return
timestamp
;
}
public
void
setTimestamp
(
String
timestamp
)
{
this
.
timestamp
=
timestamp
;
}
public
String
getElapsed
()
{
return
elapsed
;
}
public
void
setElapsed
(
String
elapsed
)
{
this
.
elapsed
=
elapsed
;
}
public
String
getLabel
()
{
return
label
;
}
public
void
setLabel
(
String
label
)
{
this
.
label
=
label
;
}
public
String
getResponseCode
()
{
return
responseCode
;
}
public
void
setResponseCode
(
String
responseCode
)
{
this
.
responseCode
=
responseCode
;
}
public
String
getResponseMessage
()
{
return
responseMessage
;
}
public
void
setResponseMessage
(
String
responseMessage
)
{
this
.
responseMessage
=
responseMessage
;
}
public
String
getThreadName
()
{
return
threadName
;
}
public
void
setThreadName
(
String
threadName
)
{
this
.
threadName
=
threadName
;
}
public
String
getDataType
()
{
return
dataType
;
}
public
void
setDataType
(
String
dataType
)
{
this
.
dataType
=
dataType
;
}
public
String
getSuccess
()
{
return
success
;
}
public
void
setSuccess
(
String
success
)
{
this
.
success
=
success
;
}
public
String
getFailureMessage
()
{
return
failureMessage
;
}
public
void
setFailureMessage
(
String
failureMessage
)
{
this
.
failureMessage
=
failureMessage
;
}
public
String
getBytes
()
{
return
bytes
;
}
public
void
setBytes
(
String
bytes
)
{
this
.
bytes
=
bytes
;
}
public
String
getSentBytes
()
{
return
sentBytes
;
}
public
void
setSentBytes
(
String
sentBytes
)
{
this
.
sentBytes
=
sentBytes
;
}
public
String
getGrpThreads
()
{
return
grpThreads
;
}
public
void
setGrpThreads
(
String
grpThreads
)
{
this
.
grpThreads
=
grpThreads
;
}
public
String
getAllThreads
()
{
return
allThreads
;
}
public
void
setAllThreads
(
String
allThreads
)
{
this
.
allThreads
=
allThreads
;
}
public
String
getUrl
()
{
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
String
getLatency
()
{
return
latency
;
}
public
void
setLatency
(
String
latency
)
{
this
.
latency
=
latency
;
}
public
String
getIdleTime
()
{
return
idleTime
;
}
public
void
setIdleTime
(
String
idleTime
)
{
this
.
idleTime
=
idleTime
;
}
public
String
getConnect
()
{
return
connect
;
}
public
void
setConnect
(
String
connect
)
{
this
.
connect
=
connect
;
}
}
frontend/src/business/components/performance/plan/EditPerformanceTestPlan.vue
浏览文件 @
6b8c059f
...
@@ -207,6 +207,10 @@
...
@@ -207,6 +207,10 @@
return
false
;
return
false
;
}
}
if
(
!
this
.
$refs
.
pressureConfig
.
validConfig
())
{
return
false
;
}
if
(
!
this
.
$refs
.
advancedConfig
.
validConfig
())
{
if
(
!
this
.
$refs
.
advancedConfig
.
validConfig
())
{
return
false
;
return
false
;
}
}
...
...
frontend/src/business/components/performance/plan/components/PerformancePressureConfig.vue
浏览文件 @
6b8c059f
...
@@ -73,6 +73,21 @@
...
@@ -73,6 +73,21 @@
<div>
{{
$t
(
'
load_test.ramp_up_time_times
'
)
}}
</div>
<div>
{{
$t
(
'
load_test.ramp_up_time_times
'
)
}}
</div>
</el-form-item>
</el-form-item>
</el-form>
</el-form>
<el-form
:inline=
"true"
class=
"input-bottom-border"
>
<el-form-item>
<div>
{{
$t
(
'
load_test.select_resource_pool
'
)
}}
</div>
</el-form-item>
<el-form-item>
<el-select
v-model=
"resourcePool"
size=
"mini"
>
<el-option
v-for=
"item in resourcePools"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
</el-col>
</el-col>
<el-col
:span=
"12"
>
<el-col
:span=
"12"
>
<chart
class=
"chart-container"
ref=
"chart1"
:options=
"orgOptions"
:autoresize=
"true"
></chart>
<chart
class=
"chart-container"
ref=
"chart1"
:options=
"orgOptions"
:autoresize=
"true"
></chart>
...
@@ -89,6 +104,7 @@
...
@@ -89,6 +104,7 @@
const
STEPS
=
"
Steps
"
;
const
STEPS
=
"
Steps
"
;
const
DURATION
=
"
duration
"
;
const
DURATION
=
"
duration
"
;
const
RPS_LIMIT
=
"
rpsLimit
"
;
const
RPS_LIMIT
=
"
rpsLimit
"
;
const
RESOURCE_POOL
=
"
resourcePoolId
"
;
export
default
{
export
default
{
name
:
"
PerformancePressureConfig
"
,
name
:
"
PerformancePressureConfig
"
,
...
@@ -101,6 +117,8 @@
...
@@ -101,6 +117,8 @@
step
:
10
,
step
:
10
,
rpsLimit
:
10
,
rpsLimit
:
10
,
orgOptions
:
{},
orgOptions
:
{},
resourcePool
:
null
,
resourcePools
:
[],
}
}
},
},
mounted
()
{
mounted
()
{
...
@@ -110,6 +128,8 @@
...
@@ -110,6 +128,8 @@
}
else
{
}
else
{
this
.
calculateChart
();
this
.
calculateChart
();
}
}
this
.
getResourcePools
();
},
},
watch
:
{
watch
:
{
'
$route
'
(
to
,
from
)
{
'
$route
'
(
to
,
from
)
{
...
@@ -125,11 +145,16 @@
...
@@ -125,11 +145,16 @@
}
}
},
},
methods
:
{
methods
:
{
getResourcePools
()
{
this
.
$get
(
'
/testresourcepool/list/all
'
,
response
=>
{
this
.
resourcePools
=
response
.
data
;
})
},
getLoadConfig
(
testId
)
{
getLoadConfig
(
testId
)
{
if
(
testId
)
{
if
(
testId
)
{
this
.
$get
(
'
/testplan/get-load-config/
'
+
testId
,
(
response
)
=>
{
this
.
$get
(
'
/testplan/get-load-config/
'
+
testId
,
(
response
)
=>
{
if
(
response
.
data
&&
response
.
data
!=
""
)
{
if
(
response
.
data
)
{
let
data
=
JSON
.
parse
(
response
.
data
);
let
data
=
JSON
.
parse
(
response
.
data
);
data
.
forEach
(
d
=>
{
data
.
forEach
(
d
=>
{
...
@@ -149,6 +174,9 @@
...
@@ -149,6 +174,9 @@
case
RPS_LIMIT
:
case
RPS_LIMIT
:
this
.
rpsLimit
=
d
.
value
;
this
.
rpsLimit
=
d
.
value
;
break
;
break
;
case
RESOURCE_POOL
:
this
.
resourcePool
=
d
.
value
;
break
;
default
:
default
:
break
;
break
;
}
}
...
@@ -252,6 +280,17 @@
...
@@ -252,6 +280,17 @@
}
}
}
}
},
},
validConfig
()
{
if
(
!
this
.
resourcePool
)
{
this
.
$message
({
message
:
this
.
$t
(
'
load_test.resource_pool_is_null
'
),
type
:
'
warning
'
});
return
false
;
}
return
true
;
},
convertProperty
()
{
convertProperty
()
{
/// todo:下面4个属性是jmeter ConcurrencyThreadGroup plugin的属性,这种硬编码不太好吧,在哪能转换这种属性?
/// todo:下面4个属性是jmeter ConcurrencyThreadGroup plugin的属性,这种硬编码不太好吧,在哪能转换这种属性?
return
[
return
[
...
@@ -259,7 +298,8 @@
...
@@ -259,7 +298,8 @@
{
key
:
RAMP_UP
,
value
:
this
.
rampUpTime
},
{
key
:
RAMP_UP
,
value
:
this
.
rampUpTime
},
{
key
:
STEPS
,
value
:
this
.
step
},
{
key
:
STEPS
,
value
:
this
.
step
},
{
key
:
DURATION
,
value
:
this
.
duration
},
{
key
:
DURATION
,
value
:
this
.
duration
},
{
key
:
RPS_LIMIT
,
value
:
this
.
rpsLimit
}
{
key
:
RPS_LIMIT
,
value
:
this
.
rpsLimit
},
{
key
:
RESOURCE_POOL
,
value
:
this
.
resourcePool
},
];
];
}
}
}
}
...
...
frontend/src/business/components/project/MsProject.vue
浏览文件 @
6b8c059f
...
@@ -46,7 +46,7 @@
...
@@ -46,7 +46,7 @@
</el-card>
</el-card>
<el-dialog
:title=
"title"
:visible.sync=
"createVisible"
>
<el-dialog
:title=
"title"
:visible.sync=
"createVisible"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.name')"
>
<el-form-item
:label=
"$t('commons.name')"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
></el-input>
<el-input
v-model=
"form.name"
autocomplete=
"off"
></el-input>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/organization/OrganizationMember.vue
浏览文件 @
6b8c059f
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
</el-card>
</el-card>
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"createVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"createVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
ref=
"form"
:rules=
"rules"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
ref=
"form"
:rules=
"rules"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-select
v-model=
"form.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-select
v-model=
"form.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-option
<el-option
...
@@ -81,7 +81,7 @@
...
@@ -81,7 +81,7 @@
</el-dialog>
</el-dialog>
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/organization/OrganizationWorkspace.vue
浏览文件 @
6b8c059f
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
</el-card>
</el-card>
<el-dialog
:title=
"$t('workspace.create')"
:visible.sync=
"createVisible"
width=
"30%"
>
<el-dialog
:title=
"$t('workspace.create')"
:visible.sync=
"createVisible"
width=
"30%"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -114,7 +114,7 @@
...
@@ -114,7 +114,7 @@
<!-- add workspace member dialog -->
<!-- add workspace member dialog -->
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"wsMemberRule"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"wsMemberRule"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-option
<el-option
...
@@ -145,7 +145,7 @@
...
@@ -145,7 +145,7 @@
<!-- update workspace member dialog -->
<!-- update workspace member dialog -->
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form
:model=
"memberForm"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/personal/PersonSetting.vue
浏览文件 @
6b8c059f
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
</el-table>
</el-table>
<el-dialog
:title=
"$t('member.modify_personal_info')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.modify_personal_info')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateUserForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/system/Organization.vue
浏览文件 @
6b8c059f
...
@@ -101,7 +101,7 @@
...
@@ -101,7 +101,7 @@
<!-- add organization form -->
<!-- add organization form -->
<el-dialog
:title=
"$t('organization.create')"
:visible.sync=
"createVisible"
width=
"30%"
@
closed=
"closeFunc"
:destroy-on-close=
"true"
>
<el-dialog
:title=
"$t('organization.create')"
:visible.sync=
"createVisible"
width=
"30%"
@
closed=
"closeFunc"
:destroy-on-close=
"true"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"createOrganization"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"createOrganization"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -116,7 +116,7 @@
...
@@ -116,7 +116,7 @@
<!-- update organization form -->
<!-- update organization form -->
<el-dialog
:title=
"$t('organization.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('organization.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateOrganizationForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateOrganizationForm"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -131,7 +131,7 @@
...
@@ -131,7 +131,7 @@
<!-- add organization member form -->
<!-- add organization member form -->
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"orgMemberRule"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"orgMemberRule"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-option
<el-option
...
@@ -162,7 +162,7 @@
...
@@ -162,7 +162,7 @@
<!-- update organization member form -->
<!-- update organization member form -->
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form
:model=
"memberForm"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/system/SystemWorkspace.vue
浏览文件 @
6b8c059f
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
<!-- add workspace dialog -->
<!-- add workspace dialog -->
<el-dialog
:title=
"$t('workspace.create')"
:visible.sync=
"createVisible"
width=
"30%"
>
<el-dialog
:title=
"$t('workspace.create')"
:visible.sync=
"createVisible"
width=
"30%"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -78,7 +78,7 @@
...
@@ -78,7 +78,7 @@
<!-- update workspace dialog -->
<!-- update workspace dialog -->
<el-dialog
:title=
"$t('workspace.update')"
:visible.sync=
"updateVisible"
width=
"30%"
>
<el-dialog
:title=
"$t('workspace.update')"
:visible.sync=
"updateVisible"
width=
"30%"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"updateForm"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"updateForm"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-form-item
:label=
"$t('commons.name')"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -154,7 +154,7 @@
...
@@ -154,7 +154,7 @@
<!-- add workspace member dialog -->
<!-- add workspace member dialog -->
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.create')"
:visible.sync=
"addMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"wsMemberRule"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"memberForm"
ref=
"form"
:rules=
"wsMemberRule"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-form-item
:label=
"$t('commons.member')"
prop=
"userIds"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-select
v-model=
"memberForm.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-option
<el-option
...
@@ -185,7 +185,7 @@
...
@@ -185,7 +185,7 @@
<!-- update workspace member dialog -->
<!-- update workspace member dialog -->
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('member.modify')"
:visible.sync=
"updateMemberVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"memberForm"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form
:model=
"memberForm"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"memberForm.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/system/TestResourcePool.vue
浏览文件 @
6b8c059f
...
@@ -69,8 +69,9 @@
...
@@ -69,8 +69,9 @@
</div>
</div>
</el-card>
</el-card>
<el-dialog
title=
"创建资源池"
:visible.sync=
"createVisible"
width=
"70%"
@
closed=
"closeFunc"
:destroy-on-close=
"true"
>
<el-dialog
v-loading=
"testLoading"
title=
"创建资源池"
:visible.sync=
"createVisible"
width=
"70%"
@
closed=
"closeFunc"
<el-form
:model=
"form"
label-position=
"left"
label-width=
"100px"
size=
"small"
:rules=
"rule"
:destroy-on-close=
"true"
>
<el-form
:model=
"form"
label-position=
"right"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"createTestResourcePoolForm"
>
ref=
"createTestResourcePoolForm"
>
<el-form-item
label=
"名称"
prop=
"name"
>
<el-form-item
label=
"名称"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
...
@@ -85,46 +86,41 @@
...
@@ -85,46 +86,41 @@
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<div
v-for=
"(item,index) in infoList "
:key=
"index"
>
<div
v-for=
"(item,index) in infoList "
:key=
"index"
>
<div
class=
"current-row"
v-if=
"form.type === 'K8S'"
>
<div
class=
"node-line"
v-if=
"form.type === 'K8S'"
>
<div
style=
"width: 35%;float: left"
>
<div
class=
"k8s-master"
>
<label
class=
"el-form-item__label"
>
Master URL
</label>
<el-col
:span=
"11"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<input
v-model=
"item.masterUrl"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-col>
</div>
<el-form-item
prop=
"masterUrl"
label=
"Master URL"
>
<el-input
v-model=
"item.masterUrl"
autocomplete=
"off"
/>
</el-form-item>
</div>
</div>
<div
style=
"width: 35%;float: left"
>
<div
class=
"k8s-token"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
Token
</label>
<el-form-item
prop=
"token"
label=
"Token"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input
v-model=
"item.token"
show-password
autocomplete=
"off"
/>
<input
v-model=
"item.token"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 30%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
最大并发数
</label>
<el-form-item
prop=
"maxConcurrency"
label=
"最大并发数"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 102px"
>
<el-input-number
v-model=
"item.maxConcurrency"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.maxConcurrency"
autocomplete=
"off"
type=
"number"
</el-form-item>
class=
"el-input__inner form-input"
/>
</div>
</div>
</div>
</div>
</div>
<div
class=
"current-row"
v-if=
"form.type === 'NODE'"
>
<div
class=
"node-line"
v-if=
"form.type === 'NODE'"
>
<div
style=
"width: 42%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
>
IP
</label>
<el-form-item
prop=
"ip"
label=
"IP"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input
v-model=
"item.ip"
autocomplete=
"off"
/>
<input
v-model=
"item.ip"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 20%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
port
</label>
<el-form-item
prop=
"port"
label=
"Port"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input-number
v-model=
"item.port"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.port"
autocomplete=
"off"
type=
"number"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 20%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
最大并发数
</label>
<el-form-item
prop=
"maxConcurrency"
label=
"最大并发数"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 102px"
>
<el-input-number
v-model=
"item.maxConcurrency"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.maxConcurrency"
autocomplete=
"off"
type=
"number"
</el-form-item>
class=
"el-input__inner form-input"
/>
</div>
</div>
</div>
<div
class=
"op"
>
<div
class=
"op"
>
<span
class=
"box"
>
<span
class=
"box"
>
...
@@ -148,8 +144,9 @@
...
@@ -148,8 +144,9 @@
</span>
</span>
</el-dialog>
</el-dialog>
<el-dialog
title=
"修改资源池"
:visible.sync=
"updateVisible"
width=
"70%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
v-loading=
"testLoading"
title=
"修改资源池"
:visible.sync=
"updateVisible"
width=
"70%"
:destroy-on-close=
"true"
<el-form
:model=
"form"
label-position=
"left"
label-width=
"100px"
size=
"small"
:rules=
"rule"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"right"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateTestResourcePoolForm"
>
ref=
"updateTestResourcePoolForm"
>
<el-form-item
label=
"名称"
prop=
"name"
>
<el-form-item
label=
"名称"
prop=
"name"
>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
<el-input
v-model=
"form.name"
autocomplete=
"off"
/>
...
@@ -158,52 +155,44 @@
...
@@ -158,52 +155,44 @@
<el-input
v-model=
"form.description"
autocomplete=
"off"
/>
<el-input
v-model=
"form.description"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"资源类型"
prop=
"type"
>
<el-form-item
label=
"资源类型"
prop=
"type"
>
<el-select
v-model=
"form.type"
placeholder=
"选择资源类型"
>
<el-select
v-model=
"form.type"
placeholder=
"选择资源类型"
@
change=
"changeResourceType()"
>
<el-option
key=
"K8S"
value=
"K8S"
label=
"Kubernetes"
>
Kubernetes
</el-option>
<el-option
key=
"K8S"
value=
"K8S"
label=
"Kubernetes"
>
Kubernetes
</el-option>
<el-option
key=
"NODE"
value=
"NODE"
label=
"独立节点"
>
独立节点
</el-option>
<el-option
key=
"NODE"
value=
"NODE"
label=
"独立节点"
>
独立节点
</el-option>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<div
v-for=
"(item,index) in infoList "
:key=
"index"
>
<div
v-for=
"(item,index) in infoList "
:key=
"index"
>
<div
class=
"current-row"
v-if=
"form.type === 'K8S'"
>
<div
class=
"node-line"
v-if=
"form.type === 'K8S'"
>
<div
style=
"width: 35%;float: left"
>
<div
class=
"k8s-master"
>
<label
class=
"el-form-item__label"
>
Master URL
</label>
<el-form-item
prop=
"masterUrl"
label=
"Master URL"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input
v-model=
"item.masterUrl"
autocomplete=
"off"
/>
<input
v-model=
"item.masterUrl"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 35%;float: left"
>
<div
class=
"k8s-token"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
Token
</label>
<el-form-item
prop=
"password"
label=
"Token"
style=
"padding-left: 20px"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input
v-model=
"item.token"
show-password
autocomplete=
"off"
/>
<input
v-model=
"item.token"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 30%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
最大并发数
</label>
<el-form-item
prop=
"maxConcurrency"
label=
"最大并发数"
style=
"padding-left: 20px"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 102px"
>
<el-input-number
v-model=
"item.maxConcurrency"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.maxConcurrency"
autocomplete=
"off"
type=
"number"
</el-form-item>
class=
"el-input__inner form-input"
/>
</div>
</div>
</div>
</div>
</div>
<div
class=
"current-row"
v-if=
"form.type === 'NODE'"
>
<div
class=
"node-line"
v-if=
"form.type === 'NODE'"
>
<div
style=
"width: 42%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
>
IP
</label>
<el-form-item
prop=
"ip"
label=
"IP"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input
v-model=
"item.ip"
autocomplete=
"off"
/>
<input
v-model=
"item.ip"
autocomplete=
"off"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 20%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
port
</label>
<el-form-item
prop=
"port"
label=
"Port"
style=
"padding-left: 20px"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 100px"
>
<el-input-number
v-model=
"item.port"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.port"
autocomplete=
"off"
type=
"number"
class=
"el-input__inner form-input"
/>
</el-form-item>
</div>
</div>
</div>
<div
style=
"width: 20%;float: left"
>
<div
style=
"width: 30%;float: left"
>
<label
class=
"el-form-item__label"
style=
"padding-left: 20px"
>
最大并发数
</label>
<el-form-item
prop=
"maxConcurrency"
label=
"最大并发数"
style=
"padding-left: 20px"
>
<div
class=
"el-form-item__content"
style=
"margin-left: 102px"
>
<el-input-number
v-model=
"item.maxConcurrency"
:min=
"1"
:max=
"9999"
></el-input-number>
<input
v-model=
"item.maxConcurrency"
autocomplete=
"off"
type=
"number"
</el-form-item>
class=
"el-input__inner form-input"
/>
</div>
</div>
</div>
<div
class=
"op"
>
<div
class=
"op"
>
<span
class=
"box"
>
<span
class=
"box"
>
...
@@ -238,6 +227,7 @@
...
@@ -238,6 +227,7 @@
data
()
{
data
()
{
return
{
return
{
loading
:
false
,
loading
:
false
,
testLoading
:
false
,
createVisible
:
false
,
createVisible
:
false
,
infoList
:
[],
infoList
:
[],
updateVisible
:
false
,
updateVisible
:
false
,
...
@@ -264,6 +254,9 @@
...
@@ -264,6 +254,9 @@
],
],
description
:
[
description
:
[
{
max
:
60
,
message
:
'
最大长度 60 个字符
'
,
trigger
:
'
blur
'
}
{
max
:
60
,
message
:
'
最大长度 60 个字符
'
,
trigger
:
'
blur
'
}
],
type
:
[
{
required
:
true
,
message
:
'
请选择资源类型
'
,
trigger
:
'
blur
'
}
]
]
}
}
}
}
...
@@ -303,6 +296,28 @@
...
@@ -303,6 +296,28 @@
});
});
}
}
},
},
validateResourceInfo
()
{
if
(
this
.
infoList
.
length
<=
0
)
{
return
{
validate
:
false
,
msg
:
"
资源池不能为空
"
}
}
let
resultValidate
=
{
validate
:
true
,
msg
:
"
请完善数据
"
}
this
.
infoList
.
forEach
(
function
(
info
)
{
for
(
let
key
in
info
)
{
if
(
info
[
key
]
!=
'
0
'
&&
!
info
[
key
])
{
resultValidate
.
validate
=
false
return
false
;
}
}
if
(
!
info
.
maxConcurrency
)
{
resultValidate
.
validate
=
false
return
false
;
}
});
return
resultValidate
;
},
buildPagePath
(
path
)
{
buildPagePath
(
path
)
{
return
path
+
"
/
"
+
this
.
currentPage
+
"
/
"
+
this
.
pageSize
;
return
path
+
"
/
"
+
this
.
currentPage
+
"
/
"
+
this
.
pageSize
;
},
},
...
@@ -349,16 +364,29 @@
...
@@ -349,16 +364,29 @@
createTestResourcePool
(
createTestResourcePoolForm
)
{
createTestResourcePool
(
createTestResourcePoolForm
)
{
this
.
$refs
[
createTestResourcePoolForm
].
validate
(
valide
=>
{
this
.
$refs
[
createTestResourcePoolForm
].
validate
(
valide
=>
{
if
(
valide
)
{
if
(
valide
)
{
this
.
form
.
info
=
JSON
.
stringify
(
this
.
infoList
);
let
vri
=
this
.
validateResourceInfo
();
this
.
$post
(
"
/testresourcepool/add
"
,
this
.
form
)
if
(
vri
.
validate
)
{
.
then
(()
=>
{
this
.
testLoading
=
true
;
this
.
$message
({
this
.
form
.
info
=
JSON
.
stringify
(
this
.
infoList
);
type
:
'
success
'
,
this
.
$post
(
"
/testresourcepool/add
"
,
this
.
form
)
message
:
'
添加成功!
'
.
then
(()
=>
{
},
this
.
$message
({
this
.
createVisible
=
false
,
type
:
'
success
'
,
this
.
initTableData
())
message
:
'
添加成功!
'
},
this
.
createVisible
=
false
,
this
.
initTableData
());
this
.
testLoading
=
false
;
});
}
else
{
this
.
$message
({
type
:
'
warning
'
,
message
:
vri
.
msg
});
});
this
.
testLoading
=
false
;
return
false
;
}
}
else
{
}
else
{
return
false
;
return
false
;
}
}
...
@@ -367,17 +395,29 @@
...
@@ -367,17 +395,29 @@
updateTestResourcePool
(
updateTestResourcePoolForm
)
{
updateTestResourcePool
(
updateTestResourcePoolForm
)
{
this
.
$refs
[
updateTestResourcePoolForm
].
validate
(
valide
=>
{
this
.
$refs
[
updateTestResourcePoolForm
].
validate
(
valide
=>
{
if
(
valide
)
{
if
(
valide
)
{
this
.
form
.
info
=
JSON
.
stringify
(
this
.
infoList
);
this
.
testLoading
=
true
;
this
.
$post
(
"
/testresourcepool/update
"
,
this
.
form
)
let
vri
=
this
.
validateResourceInfo
();
.
then
(()
=>
{
if
(
vri
.
validate
)
{
this
.
$message
({
this
.
form
.
info
=
JSON
.
stringify
(
this
.
infoList
);
type
:
'
success
'
,
this
.
$post
(
"
/testresourcepool/update
"
,
this
.
form
)
message
:
this
.
$t
(
'
commons.modify_success
'
)
.
then
(()
=>
{
},
this
.
$message
({
this
.
updateVisible
=
false
,
type
:
'
success
'
,
this
.
initTableData
(),
message
:
this
.
$t
(
'
commons.modify_success
'
)
self
.
loading
=
false
)
},
this
.
updateVisible
=
false
,
this
.
initTableData
(),
self
.
loading
=
false
);
this
.
testLoading
=
false
;
});
}
else
{
this
.
$message
({
type
:
'
warning
'
,
message
:
vri
.
msg
});
});
this
.
testLoading
=
false
;
return
false
;
}
}
else
{
}
else
{
return
false
;
return
false
;
}
}
...
@@ -414,12 +454,29 @@
...
@@ -414,12 +454,29 @@
}
}
.op
{
.op
{
line-height
:
40px
;
float
:
left
;
float
:
left
;
width
:
1
6
%
;
width
:
1
0
%
;
}
}
.box
{
.box
{
padding-left
:
5px
;
padding-left
:
5px
;
}
}
.k8s-master
{
width
:
34%
;
float
:
left
}
.k8s-token
{
width
:
36%
;
float
:
left
}
.k8s-token
.el-form-item__label
{
padding-left
:
20px
;
}
.node-line
{
clear
:
both
;
}
</
style
>
</
style
>
frontend/src/business/components/settings/system/User.vue
浏览文件 @
6b8c059f
...
@@ -65,7 +65,7 @@
...
@@ -65,7 +65,7 @@
</el-card>
</el-card>
<el-dialog
:title=
"$t('user.create')"
:visible.sync=
"createVisible"
width=
"30%"
@
closed=
"closeFunc"
:destroy-on-close=
"true"
>
<el-dialog
:title=
"$t('user.create')"
:visible.sync=
"createVisible"
width=
"30%"
@
closed=
"closeFunc"
:destroy-on-close=
"true"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"createUserForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"createUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"form.id"
autocomplete=
"off"
/>
<el-input
v-model=
"form.id"
autocomplete=
"off"
/>
</el-form-item>
</el-form-item>
...
@@ -85,7 +85,7 @@
...
@@ -85,7 +85,7 @@
</el-dialog>
</el-dialog>
<el-dialog
:title=
"$t('user.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
:title=
"$t('user.modify')"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateUserForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
:rules=
"rule"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/business/components/settings/workspace/WorkspaceMember.vue
浏览文件 @
6b8c059f
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
</el-card>
</el-card>
<el-dialog
title=
"添加成员"
:visible.sync=
"createVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
title=
"添加成员"
:visible.sync=
"createVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
ref=
"form"
:rules=
"rules"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
>
<el-form
:model=
"form"
ref=
"form"
:rules=
"rules"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
>
<el-form-item
label=
"成员"
prop=
"userIds"
>
<el-form-item
label=
"成员"
prop=
"userIds"
>
<el-select
v-model=
"form.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-select
v-model=
"form.userIds"
multiple
:placeholder=
"$t('member.please_choose_member')"
class=
"select-width"
>
<el-option
<el-option
...
@@ -80,7 +80,7 @@
...
@@ -80,7 +80,7 @@
</el-dialog>
</el-dialog>
<el-dialog
title=
"修改成员"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-dialog
title=
"修改成员"
:visible.sync=
"updateVisible"
width=
"30%"
:destroy-on-close=
"true"
@
close=
"closeFunc"
>
<el-form
:model=
"form"
label-position=
"
lef
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form
:model=
"form"
label-position=
"
righ
t"
label-width=
"100px"
size=
"small"
ref=
"updateUserForm"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-form-item
label=
"ID"
prop=
"id"
>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
<el-input
v-model=
"form.id"
autocomplete=
"off"
:disabled=
"true"
/>
</el-form-item>
</el-form-item>
...
...
frontend/src/i18n/en-US.js
浏览文件 @
6b8c059f
...
@@ -158,6 +158,8 @@ export default {
...
@@ -158,6 +158,8 @@ export default {
'
custom_http_code
'
:
'
Custom HTTP response success status code
'
,
'
custom_http_code
'
:
'
Custom HTTP response success status code
'
,
'
separated_by_commas
'
:
'
Separated by commas
'
,
'
separated_by_commas
'
:
'
Separated by commas
'
,
'
create
'
:
'
Create Test
'
,
'
create
'
:
'
Create Test
'
,
'
select_resource_pool
'
:
'
Please Select Resource Pool
'
,
'
resource_pool_is_null
'
:
'
Resource Pool is empty
'
,
},
},
fuc_test
:
{
fuc_test
:
{
'
select_resource_pool
'
:
'
Please select resource pool
'
'
select_resource_pool
'
:
'
Please select resource pool
'
...
...
frontend/src/i18n/zh-CN.js
浏览文件 @
6b8c059f
...
@@ -158,6 +158,8 @@ export default {
...
@@ -158,6 +158,8 @@ export default {
'
custom_http_code
'
:
'
自定义 HTTP 响应成功状态码
'
,
'
custom_http_code
'
:
'
自定义 HTTP 响应成功状态码
'
,
'
separated_by_commas
'
:
'
按逗号分隔
'
,
'
separated_by_commas
'
:
'
按逗号分隔
'
,
'
create
'
:
'
创建测试
'
,
'
create
'
:
'
创建测试
'
,
'
select_resource_pool
'
:
'
请选择资源池
'
,
'
resource_pool_is_null
'
:
'
资源池为空
'
,
},
},
fuc_test
:
{
fuc_test
:
{
'
select_resource_pool
'
:
'
请选择资源池
'
'
select_resource_pool
'
:
'
请选择资源池
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录