Upload files to "tests"
This commit is contained in:
243
tests/load_test.lua
Normal file
243
tests/load_test.lua
Normal file
@@ -0,0 +1,243 @@
|
||||
-- tests/load_test.lua
|
||||
-- Комплексное нагрузочное тестирование всех компонентов
|
||||
|
||||
local function run_load_test()
|
||||
print("╔══════════════════════════════════════════════════════════════╗")
|
||||
print("║ LOAD TEST SUITE ║")
|
||||
print("╚══════════════════════════════════════════════════════════════╝")
|
||||
|
||||
local test_results = {}
|
||||
|
||||
-- Функция для замера производительности
|
||||
local function measure_performance(name, fn, iterations)
|
||||
print(string.format("\n📊 Measuring: %s (%d iterations)", name, iterations))
|
||||
|
||||
local times = {}
|
||||
local errors = 0
|
||||
|
||||
for i = 1, iterations do
|
||||
local start = os.clock()
|
||||
local success, err = pcall(fn)
|
||||
local duration = os.clock() - start
|
||||
|
||||
if success then
|
||||
table.insert(times, duration)
|
||||
else
|
||||
errors = errors + 1
|
||||
print(string.format(" Error #%d: %s", i, tostring(err)))
|
||||
end
|
||||
end
|
||||
|
||||
if #times == 0 then
|
||||
print(string.format(" ❌ All %d iterations failed", iterations))
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Вычисляем статистику
|
||||
table.sort(times)
|
||||
local min = times[1]
|
||||
local max = times[#times]
|
||||
local sum = 0
|
||||
for _, t in ipairs(times) do sum = sum + t end
|
||||
local avg = sum / #times
|
||||
local p50 = times[math.floor(#times * 0.5)]
|
||||
local p95 = times[math.floor(#times * 0.95)]
|
||||
local p99 = times[math.floor(#times * 0.99)]
|
||||
|
||||
print(string.format([[
|
||||
Results:
|
||||
Success rate: %.1f%% (%d/%d)
|
||||
Min: %.3f ms
|
||||
Max: %.3f ms
|
||||
Avg: %.3f ms
|
||||
P50: %.3f ms
|
||||
P95: %.3f ms
|
||||
P99: %.3f ms
|
||||
]], (iterations - errors) / iterations * 100, iterations - errors, iterations,
|
||||
min * 1000, max * 1000, avg * 1000, p50 * 1000, p95 * 1000, p99 * 1000))
|
||||
|
||||
return {
|
||||
success_rate = (iterations - errors) / iterations,
|
||||
min_ms = min * 1000,
|
||||
max_ms = max * 1000,
|
||||
avg_ms = avg * 1000,
|
||||
p50_ms = p50 * 1000,
|
||||
p95_ms = p95 * 1000,
|
||||
p99_ms = p99 * 1000
|
||||
}
|
||||
end
|
||||
|
||||
-- Подготовка
|
||||
print("\n🔧 Preparing test environment...")
|
||||
db.execute("CREATE DATABASE IF NOT EXISTS load_test")
|
||||
db.execute("USE load_test")
|
||||
|
||||
db.execute([[
|
||||
CREATE COLLECTION IF NOT EXISTS load_collection
|
||||
WITH SETTINGS {
|
||||
max_documents = 1000000,
|
||||
auto_index_id = true
|
||||
}
|
||||
]])
|
||||
|
||||
-- Тест 1: Вставка документов
|
||||
local insert_results = measure_performance("INSERT", function()
|
||||
local doc = {
|
||||
_id = string.format("doc_%d_%d", os.time(), math.random(1, 1000000)),
|
||||
timestamp = os.time() * 1000,
|
||||
value = math.random(1, 10000),
|
||||
data = string.rep("x", 100)
|
||||
}
|
||||
db.execute(string.format(
|
||||
"INSERT INTO load_collection VALUES (%s)",
|
||||
db.json_encode(doc)
|
||||
))
|
||||
end, 1000)
|
||||
|
||||
-- Тест 2: Чтение по ID
|
||||
local read_results = measure_performance("SELECT BY ID", function()
|
||||
db.execute(string.format("SELECT * FROM load_collection WHERE _id = 'doc_%d'",
|
||||
math.random(1, 1000)))
|
||||
end, 1000)
|
||||
|
||||
-- Тест 3: Обновление
|
||||
local update_results = measure_performance("UPDATE", function()
|
||||
db.execute(string.format([[
|
||||
UPDATE load_collection
|
||||
SET value = %d, updated_at = %d
|
||||
WHERE _id = 'doc_%d'
|
||||
]], math.random(1, 10000), os.time() * 1000, math.random(1, 1000)))
|
||||
end, 1000)
|
||||
|
||||
-- Тест 4: Удаление
|
||||
local delete_results = measure_performance("DELETE", function()
|
||||
db.execute(string.format("DELETE FROM load_collection WHERE _id = 'temp_%d'",
|
||||
math.random(1, 100)))
|
||||
end, 500)
|
||||
|
||||
-- Тест 5: Сложный запрос с фильтром
|
||||
local query_results = measure_performance("COMPLEX QUERY", function()
|
||||
db.execute([[
|
||||
SELECT * FROM load_collection
|
||||
WHERE value > 5000
|
||||
AND value < 8000
|
||||
LIMIT 50
|
||||
]])
|
||||
end, 500)
|
||||
|
||||
-- Тест 6: Агрегация
|
||||
local agg_results = measure_performance("AGGREGATION", function()
|
||||
db.execute([[
|
||||
SELECT
|
||||
COUNT(*) as total,
|
||||
AVG(value) as avg_value,
|
||||
MIN(value) as min_value,
|
||||
MAX(value) as max_value
|
||||
FROM load_collection
|
||||
WHERE value > 1000
|
||||
]])
|
||||
end, 200)
|
||||
|
||||
-- Тест 7: Пакетная вставка
|
||||
local batch_results = measure_performance("BATCH INSERT", function()
|
||||
local docs = {}
|
||||
for i = 1, 10 do
|
||||
table.insert(docs, {
|
||||
_id = string.format("batch_%d_%d", os.time(), i),
|
||||
value = i
|
||||
})
|
||||
end
|
||||
db.execute(string.format(
|
||||
"INSERT INTO load_collection VALUES %s",
|
||||
db.json_encode(docs)
|
||||
))
|
||||
end, 100)
|
||||
|
||||
-- Тест 8: Транзакция
|
||||
local tx_results = measure_performance("TRANSACTION", function()
|
||||
db.execute("BEGIN TRANSACTION")
|
||||
db.execute("INSERT INTO load_collection VALUES {_id = 'tx1', value = 1}")
|
||||
db.execute("INSERT INTO load_collection VALUES {_id = 'tx2', value = 2}")
|
||||
db.execute("COMMIT")
|
||||
end, 100)
|
||||
|
||||
-- Тест 9: Поиск по индексу
|
||||
db.execute("CREATE INDEX idx_value ON load_collection(value)")
|
||||
|
||||
local index_results = measure_performance("INDEX SEARCH", function()
|
||||
db.execute("SELECT * FROM load_collection WHERE value = 5000")
|
||||
end, 500)
|
||||
|
||||
-- Тест 10: Сканирование с лимитом
|
||||
local scan_results = measure_performance("SCAN WITH LIMIT", function()
|
||||
db.execute("SELECT * FROM load_collection LIMIT 1000")
|
||||
end, 100)
|
||||
|
||||
-- Сводка
|
||||
print("\n╔══════════════════════════════════════════════════════════════╗")
|
||||
print("║ PERFORMANCE SUMMARY ║")
|
||||
print("╚══════════════════════════════════════════════════════════════╝")
|
||||
|
||||
local function print_summary(name, results)
|
||||
if results then
|
||||
local status = results.success_rate > 0.99 and "✅" or "⚠️"
|
||||
print(string.format("%s %-15s: avg=%.2fms, p95=%.2fms, success=%.1f%%",
|
||||
status, name, results.avg_ms, results.p95_ms, results.success_rate * 100))
|
||||
else
|
||||
print(string.format("❌ %-15s: FAILED", name))
|
||||
end
|
||||
end
|
||||
|
||||
print_summary("INSERT", insert_results)
|
||||
print_summary("SELECT", read_results)
|
||||
print_summary("UPDATE", update_results)
|
||||
print_summary("DELETE", delete_results)
|
||||
print_summary("QUERY", query_results)
|
||||
print_summary("AGGREGATE", agg_results)
|
||||
print_summary("BATCH", batch_results)
|
||||
print_summary("TRANSACTION", tx_results)
|
||||
print_summary("INDEX SEARCH", index_results)
|
||||
print_summary("SCAN", scan_results)
|
||||
|
||||
-- Общий вердикт
|
||||
local success_rate = (insert_results and insert_results.success_rate or 0) +
|
||||
(read_results and read_results.success_rate or 0) +
|
||||
(update_results and update_results.success_rate or 0) +
|
||||
(delete_results and delete_results.success_rate or 0) +
|
||||
(query_results and query_results.success_rate or 0) +
|
||||
(agg_results and agg_results.success_rate or 0) +
|
||||
(batch_results and batch_results.success_rate or 0) +
|
||||
(tx_results and tx_results.success_rate or 0) +
|
||||
(index_results and index_results.success_rate or 0) +
|
||||
(scan_results and scan_results.success_rate or 0)
|
||||
|
||||
success_rate = success_rate / 10 * 100
|
||||
|
||||
print("\n╔══════════════════════════════════════════════════════════════╗")
|
||||
print("║ FINAL VERDICT ║")
|
||||
print("╚══════════════════════════════════════════════════════════════╝")
|
||||
|
||||
if success_rate > 99 then
|
||||
print("✅ EXCELLENT: All operations performing optimally")
|
||||
elseif success_rate > 95 then
|
||||
print("✅ GOOD: Most operations performing well")
|
||||
elseif success_rate > 90 then
|
||||
print("⚠️ ACCEPTABLE: Some operations need optimization")
|
||||
else
|
||||
print("❌ POOR: Significant performance issues detected")
|
||||
end
|
||||
|
||||
print(string.format("Overall success rate: %.1f%%", success_rate))
|
||||
|
||||
-- Очистка
|
||||
print("\n🧹 Cleaning up...")
|
||||
db.execute("DROP DATABASE IF EXISTS load_test")
|
||||
|
||||
return success_rate > 90
|
||||
end
|
||||
|
||||
-- Запуск всех тестов
|
||||
local function run_all_tests()
|
||||
print("🚀 STARTING FULL TEST SUITE\n")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user