This article is the practice of the distributed performance test function expansion of the FunTester test framework, which is a relatively rough technical verification practice. The technical solution adopts the scenario envisaged in the distributed performance test framework use case scenario (1) .
The rough implementation scheme is divided into three parts: master scheduling machine , slave test machine and server tested service .
- master scheduling machine: handle use cases and assign tasks
- Slave test machine: accept tasks and execute use cases
- Server tested service: provide test interface
docker image
I just started to learn, I learned a little bit, here are just a few simple steps, if you are interested, you still need one to complete
Base mirror
Here i chose
By Caused: groovy.lang.GroovyRuntimeException: Conflicting Module1 versions Module1 [Groovy IS-loaded in XML Version. 3.0 .8 and you are Trying to Load Version 2.5 .7
duplicated code
Start the container
Use the command
Set up network
Because my master scheduling machine is placed on the local machine, there is an additional step to set the container to access the local host port.
Please refer to the official website document:
The IP address of the host is changing (if there is no network access, there is no IP address). We recommend that you connect to the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. This is for development purposes and does not apply to production environments other than Docker Desktop for Windows.
This feature is installed
Install vim
installation
Update dependencies
Need to use here
Update mirror
Use the command:
Update script
Push the written script to the container, and then start the corresponding script (which will be shared below), and you can perform the verification work. Should be used here
master scheduling machine
Here I only implement a scheduling function: to provide an interface that returns a test case (the object has not been encapsulated). Provide the request to the slave tester and return it to the tester for the test task (test case).
It sounds like this is a service, but I haven't started writing yet
master script
import com.alibaba.fastjson.JSONObject
import com.funtester.base.bean.Result
import com.funtester.httpclient.FunLibrary
import com.funtester.httpclient.FunRequest
import com.mocofun.moco.MocoServer
import com.sun.deploy.ui .FancyButton
import org.apache.http.client.methods.HttpGet
class DcsServer extends MocoServer {
public static void main (String[] args) {
def server = getServer( 12345 )
def res = new JSONObject()
res.times = 1000
res.thread = 20
res.mode = "ftt"
res.desc = "FunTester Distributed Test Demo"
res.runup = 10
String url = "http://192.168.80.169:12345/m"
def get = FunLibrary.getHttpGet(url)
def request = FunRequest.initFromRequest(get)
res.request = request
output (res)
server. get (urlStartsWith( "/m" ) ). response (obRes(Result.success(res) ))
def run = run(server)
waitForKey( "fun" )
run.stop()
}
}
Copy code
among them
Here I am based on the method in the test machine
def request = FunRequest.initFromRequest(get) res.request = request Copy code
Can save a lot of trouble, just put
The following is the specific response result:
~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~ JSON ~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~
{
. "Code" : 0 ,
. "Data" :{
... "Mode" : "ftt" ,
... "Request" :{
..... "Args" :{
.......
..... },
..... "Headers" :[
.......
..... ],
..... "Path" : "" ,
..... "Request" :{
....... "AllHeaders" :[
.........
....... ],
....... "Method" : "GET" ,
....... "Aborted" : false ,
....... "ProtocolVersion" :{
........ "Protocol" : "HTTP" ,
........ "Major" : 1 ,
........ "Minor" : 1
....... },
....... "RequestLine" :{
........ "Method" : "GET" ,
........ "ProtocolVersion" :{
.......... "$ref" : "$.data.request.request.protocolVersion"
......... },
........ "Uri" : "http://192.168.80.169:12345/m"
....... },
....... "Params" :{
........ "Names" :[
..........
........]
....... },
...... "URI" : "http://192.168.80.169:12345/m"
..... },
..... "RequestType" : "GET" ,
..... "Response" :{
...... "Code" :- 2 ,
....... "FunTester" : 200 ,
....... "Content" : "hello funtester!!!"
..... },
..... "Host" : "" ,
..... "Json" :{
.......
..... },
..... "Params" :{
.......
..... },
.... "Uri" : "http://192.168.80.169:12345/m"
... },
... "Times" : 1000 ,
... "Thread" : 20 ,
... "Runup" : 10 ,
... "Desc " : "FunTester Distributed Test Demo"
. },
. "Success" : true
}
~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~ JSON ~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~
Copy code
Can be seen in
slave test machine
This logic goes through simple polling
The script is as follows:
import com.funtester.config.Constant
import com.funtester.frame.execute.Concurrent
import com.funtester.frame.thread.RequestThreadTimes
import com.funtester.httpclient.FunLibrary
import com.funtester.httpclient.FunRequest
class Dcs extends FunLibrary {
public static void main (String[] args) {
while ( true ) {
String url = "http://host.docker.internal:12345/m"
//Requesting this interface will return a use case, currently there is no object encapsulation
//String url = "http://localhost:12345/m"//For local debugging
def get = getHttpGet(url)
def response = getHttpResponse(get)
if (response.getInteger( "code" ) == 0 ) {
def data = response.getJSONObject( "data" )
def r = data.getString( "request" )
/*Here will be simplified into an object in the future*/
def request = FunRequest.initFromString(r).getRequest()
//Pressure test mode
def times = data.getIntValue( "times" )
//Test termination condition
def mode = data.getString( "mode" )
//Number of threads, here the default fixed thread mode
def thread = data.getIntValue( " thread" )
//Soft start time
def runup = data.getIntValue( "runup" )
//Use case description
def desc = data.getString( "desc" )
if (mode == "ftt" ) {
Constant.RUNUP_TIME = runup
def task = new RequestThreadTimes(request, times)
def performanceResultBean = new Concurrent(task, thread, desc).start()
}
}
sleep( 5.0 )
}
}
}
Copy code
In the later stage, each different response body should be
About testing
server tested service
Also adopted
import com.mocofun.moco.MocoServer
class TestDemo extends MocoServer {
static void main (String[] args) {
def log = getServer( 12345 )
log.response( "hello funtester!!!" )
def run = run(log)
waitForKey( "fan" )
run.stop()
}
}
Copy code
This time I did not block the log, so it is more convenient to observe whether the request of the slave test machine is correct. The log content of the word request is as follows:
Request received:
GET/m HTTP/1.1
Host: 192.168 .80 .169 : 12345
Connection: Keep-Alive
- Agent-the User: the Apache-HttpClient/4.5 of 5 .6 (the Java/1.8 .0_282 )
Accept-Encoding: gzip,deflate
content-length: 0
Response return :
HTTP/1.1 200
Content-Length: 18
Content-Type: text/plain; charset=utf- 8
hello funtester!!!
Copy code
FunTester , Tencent Cloud author of the year , Boss direct contract author , GDevOps official partner media , non-famous test development.
- A Preliminary Study on the Framework Diagram of FunTester Testing Framework
- A Preliminary Study on the Framework Diagram of FunTester Test Project
- Preliminary Study on Soft Start of Performance Test
- Socket interface asynchronous verification practice
- Choose manual testing or automated testing?
- Performance test error statistics practice
- Java compress/decompress string
- Application of Lambda Expression in Thread Safe Map
- Details in the test case
- Be the one who gets off work most actively
- May 1 learning experience