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.
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 exportsEvent 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 |
|---|---|
| A plugin is loaded. |
| A plugin is unloaded. |
| A test file is loaded. |
| A Lua script is loaded. |
| A testcase file is loaded. |
| Testcase execution begins. |
| Testcase execution completes. |
| An operation execution begins. |
| An operation has been prepared and is ready for invocation. |
| An operation has been invoked (request sent). |
| Operation verification passes. |
| Operation verification fails. |
| Operation verification is complete. |
| (OAS Plugin) An HTTP request is created. |
Event Data Modification
Some events allow the event data to be modified. To do that, return the modified table from your event handler function. Drift then merges that 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.
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 sourcesFunction 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
endLua Dependencies
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
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 |
|---|---|---|
| String | Request URL (required). |
| String | HTTP method. Defaults to |
| String or Table | Query parameters. If a Table, entries are formatted as |
| Table | HTTP request headers. |
| String or Table | Request body. If a Table, it will be rendered as JSON. |
Response Fields
Field | Type | Description |
|---|---|---|
| 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)
endScript Requirements & Limitations
Lua Engine must be 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 that ative Lua extensions cannot be used and 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