futr/tests/tests.lua

282 lines
9.8 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 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