Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
14810d24
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,发现更多精彩内容 >>
提交
14810d24
编写于
4月 28, 2021
作者:
F
fit2-zhao
提交者:
fit2-zhao
4月 28, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(接口自动化): 部分缺陷修复
上级
4318d56a
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
111 addition
and
46 deletion
+111
-46
backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java
...metersphere/api/dto/definition/request/MsTestElement.java
+1
-0
backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java
...ere/api/dto/definition/request/sampler/MsJDBCSampler.java
+9
-1
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
...java/io/metersphere/api/service/ApiAutomationService.java
+14
-2
backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java
.../io/metersphere/api/service/ApiScenarioReportService.java
+0
-1
backend/src/main/java/io/metersphere/api/service/task/ParallelExecTask.java
...ava/io/metersphere/api/service/task/ParallelExecTask.java
+38
-0
backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java
...java/io/metersphere/commons/json/JSONSchemaGenerator.java
+5
-0
frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue
...onents/api/automation/scenario/component/ApiComponent.vue
+1
-1
frontend/src/business/components/common/json-schema/convert/convert.js
...business/components/common/json-schema/convert/convert.js
+42
-40
frontend/src/business/components/xpack
frontend/src/business/components/xpack
+1
-1
未找到文件。
backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java
浏览文件 @
14810d24
...
...
@@ -206,6 +206,7 @@ public abstract class MsTestElement {
}
csvDataSet
.
setIgnoreFirstLine
(
false
);
csvDataSet
.
setRecycle
(
true
);
csvDataSet
.
setProperty
(
"shareMode"
,
"shareMode.thread"
);
csvDataSet
.
setProperty
(
"recycle"
,
true
);
csvDataSet
.
setProperty
(
"delimiter"
,
item
.
getDelimiter
());
csvDataSet
.
setComment
(
StringUtils
.
isEmpty
(
item
.
getDescription
())
?
""
:
item
.
getDescription
());
...
...
backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java
浏览文件 @
14810d24
...
...
@@ -111,8 +111,16 @@ public class MsJDBCSampler extends MsTestElement {
this
.
dataSource
=
config
.
getConfig
().
get
(
this
.
getProjectId
()).
getDatabaseConfigs
().
get
(
0
);
}
}
if
(
this
.
dataSource
==
null
)
{
MSException
.
throwException
(
"数据源为空无法执行"
);
// 用自身的数据
if
(
StringUtils
.
isNotEmpty
(
dataSourceId
))
{
this
.
dataSource
=
null
;
this
.
initDataSource
();
}
if
(
this
.
dataSource
==
null
)
{
MSException
.
throwException
(
"数据源为空无法执行"
);
}
}
final
HashTree
samplerHashTree
=
tree
.
add
(
jdbcSampler
(
config
));
tree
.
add
(
jdbcDataSource
());
...
...
backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
浏览文件 @
14810d24
...
...
@@ -21,6 +21,7 @@ import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
import
io.metersphere.api.dto.scenario.environment.EnvironmentConfig
;
import
io.metersphere.api.jmeter.JMeterService
;
import
io.metersphere.api.parse.ApiImportParser
;
import
io.metersphere.api.service.task.ParallelExecTask
;
import
io.metersphere.base.domain.*
;
import
io.metersphere.base.mapper.*
;
import
io.metersphere.base.mapper.ext.*
;
...
...
@@ -57,6 +58,8 @@ import java.io.ByteArrayOutputStream;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.util.*
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.stream.Collectors
;
@Service
...
...
@@ -743,6 +746,8 @@ public class ApiAutomationService {
SqlSession
sqlSession
=
sqlSessionFactory
.
openSession
(
ExecutorType
.
BATCH
);
ApiScenarioReportMapper
batchMapper
=
sqlSession
.
getMapper
(
ApiScenarioReportMapper
.
class
);
String
reportId
=
request
.
getId
();
Map
<
String
,
HashTree
>
map
=
new
LinkedHashMap
<>();
// 按照场景执行
for
(
ApiScenarioWithBLOBs
item
:
apiScenarios
)
{
if
(
item
.
getStepTotal
()
==
null
||
item
.
getStepTotal
()
==
0
)
{
...
...
@@ -780,11 +785,18 @@ public class ApiAutomationService {
batchMapper
.
insert
(
report
);
// 调用执行方法
jMeterService
.
runDefinition
(
report
.
getId
(),
hashTree
,
request
.
getReportId
(),
request
.
getRunMode
());
// jMeterService.runDefinition(report.getId(), hashTree, request.getReportId(), request.getRunMode());
map
.
put
(
report
.
getId
(),
hashTree
);
// 重置报告ID
reportId
=
UUID
.
randomUUID
().
toString
();
}
sqlSession
.
flushStatements
();
// 开始执行
ExecutorService
executorService
=
Executors
.
newFixedThreadPool
(
map
.
size
());
for
(
String
key
:
map
.
keySet
())
{
executorService
.
submit
(
new
ParallelExecTask
(
jMeterService
,
key
,
map
.
get
(
key
),
request
));
}
return
request
.
getId
();
}
...
...
@@ -884,7 +896,7 @@ public class ApiAutomationService {
// 生成集成报告
if
(
request
.
getConfig
()
!=
null
&&
request
.
getConfig
().
getMode
().
equals
(
"serial"
)
&&
StringUtils
.
isNotEmpty
(
request
.
getConfig
().
getReportName
()))
{
request
.
getConfig
().
setReportId
(
UUID
.
randomUUID
().
toString
());
APIScenarioReportResult
report
=
createScenarioReport
(
request
.
getConfig
().
getReportId
(),
JSON
.
toJSONString
(
reportList
),
request
.
getConfig
().
getReportName
(),
request
.
getTriggerMode
()
==
null
?
ReportTriggerMode
.
MANUAL
.
name
()
:
request
.
getTriggerMod
e
(),
APIScenarioReportResult
report
=
createScenarioReport
(
request
.
getConfig
().
getReportId
(),
JSON
.
toJSONString
(
reportList
),
request
.
getConfig
().
getReportName
(),
ReportTriggerMode
.
MANUAL
.
nam
e
(),
ExecuteType
.
Saved
.
name
(),
request
.
getProjectId
(),
request
.
getReportUserID
(),
request
.
getConfig
());
batchMapper
.
insert
(
report
);
}
...
...
backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java
浏览文件 @
14810d24
...
...
@@ -361,7 +361,6 @@ public class ApiScenarioReportService {
}
else
{
report
.
setUserId
(
SessionUtils
.
getUserId
());
}
report
.
setTriggerMode
(
runMode
);
report
.
setExecuteType
(
ExecuteType
.
Saved
.
name
());
report
.
setProjectId
(
projectId
);
report
.
setScenarioName
(
scenarioNames
.
toString
().
substring
(
0
,
scenarioNames
.
toString
().
length
()
-
1
));
...
...
backend/src/main/java/io/metersphere/api/service/task/ParallelExecTask.java
0 → 100644
浏览文件 @
14810d24
/**
*
*/
package
io.metersphere.api.service.task
;
import
io.metersphere.api.dto.automation.RunScenarioRequest
;
import
io.metersphere.api.jmeter.JMeterService
;
import
io.metersphere.commons.exception.MSException
;
import
io.metersphere.commons.utils.LogUtil
;
import
org.apache.jorphan.collections.HashTree
;
import
java.util.concurrent.Callable
;
public
class
ParallelExecTask
<
T
>
implements
Callable
<
T
>
{
private
RunScenarioRequest
request
;
private
JMeterService
jMeterService
;
private
HashTree
hashTree
;
private
String
id
;
public
ParallelExecTask
(
JMeterService
jMeterService
,
String
id
,
HashTree
hashTree
,
RunScenarioRequest
request
)
{
this
.
jMeterService
=
jMeterService
;
this
.
request
=
request
;
this
.
hashTree
=
hashTree
;
this
.
id
=
id
;
}
@Override
public
T
call
()
{
try
{
jMeterService
.
runDefinition
(
id
,
hashTree
,
request
.
getReportId
(),
request
.
getRunMode
());
return
null
;
}
catch
(
Exception
ex
)
{
LogUtil
.
error
(
ex
.
getMessage
());
MSException
.
throwException
(
ex
.
getMessage
());
return
null
;
}
}
}
backend/src/main/java/io/metersphere/commons/json/JSONSchemaGenerator.java
浏览文件 @
14810d24
...
...
@@ -84,6 +84,8 @@ public class JSONSchemaGenerator {
JsonObject
propertyObj
=
propertiesObj
.
get
(
propertyKey
).
getAsJsonObject
();
analyzeProperty
(
rootObj
,
propertyKey
,
propertyObj
);
}
}
else
if
(
object
.
has
(
"type"
)
&&
object
.
get
(
"type"
).
getAsString
().
equals
(
"array"
))
{
analyzeProperty
(
rootObj
,
"MS-OBJECT"
,
object
);
}
else
if
(
object
.
has
(
"type"
)
&&
!
object
.
get
(
"type"
).
getAsString
().
equals
(
"object"
))
{
analyzeProperty
(
rootObj
,
object
.
getAsString
(),
object
);
}
...
...
@@ -298,6 +300,9 @@ public class JSONSchemaGenerator {
generator
(
jsonSchema
,
root
);
// 格式化返回
Gson
gson
=
new
GsonBuilder
().
serializeNulls
().
setPrettyPrinting
().
create
();
if
(
root
.
get
(
"MS-OBJECT"
)
!=
null
)
{
return
gson
.
toJson
(
root
.
get
(
"MS-OBJECT"
));
}
return
gson
.
toJson
(
root
);
}
else
{
return
report
.
getExceptionThreshold
().
toString
();
...
...
frontend/src/business/components/api/automation/scenario/component/ApiComponent.vue
浏览文件 @
14810d24
...
...
@@ -45,7 +45,7 @@
:request=
"request"
:showScript=
"false"
/>
<ms-sql-basis-parameters
v-if=
"request.protocol==='SQL'|| request.type==='JDBCSampler'"
:request=
"request"
:is-scenario=
"
tru
e"
:environment=
"environment"
:request=
"request"
:is-scenario=
"
fals
e"
:environment=
"environment"
:showScript=
"false"
/>
<ms-dubbo-basis-parameters
v-if=
"request.protocol==='DUBBO' || request.protocol==='dubbo://'|| request.type==='DubboSampler'"
:request=
"request"
...
...
frontend/src/business/components/common/json-schema/convert/convert.js
浏览文件 @
14810d24
const
isBoolean
=
require
(
"
lodash.isboolean
"
)
const
isEmpty
=
require
(
"
lodash.isempty
"
)
const
isInteger
=
require
(
"
lodash.isinteger
"
)
const
isNull
=
require
(
"
lodash.isnull
"
)
const
isNumber
=
require
(
"
lodash.isnumber
"
)
const
isObject
=
require
(
"
lodash.isobject
"
)
const
isString
=
require
(
"
lodash.isstring
"
)
const
isArray
=
Array
.
isArray
const
isBoolean
=
require
(
"
lodash.isboolean
"
)
;
const
isEmpty
=
require
(
"
lodash.isempty
"
)
;
const
isInteger
=
require
(
"
lodash.isinteger
"
)
;
const
isNull
=
require
(
"
lodash.isnull
"
)
;
const
isNumber
=
require
(
"
lodash.isnumber
"
)
;
const
isObject
=
require
(
"
lodash.isobject
"
)
;
const
isString
=
require
(
"
lodash.isstring
"
)
;
const
isArray
=
Array
.
isArray
;
class
Convert
{
...
...
@@ -14,7 +14,7 @@ class Convert {
$id
:
"
http://example.com/root.json
"
,
$schema
:
"
http://json-schema.org/draft-07/schema#
"
,
}
this
.
_object
=
null
this
.
_object
=
null
;
}
/**
...
...
@@ -25,22 +25,22 @@ class Convert {
format
(
object
,
option
=
{})
{
// 数据校验,确保传入的的object只能是对象或数组
if
(
!
isObject
(
object
))
{
throw
new
TypeError
(
"
传入参数只能是对象或数组
"
)
throw
new
TypeError
(
"
传入参数只能是对象或数组
"
)
;
}
// 合并属性
this
.
_option
=
Object
.
assign
(
this
.
_option
,
option
)
this
.
_option
=
Object
.
assign
(
this
.
_option
,
option
)
;
// 需要转换的对象
this
.
_object
=
object
let
convertRes
this
.
_object
=
object
;
let
convertRes
;
// 数组类型和对象类型结构不一样
if
(
isArray
(
object
))
{
convertRes
=
this
.
_arrayToSchema
()
convertRes
=
this
.
_arrayToSchema
()
;
}
else
{
convertRes
=
this
.
_objectToSchema
()
convertRes
=
this
.
_objectToSchema
()
;
}
// 释放
this
.
_object
=
null
return
convertRes
this
.
_object
=
null
;
return
convertRes
;
}
/**
...
...
@@ -48,16 +48,16 @@ class Convert {
*/
_arrayToSchema
()
{
// root节点基本信息
let
result
=
this
.
_value2object
(
this
.
_object
,
this
.
_option
.
$id
,
""
,
true
)
let
result
=
this
.
_value2object
(
this
.
_object
,
this
.
_option
.
$id
,
""
,
true
)
;
if
(
this
.
_object
.
length
>
0
)
{
// 创建items对象的基本信息
let
objectItem
=
this
.
_object
[
0
]
result
[
"
items
"
]
=
this
.
_value2object
(
objectItem
,
`#/items`
,
'
items
'
)
result
[
"
items
"
]
=
this
.
_value2object
(
objectItem
,
`#/items`
,
'
items
'
)
;
if
(
isObject
(
objectItem
)
&&
!
isEmpty
(
objectItem
))
{
// 递归遍历
let
objectItemSchema
=
this
.
_json2schema
(
objectItem
,
`#/items`
)
let
objectItemSchema
=
this
.
_json2schema
(
objectItem
,
`#/items`
)
;
// 合并对象
result
[
"
items
"
]
=
Object
.
assign
(
result
[
"
items
"
],
objectItemSchema
)
result
[
"
items
"
]
=
Object
.
assign
(
result
[
"
items
"
],
objectItemSchema
)
;
}
}
return
result
...
...
@@ -90,9 +90,9 @@ class Convert {
let
result
=
{};
// 判断传入object是对象还是数组。
if
(
isArray
(
object
))
{
result
.
items
=
{}
result
.
items
=
{}
;
}
else
{
result
.
properties
=
{}
result
.
properties
=
{}
;
}
// 遍历传入的对象
for
(
const
key
in
object
)
{
...
...
@@ -100,7 +100,7 @@ class Convert {
const
element
=
object
[
key
];
// 如果只是undefined。跳过
if
(
element
===
undefined
)
{
continue
continue
;
}
let
$id
=
`
${
name
}
/properties/
${
key
}
`
// 判断当前 element 的值 是否也是对象,如果是就继续递归,不是就赋值给result
...
...
@@ -111,22 +111,22 @@ class Convert {
// 针对空数组和有值的数组做不同处理
if
(
element
.
length
>
0
)
{
// 如果是数组,那么就取第一项
let
elementItem
=
element
[
0
]
let
elementItem
=
element
[
0
]
;
// 创建items对象的基本信息
result
[
"
properties
"
][
key
][
"
items
"
]
=
this
.
_value2object
(
elementItem
,
`
${
$id
}
/items`
,
key
+
'
items
'
)
result
[
"
properties
"
][
key
][
"
items
"
]
=
this
.
_value2object
(
elementItem
,
`
${
$id
}
/items`
,
key
+
'
items
'
)
;
// 判断第一项是否是对象,且对象属性不为空
if
(
isObject
(
elementItem
)
&&
!
isEmpty
(
elementItem
))
{
// 新增的properties才合并进来
result
[
"
properties
"
][
key
][
"
items
"
]
=
Object
.
assign
(
result
[
"
properties
"
][
key
][
"
items
"
],
this
.
_json2schema
(
elementItem
,
`
${
$id
}
/items`
))
result
[
"
properties
"
][
key
][
"
items
"
]
=
Object
.
assign
(
result
[
"
properties
"
][
key
][
"
items
"
],
this
.
_json2schema
(
elementItem
,
`
${
$id
}
/items`
))
;
}
}
}
else
{
// 不是数组,递归遍历获取,然后合并对象属性
result
[
"
properties
"
][
key
]
=
Object
.
assign
(
result
[
"
properties
"
][
key
],
this
.
_json2schema
(
element
,
$id
))
result
[
"
properties
"
][
key
]
=
Object
.
assign
(
result
[
"
properties
"
][
key
],
this
.
_json2schema
(
element
,
$id
))
;
}
}
else
{
// 一般属性直接获取基本信息
result
[
"
properties
"
][
key
]
=
this
.
_value2object
(
element
,
$id
,
key
)
result
[
"
properties
"
][
key
]
=
this
.
_value2object
(
element
,
$id
,
key
)
;
}
}
}
...
...
@@ -150,29 +150,31 @@ class Convert {
// 判断是否为初始化root数据
if
(
root
)
{
objectTemplate
[
"
$schema
"
]
=
this
.
_option
.
$schema
objectTemplate
[
"
title
"
]
=
`The Root Schema`
objectTemplate
[
"
mock
"
]
=
undefined
objectTemplate
[
"
$schema
"
]
=
this
.
_option
.
$schema
;
objectTemplate
[
"
title
"
]
=
`The Root Schema`
;
objectTemplate
[
"
mock
"
]
=
undefined
;
}
if
(
isInteger
(
value
))
{
objectTemplate
.
type
=
"
integer
"
objectTemplate
.
type
=
"
integer
"
;
}
else
if
(
isNumber
(
value
))
{
objectTemplate
.
type
=
"
number
"
objectTemplate
.
type
=
"
number
"
;
}
else
if
(
isString
(
value
))
{
objectTemplate
.
type
=
"
string
"
objectTemplate
.
type
=
"
string
"
;
}
else
if
(
isBoolean
(
value
))
{
objectTemplate
.
type
=
"
boolean
"
objectTemplate
.
type
=
"
boolean
"
;
}
else
if
(
isNull
(
value
))
{
objectTemplate
.
type
=
"
null
"
objectTemplate
.
type
=
"
null
"
;
}
else
if
(
isArray
(
value
))
{
objectTemplate
.
type
=
"
array
"
objectTemplate
.
type
=
"
array
"
;
objectTemplate
[
"
mock
"
]
=
undefined
;
}
else
if
(
isObject
(
value
))
{
objectTemplate
.
type
=
"
object
"
objectTemplate
[
"
mock
"
]
=
undefined
;
}
return
objectTemplate
return
objectTemplate
;
}
}
module
.
exports
=
Convert
module
.
exports
=
Convert
;
xpack
@
e7709b9a
比较
e50f0463
...
e7709b9a
Subproject commit e
50f0463826ac4d7837ea3a237333827774a1b19
Subproject commit e
7709b9a340394e78610b91105b2cec0f1b8289d
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录