-- tests/runtime_limits_test.lua -- Тестирование runtime-ограничений на размер коллекции и документа local function setup_limits_test() print("=== Setup Runtime Limits Test ===") db.execute("CREATE DATABASE IF NOT EXISTS limits_test") db.execute("USE limits_test") -- Устанавливаем тестовые ограничения db.execute([[ SET RUNTIME_LIMITS { global_max_doc_size_mb = 1, global_max_coll_size_mb = 10, global_max_docs_per_coll = 1000 } ]]) db.execute([[ CREATE COLLECTION IF NOT EXISTS test_collection ]]) return true end local function test_max_document_size() print("\n=== Test 1: Max Document Size ===") -- Создаём документ меньше лимита (0.5 MB) local small_doc = { _id = "small_doc", data = string.rep("x", 500 * 1024) -- 500KB } local success, err = pcall(function() return db.execute(string.format( "INSERT INTO test_collection VALUES (%s)", db.json_encode(small_doc) )) end) if success then print("✅ Small document (500KB) inserted successfully") else print("❌ Small document rejected: " .. tostring(err)) return false end -- Создаём документ больше лимита (2 MB) local large_doc = { _id = "large_doc", data = string.rep("x", 2 * 1024 * 1024) -- 2MB } success, err = pcall(function() return db.execute(string.format( "INSERT INTO test_collection VALUES (%s)", db.json_encode(large_doc) )) end) if not success and string.find(err or "", "exceeds limit") then print("✅ Large document (2MB) correctly rejected") return true else print("❌ Large document should have been rejected: " .. tostring(err)) return false end end local function test_max_collection_size() print("\n=== Test 2: Max Collection Size ===") local inserted = 0 local rejected = 0 for i = 1, 20 do -- Каждый документ ~1MB local doc = { _id = string.format("doc_%d", i), data = string.rep("x", 900 * 1024), -- 900KB index = i } local success, err = pcall(function() return db.execute(string.format( "INSERT INTO test_collection VALUES (%s)", db.json_encode(doc) )) end) if success then inserted = inserted + 1 print(string.format(" Inserted doc %d, total inserted: %d", i, inserted)) else rejected = rejected + 1 if string.find(err or "", "exceeds limit") then print(string.format(" Doc %d rejected: collection size limit reached", i)) end end end print(string.format("Final: %d inserted, %d rejected", inserted, rejected)) -- Должно быть вставлено не более 10 документов (~10MB) if inserted <= 11 and inserted >= 8 then print("✅ Collection size limit working correctly") return true else print(string.format("❌ Unexpected number of inserts: %d", inserted)) return false end end local function test_max_document_count() print("\n=== Test 3: Max Document Count ===") -- Создаём новую коллекцию для этого теста db.execute("CREATE COLLECTION IF NOT EXISTS count_test") -- Устанавливаем лимит в 50 документов db.execute([[ ALTER COLLECTION count_test SET LIMITS { max_documents = 50 } ]]) local inserted = 0 local rejected = 0 for i = 1, 60 do local doc = { _id = string.format("count_doc_%d", i), value = i } local success, err = pcall(function() return db.execute(string.format( "INSERT INTO count_test VALUES (%s)", db.json_encode(doc) )) end) if success then inserted = inserted + 1 else rejected = rejected + 1 end end print(string.format("Inserted: %d, Rejected: %d", inserted, rejected)) if inserted == 50 and rejected == 10 then print("✅ Document count limit working correctly") return true else print(string.format("❌ Expected 50 inserts, got %d", inserted)) return false end db.execute("DROP COLLECTION count_test") end local function test_collection_override_limits() print("\n=== Test 4: Collection Override Limits ===") -- Создаём коллекцию с собственными лимитами db.execute([[ CREATE COLLECTION override_test WITH LIMITS { max_doc_size_mb = 5, max_docs = 200 } ]]) -- Проверяем, что можно вставить 4MB документ local large_doc = { _id = "large_override", data = string.rep("y", 4 * 1024 * 1024) } local success, err = pcall(function() return db.execute(string.format( "INSERT INTO override_test VALUES (%s)", db.json_encode(large_doc) )) end) if not success then print("❌ Failed to insert 4MB document with 5MB limit: " .. tostring(err)) return false end print("✅ Collection override limits working correctly") db.execute("DROP COLLECTION override_test") return true end local function test_runtime_limits_metrics() print("\n=== Test 5: Runtime Limits Metrics ===") local metrics = db.execute("SHOW RUNTIME_LIMITS METRICS") local metrics_data = db.json_decode(metrics) print("Runtime limits metrics:") for key, value in pairs(metrics_data) do print(string.format(" %s: %s", key, tostring(value))) end local required_fields = { "rejected_by_size", "rejected_by_doc_count", "rejected_by_coll_size", "global_max_doc_size_mb", "global_max_coll_size_mb", "global_max_docs_per_coll", "enabled" } for _, field in ipairs(required_fields) do if metrics_data[field] == nil then print("❌ Missing metric: " .. field) return false end end print("✅ All required metrics present") return true end local function test_dynamic_limit_change() print("\n=== Test 6: Dynamic Limit Change ===") -- Создаём коллекцию db.execute("CREATE COLLECTION dynamic_test") -- Меняем лимиты динамически db.execute("ALTER COLLECTION dynamic_test SET LIMITS { max_docs = 10 }") -- Вставляем 10 документов for i = 1, 10 do db.execute(string.format( "INSERT INTO dynamic_test VALUES {_id = 'dyn_%d'}", i )) end -- Пытаемся вставить 11-й local success, err = pcall(function() return db.execute("INSERT INTO dynamic_test VALUES {_id = 'dyn_11'}") end) if success then print("❌ Should have rejected after dynamic limit change") return false end -- Увеличиваем лимит db.execute("ALTER COLLECTION dynamic_test SET LIMITS { max_docs = 20 }") -- Теперь 11-й должен пройти success, err = pcall(function() return db.execute("INSERT INTO dynamic_test VALUES {_id = 'dyn_11'}") end) if not success then print("❌ Should have accepted after limit increase") return false end print("✅ Dynamic limit change working correctly") db.execute("DROP COLLECTION dynamic_test") return true end local function cleanup_limits() print("\n=== Cleanup ===") db.execute("DROP DATABASE IF EXISTS limits_test") db.execute("SET RUNTIME_LIMITS DEFAULT") print("Cleanup completed") end local function run_all_runtime_limits_tests() print("╔══════════════════════════════════════════════════════════════╗") print("║ RUNTIME LIMITS TESTS SUITE ║") print("╚══════════════════════════════════════════════════════════════╝") setup_limits_test() local results = { test_max_document_size(), test_max_collection_size(), test_max_document_count(), test_collection_override_limits(), test_runtime_limits_metrics(), test_dynamic_limit_change() } print("\n╔══════════════════════════════════════════════════════════════╗") print("║ TEST RESULTS ║") print("╚══════════════════════════════════════════════════════════════╝") local passed = 0 for i, result in ipairs(results) do local status = result and "✅ PASSED" or "⚠️ SKIPPED/FAILED" print(string.format("Test %d: %s", i, status)) if result then passed = passed + 1 end end print(string.format("\nTotal: %d/%d tests passed", passed, #results)) cleanup_limits() return passed == #results end return run_all_runtime_limits_tests()