gatling-convert-from-loadrunner — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited gatling-convert-from-loadrunner (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Action.c, vuser_init.c, vuser_end.c: the standard three-file layout.c or .h files in a LoadRunner script directory (look for a .usr or .lrs descriptor file nearby).c file containing all sections.c and .h files before proceeding.dat files as plain text fil esdefault.cfg file in the same directory and read it if present.prm file in the same directory and read it if presentEither find an existing Gatling project or initialize a new one:
#### Preamble
##### Java SDK
IF a variable needs to be saved inside the function AND the function is used within an Expression Language string:
When parsing dates, use java.time.format.DateTimeFormatter.ofPattern with system default zone and store it outside a function to avoid creation cost overhead.
For regular expression, use java.util.regex.Pattern.compile and store it outside a function to avoid creation cost overhead.
##### Gatling DSL
Be aware of DSL differences between all the languages Gatling support.
Some methods needs to be followed by .on() in Java, JavaScript and Kotlin but not Scala:
exitBlockOnFail { ... }: exitBlockOnFail().on(...)group("name") { ... }: group("name").on(...)Session handling is different, e.g.:
session.getString("name") in Java, JavaScript and Kotlin, session("name").as[String] in Scala#### Script structure
A LoadRunner script has up to three logical sections. Map them as follows:
vuser_init: before block on the simulationAction: one or more scenario + execvuser_end: after block on the simulationIf the script only has an Action section (or a single .c file), produce a simulation with just a scenario.
#### Runtime settings from default.cfg
IF a default.cfg file is present for runtime settings that affects HTTP behavior:
Check the [General] section:
AutomaticTransactions=1 and/or AutomaticTransactionsPerFunc=1: LoadRunner can auto-wrap actions or function calls into transactions. In Gatling, scenario and request names serve this purpose directly; no group() blocks are needed hereDefaultRunLogic: read the file, check RunLogicActionOrder in the [RunLogicRunRoot] section actions order, chain them with execContinueOnError=1: add exitHereIfFailed() between requests, otherwise Gatling continues on error by default; mention this to the userFailTransOnErrorMsg=1: apply the logic of lr_error_message as Gatling checks if possible, wrap the transaction inside a exitBlockOnFail() blockCheck the [ThinkTime] section:
Options=NOTHINK: keep pauses times but add .disablePauses() to setUpOptions=RECORDED: keep pauses timesOptions=MULTIPLY: keep original pauses times, Gatling does not have a direct equivalent; mention this to the userOptions=RANDOM: keep pauses times, use ThinkTimeRandomLow and ThinkTimeRandomHigh, add .uniformPauses() to setUp with the closest number that matches the original plus or minus valuesCheck the [WEB] section:
CustomUserAgent: add .userAgentHeader() to httpProtocolSearchForImages=1: add .inferHtmlResources() to httpProtocol#### HTTP requests
web_url(name, url, ...): http(name).get(url)web_submit_data(name, ...): http(name).post(url).formParam(...)web_submit_form(name, ...): http(name).post(url).formParam(...)web_custom_request(name, method, url, ...): http(name).httpRequest(method, url)web_add_header(name, value): .header(name, value) on the next request only, never on httpProtocolweb_add_auto_header(name, value): httpProtocol.header(name, value) if called before any request; otherwise add .header(name, value) to every subsequent request manuallyweb_add_header is one-shot: it applies only to the immediately following request, then is cleared; never hoist it into httpProtocol web_add_auto_header persists from the point of the call onward. If it appears before any request in the script, map it to httpProtocol.header(...); if it appears mid-script, add .header(...) to each request that follows it
For web_submit_data, extract each ITEMDATA name/value pair as a .formParam(name, value).
#### Response checks and correlation
web_reg_find(text=...): .check(bodyString.contains(...))web_reg_save_param(param, LB=, RB=): .check(regex("LB(.*?)RB").saveAs("param"))web_reg_save_param_ex(...): .check(regex(...).saveAs(...)) or .check(xpath(...))web_reg_save_param_json(...): convert QueryString to jmesPath as .check(jmesPath(...))Place .check(...) calls on the request that triggers the response being checked. web_reg_* functions are registered before the request they apply to, find the next web_url/web_submit_data and attach the check there.
#### Parameters and session variables
{ParamName} (LR parameter substitution): #{paramName} (Gatling EL)lr_save_string(value, "param"): .exec(session -> session.set("param", value))lr_param_sprintf("param", fmt, ...): .exec(session -> session.set("param", ...)) with string formattinglr_eval_string("{param}"): session.getString("param") or "#{param}" in EL stringsFor parameter files (.dat files referenced in the script or .usr descriptor), convert them to Gatling feeders. Copy the data file to the Gatling project's resources directory.
IF a .prm file is present, check it for each [parameter:<parameter name>] entries:
ColumnName="Col <number>":ColumnName="<column name>":Delimiter="<char>": use csv, tsv, or separatedValues("<file path>", '<char>')SelectNextRow="Random": use .random()SelectNextRow="Same line as <parameter name>": ensure configuration is the same as <parameter name>SelectNextRow="Sequential": use .circular()SelectNextRow="Unique": use .queue() but it has no real Gatling equivalent; mention this to the user#### Transactions
In LoadRunner, transactions are the only way to name and track individual requests, so developers routinely wrap every single request in a transaction. In Gatling, HTTP requests are named and tracked individually in reports, making single-request groups redundant.
Apply this rule when mapping lr_start_transaction / lr_end_transaction pairs:
group() wrapper entirely. Use the transaction name as the http("name") request name instead.group("name") block as usual.When FailTransOnErrorMsg=1 applies to a single-request transaction, wrap the request directly in exitBlockOnFail() without a surrounding group().
#### Logging
lr_output_message, lr_log_message: remove these or convert to a comment, Gatling handles logging at the framework levellr_error_message: keep, wrap inside an exec block with session and use .markAsFailed() on session if necessary#### Rendezvous points
lr_rendezvous("name"): remove, Gatling does not have a direct equivalent; mention this to the user if present#### Resource files
Any files referenced in the script (e.g., request body files, upload files, data files) should be copied to the Gatling project's resources directory and referenced via RawFileBody("filename") or a feeder.
Use the build-tool skill if available.
After the conversion, inform the user of:
HttpProtocol configuration (base URL, common headers) into a shared httpProtocol objectformParam blocks with a map if there are many parameters~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.