Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
auto-test
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xie.qin
auto-test
Commits
31146c0b
Commit
31146c0b
authored
Jul 23, 2021
by
xie.qin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
temp commit.
parent
1d5801ea
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
245 additions
and
39 deletions
+245
-39
README.md
README.md
+5
-2
build.gradle
build.gradle
+3
-0
H2RestMessageEntity.java
...ava/com/fuzamei/autotest/openapi/H2RestMessageEntity.java
+31
-0
H2RestMessageEvent.java
...java/com/fuzamei/autotest/openapi/H2RestMessageEvent.java
+19
-0
H2RestMessageEventListener.java
.../fuzamei/autotest/openapi/H2RestMessageEventListener.java
+68
-0
H2RestMessageProducer.java
...a/com/fuzamei/autotest/openapi/H2RestMessageProducer.java
+73
-0
OpenApiParser.java
...main/java/com/fuzamei/autotest/openapi/OpenApiParser.java
+33
-15
RestfulMessageEventListener.java
...fuzamei/autotest/openapi/RestfulMessageEventListener.java
+12
-21
application.properties
src/main/resources/application.properties
+1
-1
No files found.
README.md
View file @
31146c0b
...
...
@@ -77,9 +77,12 @@ N/A
##### 优点
-
测试数据支持动态修改,无需重启服务。
-
返回结果支持参数化,即可以根据请求路径中的参数,动态替换返回结果中对应的参数的值。
-
自动适配客户端http请求模式(HTTP1.X/HTTP2)并响应
。
-
适配客户端http/https请求模式并响应;HTTP协议支持HTTP1.X和HTTP2, HTTP2同时支持h2和h2c
。
-
如何在本机生成证书?使用命令: keytool -genkey -alias netty-reactor -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
-
相关参数应根据在application.properties内的定义进行修改
-
相关参数应根据在application.properties内的定义进行修改
-
curl命令验证例子: curl -H "Content-Type:application/json" -X POST -d '{"user_id": "123", "coin":100, "success":1, "msg":"OK!" }' -v --http2-prior-knowledge http://172.22.17.74:8080/userservice/fedFromOrg/87654321
build.gradle
View file @
31146c0b
...
...
@@ -34,6 +34,9 @@ dependencies {
implementation
'io.rest-assured:xml-path:4.4.0'
implementation
'io.rest-assured:json-schema-validator:4.4.0'
implementation
'io.qameta.allure:allure-rest-assured:2.14.0'
implementation
'com.squareup.okhttp3:okhttp:4.9.0'
implementation
'io.qameta.allure:allure-okhttp3:2.14.0'
compileOnly
'org.projectlombok:lombok:1.18.20'
testCompileOnly
'org.projectlombok:lombok:1.18.20'
runtimeOnly
'mysql:mysql-connector-java'
...
...
src/main/java/com/fuzamei/autotest/openapi/H2RestMessageEntity.java
0 → 100644
View file @
31146c0b
package
com
.
fuzamei
.
autotest
.
openapi
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
okhttp3.Headers
;
import
okhttp3.MediaType
;
import
okhttp3.RequestBody
;
import
okhttp3.ResponseBody
;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
H2RestMessageEntity
{
private
MediaType
contentType
;
private
String
method
;
private
Boolean
isHttps
;
private
String
path
;
private
RequestBody
requestBody
;
private
Integer
statusCode
;
private
ResponseBody
responseBody
;
}
src/main/java/com/fuzamei/autotest/openapi/H2RestMessageEvent.java
0 → 100644
View file @
31146c0b
package
com
.
fuzamei
.
autotest
.
openapi
;
import
org.springframework.context.ApplicationEvent
;
public
class
H2RestMessageEvent
extends
ApplicationEvent
{
private
H2RestMessageEntity
restfulMsg
;
public
H2RestMessageEvent
(
Object
source
)
{
super
(
source
);
}
public
H2RestMessageEntity
getMsg
()
{
return
restfulMsg
;
}
public
void
setMsg
(
H2RestMessageEntity
restfulMsg
)
{
this
.
restfulMsg
=
restfulMsg
;
}
}
src/main/java/com/fuzamei/autotest/openapi/H2RestMessageEventListener.java
0 → 100644
View file @
31146c0b
package
com
.
fuzamei
.
autotest
.
openapi
;
import
com.fuzamei.autotest.properties.GlobalProperties
;
import
io.restassured.http.Header
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.Headers
;
import
okhttp3.Request
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.event.EventListener
;
import
org.springframework.stereotype.Component
;
import
java.util.Iterator
;
@Component
@Slf4j
public
class
H2RestMessageEventListener
{
@Autowired
GlobalProperties
globalProperties
;
@EventListener
public
void
processRestfulMessageEvent
(
H2RestMessageEvent
h2RestMessageEvent
){
H2RestMessageEntity
h2RestMessageEntity
=
h2RestMessageEvent
.
getMsg
();
log
.
debug
(
"subscriber received a http2 message and the message content is {}. "
,
h2RestMessageEntity
.
toString
());
processRestMsgEventWithHttp2
(
h2RestMessageEntity
);
}
private
void
processRestMsgEventWithHttp2
(
H2RestMessageEntity
h2RestMessageEntity
)
{
final
String
tmpTarget
=
h2RestMessageEntity
.
getMethod
()
+
" "
+
h2RestMessageEntity
.
getPath
();
Request
request
=
null
;
try
{
switch
(
h2RestMessageEntity
.
getMethod
()){
case
"get"
:
request
=
new
Request
.
Builder
()
.
url
(
h2RestMessageEntity
.
getPath
())
.
header
(
"User-ID"
,
globalProperties
.
getDftuserid
().
toString
())
.
header
(
"User-Name"
,
globalProperties
.
getDftusername
())
.
get
()
.
build
();
break
;
case
"post"
:
request
=
new
Request
.
Builder
()
.
url
(
h2RestMessageEntity
.
getPath
())
.
header
(
"User-ID"
,
globalProperties
.
getDftuserid
().
toString
())
.
header
(
"User-Name"
,
globalProperties
.
getDftusername
())
.
post
(
h2RestMessageEntity
.
getRequestBody
())
.
build
();
break
;
case
"put"
:
request
=
new
Request
.
Builder
()
.
url
(
h2RestMessageEntity
.
getPath
())
.
header
(
"User-ID"
,
globalProperties
.
getDftuserid
().
toString
())
.
header
(
"User-Name"
,
globalProperties
.
getDftusername
())
.
put
(
h2RestMessageEntity
.
getRequestBody
())
.
build
();
break
;
default
:
break
;
}
}
catch
(
Exception
ex
){
log
.
error
(
"HTTP2 REST message [{}] send failed as error: {}"
,
tmpTarget
,
ex
);
throwExceptionInFeatureTest
(
restfulMessageEntity
,
ex
.
toString
());
return
;
}
}
}
src/main/java/com/fuzamei/autotest/openapi/H2RestMessageProducer.java
0 → 100644
View file @
31146c0b
package
com
.
fuzamei
.
autotest
.
openapi
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fuzamei.autotest.properties.GlobalProperties
;
import
io.restassured.http.Method
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.*
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationContext
;
import
javax.annotation.Resource
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Slf4j
public
class
H2RestMessageProducer
{
@Resource
private
ApplicationContext
applicationContext
;
public
void
produceRestMessageWithModeH2
(
MediaType
mediaType
,
RestfulMessageEntity
restfulMessageEntity
)
{
String
path
=
restfulMessageEntity
.
getPath
();
Boolean
isHttps
=
false
;
if
(
path
.
contains
(
"https:"
)){
isHttps
=
true
;
}
RequestBody
requestBody
=
null
;
if
(
restfulMessageEntity
.
getReqJsonBody
()
!=
null
)
{
String
strReqJsonBody
=
restfulMessageEntity
.
getReqJsonBody
().
toString
();
requestBody
=
RequestBody
.
create
(
strReqJsonBody
,
mediaType
);
}
else
if
(
restfulMessageEntity
.
getReqJsonArrayBody
()
!=
null
)
{
String
strReqJsonArrBody
=
restfulMessageEntity
.
getReqJsonArrayBody
().
toString
();
requestBody
=
RequestBody
.
create
(
strReqJsonArrBody
,
mediaType
);
}
else
if
(
restfulMessageEntity
.
getMapperReqJsonBody
()
!=
null
)
{
String
strReqMapperBody
=
restfulMessageEntity
.
getMapperReqJsonBody
().
toString
();
requestBody
=
RequestBody
.
create
(
strReqMapperBody
,
mediaType
);
}
ResponseBody
responseBody
=
null
;
MediaType
responseMediaType
=
MediaType
.
get
(
"application/json; charset=utf-8"
);
if
(
restfulMessageEntity
.
getRespJsonBody
()
!=
null
)
{
String
strRespJsonBody
=
restfulMessageEntity
.
getRespJsonBody
().
toString
();
responseBody
=
ResponseBody
.
create
(
strRespJsonBody
,
responseMediaType
);
}
else
if
(
restfulMessageEntity
.
getRespJsonArrayBody
()
!=
null
)
{
String
strRespJsonArrBody
=
restfulMessageEntity
.
getRespJsonArrayBody
().
toString
();
responseBody
=
ResponseBody
.
create
(
strRespJsonArrBody
,
responseMediaType
);
}
else
if
(
restfulMessageEntity
.
getMapperRespJsonBody
()
!=
null
)
{
String
strRespMapperBody
=
restfulMessageEntity
.
getMapperRespJsonBody
().
toString
();
responseBody
=
ResponseBody
.
create
(
strRespMapperBody
,
responseMediaType
);
}
H2RestMessageEntity
h2RestMessageEntity
=
H2RestMessageEntity
.
builder
()
.
contentType
(
mediaType
)
.
method
(
restfulMessageEntity
.
getMethod
().
name
().
toLowerCase
())
.
path
(
path
)
.
isHttps
(
isHttps
)
.
requestBody
(
requestBody
)
.
responseBody
(
responseBody
)
.
build
();
H2RestMessageEvent
h2RestMessageEvent
=
new
H2RestMessageEvent
(
this
);
h2RestMessageEvent
.
setMsg
(
h2RestMessageEntity
);
applicationContext
.
publishEvent
(
h2RestMessageEvent
);
}
}
src/main/java/com/fuzamei/autotest/openapi/OpenApiParser.java
View file @
31146c0b
...
...
@@ -12,6 +12,7 @@ import io.restassured.http.Header;
import
io.restassured.http.Headers
;
import
io.restassured.http.Method
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.MediaType
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.stereotype.Component
;
...
...
@@ -76,15 +77,7 @@ public class OpenApiParser {
public
void
handleEachHttpMethodInOpenApiFile
(
String
URL
,
Method
httpMethod
,
JsonNode
methodNode
,
JsonNode
definitionNode
,
String
serviceName
)
{
String
path
=
""
;
//parse field consumes
ContentType
contentType
=
ContentType
.
JSON
;
if
(
methodNode
.
has
(
"consumes"
))
{
ArrayNode
consumesArrayNode
=
(
ArrayNode
)
methodNode
.
get
(
"consumes"
);
for
(
JsonNode
node
:
consumesArrayNode
){
contentType
=
translateStringToContentType
(
node
.
asText
());
break
;
}
}
Boolean
h2Enabled
=
false
;
//get whole path
switch
(
serviceName
.
toLowerCase
()){
case
"backend"
:
...
...
@@ -103,8 +96,30 @@ public class OpenApiParser {
path
.
replaceAll
(
"\\{.*?\\}"
,
globalProperties
.
getInt32max
().
toString
());
//replaced by 9223372036854775807 ??
}
log
.
info
(
"now we're handling REST request: '{} {}'"
,
httpMethod
.
name
(),
path
);
if
(
backendServiceProperties
.
getHttp2
()){
h2Enabled
=
true
;
}
break
;
}
//parse field consumes
ContentType
contentType
=
ContentType
.
JSON
;
if
(
methodNode
.
has
(
"consumes"
))
{
ArrayNode
consumesArrayNode
=
(
ArrayNode
)
methodNode
.
get
(
"consumes"
);
for
(
JsonNode
node
:
consumesArrayNode
){
contentType
=
translateStringToContentType
(
node
.
asText
());
break
;
}
}
//preprocess for okhttp/http2
MediaType
mediaType
=
MediaType
.
get
(
"application/json; charset=utf-8"
);
if
(
methodNode
.
has
(
"consumes"
))
{
ArrayNode
consumesArrayNode
=
(
ArrayNode
)
methodNode
.
get
(
"consumes"
);
String
combinedMediaType
=
""
;
for
(
JsonNode
node
:
consumesArrayNode
)
{
combinedMediaType
+=
node
.
asText
()
+
";"
;
}
mediaType
=
MediaType
.
get
(
combinedMediaType
);
}
//specify headers. only two conditions: with User-ID, User-Name or without User-ID, User-Name
Header
userID
=
new
Header
(
"User-ID"
,
globalProperties
.
getDftuserid
().
toString
());
Header
userName
=
new
Header
(
"User-Name"
,
globalProperties
.
getDftusername
());
...
...
@@ -114,11 +129,7 @@ public class OpenApiParser {
ArrayNode
parametersArrayNode
=
null
;
Map
<
String
,
Object
>
reqJsonBody
=
new
HashMap
<
String
,
Object
>();
List
<
Object
>
reqJsonArrayBody
=
new
ArrayList
<>();
/*if(contentType.compareTo(ContentType.JSON) == 0) {
}
else {
//handle contentType = multipart/form-data
}*/
if
(
methodNode
.
has
(
"parameters"
))
{
parametersArrayNode
=
(
ArrayNode
)
methodNode
.
get
(
"parameters"
);
for
(
JsonNode
paraNode
:
parametersArrayNode
){
...
...
@@ -548,6 +559,12 @@ public class OpenApiParser {
}
}
if
(
h2Enabled
){
H2RestMessageProducer
h2RestMessageProducer
=
new
H2RestMessageProducer
();
h2RestMessageProducer
.
produceRestMessageWithModeH2
(
mediaType
,
restfulMsgWithHeaders
);
return
;
}
//publish message and wait subscriber(e.g. rest-assure) to send out request
RestfulMessageEvent
restfulMessageEvent
=
new
RestfulMessageEvent
(
this
);
restfulMessageEvent
.
setMsg
(
restfulMsgWithHeaders
);
...
...
@@ -889,4 +906,5 @@ public class OpenApiParser {
return
null
;
}
}
}
src/main/java/com/fuzamei/autotest/openapi/RestfulMessageEventListener.java
View file @
31146c0b
...
...
@@ -2,8 +2,6 @@ package com.fuzamei.autotest.openapi;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fuzamei.autotest.properties.BackendServiceProperties
;
import
com.fuzamei.autotest.properties.GlobalProperties
;
import
com.fuzamei.autotest.properties.SpecificProperties
;
import
io.qameta.allure.restassured.AllureRestAssured
;
import
io.restassured.RestAssured
;
...
...
@@ -17,7 +15,7 @@ import io.restassured.path.json.exception.JsonPathException;
import
io.restassured.response.Response
;
import
io.restassured.specification.MultiPartSpecification
;
import
lombok.extern.slf4j.Slf4j
;
import
org.aopalliance.aop.AspectException
;
import
org.apache.http.client.config.RequestConfig
;
import
org.apache.http.impl.client.HttpClientBuilder
;
import
org.springframework.beans.factory.annotation.Autowired
;
...
...
@@ -41,24 +39,11 @@ public class RestfulMessageEventListener {
@Autowired
SpecificProperties
specificProperties
;
@Autowired
BackendServiceProperties
backendServiceProperties
;
@Autowired
GlobalProperties
globalProperties
;
@EventListener
public
void
processRestfulMessageEvent
(
RestfulMessageEvent
restfulMessageEvent
){
RestfulMessageEntity
restfulMessageEntity
=
restfulMessageEvent
.
getMsg
();
log
.
debug
(
"subscriber received a message and the message content is {}. "
,
restfulMessageEntity
.
toString
());
if
(!
backendServiceProperties
.
getHttp2
()){
processRestMsgEventWithHttp1x
(
restfulMessageEntity
);
}
else
{
processRestMsgEventWithHttp2
(
restfulMessageEntity
);
}
processRestMsgEventWithHttp1x
(
restfulMessageEntity
);
}
private
void
processRestMsgEventWithHttp1x
(
RestfulMessageEntity
restfulMessageEntity
)
{
...
...
@@ -88,6 +73,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
multiPart
(
multiPartSpecBuilder
)
//.body(restfulMessageEntity.getReqJsonBody())
...
...
@@ -104,6 +90,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getReqJsonBody
())
.
when
()
...
...
@@ -121,6 +108,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getMapperReqJsonBody
(),
ObjectMapperType
.
JACKSON_2
)
.
when
()
...
...
@@ -137,6 +125,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getReqJsonArrayBody
())
.
when
()
...
...
@@ -153,6 +142,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
when
()
//.contentType(restfulMessageEntity.getContentType())
...
...
@@ -183,6 +173,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
multiPart
(
multiPartSpecBuilder
)
//.body(restfulMessageEntity.getReqJsonBody())
...
...
@@ -200,6 +191,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getReqJsonBody
())
.
when
()
...
...
@@ -216,6 +208,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getMapperReqJsonBody
(),
ObjectMapperType
.
JACKSON_2
)
.
when
()
...
...
@@ -231,6 +224,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
body
(
restfulMessageEntity
.
getReqJsonArrayBody
())
.
when
()
...
...
@@ -246,6 +240,7 @@ public class RestfulMessageEventListener {
response
=
given
()
.
filter
(
new
AllureRestAssured
())
.
relaxedHTTPSValidation
()
//.config(config)
.
when
()
//.contentType(restfulMessageEntity.getContentType())
...
...
@@ -395,10 +390,6 @@ public class RestfulMessageEventListener {
}
private
void
processRestMsgEventWithHttp2
(
RestfulMessageEntity
restfulMessageEntity
)
{
}
private
void
matchKeyAndDataTypeInRespWithExpectation
(
Map
<
String
,
Object
>
recvRespBody
,
Map
<
String
,
Object
>
expectedRespBody
)
{
//how to match: traverse expectedRespBody and found corresponding key in recvRespBody
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
expectedRespBody
.
entrySet
())
{
...
...
src/main/resources/application.properties
View file @
31146c0b
...
...
@@ -12,7 +12,7 @@ global.test.datacollectionpath=src/test/resources/testdatacollection/
server.port
=
8080
server.http2.enabled
=
true
server.ssl.enabled
=
tru
e
server.ssl.enabled
=
fals
e
server.ssl.key-store-type
=
PKCS12
server.ssl.key-store
=
classpath:keystore.p12
server.ssl.key-store-password
=
123456
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment