Repository navigation
Expand file tree
/
Copy pathbase.lua
More file actions
176 lines (149 loc) · 5.75 KB
/
Copy pathbase.lua
File metadata and controls
176 lines (149 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
Wrk = require "wrk"
Date = os.date("%Y-%m-%d-%H-%M-%S")
ErrorLogFile = io.open("wrk-error-" .. Date .. ".log", "w")
if not ErrorLogFile then
print("Error: Unable to open error.log")
os.exit(1)
end
local function buildQueryString(params)
local queryParts = {}
for key, value in pairs(params) do
table.insert(queryParts, key .. "=" .. tostring(value))
end
return table.concat(queryParts, "&")
end
function ReadCookies()
local file = io.open("cookies.txt", "r")
local cookies = ""
if file then
cookies = file:read("*all")
cookies = cookies:gsub("\n$", "")
file:close()
else
print("cookies.txt not found")
os.exit()
end
return cookies
end
function CreateTestConfig(options)
local config = {
path = "/",
method = "GET",
params = {},
headers = {},
body = nil,
logErrors = true,
customTransformations = {},
}
for key, value in pairs(options) do
config[key] = value
end
return config
end
function RunTest(config)
local counter = 1
local threads = {}
if config.customTransformations and type(config.customTransformations) == "table" then
for _, transformation in ipairs(config.customTransformations) do
if type(transformation.func) == "function" then
local result = transformation.func()
if transformation.target == "headers" and type(result) == "table" then
for header, value in pairs(result) do
config.headers[header] = value
end
elseif transformation.target == "body" and type(result) == "string" then
config.body = result
elseif transformation.target == "query" and type(result) == "table" then
for param, value in pairs(result) do
config.params[param] = value
end
end
end
end
end
Wrk.method = config.method
for key, value in pairs(config.headers) do
Wrk.headers[key] = value
end
if config.params then
config.path = config.path .. "?" .. buildQueryString(config.params)
end
Wrk.path = config.path
---@diagnostic disable-next-line: lowercase-global
request = function()
Requests = Requests + 1
if config.body then
return Wrk.format(config.method, config.path, config.headers, config.body)
else
return Wrk.format(config.method, config.path, config.headers)
end
end
---@diagnostic disable-next-line: lowercase-global
setup = function(thread)
thread:set("id", counter)
table.insert(threads, thread)
counter = counter + 1
end
---@diagnostic disable-next-line: lowercase-global
init = function(_)
Requests = 0
Responses = 0
end
---@diagnostic disable-next-line: lowercase-global
response = function(status, _headers, body)
if status == nil then
ErrorLogFile:write("Socket error or timeout\n" ..
"\n---------------------------------------------------\n")
else
Responses = Responses + 1
if config.logErrors and status ~= 200 then
ErrorLogFile:write(string.format(
"Status: %d, Body: %s\n---------------------------------------------------\n", status, body))
end
end
end
---@diagnostic disable-next-line: lowercase-global
done = function(summary, latency, _requests)
local summaryFileName = "wrk-summary-" .. Date .. ".log"
local summaryFile = io.open(summaryFileName, "w")
if not summaryFile then
print("Error: Unable to open " .. summaryFileName)
return
end
summaryFile:write("========== Performance Test Summary ==========\n\n")
summaryFile:write("Latency Percentiles:\n")
summaryFile:write(string.format("%-10s | %-15s\n", "Percentile", "Latency (ms)"))
summaryFile:write(string.rep('-', 28) .. '\n')
for _, p in pairs({ 50, 75, 90, 95, 99, 99.999 }) do
local n = latency:percentile(p)
summaryFile:write(string.format("%-10f%% | %-15.6f\n", p, n))
end
summaryFile:write("\n")
local totalRequests = 0
local totalResponses = 0
for _, thread in ipairs(threads) do
totalRequests = totalRequests + thread:get("Requests")
totalResponses = totalResponses + thread:get("Responses")
end
summaryFile:write("Test Summary:\n")
summaryFile:write(string.format("%-15s: %ds\n", "Test Duration", summary.duration / 1e6)) -- Convert from microseconds to seconds
summaryFile:write(string.format("%-15s: %d\n", "Total Requests", totalRequests))
summaryFile:write(string.format("%-15s: %d\n", "Total Responses", totalResponses))
summaryFile:write(string.format("%-15s: %d\n", "Total Errors",
summary.errors.connect + summary.errors.read + summary.errors.write + summary.errors.status +
summary.errors.timeout))
summaryFile:write("\n")
summaryFile:write("Individual Thread Statistics:\n")
for _, thread in ipairs(threads) do
local threadId = thread:get("id")
local threadRequests = thread:get("Requests")
local threadResponses = thread:get("Responses")
summaryFile:write(string.format("Thread %-4d: Made %-10d requests and got %-10d responses\n", threadId,
threadRequests,
threadResponses))
end
summaryFile:write("\n========== End of Test Summary ==========\n")
summaryFile:close()
ErrorLogFile:close()
end
end