Introduction
Load testing is a type of non-functional testing. A load test is type of software testing which is conducted to understand the behavior of the application under a specific expected load. Load testing is performed to determine a system’s behavior under both normal and at peak conditions.
No amount of testing can prove a software right, a single test can prove a software wrong. - Amir Ghahrai
Example Scenario
Let’s say, We have to perform Two Million HTTP requests load in AWS Lambda function via API Gateway. Obviously, to perform 2M requests we need to run load testing in cluster mode.
Gatling Frontline support cluster load testing directly. With Gatling Community Version we need to do some extra work to achieve cluster mode load testing.
Code Example
This article is accompanied by working example code on GitHub
Create Handler Functions - on Github
Let’s consider we have to expose APIs to manage an order:
- Put order into the db (DynamoDB)
To achieve these two operations in serverless, we need two lambda functions with http event type:
- POST : Store order into the db
Load Testing - on Github
I used gatling-aws-maven-plugin to run 20 EC2 instances together, which runs load testing parallel. For two millions http requests by using 20 instances together, in gatling our plan will be like below:
REPETITION -> 2000
NO_OF_USERS -> 50
-----------------------------------------------
TOTAL REQUEST = 2000 * 50 = 100000
WITH 20 INSTANCES = 100000 * 20 = 2000000 = 2M
Now our load testing simulation will looks like:
import java.util.UUID.randomUUID
import io.gatling.core.Predef._
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef._
class LoadTestingSimulation extends Simulation {
private val ENDPOINT = "https://xxxxx.execute-api.ap-southeast-2.amazonaws.com/test"
private val BODY: String = "{\"customerId\" : \"@@customerId@@\" }"
private val scn: ScenarioBuilder = scenario("Load Testing")
.repeat(2000) {
exec(
http("initiation")
.post(ENDPOINT + "/orders")
.check(status.is(200))
.body(StringBody(session => BODY.replaceAll("@@customerId@@", newId)))
.header("Content-type", "text/xml")
)
}
setUp(scn.inject(atOnceUsers(50))
.protocols(http
.baseURL(ENDPOINT)
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("en-US,en;q=0.5")
.userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")))
private def newId = {
randomUUID().toString.substring(0, 33)
}
}
make deploy
When you run the command make deploy
then it will deploy the lambda function to AWS.
make test
To run the command make test
provide correct AWS accessKey
and secretKey
in aws.properties. Also, change values in runLoadtestRemotely.sh according to you configuration.
S3_BUCKET=load-testing-s3-bucket
EC2_KEY_PAIR=loadtest-keypair
NO_OF_INSTANCES=20
EC2_ENDPOINT=https://ec2.us-west-1.amazonaws.com
EC2_SECURITY_GROUP_ID=sg-xxxxxxx
AMI_ID=ami-0782017a917e973e7
SSH_USER=ec2-user
Then you can run make test
and analyze the result.