-- 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") local test_modules = { {name = "AUTOSCALING", path = "autoscaling_test.lua"}, {name = "BACKPRESSURE", path = "backpressure_test.lua"}, {name = "RUNTIME_LIMITS", path = "runtime_limits_test.lua"}, {name = "BACKUP", path = "backup_test.lua"}, {name = "SCHEMA_MIGRATION", path = "schema_migration_test.lua"}, {name = "LOAD_TEST", path = nil, fn = run_load_test} } local results = {} for _, module in ipairs(test_modules) do print("\n" .. string.rep("=", 70)) print(string.format("▶️ RUNNING %s TESTS", module.name)) print(string.rep("=", 70)) local result if module.fn then result = module.fn() else -- Загружаем и выполняем тестовый модуль local chunk, err = loadfile(module.path) if chunk then local test_fn = chunk() result = test_fn() else print("❌ Failed to load test module: " .. tostring(err)) result = false end end table.insert(results, {name = module.name, passed = result}) end -- Итоговый отчёт print("\n" .. string.rep("=", 70)) print("🏁 FINAL TEST SUMMARY") print(string.rep("=", 70)) local passed_count = 0 for _, result in ipairs(results) do local status = result.passed and "✅ PASSED" or "❌ FAILED" print(string.format(" %-20s: %s", result.name, status)) if result.passed then passed_count = passed_count + 1 end end print(string.rep("-", 70)) print(string.format(" TOTAL: %d/%d tests passed", passed_count, #results)) print(string.rep("=", 70)) return passed_count == #results end -- Запуск return run_all_tests()