-- tests.lua - Комплексные тесты для СУБД futriix local test_utils = {} function test_utils.assert(condition, message) if not condition then error("TEST FAILED: " .. (message or "Assertion failed")) end end function test_utils.run_test(test_name, test_func) print("Running test: " .. test_name) local success, result = pcall(test_func) if success then print("✓ " .. test_name .. " - PASSED") return true else print("✗ " .. test_name .. " - FAILED: " .. result) return false end end -- 1. Регрессионный тест function regression_test() -- Проверяем, что базовые операции работают корректно create_space("regression_test_space") -- Тест создания документа local test_data = {name = "test", value = 42, tags = {"a", "b", "c"}} insert("regression_test_space", "doc1", json_encode(test_data)) -- Тест чтения local result = get("regression_test_space", "doc1") test_utils.assert(result ~= "null", "Document should exist") local parsed = json_decode(result) test_utils.assert(parsed.name == "test", "Name should match") test_utils.assert(parsed.value == 42, "Value should match") -- Тест обновления local update_data = {name = "updated", value = 100, new_field = "added"} update("regression_test_space", "doc1", json_encode(update_data)) local updated = json_decode(get("regression_test_space", "doc1")) test_utils.assert(updated.name == "updated", "Name should be updated") test_utils.assert(updated.new_field == "added", "New field should exist") -- Тест удаления delete("regression_test_space", "doc1") local deleted = get("regression_test_space", "doc1") test_utils.assert(deleted == "null", "Document should be deleted") -- Очистка delete_space("regression_test_space") return "Regression test completed successfully" end -- 2. Smoke-тест (проверка работоспособности) function smoke_test() -- Проверяем базовую функциональность системы test_utils.assert(pcall(create_space, "smoke_test_space"), "Should create space") test_utils.assert(pcall(delete_space, "smoke_test_space"), "Should delete space") -- Проверяем функции JSON local test_obj = {test = true, number = 123} local encoded = json_encode(test_obj) local decoded = json_decode(encoded) test_utils.assert(decoded.test == true, "JSON encode/decode should work") test_utils.assert(decoded.number == 123, "JSON numbers should work") -- Проверяем MD5 local hash = md5("test") test_utils.assert(type(hash) == "string", "MD5 should return string") test_utils.assert(#hash == 32, "MD5 hash should be 32 characters") return "Smoke test passed - system is operational" end -- 3. Unit-тест (тестирование отдельных функций) function unit_test_md5() -- Тестируем функцию MD5 хеширования local test_cases = { {"", "d41d8cd98f00b204e9800998ecf8427e"}, {"hello", "5d41402abc4b2a76b9719d911017c592"}, {"futriix", "3e8c8d2e7e7a6e8f7b6c8a9d0e1f2a3b"} -- пример хеша } for i, case in ipairs(test_cases) do local input, expected = case[1], case[2] local result = md5(input) test_utils.assert(result == expected, string.format("MD5('%s') should be '%s', got '%s'", input, expected, result)) end return "MD5 unit test passed" end function unit_test_json() -- Тестируем JSON функции local complex_obj = { string = "test", number = 42.5, boolean = true, array = {1, 2, 3}, nested = {key = "value"} } local encoded = json_encode(complex_obj) local decoded = json_decode(encoded) test_utils.assert(decoded.string == "test", "String should match") test_utils.assert(decoded.number == 42.5, "Number should match") test_utils.assert(decoded.boolean == true, "Boolean should match") test_utils.assert(#decoded.array == 3, "Array length should match") test_utils.assert(decoded.nested.key == "value", "Nested object should match") return "JSON unit test passed" end -- 4. Нагрузочный тест function load_test() local space_name = "load_test_space" create_space(space_name) local start_time = os.time() local operations_count = 100 -- Уменьшено для демонстрации -- Тест записи for i = 1, operations_count do local data = { id = i, timestamp = os.time(), data = string.rep("X", 100) -- 100 байт данных } insert(space_name, "key_" .. i, json_encode(data)) end -- Тест чтения for i = 1, operations_count do local result = get(space_name, "key_" .. i) test_utils.assert(result ~= "null", "Should read written data") end local end_time = os.time() local duration = end_time - start_time -- Очистка for i = 1, operations_count do delete(space_name, "key_" .. i) end delete_space(space_name) local ops_per_second = operations_count * 2 / duration -- запись + чтение return string.format("Load test completed: %d operations in %d seconds (%.2f ops/sec)", operations_count * 2, duration, ops_per_second) end -- 5. Интеграционный тест function integration_test() -- Тестируем взаимодействие различных компонентов create_space("users") create_space("profiles") -- Создаем пользователя с профилем local user_data = { username = "testuser", email = "test@example.com", password = md5("password123"), created_at = os.date() } local profile_data = { user_id = "testuser", full_name = "Test User", preferences = {theme = "dark", notifications = true} } insert("users", "testuser", json_encode(user_data)) insert("profiles", "testuser_profile", json_encode(profile_data)) -- Проверяем связность данных local user = json_decode(get("users", "testuser")) local profile = json_decode(get("profiles", "testuser_profile")) test_utils.assert(user.username == profile.user_id, "User ID should match") test_utils.assert(user.password == md5("password123"), "Password should be hashed") -- Тестируем транзакционность (имитация) local tx_id = "test_tx_" .. os.time() begin_transaction(tx_id) -- В реальной системе здесь были бы операции в транзакции print("Transaction started: " .. tx_id) -- Очистка delete("users", "testuser") delete("profiles", "testuser_profile") delete_space("users") delete_space("profiles") return "Integration test passed - components work together correctly" end -- 6. API тест function api_test() -- Тестируем API-подобные операции через быстрые команды -- (это имитация HTTP API вызовов) create_space("api_test_space") -- Имитация POST /document/space/key local post_data = {action = "create", data = {test = "value"}} insert("api_test_space", "api_doc", json_encode(post_data)) -- Имитация GET /document/space/key local get_result = get("api_test_space", "api_doc") test_utils.assert(get_result ~= "null", "API should retrieve document") local parsed_get = json_decode(get_result) test_utils.assert(parsed_get.action == "create", "API data should match") -- Имитация PUT /document/space/key local put_data = {action = "update", data = {test = "new_value"}} update("api_test_space", "api_doc", json_encode(put_data)) local updated = json_decode(get("api_test_space", "api_doc")) test_utils.assert(updated.action == "update", "API update should work") -- Имитация DELETE /document/space/key delete("api_test_space", "api_doc") test_utils.assert(get("api_test_space", "api_doc") == "null", "API delete should work") delete_space("api_test_space") return "API test passed - all HTTP verb simulations work correctly" end -- Главная функция запуска всех тестов function run_all_tests() print("=== Running futriix Database Tests ===\n") local tests = { {"Smoke Test", smoke_test}, {"Unit Test - MD5", unit_test_md5}, {"Unit Test - JSON", unit_test_json}, {"Regression Test", regression_test}, {"Integration Test", integration_test}, {"API Test", api_test}, {"Load Test", load_test} } local passed = 0 local total = #tests for _, test_info in ipairs(tests) do local test_name, test_func = test_info[1], test_info[2] if test_utils.run_test(test_name, test_func) then passed = passed + 1 end print() end print(string.format("=== Test Results: %d/%d passed ===", passed, total)) if passed == total then print(" ALL TESTS PASSED! ") return true else print("❌ SOME TESTS FAILED") return false end end -- Запуск тестов при прямом выполнении файла if arg and arg[0] and string.match(arg[0], "tests.lua") then run_all_tests() else print("futriix test library loaded. Call 'run_all_tests()' to execute tests.") end