Files
futriix/tests/test_perfomance.lua

276 lines
9.6 KiB
Lua

-- ============================================================================
-- test_performance.lua - Нагрузочный тест
-- ============================================================================
-- Назначение: Оценка производительности под нагрузкой
-- Покрывает: Пропускную способность, латентность, параллелизм
local function measure_latency(operation, fn)
local start_time = os.clock()
local result = fn()
local end_time = os.clock()
local latency_ms = (end_time - start_time) * 1000
if not result then
print("" .. operation .. " failed")
return nil
end
print(string.format(" ✓ %s: %.2f ms", operation, latency_ms))
return latency_ms
end
local function performance_insert_test(count)
print(string.format("\n[Performance] Insert %d documents...", count))
local latencies = {}
local successes = 0
for i = 1, count do
local latency = measure_latency("Insert " .. i, function()
local resp = http.request("POST", "http://localhost:8080/api/db/perf_test/benchmark",
{["X-Session-ID"] = "test_session"},
{
_id = "perf_" .. i,
value = math.random(1, 1000000),
text = string.rep("x", 100),
timestamp = os.time()
}
)
if resp and resp.success then
successes = successes + 1
return true
end
return false
end)
if latency then
table.insert(latencies, latency)
end
end
-- Calculate statistics
local total_ms = 0
for _, lat in ipairs(latencies) do
total_ms = total_ms + lat
end
local avg_latency = total_ms / #latencies
local throughput = (successes / (total_ms / 1000))
print(string.format("\n Results: %d/%d successful", successes, count))
print(string.format(" Average latency: %.2f ms", avg_latency))
print(string.format(" Throughput: %.2f ops/sec", throughput))
return {successes = successes, avg_latency = avg_latency, throughput = throughput}
end
local function performance_read_test(doc_count)
print(string.format("\n[Performance] Read %d documents...", doc_count))
local latencies = {}
local successes = 0
for i = 1, doc_count do
local latency = measure_latency("Read " .. i, function()
local resp = http.request("GET", "http://localhost:8080/api/db/perf_test/benchmark/perf_" .. i,
{["X-Session-ID"] = "test_session"}
)
if resp and resp.success then
successes = successes + 1
return true
end
return false
end)
if latency then
table.insert(latencies, latency)
end
end
local total_ms = 0
for _, lat in ipairs(latencies) do
total_ms = total_ms + lat
end
local avg_latency = total_ms / #latencies
local throughput = (successes / (total_ms / 1000))
print(string.format("\n Results: %d/%d successful", successes, doc_count))
print(string.format(" Average latency: %.2f ms", avg_latency))
print(string.format(" Throughput: %.2f ops/sec", throughput))
return {successes = successes, avg_latency = avg_latency, throughput = throughput}
end
local function performance_index_query_test()
print("\n[Performance] Index query test...")
-- Create index
local idx_resp = http.request("POST", "http://localhost:8080/api/index/perf_test/benchmark/create",
{["X-Session-ID"] = "test_session"},
{name = "value_idx", fields = {"value"}, unique = false}
)
local latencies = {}
local queries = 100
for i = 1, queries do
local search_value = math.random(1, 1000000)
local latency = measure_latency("Query " .. i, function()
local resp = http.request("GET",
"http://localhost:8080/api/db/perf_test/benchmark?index=value_idx&value=" .. search_value,
{["X-Session-ID"] = "test_session"}
)
return resp and resp.success
end)
if latency then
table.insert(latencies, latency)
end
end
local total_ms = 0
for _, lat in ipairs(latencies) do
total_ms = total_ms + lat
end
local avg_latency = total_ms / #latencies
print(string.format("\n Average index query latency: %.2f ms", avg_latency))
return avg_latency
end
local function performance_concurrent_test()
print("\n[Performance] Concurrent operations test...")
print(" ⚠ This test simulates concurrent operations")
print(" Note: Lua concurrency is simulated via sequential requests")
local concurrency_levels = {10, 50, 100}
local results = {}
for _, level in ipairs(concurrency_levels) do
print(string.format("\n Testing concurrency level: %d", level))
local start_time = os.clock()
local success_count = 0
for i = 1, level do
local resp = http.request("POST", "http://localhost:8080/api/db/perf_test/concurrent",
{["X-Session-ID"] = "test_session"},
{
_id = "concurrent_" .. i .. "_" .. os.time(),
thread_id = i,
timestamp = os.time()
}
)
if resp and resp.success then
success_count = success_count + 1
end
end
local duration = os.clock() - start_time
local throughput = success_count / duration
table.insert(results, {
level = level,
duration = duration,
throughput = throughput,
success_rate = (success_count / level) * 100
})
print(string.format(" Duration: %.2f sec", duration))
print(string.format(" Throughput: %.2f ops/sec", throughput))
print(string.format(" Success rate: %.1f%%", (success_count / level) * 100))
end
return results
end
local function performance_mixed_workload_test()
print("\n[Performance] Mixed workload (70% read, 20% write, 10% update)...")
local operations = 200
local reads = 0
local writes = 0
local updates = 0
local start_time = os.clock()
for i = 1, operations do
local rand = math.random(1, 100)
if rand <= 70 then
-- Read operation
local doc_id = "perf_" .. math.random(1, 100)
local resp = http.request("GET", "http://localhost:8080/api/db/perf_test/benchmark/" .. doc_id,
{["X-Session-ID"] = "test_session"}
)
if resp and resp.success then reads = reads + 1 end
elseif rand <= 90 then
-- Write operation
local resp = http.request("POST", "http://localhost:8080/api/db/perf_test/benchmark",
{["X-Session-ID"] = "test_session"},
{
_id = "mixed_" .. i .. "_" .. os.time(),
data = "mixed workload test",
timestamp = os.time()
}
)
if resp and resp.success then writes = writes + 1 end
else
-- Update operation
local doc_id = "perf_" .. math.random(1, 100)
local resp = http.request("PUT", "http://localhost:8080/api/db/perf_test/benchmark/" .. doc_id,
{["X-Session-ID"] = "test_session"},
{updated = true, update_time = os.time()}
)
if resp and resp.success then updates = updates + 1 end
end
end
local duration = os.clock() - start_time
print(string.format("\n Results:"))
print(string.format(" Total operations: %d", operations))
print(string.format(" Reads: %d (%.1f%%)", reads, (reads/operations)*100))
print(string.format(" Writes: %d (%.1f%%)", writes, (writes/operations)*100))
print(string.format(" Updates: %d (%.1f%%)", updates, (updates/operations)*100))
print(string.format(" Total duration: %.2f sec", duration))
print(string.format(" Overall throughput: %.2f ops/sec", operations/duration))
return {reads = reads, writes = writes, updates = updates, duration = duration}
end
-- Run performance tests
print("\n" .. string.rep("=", 50))
print("PERFORMANCE TEST SUITE")
print(string.rep("=", 50))
-- Warm-up
print("\n[Performance] Warming up...")
for i = 1, 10 do
http.request("POST", "http://localhost:8080/api/db/perf_test/benchmark",
{["X-Session-ID"] = "test_session"},
{_id = "warmup_" .. i, data = "warmup"}
)
end
local insert_results = performance_insert_test(100)
local read_results = performance_read_test(100)
local index_latency = performance_index_query_test()
local concurrent_results = performance_concurrent_test()
local mixed_results = performance_mixed_workload_test()
print("\n" .. string.rep("=", 50))
print("PERFORMANCE SUMMARY")
print(string.rep("=", 50))
print(string.format("Insert throughput: %.2f ops/sec", insert_results.throughput or 0))
print(string.format("Read throughput: %.2f ops/sec", read_results.throughput or 0))
print(string.format("Index query latency: %.2f ms", index_latency or 0))
print(string.format("Mixed workload throughput: %.2f ops/sec", mixed_results.duration and 200/mixed_results.duration or 0))
print("\n✓ PERFORMANCE TESTS COMPLETED ✓\n")