Lookup load
Lookup Load Test Script for wrkยถ
lookup_load.lua
-- === CONFIG ===
local NUM_MSISDNS = 30000
local BASE_URL = "https://api.il.unibeam.com"
local CALLBACK_URL = "https://roiwebhook.unibeam.us/callback"
local CUSTOMER_ID = "roi"
local AUTH_USERNAME = "unibeam"
local AUTH_PASSWORD = "abcd1234"
local MESSAGE = "hello7"
-- === TOKEN CONFIG ===
local token_expiration_minutes = 60
local token_valid_for = token_expiration_minutes * 60
local token_fetched_at = 0
local token = nil
local authenticated = false
-- === GLOBALS ===
local msisdn_index = 1
local api_paths = {
"/api/v1/lookup"
}
local threads = {}
-- === UTILS ===
local function uuid()
local template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
return string.gsub(template, "[xy]", function(c)
local v = (c == "x") and math.random(0, 15) or math.random(8, 11)
return string.format("%x", v)
end)
end
-- === MSISDN LIST ===
local msisdns = (function()
local list = {}
for i = 1, NUM_MSISDNS do
list[i] = tostring(i)
end
return list
end)()
-- === SETUP ===
function setup(thread)
table.insert(threads, thread)
local threadId = tonumber(tostring(thread):match("0x%x+")) or 0
math.randomseed(os.time() + threadId)
local offset = math.random(0, NUM_MSISDNS)
thread:set("offset", offset)
thread:set("status_not_found", 0)
end
-- === REQUEST ===
function request()
local now = os.time()
local token_expired = (not token_fetched_at) or (now - token_fetched_at >= token_valid_for)
if not authenticated or token_expired then
authenticated = false
token = nil
local body = string.format('{"username":"%s","password":"%s"}', AUTH_USERNAME, AUTH_PASSWORD)
return wrk.format("POST", "/authenticate", {
["Content-Type"] = "application/json",
["customerId"] = CUSTOMER_ID
}, body)
end
-- MSISDN & API rotation logic
local offset = wrk.thread:get("offset") or 0
local index = ((msisdn_index + offset - 1) % NUM_MSISDNS) + 1
local msisdn = msisdns[index]
local api_index = ((msisdn_index - 1) % #api_paths) + 1
local path = api_paths[api_index]
local reqId = uuid()
local body = ""
if api_index == 1 then
body = string.format([[{
"msisdn":"%s",
"cbUrl":"%s",
"requestId":"%s",
"message":"%s",
"rejectOnActiveCall":false
}]], msisdn, CALLBACK_URL, reqId, MESSAGE)
elseif api_index == 2 then
body = string.format([[{
"msisdn":"%s",
"cbUrl":"%s",
"requestId":"%s",
"message":"%s"
}]], msisdn, CALLBACK_URL, reqId, MESSAGE)
elseif api_index == 3 then
body = string.format([[{
"msisdn":"%s",
"cbUrl":"%s",
"requestId":"%s"
}]], msisdn, CALLBACK_URL, reqId)
end
-- Increment index
msisdn_index = msisdn_index + 1
if msisdn_index > NUM_MSISDNS then msisdn_index = 1 end
return wrk.format("POST", path, {
["Content-Type"] = "application/json",
["customerId"] = CUSTOMER_ID,
["Authorization"] = "Bearer " .. token
}, body)
end
-- === RESPONSE ===
function response(status, headers, body)
if body then local _ = body:sub(1, 1) end
if not authenticated and status == 200 and body then
token = body:match('"token"%s*:%s*"([^"]+)"')
if token then
authenticated = true
token_fetched_at = os.time()
end
end
-- Count status codes
local key = "status_" .. tostring(status)
local count = wrk.thread:get(key) or 0
wrk.thread:set(key, count + 1)
-- Look for "status":"NOT_FOUND" in JSON body
if status == 200 and body and body:match('"status"%s*:%s*"NOT_FOUND"') then
local nf = wrk.thread:get("status_not_found") or 0
wrk.thread:set("status_not_found", nf + 1)
end
end
-- === DONE ===
function done(summary, latency, requests)
local status_counts = {
["200"] = 0,
["400"] = 0,
["401"] = 0,
["403"] = 0,
["500"] = 0
}
local other = 0
for _, thread in ipairs(threads) do
for _, code in ipairs({"200", "400", "401", "403", "500"}) do
local key = "status_" .. code
local count = thread:get(key) or 0
status_counts[code] = status_counts[code] + count
end
for i = 100, 599 do
local code = tostring(i)
if not status_counts[code] then
local key = "status_" .. code
local count = thread:get(key)
if count then other = other + count end
end
end
end
print("------------------------------")
print("๐ Response Code Breakdown:")
for _, code in ipairs({"200", "400", "401", "403", "500"}) do
print(string.format("%s: %d", code, status_counts[code]))
end
local not_found_total = 0
for _, thread in ipairs(threads) do
local nf = thread:get("status_not_found") or 0
not_found_total = not_found_total + nf
end
print(string.format("โ NOT_FOUND in response body: %d", not_found_total))
print(string.format("Other: %d", other))
print("๐ฆ Total requests: " .. summary.requests)
print("------------------------------")
end