futr/tests/tests.lua

282 lines
9.8 KiB
Lua
Raw Permalink Normal View History

2025-11-18 21:36:13 +00:00
-- 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