Hello team i am facing issue in gatling opensource and tried implement the curl command scripts in gatling.
My requirement is :
read the curl input from CSV
Split the Data into method, url, headers, data
Then as per the csv input my script should execute.
Note : when i am hard codded my curl command its working fine but when i am reading the data from csv session is not sending the request so could you please help us.
With CSV in put simulation code :
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.http.request.builder.HttpRequestBuilder
class Curl1Simulation extends Simulation {
// Define the HTTP protocol configuration
val httpProtocol = http
.baseUrl("https://example.com/api/resource")
.inferHtmlResources()
// Function to parse the cURL command
def parseCurlCommand(curl: String): (String, String, Map[String, String], String) = {
val methodPattern = "-X (\\w+)".r
val urlPattern = "((https?|ftp)://[^\\s]+)".r
val headerPattern = "-H '([^']+)'".r
val dataPattern = "-d '([^']+)'".r
val method = methodPattern.findFirstMatchIn(curl).map(_.group(1).toUpperCase).getOrElse("GET")
val url = urlPattern.findFirstIn(curl).getOrElse("")
val headers = headerPattern.findAllMatchIn(curl).map { m =>
val header = m.group(1)
val Array(key, value) = header.split(": ", 2)
key -> value.stripPrefix("\"").stripSuffix("\"")
}.toMap
val data = dataPattern.findFirstMatchIn(curl).map(_.group(1)).getOrElse("")
(method, url, headers, data)
}
// Function to create the HTTP request outside of the session
def createHttpRequest(curlCommand: String): HttpRequestBuilder = {
val (method, url, headers, body) = parseCurlCommand(curlCommand)
println(s"Method: $method, URL: $url, Headers: $headers, Body: $body")
method match {
case "GET" => http("GET Request").get(url).headers(headers)
case "POST" => http("POST Request").post(url).headers(headers).body(StringBody(body)).asJson
case "PUT" => http("PUT Request").put(url).headers(headers).body(StringBody(body)).asJson
case "DELETE" => http("DELETE Request").delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
}
// Load the CSV file containing the cURL commands
val csvFeeder = csv("data/ServiceCurl.csv").circular
// Define the scenario
val scn = scenario("Curl Scenario")
.feed(csvFeeder) // Feeder to load curlCommand from CSV
.exec ({ session =>
val curlCommand = session("curlCommand").as[String]
val httpRequest = createHttpRequest(curlCommand)
session.set("httpRequest", httpRequest)
})
// Set up the simulation
setUp(
scn.inject(atOnceUsers(1)) // Adjust the number of users and injection profile as needed
).protocols(httpProtocol)
}
import config.GatlingConfig.market
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class ServiceCurlSimulation extends Simulation {
// Get the cURL command from system properties
val curlCommand: String = System.getProperty("CURL_COMMAND", "curl -X GET https://example.com/api/resource -H "Authorization: Bearer token"'")
// Function to parse the cURL command
def parseCurlCommand(curl: String): (String, String, Map[String, String], String) = {
val methodPattern = "-X (\\w+)".r
val urlPattern = "((https?|ftp)://[^\\s]+)".r
val headerPattern = "-H '([^']+)'".r
val dataPattern = "-d '([^']+)'".r
// Extract HTTP method
val method = methodPattern.findFirstMatchIn(curl).map(_.group(1).toUpperCase).getOrElse("GET")
// Extract URL
val url = urlPattern.findFirstIn(curl).getOrElse("")
// Extract headers
val headers = headerPattern.findAllMatchIn(curl).map { m =>
val header = m.group(1)
val Array(key, value) = header.split(": ", 2)
key -> value.stripPrefix("\"").stripSuffix("\"")
}.toMap
// Extract body data
val data = dataPattern.findFirstMatchIn(curl).map(_.group(1)).getOrElse("")
(method, url, headers, data)
}
// Parse the cURL command
val (method, url, headers, body) = parseCurlCommand(curlCommand)
// Configure the HTTP protocol
val httpProtocol = http
.baseUrl(url.split("/").take(3).mkString("/")) // Extract base URL
.inferHtmlResources()
// Define the HTTP request based on the method
val httpRequest = method match {
case "GET" => http("Request").get(url).headers(headers)
case "POST" => http("Request").post(url).headers(headers).body(StringBody(body)).asJson
case "PUT" => http("Request").put(url).headers(headers).body(StringBody(body)).asJson
case "DELETE" => http("Request").delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
// Define the scenario
val scn = scenario("Curl Scenario")
.exec(httpRequest.check(status.is(200)))
// Set up the simulation
setUp(
scn.inject(atOnceUsers(1))
).protocols(httpProtocol)
}
Hard coded curl command scripts and its working as expected but we have to read the data from csv and then execute the scripts that changes is required.
method match {
case "GET" => http("GET Request").get(url).headers(headers)
case "POST" => http("POST Request").post(url).headers(headers).body(StringBody(body)).asJson
case "PUT" => http("PUT Request").put(url).headers(headers).body(StringBody(body)).asJson
case "DELETE" => http("DELETE Request").delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
I don’t actually understand your logic to support on this, perhaps you can give me the script where you hardcoded the curl ?
Also, for methods that are not impacted directly and verified worked on hardcoded value, please leave the name function only so that people can have better view and understanding what you are trying to do.
Trinp for your reference hardcoded curl code on below.
import config.GatlingConfig.market
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class ServiceCurlSimulation extends Simulation {
// Get the cURL command from system properties
val curlCommand: String = System.getProperty("CURL_COMMAND", "curl -X GET https://example.com/api/resource -H "Authorization: Bearer token"'")
// Function to parse the cURL command
def parseCurlCommand(curl: String): (String, String, Map[String, String], String) = {
val methodPattern = "-X (\\w+)".r
val urlPattern = "((https?|ftp)://[^\\s]+)".r
val headerPattern = "-H '([^']+)'".r
val dataPattern = "-d '([^']+)'".r
// Extract HTTP method
val method = methodPattern.findFirstMatchIn(curl).map(_.group(1).toUpperCase).getOrElse("GET")
// Extract URL
val url = urlPattern.findFirstIn(curl).getOrElse("")
// Extract headers
val headers = headerPattern.findAllMatchIn(curl).map { m =>
val header = m.group(1)
val Array(key, value) = header.split(": ", 2)
key -> value.stripPrefix("\"").stripSuffix("\"")
}.toMap
// Extract body data
val data = dataPattern.findFirstMatchIn(curl).map(_.group(1)).getOrElse("")
(method, url, headers, data)
}
// Parse the cURL command
val (method, url, headers, body) = parseCurlCommand(curlCommand)
// Configure the HTTP protocol
val httpProtocol = http
.baseUrl(url.split("/").take(3).mkString("/")) // Extract base URL
.inferHtmlResources()
// Define the HTTP request based on the method
val httpRequest = method match {
case "GET" => http("Request").get(url).headers(headers)
case "POST" => http("Request").post(url).headers(headers).body(StringBody(body)).asJson
case "PUT" => http("Request").put(url).headers(headers).body(StringBody(body)).asJson
case "DELETE" => http("Request").delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
// Define the scenario
val scn = scenario("Curl Scenario")
.exec(httpRequest.check(status.is(200)))
// Set up the simulation
setUp(
scn.inject(atOnceUsers(1))
).protocols(httpProtocol)
}
based on your code, I think that you did not actually used my recommendation, at least in the csv feeder
Pseudo-code you may want to see:
class ServiceCurlSimulation extends Simulation {
//I removed all method code for easier view
val scn = scenario("Curl Scenario")
.feed(curlCSV) //your CSV feed should be here
.exec(session => {
val string = session("ColumnName").as[String] //you need to take curl value here then do your modification on it.
//your logic method etc. etc.
})
.exec(httpRequest.check(status.is(200)))
// Set up the simulation
setUp(
scn.inject(atOnceUsers(1))
).protocols(httpProtocol)
}
If i use your method how it will parse the url and headers deatils to this method.
// Define the HTTP request based on the method
val httpRequest = method match {
case “GET” => http(“Request”).get(url).headers(headers)
case “POST” => http(“Request”).post(url).headers(headers).body(StringBody(body)).asJson
case “PUT” => http(“Request”).put(url).headers(headers).body(StringBody(body)).asJson
case “DELETE” => http(“Request”).delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
that is what you should think for, as I saw above you had handled everything by yourself, using session of Gatling will put all method there to process your data.
which ever possibilities you said right i have already tried but its not send any request and seeing below error.
Generating reports…
Exception in thread “main” java.lang.UnsupportedOperationException: There were no requests sent during the simulation,
Please refer the below code for your ref. and please run the scripts in your local machine.
import config.DataConfig.serviceNamesData
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class Curl2Simulation extends Simulation {
// Function to parse the cURL command
def parseCurlCommand(curl: String): (String, String, Map[String, String], String) = {
val methodPattern = "-X (\\w+)".r
val urlPattern = "((https?|ftp)://[^\\s]+)".r
val headerPattern = "-H '([^']+)'".r
val dataPattern = "-d '([^']+)'".r
// Extract HTTP method
val method = methodPattern.findFirstMatchIn(curl).map(_.group(1).toUpperCase).getOrElse("GET")
// Extract URL
val url = urlPattern.findFirstIn(curl).getOrElse("")
// Extract headers
val headers = headerPattern.findAllMatchIn(curl).map { m =>
val header = m.group(1)
val Array(key, value) = header.split(": ", 2)
key -> value.stripPrefix("\"").stripSuffix("\"")
}.toMap
// Extract body data
val data = dataPattern.findFirstMatchIn(curl).map(_.group(1)).getOrElse("")
(method, url, headers, data)
}
// Configure the HTTP protocol
val httpProtocol = http
.inferHtmlResources()
// Define the scenario
val scn = scenario("Curl Scenario")
.feed(serviceNamesData) // Feeder to load curlCommand from CSV
.exec(session => {
// Get the cURL command from the session
val curlCommand = session("curlCommand").as[String]
// Parse the cURL command
val (method, url, headers, body) = parseCurlCommand(curlCommand)
// Store the parsed values in the session for further use
session
.set("method", method)
.set("url", url)
.set("headers", headers)
.set("body", body)
})
.exec(session => {
// Retrieve parsed values from the session
val method = session("method").as[String]
val url = session("url").as[String]
val headers = session("headers").as[Map[String, String]]
val body = session("body").as[String]
// Build the HTTP request based on the parsed method
val httpRequest = method match {
case "GET" => http("GET Request").get(url).headers(headers)
case "POST" => http("POST Request").post(url).headers(headers).body(StringBody(body)).asJson
case "PUT" => http("PUT Request").put(url).headers(headers).body(StringBody(body)).asJson
case "DELETE" => http("DELETE Request").delete(url).headers(headers)
case _ => throw new IllegalArgumentException(s"Unsupported method: $method")
}
// Execute the HTTP request and check the response status
httpRequest.check(status.is(200))
session
})
// Set up the simulation
setUp(
scn.inject(atOnceUsers(1)) // Adjust the number of users and injection profile as needed
).protocols(httpProtocol)
}