Lua Scripting Guide
Drift testcases can be extended using Lua 5.4. This allows you to export functions to bind to testcase values or respond to lifecycle events with custom logic.
1. Script Structureβ
Every Drift script must return a Lua Table containing event_handlers and exported_functions.
local function bearer_token(token)
return "12345678"
end
local exports = {
event_handlers = {
-- Respond to lifecycle events here
["operation:started"] = function(event, data)
print("Starting: " .. data[2]) -- Prints operation ID
end
},
exported_functions = {
-- Map Lua functions to names used in YAML
token = bearer_token
}
}
return exports
2. Event Handlersβ
Events are strings structured with colons (e.g., namespace:event). You can use the * wildcard to match event patterns.
Wildcard Patternsβ
*: Matches all events.operation:*: Matches all events in theoperationnamespace (e.g.,operation:started,operation:finished).*:failed: Matches any event ending withfailed(e.g.,operation:failed).- Multiple namespaces are supported (e.g.,
xxx:yyy:zzz).
Core Framework Eventsβ
| Event | Triggered When... |
|---|---|
plugin:loaded | A plugin is loaded. |
plugin:unloaded | A plugin is unloaded. |
file:loaded | A test file is loaded. |
script:loaded | A Lua script is loaded. |
testcase:loaded | A testcase file is loaded. |
testcase:started | Testcase execution begins. |
testcase:finished | Testcase execution completes. |
operation:started | An operation execution begins. |
operation:prepared | An operation has been prepared and is ready for invocation. |
operation:invoked | An operation has been invoked (request sent). |
operation:passed | Operation verification passes. |
operation:failed | Operation verification fails. |
operation:finished | Operation verification is complete. |
http:request | (OAS Plugin) An HTTP request is created. |
Event Data Modificationβ
Some events allow the event data to be modified. To modify event data, return the modified table from your event handler function. This modified data will then be merged into the event data before passing it to subsequent handlers.
For example, HTTP events allow you to modify headers or bodies before the request is sent:
["http:request"] = function(event, data)
data.headers["authorization"] = "bearer 12345678"
return data -- Return modified data
end
Note that most events are purely informationalβreturning modified data will only affect subsequent event handlers, not the original event.
3. Bound Functionsβ
Bound functions allow you to inject dynamic values into your yaml or validate expected values.
YAML Usageβ
parameters:
authentication:
scheme: bearer
token: ${functions:token} # 'functions' is the namespace in sources
Function Signaturesβ
Exported functions are invoked with a single parameter:
- Generation mode (parameter is
nil): Return a generated value for the testcase to use.
Example: Simple Token Generationβ
local function bearer_token(token)
if token then
-- Validation: Check if token is valid
if #token < 8 then
return error("Token too short")
end
else
-- Generation: Create a new token
return "12345678"
end
end
4. Lua Dependenciesβ
Importing Other Lua Scriptsβ
You can import other Lua scripts using standard Lua mechanisms, as long as they don't use native extensions:
local date = require "date" -- Load another Lua module from the file system
LuaRocks Packagesβ
LuaRocks packages are supported, with the following requirements:
- Only pure Lua packages are supported. Native C/FFI extensions cannot be used.
- System-wide rocks should work without modification.
- User-local rocks must be installed to the standard LuaRocks directory:
- Unix-like systems:
$HOME/.luarocks/share/lua/5.4
- Unix-like systems:
5. Provided Helper Functionsβ
Drift injects convenience functions directly into the Lua environment.
dbg(data)β
Returns a human-readable string representation of complex Lua Tables. Useful for debugging event data.
Example:
["operation:started"] = function(event, data)
print(dbg(data)) -- Pretty-prints the data structure
end
Output:
Table(
Integer(1) => String("Operation description"),
Integer(2) => String("operationId"),
Integer(3) => String("Test case title")
)
http(request_table)β
Executes synchronous HTTP requests. Essential because most Lua HTTP libraries use unsupported native extensions.
Request Fields:
| Field | Type | Description |
|---|---|---|
url | String | Request URL (required). |
method | String | HTTP method. Defaults to GET if not provided. |
query | String or Table | Query parameters. If a Table, entries are formatted as key=value and separated by &. |
headers | Table | HTTP request headers. |
body | String or Table | Request body. If a Table, it will be rendered as JSON. |
Response Fields:
| Field | Type | Description |
|---|---|---|
status | Integer | HTTP response status code. |
headers | Table | Response headers. |
body | String or Table | Response body. JSON payloads are automatically parsed into Tables; other content types are returned as Strings. |
Example:
local res = http({
url = "http://localhost:8080/api/users",
method = "POST",
headers = {
["Content-Type"] = "application/json",
["Authorization"] = "Bearer token123"
},
body = { name = "John", email = "john@example.com" }
})
if res.status == 201 then
print("User created: " .. res.body.id)
else
print("Error: " .. res.status)
end
6. Script Requirements & Limitationsβ
Lua Engineβ
- Embedded Lua 5.4 VM.
Capabilitiesβ
Scripts have access to:
- OS environment (via standard Lua
osmodule) - File system (via standard Lua
iomodule) - Networking (via the provided
http()function and other Lua networking libraries) - Using other Lua scripts (via
require()for pure Lua modules) - LuaRocks packages (as long as they are pure Lua)
Restrictionsβ
- No C/FFI extensions are supported. This means:
- Native Lua extensions cannot be used
- LuaRocks packages must be pure Lua only
- Pure Lua LuaRocks packages can be used if installed to the standard location:
- Unix-like systems:
$HOME/.luarocks/share/lua/5.4
- Unix-like systems: