Skip to content

Unibeam test

Unibeam Test Launcher Script for wrkยถ

unibeam_test.lau
-- === 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/business/transaction-multisecure",
  "/api/v1/business/transaction-touch",
  "/api/v1/auth/silent"
}
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)
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

  local key = "status_" .. tostring(status)
  local count = wrk.thread:get(key) or 0
  wrk.thread:set(key, count + 1)
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
  print(string.format("Other: %d", other))
  print("๐Ÿ“ฆ Total requests: " .. summary.requests)
  print("------------------------------")
end