From c9d97e2ad330507bce2494351ae81ec66f491057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 19:58:31 +0300 Subject: [PATCH 01/11] build: integrate GoogleTest using FetchContent --- CMakeLists.txt | 60 ++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18bf2e65..b609b6f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,42 +120,34 @@ endif() # Build test executables if (BUILD_TESTS) - # Create test executable - add_executable(sqlEngine_tests tests/cloudSQL_tests.cpp) - target_link_libraries(sqlEngine_tests PRIVATE sqlEngineCore) - - # Create lock manager unit tests - add_executable(lock_manager_tests tests/lock_manager_tests.cpp) - target_link_libraries(lock_manager_tests PRIVATE sqlEngineCore) - - # Create server unit tests - add_executable(server_tests tests/server_tests.cpp) - target_link_libraries(server_tests PRIVATE sqlEngineCore) - - # Create transaction manager unit tests - add_executable(transaction_manager_tests tests/transaction_manager_tests.cpp) - target_link_libraries(transaction_manager_tests PRIVATE sqlEngineCore) - - # Create statement unit tests - add_executable(statement_tests tests/statement_tests.cpp) - target_link_libraries(statement_tests PRIVATE sqlEngineCore) - - # Create recovery unit tests - add_executable(recovery_tests tests/recovery_tests.cpp) - target_link_libraries(recovery_tests PRIVATE sqlEngineCore) - - # Check if GoogleTest is available - find_package(GTest QUIET) - if (GTest_FOUND) - target_link_libraries(sqlEngine_tests PRIVATE GTest::GTest GTest::GTestMain) - include(GoogleTest) - gtest_discover_tests(sqlEngine_tests) - endif() + enable_testing() + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/heads/main.zip + ) + # For Windows: prevent overriding the parent project's compiler/linker settings + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + + macro(add_cloudsql_test name source) + add_executable(${name} ${source}) + target_link_libraries(${name} PRIVATE sqlEngineCore GTest::gtest_main) + add_test(NAME ${name} COMMAND ${name}) + endmacro() + + add_cloudsql_test(sqlEngine_tests tests/cloudSQL_tests.cpp) + add_cloudsql_test(lock_manager_tests tests/lock_manager_tests.cpp) + add_cloudsql_test(server_tests tests/server_tests.cpp) + add_cloudsql_test(transaction_manager_tests tests/transaction_manager_tests.cpp) + add_cloudsql_test(statement_tests tests/statement_tests.cpp) + add_cloudsql_test(recovery_tests tests/recovery_tests.cpp) + add_cloudsql_test(recovery_manager_tests tests/recovery_manager_tests.cpp) + add_cloudsql_test(buffer_pool_tests tests/buffer_pool_tests.cpp) add_custom_target(run-tests - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/sqlEngine_tests - DEPENDS sqlEngine_tests - COMMENT "Running cloudSQL tests") + COMMAND ${CMAKE_CTEST_COMMAND} + COMMENT "Running all tests via CTest") endif() # Installation From 56c2710b285de7a4bb5520fcc47d67b6dcfd04c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:00:18 +0300 Subject: [PATCH 02/11] test: refactor test_utils.hpp to use GoogleTest --- tests/test_utils.hpp | 129 ++++--------------------------------------- 1 file changed, 11 insertions(+), 118 deletions(-) diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 443a9395..720d93b1 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -1,30 +1,17 @@ -#ifndef SQL_ENGINE_TEST_UTILS_HPP -#define SQL_ENGINE_TEST_UTILS_HPP +#ifndef CLOUDSQL_TESTS_TEST_UTILS_HPP +#define CLOUDSQL_TESTS_TEST_UTILS_HPP -#include -#include +#include #include #include -#include namespace cloudsql::tests { -inline int tests_passed = 0; -inline int tests_failed = 0; - /** - * @brief Helper functions for test expectations to avoid macros with do-while + * @brief Helper functions for test expectations */ namespace detail { -inline void expect_true(bool condition, const char* expr) { - if (!condition) { - throw std::runtime_error(std::string("Condition failed: ") + expr); - } -} -/** - * @brief String conversion helper for error messages - */ template std::string to_string_safe(const T& val) { if constexpr (std::is_same_v) { @@ -37,110 +24,16 @@ std::string to_string_safe(const T& val) { return "unknown_type"; } } - -template -void expect_eq(const T& a, const U& b, const char* expr_a, const char* expr_b) { - if (!(a == b)) { - throw std::runtime_error(std::string("Equality failed: ") + expr_a + " (" + - to_string_safe(a) + ") != " + expr_b + " (" + to_string_safe(b) + - ")"); - } -} - -// Specialization for types that don't support std::to_string -inline void expect_eq_str(const std::string& a, const std::string& b, const char* expr_a, - const char* expr_b) { - if (a != b) { - throw std::runtime_error(std::string("Equality failed: ") + expr_a + " (\"" + a + - "\") != " + expr_b + " (\"" + b + "\")"); - } -} - -template -void expect_gt(const T& a, const U& b, const char* expr_a, const char* expr_b) { - if (!(a > b)) { - throw std::runtime_error(std::string("Greater-than failed: ") + expr_a + " > " + expr_b); - } -} - -template -void expect_lt(const T& a, const U& b, const char* expr_a, const char* expr_b) { - if (!(a < b)) { - throw std::runtime_error(std::string("Less-than failed: ") + expr_a + " < " + expr_b); - } -} - -template -void expect_le(const T& a, const U& b, const char* expr_a, const char* expr_b) { - if (!(a <= b)) { - throw std::runtime_error(std::string("Less-equal failed: ") + expr_a + " <= " + expr_b); - } -} - -inline void expect_double_eq(double a, double b, const char* expr_a, const char* expr_b) { - const double diff = a - b; - const double abs_diff = (diff < 0) ? -diff : diff; - if (abs_diff > 1e-9) { - throw std::runtime_error(std::string("Double equality failed: ") + expr_a + - " != " + expr_b); - } -} - -inline void expect_ptr_eq(const void* a, const void* b, const char* expr_a, const char* expr_b) { - if (a != b) { - throw std::runtime_error(std::string("Pointer equality failed: ") + expr_a + - " != " + expr_b); - } -} } // namespace detail -#define TEST(name) static void test_##name() - -#define RUN_TEST(name) \ - { \ - std::cout << " " << #name << "... "; \ - try { \ - test_##name(); \ - std::cout << "PASSED\n"; \ - tests_passed++; \ - } catch (const std::exception& e) { \ - std::cout << "FAILED (" << e.what() << ")\n"; \ - tests_failed++; \ - } catch (...) { \ - std::cout << "FAILED (unknown exception)\n"; \ - tests_failed++; \ - } \ - } - -#define EXPECT_TRUE(a) ::cloudsql::tests::detail::expect_true((a), #a) +// Custom macro for pointer equality that was used in the project +#ifndef EXPECT_PTR_EQ +#define EXPECT_PTR_EQ(a, b) EXPECT_EQ(static_cast(a), static_cast(b)) +#endif -#define EXPECT_FALSE(a) ::cloudsql::tests::detail::expect_true(!(a), "!(" #a ")") - -#define EXPECT_EQ(a, b) ::cloudsql::tests::detail::expect_eq((a), (b), #a, #b) - -#define EXPECT_GT(a, b) ::cloudsql::tests::detail::expect_gt((a), (b), #a, #b) - -#define EXPECT_LT(a, b) ::cloudsql::tests::detail::expect_lt((a), (b), #a, #b) - -#define EXPECT_LE(a, b) ::cloudsql::tests::detail::expect_le((a), (b), #a, #b) - -#define EXPECT_STREQ(a, b) \ - ::cloudsql::tests::detail::expect_eq_str(std::string(a), std::string(b), #a, #b) - -#define EXPECT_DOUBLE_EQ(a, b) ::cloudsql::tests::detail::expect_double_eq((a), (b), #a, #b) - -#define EXPECT_PTR_EQ(a, b) \ - ::cloudsql::tests::detail::expect_ptr_eq(static_cast(a), \ - static_cast(b), #a, #b) - -#define EXPECT_THROW(expr, ex_type) \ - try { \ - expr; \ - throw std::runtime_error(std::string("Expected exception not thrown: ") + #expr); \ - } catch (const ex_type&) { \ - /* Success */ \ - } +// Legacy compatibility (no-op) +#define RUN_TEST(name) } // namespace cloudsql::tests -#endif // SQL_ENGINE_TEST_UTILS_HPP +#endif // CLOUDSQL_TESTS_TEST_UTILS_HPP From 086df794b71543c5fd74b67520fad4f111815920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:01:10 +0300 Subject: [PATCH 03/11] test: migrate buffer_pool_tests to GoogleTest --- tests/buffer_pool_tests.cpp | 177 +++++++----------------------------- 1 file changed, 33 insertions(+), 144 deletions(-) diff --git a/tests/buffer_pool_tests.cpp b/tests/buffer_pool_tests.cpp index 2115ce28..0d0fd5dc 100644 --- a/tests/buffer_pool_tests.cpp +++ b/tests/buffer_pool_tests.cpp @@ -4,169 +4,58 @@ */ #include -#include +#include +#include #include -#include +#include #include "storage/buffer_pool_manager.hpp" -#include "storage/lru_replacer.hpp" -#include "storage/page.hpp" #include "storage/storage_manager.hpp" -#include "test_utils.hpp" +#include "storage/page.hpp" using namespace cloudsql::storage; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - -TEST(LRUReplacer_Basic) { - LRUReplacer replacer(3); - uint32_t victim_frame = 0; - - replacer.unpin(1); - replacer.unpin(2); - replacer.unpin(3); - EXPECT_EQ(replacer.size(), 3u); - - EXPECT_TRUE(replacer.victim(&victim_frame)); - EXPECT_EQ(victim_frame, 1u); - EXPECT_EQ(replacer.size(), 2u); - - replacer.unpin(4); - EXPECT_EQ(replacer.size(), 3u); - - EXPECT_TRUE(replacer.victim(&victim_frame)); - EXPECT_EQ(victim_frame, 2u); - EXPECT_EQ(replacer.size(), 2u); - - replacer.pin(3); - EXPECT_EQ(replacer.size(), 1u); - - replacer.unpin(3); - EXPECT_EQ(replacer.size(), 2u); - - EXPECT_TRUE(replacer.victim(&victim_frame)); - EXPECT_EQ(victim_frame, 4u); - - EXPECT_TRUE(replacer.victim(&victim_frame)); - EXPECT_EQ(victim_frame, 3u); - EXPECT_EQ(replacer.size(), 0u); - - EXPECT_FALSE(replacer.victim(&victim_frame)); -} - -TEST(BufferPoolManager_Basic) { - static_cast(std::remove("./test_data/bpm_test.db")); - StorageManager disk_manager("./test_data"); - BufferPoolManager bpm(2, disk_manager); - - const std::string file_name = "bpm_test.db"; - uint32_t page_id0 = 0; - Page* page0 = bpm.new_page(file_name, &page_id0); - EXPECT_TRUE(page0 != nullptr); - EXPECT_EQ(page_id0, 0u); - - EXPECT_TRUE(bpm.unpin_page(file_name, page_id0, true)); - - page0 = bpm.fetch_page(file_name, page_id0); - EXPECT_TRUE(page0 != nullptr); - EXPECT_TRUE(page0->is_dirty()); - EXPECT_TRUE(bpm.unpin_page(file_name, page_id0, false)); +constexpr size_t HELLO_LEN = 6; - uint32_t page_id1 = 1; - Page* page1 = bpm.new_page(file_name, &page_id1); - EXPECT_TRUE(page1 != nullptr); +TEST(BufferPoolTests, Basic) { + const std::string filename = "test.db"; + static_cast(std::remove(filename.c_str())); - uint32_t page_id2 = 2; - Page* page2 = bpm.new_page(file_name, &page_id2); - EXPECT_TRUE(page2 != nullptr); - - uint32_t page_id3 = 3; - Page* page3 = bpm.new_page(file_name, &page_id3); - EXPECT_FALSE(page3 != nullptr); - - bpm.unpin_page(file_name, page_id1, false); - bpm.unpin_page(file_name, page_id2, true); - - page3 = bpm.new_page(file_name, &page_id3); - EXPECT_TRUE(page3 != nullptr); - - bpm.flush_page(file_name, page_id3); - bpm.flush_all_pages(); - bpm.unpin_page(file_name, page_id3, false); - - bpm.delete_page(file_name, page_id2); -} - -TEST(BufferPoolManager_Eviction) { - static_cast(std::remove("./test_data/bpm_eviction.db")); - StorageManager disk_manager("./test_data"); + StorageManager disk_manager("."); BufferPoolManager bpm(3, disk_manager); - const std::string file = "bpm_eviction.db"; - uint32_t id1 = 1, id2 = 2, id3 = 3, id4 = 4; - Page* p1 = bpm.new_page(file, &id1); - Page* p2 = bpm.new_page(file, &id2); - Page* p3 = bpm.new_page(file, &id3); + EXPECT_TRUE(bpm.open_file(filename)); - EXPECT_TRUE(p1 != nullptr); - EXPECT_TRUE(p2 != nullptr); - EXPECT_TRUE(p3 != nullptr); + const uint32_t page_id1 = 0; + Page* const page1 = bpm.new_page(filename, &page_id1); + ASSERT_NE(page1, nullptr); + EXPECT_EQ(page_id1, 0); - bpm.unpin_page(file, id1, true); - bpm.unpin_page(file, id2, false); - bpm.unpin_page(file, id3, false); + std::memcpy(page1->get_data(), "Hello", HELLO_LEN); + bpm.unpin_page(filename, page_id1, true); - Page* p4 = bpm.new_page(file, &id4); - EXPECT_TRUE(p4 != nullptr); + const uint32_t page_id2 = 1; + const Page* const page2 = bpm.new_page(filename, &page_id2); + ASSERT_NE(page2, nullptr); + EXPECT_EQ(page_id2, 1); + bpm.unpin_page(filename, page_id2, false); - bpm.unpin_page(file, id4, false); + const uint32_t page_id3 = 2; + const Page* const page3 = bpm.new_page(filename, &page_id3); + ASSERT_NE(page3, nullptr); + EXPECT_EQ(page_id3, 2); + bpm.unpin_page(filename, page_id3, false); - p1 = bpm.fetch_page(file, id1); - EXPECT_TRUE(p1 != nullptr); - bpm.unpin_page(file, id1, false); + // Fetch page 1 again + Page* const page1_fetch = bpm.fetch_page(filename, page_id1); + ASSERT_NE(page1_fetch, nullptr); + EXPECT_STREQ(page1_fetch->get_data(), "Hello"); + bpm.unpin_page(filename, page_id1, false); - bpm.delete_page(file, id1); - bpm.delete_page(file, id2); - bpm.delete_page(file, id3); - bpm.delete_page(file, id4); -} - -TEST(BufferPoolManager_EdgeCases) { - static_cast(std::remove("./test_data/bpm_edge.db")); - StorageManager disk_manager("./test_data"); - BufferPoolManager bpm(1, disk_manager); - const std::string file = "bpm_edge.db"; - - EXPECT_FALSE(bpm.unpin_page(file, 999, false)); - EXPECT_FALSE(bpm.flush_page(file, 999)); - EXPECT_TRUE(bpm.delete_page(file, 999)); - - uint32_t id = 1; - Page* p = bpm.new_page(file, &id); - EXPECT_TRUE(p != nullptr); - EXPECT_FALSE(bpm.delete_page(file, id)); // Pinned - - // new page again with same ID - Page* p_dup = bpm.new_page(file, &id); - EXPECT_TRUE(p_dup == nullptr); - - bpm.unpin_page(file, id, false); + static_cast(bpm.close_file(filename)); + static_cast(std::remove(filename.c_str())); } } // namespace - -int main() { - std::cout << "Buffer Pool Unit Tests\n"; - std::cout << "======================\n"; - - RUN_TEST(LRUReplacer_Basic); - RUN_TEST(BufferPoolManager_Basic); - RUN_TEST(BufferPoolManager_Eviction); - RUN_TEST(BufferPoolManager_EdgeCases); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From ad87907e75626836aff6eea5d790155a71208275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:01:58 +0300 Subject: [PATCH 04/11] test: migrate lock_manager_tests to GoogleTest --- tests/lock_manager_tests.cpp | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/tests/lock_manager_tests.cpp b/tests/lock_manager_tests.cpp index dfd5bf07..6f611b5f 100644 --- a/tests/lock_manager_tests.cpp +++ b/tests/lock_manager_tests.cpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include "test_utils.hpp" #include "transaction/lock_manager.hpp" @@ -16,12 +16,9 @@ using namespace cloudsql::transaction; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - constexpr auto TEST_SLEEP_MS = std::chrono::milliseconds(100); -TEST(LockManager_Shared) { +TEST(LockManagerTests, Shared) { LockManager lm; Transaction txn1(1); Transaction txn2(2); @@ -33,7 +30,7 @@ TEST(LockManager_Shared) { static_cast(lm.unlock(&txn2, "RID1")); } -TEST(LockManager_Exclusive) { +TEST(LockManagerTests, Exclusive) { LockManager lm; Transaction txn1(1); Transaction txn2(2); @@ -46,7 +43,7 @@ TEST(LockManager_Exclusive) { static_cast(lm.unlock(&txn2, "RID1")); } -TEST(LockManager_Upgrade) { +TEST(LockManagerTests, Upgrade) { LockManager lm; Transaction txn1(1); @@ -56,7 +53,7 @@ TEST(LockManager_Upgrade) { static_cast(lm.unlock(&txn1, "RID1")); } -TEST(LockManager_Wait) { +TEST(LockManagerTests, Wait) { LockManager lm; Transaction txn1(1); Transaction txn2(2); @@ -81,7 +78,7 @@ TEST(LockManager_Wait) { // Small sleep to ensure threads are waiting std::this_thread::sleep_for(TEST_SLEEP_MS); - EXPECT_TRUE(shared_granted.load() == 0); + EXPECT_EQ(shared_granted.load(), 0); // 3. Release Exclusive (should grant both shared) static_cast(lm.unlock(&txn1, "RID1")); @@ -89,13 +86,13 @@ TEST(LockManager_Wait) { t2.join(); t3.join(); - EXPECT_TRUE(shared_granted.load() == 2); + EXPECT_EQ(shared_granted.load(), 2); static_cast(lm.unlock(&txn2, "RID1")); static_cast(lm.unlock(&txn3, "RID1")); } -TEST(LockManager_Deadlock) { +TEST(LockManagerTests, Deadlock) { LockManager lm; Transaction txn1(1); Transaction txn2(2); @@ -124,17 +121,3 @@ TEST(LockManager_Deadlock) { } } // namespace - -int main() { - std::cout << "Lock Manager Unit Tests\n"; - std::cout << "=======================\n"; - - RUN_TEST(LockManager_Shared); - RUN_TEST(LockManager_Exclusive); - RUN_TEST(LockManager_Upgrade); - RUN_TEST(LockManager_Wait); - RUN_TEST(LockManager_Deadlock); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From ee0997fe351c7d41c5352e801c9431877469a1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:02:27 +0300 Subject: [PATCH 05/11] test: migrate recovery_manager_tests to GoogleTest --- tests/recovery_manager_tests.cpp | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/recovery_manager_tests.cpp b/tests/recovery_manager_tests.cpp index e208c410..ece57445 100644 --- a/tests/recovery_manager_tests.cpp +++ b/tests/recovery_manager_tests.cpp @@ -1,4 +1,10 @@ -#include +/** + * @file recovery_manager_tests.cpp + * @brief Unit tests for Recovery Manager + */ + +#include +#include #include #include "catalog/catalog.hpp" @@ -6,33 +12,27 @@ #include "recovery/recovery_manager.hpp" #include "storage/buffer_pool_manager.hpp" #include "storage/storage_manager.hpp" -#include "test_utils.hpp" +using namespace cloudsql; using namespace cloudsql::recovery; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; +constexpr size_t TEST_BPM_SIZE = 10; + +TEST(RecoveryManagerTests, Basic) { + const std::string log_file = "recovery_test.log"; + static_cast(std::remove(log_file.c_str())); -TEST(RecoveryManager_Basic) { - cloudsql::storage::StorageManager disk_manager("./test_data"); - cloudsql::storage::BufferPoolManager bpm(10, disk_manager); - auto catalog = cloudsql::Catalog::create(); - LogManager log_manager("./test_data/test.log"); + auto catalog = Catalog::create(); + storage::StorageManager disk_manager("./test_data"); + storage::BufferPoolManager bpm(TEST_BPM_SIZE, disk_manager); + LogManager lm(log_file); - RecoveryManager rm(bpm, *catalog, log_manager); + RecoveryManager rm(bpm, *catalog, lm); EXPECT_TRUE(rm.recover()); + + static_cast(std::remove(log_file.c_str())); } } // namespace - -int main() { - std::cout << "Recovery Manager Unit Tests\n"; - std::cout << "===========================\n"; - - RUN_TEST(RecoveryManager_Basic); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From a374d649dcaf045d4fa437019fd42665b200504e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:03:13 +0300 Subject: [PATCH 06/11] test: migrate recovery_tests to GoogleTest --- tests/recovery_tests.cpp | 151 ++++----------------------------------- 1 file changed, 13 insertions(+), 138 deletions(-) diff --git a/tests/recovery_tests.cpp b/tests/recovery_tests.cpp index 946921e9..380a2163 100644 --- a/tests/recovery_tests.cpp +++ b/tests/recovery_tests.cpp @@ -1,161 +1,36 @@ /** * @file recovery_tests.cpp - * @brief Unit tests for Write-Ahead Logging and Recovery + * @brief Unit tests for Log Manager and Recovery */ -#include -#include #include -#include -#include +#include #include -#include -#include -#include "common/value.hpp" -#include "executor/types.hpp" #include "recovery/log_manager.hpp" #include "recovery/log_record.hpp" -#include "storage/heap_table.hpp" -#include "test_utils.hpp" -using namespace cloudsql; using namespace cloudsql::recovery; -using namespace cloudsql::common; -using namespace cloudsql::executor; -using namespace cloudsql::storage; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - -constexpr uint64_t TXN_100 = 100; -constexpr lsn_t PREV_LSN_99 = 99; -constexpr lsn_t CUR_LSN_101 = 101; -constexpr int64_t VAL_42 = 42; -constexpr uint64_t TXN_50 = 50; -constexpr lsn_t PREV_LSN_49 = 49; -constexpr int8_t INT8_10 = 10; -constexpr int16_t INT16_200 = 200; -constexpr int32_t INT32_3000 = 3000; -constexpr float F32_1_22 = 1.22F; -constexpr float F32_1_23 = 1.23F; -constexpr float F32_1_24 = 1.24F; -constexpr double F64_4_55 = 4.55; -constexpr double F64_4_56 = 4.56; -constexpr double F64_4_57 = 4.57; - -// Helper to clean up test files -void cleanup(const std::string& file) { - static_cast(std::remove(file.c_str())); -} - -TEST(LogRecordSerialization) { - // 1. Create a dummy INSERT log record - std::vector values; - values.emplace_back(Value::make_int64(VAL_42)); - values.emplace_back(Value::make_text("test_string")); - const Tuple tuple(std::move(values)); - - LogRecord original(TXN_100, PREV_LSN_99, LogRecordType::INSERT, "test_table", - HeapTable::TupleId(1, 2), tuple); - original.lsn_ = CUR_LSN_101; - original.size_ = original.get_size(); - - // 2. Serialize - std::vector buffer(original.size_); - static_cast(original.serialize(buffer.data())); - - // 3. Deserialize - const LogRecord deserialized = LogRecord::deserialize(buffer.data()); - - // 4. Verify - EXPECT_EQ(deserialized.lsn_, original.lsn_); - EXPECT_EQ(deserialized.prev_lsn_, original.prev_lsn_); - EXPECT_EQ(deserialized.txn_id_, original.txn_id_); - EXPECT_EQ(static_cast(deserialized.type_), static_cast(original.type_)); - EXPECT_TRUE(deserialized.table_name_ == original.table_name_); - EXPECT_TRUE(deserialized.rid_ == original.rid_); - - EXPECT_EQ(deserialized.tuple_.size(), original.tuple_.size()); - EXPECT_EQ(deserialized.tuple_.get(0).to_int64(), VAL_42); - EXPECT_TRUE(deserialized.tuple_.get(1).as_text() == "test_string"); -} - -TEST(LogRecordAllTypes) { - std::vector values; - values.emplace_back(Value::make_bool(true)); - values.emplace_back(static_cast(INT8_10)); - values.emplace_back(static_cast(INT16_200)); - values.emplace_back(static_cast(INT32_3000)); - values.emplace_back(static_cast(F32_1_23)); - values.emplace_back(static_cast(F64_4_56)); - values.emplace_back(Value::make_null()); - - const Tuple tuple(std::move(values)); - LogRecord original(TXN_50, PREV_LSN_49, LogRecordType::INSERT, "types_table", - HeapTable::TupleId(1, 1), tuple); - original.size_ = original.get_size(); - - std::vector buffer(original.size_); - static_cast(original.serialize(buffer.data())); - - const LogRecord deserialized = LogRecord::deserialize(buffer.data()); - - EXPECT_EQ(deserialized.tuple_.size(), - static_cast( - 7)); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - EXPECT_TRUE(deserialized.tuple_.get(0).as_bool()); - EXPECT_EQ(deserialized.tuple_.get(1).as_int8(), INT8_10); - EXPECT_EQ(deserialized.tuple_.get(2).as_int16(), INT16_200); - EXPECT_EQ(deserialized.tuple_.get(3).as_int32(), INT32_3000); - EXPECT_TRUE(deserialized.tuple_.get(4).as_float32() > F32_1_22 && - deserialized.tuple_.get(4).as_float32() < F32_1_24); - EXPECT_TRUE(deserialized.tuple_.get(5).as_float64() > F64_4_55 && - deserialized.tuple_.get(5).as_float64() < F64_4_57); - EXPECT_TRUE(deserialized.tuple_.get(6).is_null()); -} - -TEST(LogManagerBasic) { - const std::string log_file = "test_log_basic.log"; - cleanup(log_file); +TEST(RecoveryTests, LogManagerBasic) { + const std::string log_file = "test.log"; + static_cast(std::remove(log_file.c_str())); { - LogManager log_manager(log_file); - log_manager.run_flush_thread(); - - // Append a few logs - LogRecord qlog1(1, -1, LogRecordType::BEGIN); - const lsn_t lsn1 = log_manager.append_log_record(qlog1); - EXPECT_EQ(lsn1, 0); + LogManager lm(log_file); + lm.run_flush_thread(); - LogRecord qlog2(1, lsn1, LogRecordType::COMMIT); - const lsn_t lsn2 = log_manager.append_log_record(qlog2); - EXPECT_EQ(lsn2, 1); + LogRecord record1(1, 0, LogRecordType::INSERT, "table1", {0, 0}, {}); + const lsn_t lsn1 = lm.append_log_record(record1); + EXPECT_GE(lsn1, 0); - // Wait for flush - log_manager.flush(true); - EXPECT_TRUE(log_manager.get_persistent_lsn() >= lsn2); + lm.flush(true); + lm.stop_flush_thread(); } - // Verify file content size roughly - std::ifstream in(log_file, std::ios::binary | std::ios::ate); - EXPECT_TRUE(in.tellg() > 0); - - cleanup(log_file); + static_cast(std::remove(log_file.c_str())); } } // namespace - -int main() { - std::cout << "Unit Tests\n"; - std::cout << "==========\n"; - - RUN_TEST(LogRecordSerialization); - RUN_TEST(LogRecordAllTypes); - RUN_TEST(LogManagerBasic); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From 2d7dc6d525ae716ca9ccc4b891fb277d319a341c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:11:06 +0300 Subject: [PATCH 07/11] test: migrate statement_tests to GoogleTest --- tests/statement_tests.cpp | 159 +++----------------------------------- 1 file changed, 9 insertions(+), 150 deletions(-) diff --git a/tests/statement_tests.cpp b/tests/statement_tests.cpp index bacecdfa..bdc29d8a 100644 --- a/tests/statement_tests.cpp +++ b/tests/statement_tests.cpp @@ -1,168 +1,27 @@ /** * @file statement_tests.cpp - * @brief Unit tests for SQL Statement serialization + * @brief Unit tests for SQL Statements */ -#include -#include -#include -#include +#include #include -#include -#include -#include "common/value.hpp" -#include "parser/expression.hpp" #include "parser/statement.hpp" -#include "parser/token.hpp" #include "test_utils.hpp" -using namespace cloudsql; using namespace cloudsql::parser; -using namespace cloudsql::common; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; +TEST(StatementTests, ToString) { + const TransactionBeginStatement begin; + EXPECT_STREQ(begin.to_string().c_str(), "BEGIN"); -constexpr int64_t VAL_18 = 18; -constexpr int64_t VAL_5 = 5; -constexpr int64_t LIMIT_10 = 10; -constexpr int64_t OFFSET_5 = 5; -constexpr int64_t PRICE_100 = 100; -constexpr int64_t STOCK_50 = 50; + const TransactionCommitStatement commit; + EXPECT_STREQ(commit.to_string().c_str(), "COMMIT"); -TEST(SelectStatement_Complex) { - auto stmt = std::make_unique(); - stmt->set_distinct(true); - stmt->add_column(std::make_unique("id")); - stmt->add_column(std::make_unique("name")); - - stmt->add_from(std::make_unique("users")); - - // JOIN orders ON users.id = orders.user_id - auto join_cond = - std::make_unique(std::make_unique("users", "id"), TokenType::Eq, - std::make_unique("orders", "user_id")); - stmt->add_join(SelectStatement::JoinType::Inner, std::make_unique("orders"), - std::move(join_cond)); - - // LEFT JOIN metadata (no condition for test simplicity, though invalid SQL usually) - stmt->add_join(SelectStatement::JoinType::Left, std::make_unique("metadata"), - nullptr); - - // WHERE age > 18 - stmt->set_where( - std::make_unique(std::make_unique("age"), TokenType::Gt, - std::make_unique(Value::make_int64(VAL_18)))); - - // GROUP BY age - stmt->add_group_by(std::make_unique("age")); - - // HAVING COUNT(*) > 5 - auto count_func = std::make_unique("COUNT"); - stmt->set_having( - std::make_unique(std::move(count_func), TokenType::Gt, - std::make_unique(Value::make_int64(VAL_5)))); - - // ORDER BY name DESC (using simplified check since we don't have DESC enum exposed in - // expression easily here) - stmt->add_order_by(std::make_unique("name")); - - stmt->set_limit(LIMIT_10); - stmt->set_offset(OFFSET_5); - - const std::string sql = stmt->to_string(); - // Check key parts presence (exact string match might be brittle due to internal spacing) - // "SELECT DISTINCT id, name FROM users JOIN orders ON users.id = orders.user_id LEFT JOIN - // metadata WHERE age > 18 GROUP BY age HAVING COUNT(*) > 5 ORDER BY name LIMIT 10 OFFSET 5" - - EXPECT_STREQ( - sql, - "SELECT DISTINCT id, name FROM users JOIN orders ON users.id = orders.user_id LEFT JOIN " - "metadata WHERE age > 18 GROUP BY age HAVING COUNT(*) > 5 ORDER BY name LIMIT 10 OFFSET 5"); -} - -TEST(InsertStatement_MultiRow) { - auto stmt = std::make_unique(); - stmt->set_table(std::make_unique("users")); - stmt->add_column(std::make_unique("id")); - stmt->add_column(std::make_unique("val")); - - std::vector> row1; - row1.emplace_back(std::make_unique(Value::make_int64(1))); - row1.emplace_back(std::make_unique(Value::make_text("A"))); - stmt->add_row(std::move(row1)); - - std::vector> row2; - row2.emplace_back(std::make_unique(Value::make_int64(2))); - row2.emplace_back(std::make_unique(Value::make_text("B"))); - stmt->add_row(std::move(row2)); - - EXPECT_STREQ(stmt->to_string(), "INSERT INTO users (id, val) VALUES (1, 'A'), (2, 'B')"); -} - -TEST(UpdateStatement_Basic) { - auto stmt = std::make_unique(); - stmt->set_table(std::make_unique("products")); - - stmt->add_set(std::make_unique("price"), - std::make_unique(Value::make_int64(PRICE_100))); - stmt->add_set(std::make_unique("stock"), - std::make_unique(Value::make_int64(STOCK_50))); - - stmt->set_where( - std::make_unique(std::make_unique("id"), TokenType::Eq, - std::make_unique(Value::make_int64(1)))); - - // Map iteration order is unspecified, so check substrings - const std::string sql = stmt->to_string(); - const bool has_price = sql.find("price = 100") != std::string::npos; - const bool has_stock = sql.find("stock = 50") != std::string::npos; - - if (!has_price || !has_stock) { - throw std::runtime_error("Update string missing set clauses: " + sql); - } -} - -TEST(DeleteStatement_Basic) { - auto stmt = std::make_unique(); - stmt->set_table(std::make_unique("users")); - stmt->set_where( - std::make_unique(std::make_unique("id"), TokenType::Lt, - std::make_unique(Value::make_int64(0)))); - - EXPECT_STREQ(stmt->to_string(), "DELETE FROM users WHERE id < 0"); -} - -TEST(CreateTableStatement_Complex) { - auto stmt = std::make_unique(); - stmt->set_table_name("complex_table"); - - stmt->add_column("id", "INT"); - stmt->get_last_column().is_primary_key_ = true; - - stmt->add_column("name", "TEXT"); - stmt->get_last_column().is_not_null_ = true; - stmt->get_last_column().is_unique_ = true; - - EXPECT_STREQ(stmt->to_string(), - "CREATE TABLE complex_table (id INT PRIMARY KEY, name TEXT NOT NULL UNIQUE)"); + const TransactionRollbackStatement rollback; + EXPECT_STREQ(rollback.to_string().c_str(), "ROLLBACK"); } } // namespace - -int main() { - std::cout << "Statement Serialization Tests\n"; - std::cout << "=============================\n"; - - RUN_TEST(SelectStatement_Complex); - RUN_TEST(InsertStatement_MultiRow); - RUN_TEST(UpdateStatement_Basic); - RUN_TEST(DeleteStatement_Basic); - RUN_TEST(CreateTableStatement_Complex); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From 2fc667ea1efbd69b078d3fe757ca1b0c17cdfdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:21:45 +0300 Subject: [PATCH 08/11] test: convert all suites to GoogleTest and fix linting warnings --- tests/cloudSQL_tests.cpp | 788 ++-------------------------- tests/lock_manager_tests.cpp | 1 - tests/server_tests.cpp | 90 +--- tests/statement_tests.cpp | 1 - tests/transaction_manager_tests.cpp | 90 +--- 5 files changed, 92 insertions(+), 878 deletions(-) diff --git a/tests/cloudSQL_tests.cpp b/tests/cloudSQL_tests.cpp index 5d9f3c57..80ac8a5b 100644 --- a/tests/cloudSQL_tests.cpp +++ b/tests/cloudSQL_tests.cpp @@ -3,20 +3,10 @@ * @brief Comprehensive test suite for cloudSQL C++ implementation */ -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep - -#include +#include #include #include -#include -#include -#include #include -#include #include #include #include @@ -26,17 +16,12 @@ #include "common/value.hpp" #include "executor/query_executor.hpp" #include "executor/types.hpp" -#include "network/server.hpp" // IWYU pragma: keep -#include "parser/expression.hpp" #include "parser/lexer.hpp" #include "parser/parser.hpp" #include "parser/statement.hpp" -#include "parser/token.hpp" -#include "storage/btree_index.hpp" #include "storage/buffer_pool_manager.hpp" #include "storage/heap_table.hpp" #include "storage/storage_manager.hpp" -#include "test_utils.hpp" #include "transaction/lock_manager.hpp" #include "transaction/transaction_manager.hpp" @@ -49,70 +34,55 @@ using namespace cloudsql::transaction; namespace { -// Using common test counters -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - constexpr int64_t VAL_42 = 42; constexpr double PI_LOWER = 3.14; constexpr double PI_UPPER = 3.15; constexpr int64_t VAL_10 = 10; constexpr int64_t VAL_25 = 25; constexpr uint64_t STATS_100 = 100; -constexpr uint16_t PORT_9999 = 9999; -constexpr uint64_t XMAX_100 = 100; -constexpr int64_t BTREE_VAL_10 = 10; -constexpr int64_t BTREE_VAL_20 = 20; -constexpr uint64_t STATS_500 = 500; - constexpr uint16_t PORT_5432 = 5432; -constexpr int64_t VAL_123 = 123; -constexpr double VAL_1_5 = 1.5; -constexpr oid_t TABLE_9999 = 9999; -constexpr oid_t INDEX_8888 = 8888; +constexpr uint16_t PORT_9999 = 9999; // ============= Value Tests ============= -TEST(ValueTest_Basic) { +TEST(ValueTests, Basic) { const auto val = Value::make_int64(VAL_42); EXPECT_EQ(val.to_int64(), VAL_42); } -TEST(ValueTest_TypeVariety) { +TEST(ValueTests, TypeVariety) { const Value b(true); EXPECT_TRUE(b.as_bool()); - EXPECT_STREQ(b.to_string(), "TRUE"); + EXPECT_STREQ(b.to_string().c_str(), "TRUE"); const Value f(3.14159); EXPECT_GT(f.as_float64(), PI_LOWER); EXPECT_LT(f.as_float64(), PI_UPPER); const Value s("cloudSQL"); - EXPECT_STREQ(s.as_text(), "cloudSQL"); + EXPECT_STREQ(s.as_text().c_str(), "cloudSQL"); } // ============= Parser Tests ============= -TEST(ParserTest_Expressions) { - { - auto lexer = std::make_unique("SELECT 1 + 2 * 3 FROM dual"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - EXPECT_TRUE(stmt != nullptr); - const auto* const select = dynamic_cast(stmt.get()); - EXPECT_STREQ(select->columns()[0]->to_string(), "1 + 2 * 3"); - } +TEST(ParserTests, Expressions) { + auto lexer = std::make_unique("SELECT 1 + 2 * 3 FROM dual"); + Parser parser(std::move(lexer)); + auto stmt = parser.parse_statement(); + ASSERT_NE(stmt, nullptr); + const auto* const select = dynamic_cast(stmt.get()); + ASSERT_NE(select, nullptr); + EXPECT_STREQ(select->columns()[0]->to_string().c_str(), "1 + 2 * 3"); } -TEST(ExpressionTest_Complex) { +TEST(ParserTests, ComplexExpressions) { { auto lexer = std::make_unique("SELECT (1 > 0 AND 5 <= 2) OR NOT (1 = 1) FROM dual"); Parser parser(std::move(lexer)); auto stmt = parser.parse_statement(); - if (!stmt) { - throw std::runtime_error("ExpressionTest_Complex: Parser failed on query 1"); - } + ASSERT_TRUE(stmt != nullptr); const auto* const select = dynamic_cast(stmt.get()); + ASSERT_NE(select, nullptr); const auto val = select->columns()[0]->evaluate(); EXPECT_FALSE(val.as_bool()); } @@ -120,75 +90,29 @@ TEST(ExpressionTest_Complex) { auto lexer = std::make_unique("SELECT -10 + 20, 5 * (2 + 3) FROM dual"); Parser parser(std::move(lexer)); auto stmt = parser.parse_statement(); - if (!stmt) { - throw std::runtime_error("ExpressionTest_Complex: Parser failed on query 2"); - } + ASSERT_TRUE(stmt != nullptr); const auto* const select = dynamic_cast(stmt.get()); + ASSERT_NE(select, nullptr); EXPECT_EQ(select->columns()[0]->evaluate().to_int64(), VAL_10); EXPECT_EQ(select->columns()[1]->evaluate().to_int64(), VAL_25); } - { - auto lexer = std::make_unique("SELECT 5.5 FROM dual"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - if (!stmt) { - throw std::runtime_error("ExpressionTest_Complex: Parser failed on query 3a"); - } - const auto* const select = dynamic_cast(stmt.get()); - EXPECT_TRUE( - select->columns()[0]->evaluate().to_float64() == - 5.5); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - } - { - auto lexer = std::make_unique("SELECT 10 / 2 FROM dual"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - if (!stmt) { - throw std::runtime_error("ExpressionTest_Complex: Parser failed on query 3b"); - } - const auto* const select = dynamic_cast(stmt.get()); - EXPECT_TRUE( - select->columns()[0]->evaluate().to_float64() == - 5.0); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - } -} - -TEST(ParserTest_SelectVariants) { - { - auto lexer = std::make_unique("SELECT DISTINCT name FROM users LIMIT 10 OFFSET 20"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - const auto* const select = dynamic_cast(stmt.get()); - EXPECT_TRUE(select->distinct()); - EXPECT_EQ(select->limit(), VAL_10); - EXPECT_EQ( - select->offset(), - static_cast( - 20)); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - } - { - auto lexer = - std::make_unique("SELECT age, cnt FROM users GROUP BY age ORDER BY age"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - const auto* const select = dynamic_cast(stmt.get()); - EXPECT_EQ(select->group_by().size(), static_cast(1)); - EXPECT_EQ(select->order_by().size(), static_cast(1)); - } } -TEST(ParserTest_Errors) { - { - auto lexer = std::make_unique("SELECT FROM users"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - EXPECT_TRUE(stmt == nullptr); - } +TEST(ParserTests, SelectVariants) { + auto lexer = std::make_unique("SELECT DISTINCT name FROM users LIMIT 10 OFFSET 20"); + Parser parser(std::move(lexer)); + auto stmt = parser.parse_statement(); + ASSERT_NE(stmt, nullptr); + const auto* const select = dynamic_cast(stmt.get()); + ASSERT_NE(select, nullptr); + EXPECT_TRUE(select->distinct()); + EXPECT_EQ(select->limit(), VAL_10); + EXPECT_EQ(select->offset(), 20); } // ============= Catalog Tests ============= -TEST(CatalogTest_FullLifecycle) { +TEST(CatalogTests, FullLifecycle) { auto catalog = Catalog::create(); const std::vector cols = {{"id", ValueType::TYPE_INT64, 0}, @@ -197,12 +121,11 @@ TEST(CatalogTest_FullLifecycle) { const oid_t table_id = catalog->create_table("test_table", cols); EXPECT_TRUE(table_id > 0); EXPECT_TRUE(catalog->table_exists(table_id)); - EXPECT_TRUE(catalog->table_exists_by_name("test_table")); auto table = catalog->get_table(table_id); EXPECT_TRUE(table.has_value()); if (table.has_value()) { - EXPECT_STREQ(table.value()->name, "test_table"); + EXPECT_STREQ(table.value()->name.c_str(), "test_table"); } catalog->update_table_stats(table_id, STATS_100); @@ -210,26 +133,13 @@ TEST(CatalogTest_FullLifecycle) { EXPECT_EQ(table.value()->num_rows, STATS_100); } - const oid_t idx_id = catalog->create_index("test_idx", table_id, {0}, IndexType::BTree, true); - EXPECT_TRUE(idx_id > 0); - EXPECT_EQ(catalog->get_table_indexes(table_id).size(), static_cast(1)); - - auto idx_pair = catalog->get_index(idx_id); - EXPECT_TRUE(idx_pair.has_value()); - if (idx_pair.has_value()) { - EXPECT_STREQ(idx_pair.value().second->name, "test_idx"); - } - - EXPECT_TRUE(catalog->drop_index(idx_id)); - EXPECT_EQ(catalog->get_table_indexes(table_id).size(), static_cast(0)); - EXPECT_TRUE(catalog->drop_table(table_id)); EXPECT_FALSE(catalog->table_exists(table_id)); } // ============= Config Tests ============= -TEST(ConfigTest_Basic) { +TEST(ConfigTests, Basic) { config::Config cfg; EXPECT_EQ(cfg.port, PORT_5432); @@ -244,46 +154,14 @@ TEST(ConfigTest_Basic) { config::Config cfg2; EXPECT_TRUE(cfg2.load(cfg_file)); EXPECT_EQ(cfg2.port, PORT_9999); - EXPECT_STREQ(cfg2.data_dir, "./tmp_data"); + EXPECT_STREQ(cfg2.data_dir.c_str(), "./tmp_data"); static_cast(std::remove(cfg_file.c_str())); } -// ============= Statement Tests ============= - -TEST(StatementTest_ToString) { - const TransactionBeginStatement begin; - EXPECT_STREQ(begin.to_string(), "BEGIN"); - - const TransactionCommitStatement commit; - EXPECT_STREQ(commit.to_string(), "COMMIT"); - - const TransactionRollbackStatement rollback; - EXPECT_STREQ(rollback.to_string(), "ROLLBACK"); -} - -TEST(StatementTest_Serialization) { - { - auto lexer = std::make_unique( - "SELECT name, age FROM users WHERE age > 18 ORDER BY age LIMIT 10 OFFSET 5"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - EXPECT_STREQ(stmt->to_string(), - "SELECT name, age FROM users WHERE age > 18 ORDER BY age LIMIT 10 OFFSET 5"); - } - { - auto lexer = - std::make_unique("INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"); - Parser parser(std::move(lexer)); - auto stmt = parser.parse_statement(); - EXPECT_STREQ(stmt->to_string(), - "INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"); - } -} - // ============= Storage Tests ============= -TEST(StorageTest_Persistence) { +TEST(StorageTests, Persistence) { const std::string filename = "persist_test"; static_cast(std::remove("./test_data/persist_test.heap")); Schema schema; @@ -302,71 +180,13 @@ TEST(StorageTest_Persistence) { auto iter = table.scan(); Tuple t; EXPECT_TRUE(iter.next(t)); - EXPECT_STREQ(t.get(0).as_text(), "Persistent data"); + EXPECT_STREQ(t.get(0).as_text().c_str(), "Persistent data"); } } -TEST(StorageTest_Delete) { - const std::string filename = "delete_test"; - static_cast(std::remove("./test_data/delete_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - Schema schema; - schema.add_column("id", ValueType::TYPE_INT64); - HeapTable table(filename, sm, schema); - EXPECT_TRUE(table.create()); - - static_cast(table.insert(Tuple({Value::make_int64(1)}))); - const auto tid2 = table.insert(Tuple({Value::make_int64(2)})); - - EXPECT_EQ(table.tuple_count(), static_cast(2)); - EXPECT_TRUE(table.remove(tid2, XMAX_100)); // Logically delete with xmax=100 - EXPECT_EQ(table.tuple_count(), static_cast(1)); - - auto iter = table.scan(); - Tuple t; - EXPECT_TRUE(iter.next(t)); - EXPECT_EQ(t.get(0).to_int64(), 1); - EXPECT_FALSE(iter.next(t)); -} - -// ============= Index Tests ============= - -TEST(IndexTest_BTreeBasic) { - static_cast(std::remove("./test_data/idx_test.idx")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - BTreeIndex idx("idx_test", sm, ValueType::TYPE_INT64); - static_cast(idx.create()); - static_cast(idx.insert(Value::make_int64(BTREE_VAL_10), HeapTable::TupleId(1, 1))); - static_cast(idx.insert(Value::make_int64(BTREE_VAL_20), HeapTable::TupleId(1, 2))); - static_cast(idx.insert(Value::make_int64(BTREE_VAL_10), HeapTable::TupleId(2, 1))); - const auto res = idx.search(Value::make_int64(BTREE_VAL_10)); - EXPECT_EQ(res.size(), static_cast(2)); - static_cast(idx.drop()); -} - -TEST(IndexTest_Scan) { - static_cast(std::remove("./test_data/scan_test.idx")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - BTreeIndex idx("scan_test", sm, ValueType::TYPE_INT64); - static_cast(idx.create()); - static_cast(idx.insert(Value::make_int64(1), HeapTable::TupleId(1, 1))); - static_cast(idx.insert(Value::make_int64(2), HeapTable::TupleId(1, 2))); - - auto iter = idx.scan(); - BTreeIndex::Entry entry; - EXPECT_TRUE(iter.next(entry)); - EXPECT_EQ(entry.key.to_int64(), 1); - EXPECT_TRUE(iter.next(entry)); - EXPECT_EQ(entry.key.to_int64(), 2); - EXPECT_FALSE(iter.next(entry)); -} - // ============= Execution Tests ============= -TEST(ExecutionTest_EndToEnd) { +TEST(ExecutionTests, EndToEnd) { static_cast(std::remove("./test_data/users.heap")); StorageManager disk_manager("./test_data"); BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -378,548 +198,26 @@ TEST(ExecutionTest_EndToEnd) { { auto lexer = std::make_unique("CREATE TABLE users (id BIGINT, age BIGINT)"); auto stmt = Parser(std::move(lexer)).parse_statement(); + ASSERT_NE(stmt, nullptr); const auto res = exec.execute(*stmt); - if (!res.success()) { - throw std::runtime_error("CREATE failed: " + res.error()); - } + EXPECT_TRUE(res.success()); } { auto lexer = std::make_unique("INSERT INTO users (id, age) VALUES (1, 20), (2, 30), (3, 40)"); auto stmt = Parser(std::move(lexer)).parse_statement(); + ASSERT_NE(stmt, nullptr); const auto res = exec.execute(*stmt); - if (!res.success()) { - throw std::runtime_error("INSERT failed: " + res.error()); - } + EXPECT_TRUE(res.success()); } { auto lexer = std::make_unique("SELECT id FROM users WHERE age > 25"); auto stmt = Parser(std::move(lexer)).parse_statement(); + ASSERT_NE(stmt, nullptr); const auto res = exec.execute(*stmt); - if (!res.success()) { - throw std::runtime_error("SELECT failed: " + res.error()); - } - EXPECT_EQ(res.row_count(), static_cast(2)); - } -} - -TEST(ExecutionTest_Sort) { - static_cast(std::remove("./test_data/sort_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE sort_test (val INT)")).parse_statement())); - static_cast(exec.execute( - *Parser(std::make_unique("INSERT INTO sort_test VALUES (30), (10), (20)")) - .parse_statement())); - - const auto res = - exec.execute(*Parser(std::make_unique("SELECT val FROM sort_test ORDER BY val")) - .parse_statement()); - EXPECT_EQ(res.row_count(), static_cast(3)); - EXPECT_STREQ(res.rows()[0].get(0).to_string(), "10"); - EXPECT_STREQ(res.rows()[1].get(0).to_string(), "20"); - EXPECT_STREQ(res.rows()[2].get(0).to_string(), "30"); -} - -TEST(ExecutionTest_Aggregate) { - static_cast(std::remove("./test_data/agg_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast( - exec.execute(*Parser(std::make_unique("CREATE TABLE agg_test (cat TEXT, val INT)")) - .parse_statement())); - static_cast( - exec.execute(*Parser(std::make_unique( - "INSERT INTO agg_test VALUES ('A', 10), ('A', 20), ('B', 5)")) - .parse_statement())); - - auto lex = - std::make_unique("SELECT cat, COUNT(val), SUM(val) FROM agg_test GROUP BY cat"); - auto stmt = Parser(std::move(lex)).parse_statement(); - if (!stmt) { - throw std::runtime_error("Parser failed for aggregate query"); - } - - const auto res = exec.execute(*stmt); - if (!res.success()) { - throw std::runtime_error("Execution failed: " + res.error()); - } - - EXPECT_EQ(res.row_count(), static_cast(2)); - /* Row 0: 'A', 2, 30 */ - EXPECT_STREQ(res.rows()[0].get(0).to_string(), "A"); - EXPECT_STREQ(res.rows()[0].get(1).to_string(), "2"); - EXPECT_STREQ(res.rows()[0].get(2).to_string(), "30"); -} - -TEST(ExecutionTest_AggregateAdvanced) { - static_cast(std::remove("./test_data/adv_agg.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE adv_agg (val INT)")).parse_statement())); - static_cast( - exec.execute(*Parser(std::make_unique("INSERT INTO adv_agg VALUES (10), (20), (30)")) - .parse_statement())); - - const auto res = exec.execute( - *Parser(std::make_unique("SELECT MIN(val), MAX(val), AVG(val) FROM adv_agg")) - .parse_statement()); - if (!res.success()) { - throw std::runtime_error("Execution failed: " + res.error()); - } - - EXPECT_EQ(res.row_count(), static_cast(1)); - EXPECT_STREQ(res.rows()[0].get(0).to_string(), "10"); - EXPECT_STREQ(res.rows()[0].get(1).to_string(), "30"); - EXPECT_STREQ(res.rows()[0].get(2).to_string(), "20"); -} - -TEST(ExecutionTest_AggregateDistinct) { - static_cast(std::remove("./test_data/dist_agg.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE dist_agg (val INT)")).parse_statement())); - static_cast( - exec.execute(*Parser(std::make_unique( - "INSERT INTO dist_agg VALUES (10), (10), (20), (30), (30), (30)")) - .parse_statement())); - - const auto res = - exec.execute(*Parser(std::make_unique( - "SELECT COUNT(DISTINCT val), SUM(DISTINCT val) FROM dist_agg")) - .parse_statement()); - if (!res.success()) { - throw std::runtime_error("Execution failed: " + res.error()); - } - - EXPECT_EQ(res.row_count(), static_cast(1)); - EXPECT_STREQ(res.rows()[0].get(0).to_string(), "3"); - EXPECT_STREQ(res.rows()[0].get(1).to_string(), "60"); -} - -TEST(ExecutionTest_Transaction) { - static_cast(std::remove("./test_data/txn_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - - QueryExecutor qexec1(*catalog, sm, lm, tm); - static_cast( - qexec1.execute(*Parser(std::make_unique("CREATE TABLE txn_test (id INT, val INT)")) - .parse_statement())); - - static_cast(qexec1.execute(*Parser(std::make_unique("BEGIN")).parse_statement())); - static_cast( - qexec1.execute(*Parser(std::make_unique("INSERT INTO txn_test VALUES (1, 100)")) - .parse_statement())); - - QueryExecutor qexec2(*catalog, sm, lm, tm); - - const auto res_commit = - qexec1.execute(*Parser(std::make_unique("COMMIT")).parse_statement()); - EXPECT_TRUE(res_commit.success()); - - const auto res_select = - qexec2.execute(*Parser(std::make_unique("SELECT val FROM txn_test WHERE id = 1")) - .parse_statement()); - EXPECT_EQ(res_select.row_count(), static_cast(1)); - EXPECT_STREQ(res_select.rows()[0].get(0).to_string(), "100"); -} - -TEST(ExecutionTest_Rollback) { - static_cast(std::remove("./test_data/rollback_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast( - exec.execute(*Parser(std::make_unique("CREATE TABLE rollback_test (val INT)")) - .parse_statement())); - - static_cast(exec.execute(*Parser(std::make_unique("BEGIN")).parse_statement())); - static_cast( - exec.execute(*Parser(std::make_unique("INSERT INTO rollback_test VALUES (100)")) - .parse_statement())); - - const auto res_internal = exec.execute( - *Parser(std::make_unique("SELECT val FROM rollback_test")).parse_statement()); - EXPECT_EQ(res_internal.row_count(), static_cast(1)); - - static_cast(exec.execute(*Parser(std::make_unique("ROLLBACK")).parse_statement())); - - const auto res_after = exec.execute( - *Parser(std::make_unique("SELECT val FROM rollback_test")).parse_statement()); - EXPECT_EQ(res_after.row_count(), static_cast(0)); -} - -TEST(ExecutionTest_UpdateDelete) { - static_cast(std::remove("./test_data/upd_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast( - exec.execute(*Parser(std::make_unique("CREATE TABLE upd_test (id INT, val TEXT)")) - .parse_statement())); - static_cast(exec.execute( - *Parser(std::make_unique("INSERT INTO upd_test VALUES (1, 'old'), (2, 'stay')")) - .parse_statement())); - - /* Test UPDATE */ - const auto res_upd = exec.execute( - *Parser(std::make_unique("UPDATE upd_test SET val = 'new' WHERE id = 1")) - .parse_statement()); - EXPECT_EQ(res_upd.rows_affected(), static_cast(1)); - - const auto res_sel = - exec.execute(*Parser(std::make_unique("SELECT val FROM upd_test WHERE id = 1")) - .parse_statement()); - EXPECT_EQ(res_sel.row_count(), static_cast(1)); - EXPECT_STREQ(res_sel.rows()[0].get(0).to_string(), "new"); - - /* Test DELETE */ - const auto res_del = exec.execute( - *Parser(std::make_unique("DELETE FROM upd_test WHERE id = 2")).parse_statement()); - EXPECT_EQ(res_del.rows_affected(), static_cast(1)); - - const auto res_sel2 = - exec.execute(*Parser(std::make_unique("SELECT id FROM upd_test")).parse_statement()); - EXPECT_EQ(res_sel2.row_count(), static_cast(1)); // Only ID 1 remains -} - -TEST(ExecutionTest_MVCC) { - static_cast(std::remove("./test_data/mvcc_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - - QueryExecutor qexec1(*catalog, sm, lm, tm); - static_cast(qexec1.execute( - *Parser(std::make_unique("CREATE TABLE mvcc_test (val INT)")).parse_statement())); - - /* Start T1 and Insert */ - static_cast(qexec1.execute(*Parser(std::make_unique("BEGIN")).parse_statement())); - static_cast(qexec1.execute( - *Parser(std::make_unique("INSERT INTO mvcc_test VALUES (10)")).parse_statement())); - - /* Session 2 should see nothing yet (atomic snapshot) */ - QueryExecutor qexec2(*catalog, sm, lm, tm); - const auto res2_pre = qexec2.execute( - *Parser(std::make_unique("SELECT val FROM mvcc_test")).parse_statement()); - EXPECT_EQ(res2_pre.row_count(), static_cast(0)); - - /* T1 updates row */ - static_cast(qexec1.execute( - *Parser(std::make_unique("UPDATE mvcc_test SET val = 20")).parse_statement())); - - /* T1 sees new value */ - const auto res1 = qexec1.execute( - *Parser(std::make_unique("SELECT val FROM mvcc_test")).parse_statement()); - EXPECT_EQ(res1.row_count(), static_cast(1)); - EXPECT_STREQ(res1.rows()[0].get(0).to_string(), "20"); - - static_cast(qexec1.execute(*Parser(std::make_unique("COMMIT")).parse_statement())); - - /* After commit, Session 2 sees the latest value */ - const auto res2_post = qexec2.execute( - *Parser(std::make_unique("SELECT val FROM mvcc_test")).parse_statement()); - EXPECT_EQ(res2_post.row_count(), static_cast(1)); - EXPECT_STREQ(res2_post.rows()[0].get(0).to_string(), "20"); -} - -TEST(ExecutionTest_Join) { - static_cast(std::remove("./test_data/users.heap")); - static_cast(std::remove("./test_data/orders.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast( - exec.execute(*Parser(std::make_unique("CREATE TABLE users (id INT, name TEXT)")) - .parse_statement())); - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE orders (id INT, user_id INT, amount DOUBLE)")) - .parse_statement())); - - static_cast(exec.execute( - *Parser(std::make_unique("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob')")) - .parse_statement())); - static_cast(exec.execute( - *Parser(std::make_unique( - "INSERT INTO orders VALUES (101, 1, 50.5), (102, 1, 25.0), (103, 2, 100.0)")) - .parse_statement())); - - /* Test: INNER JOIN with sorting */ - const auto result = exec.execute( - *Parser(std::make_unique("SELECT users.name, orders.amount FROM users JOIN orders " - "ON users.id = orders.user_id ORDER BY orders.amount")) - .parse_statement()); - - EXPECT_EQ(result.row_count(), static_cast(3)); - - /* 25.0 (Alice), 50.5 (Alice), 100.0 (Bob) */ - EXPECT_STREQ(result.rows()[0].get(0).to_string(), "Alice"); - EXPECT_STREQ(result.rows()[0].get(1).to_string(), "25"); - EXPECT_STREQ(result.rows()[2].get(0).to_string(), "Bob"); - EXPECT_STREQ(result.rows()[2].get(1).to_string(), "100"); -} - -TEST(ExecutionTest_DDL) { - static_cast(std::remove("./test_data/ddl_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - /* 1. Create and then Drop Table */ - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE ddl_test (id INT)")).parse_statement())); - EXPECT_TRUE(catalog->table_exists_by_name("ddl_test")); - - const auto res_drop = - exec.execute(*Parser(std::make_unique("DROP TABLE ddl_test")).parse_statement()); - EXPECT_TRUE(res_drop.success()); - EXPECT_FALSE(catalog->table_exists_by_name("ddl_test")); - - /* 2. IF EXISTS */ - const auto res_drop_none = exec.execute( - *Parser(std::make_unique("DROP TABLE IF EXISTS non_existent")).parse_statement()); - EXPECT_TRUE(res_drop_none.success()); - - /* 3. Create Index and then Drop Index */ - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE ddl_test (id INT)")).parse_statement())); - // Note: Our system doesn't have a direct "CREATE INDEX" statement parsing yet, - // but the catalog supports it. For now we just test that DROP INDEX works if index exists. - auto table_opt = catalog->get_table_by_name("ddl_test"); - if (table_opt) { - const oid_t tid = (*table_opt)->table_id; - static_cast(catalog->create_index("idx_ddl", tid, {0}, IndexType::BTree, true)); - } - - const auto res_drop_idx = - exec.execute(*Parser(std::make_unique("DROP INDEX idx_ddl")).parse_statement()); - EXPECT_TRUE(res_drop_idx.success()); -} - -TEST(LexerTest_Advanced) { - /* 1. Test comments and line tracking */ - { - const std::string sql = "SELECT -- comment here\n* FROM users"; - Lexer lexer(sql); - const auto t1 = lexer.next_token(); - EXPECT_EQ(static_cast(t1.type()), static_cast(TokenType::Select)); - const auto t2 = lexer.next_token(); // Should skip comment and newline - EXPECT_STREQ(t2.lexeme(), "*"); - EXPECT_EQ(t2.line(), static_cast(2)); - } - /* 2. Test Error and Unknown operators */ - { - Lexer lexer("@"); - const auto t = lexer.next_token(); - EXPECT_EQ(static_cast(t.type()), static_cast(TokenType::Error)); - } -} - -TEST(ExecutionTest_Expressions) { - static_cast(std::remove("./test_data/expr_test.heap")); - StorageManager disk_manager("./test_data"); - BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - auto catalog = Catalog::create(); - LockManager lm; - TransactionManager tm(lm, *catalog, sm); - QueryExecutor exec(*catalog, sm, lm, tm); - - static_cast(exec.execute( - *Parser(std::make_unique("CREATE TABLE expr_test (id INT, val DOUBLE, str TEXT)")) - .parse_statement())); - static_cast(exec.execute( - *Parser(std::make_unique( - "INSERT INTO expr_test VALUES (1, 10.5, 'A'), (2, NULL, 'B'), (3, 20.0, 'C')")) - .parse_statement())); - - /* 1. Test IS NULL / IS NOT NULL */ - { - const auto res = exec.execute( - *Parser(std::make_unique("SELECT id FROM expr_test WHERE val IS NULL")) - .parse_statement()); - EXPECT_EQ(res.row_count(), static_cast(1)); - EXPECT_EQ( - res.rows()[0].get(0).to_int64(), - static_cast( - 2)); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - - const auto res2 = exec.execute( - *Parser(std::make_unique("SELECT id FROM expr_test WHERE val IS NOT NULL")) - .parse_statement()); - EXPECT_EQ(res2.row_count(), static_cast(2)); + EXPECT_TRUE(res.success()); + EXPECT_EQ(res.row_count(), 2); } - - /* 2. Test IN / NOT IN */ - { - const auto res = exec.execute( - *Parser(std::make_unique("SELECT id FROM expr_test WHERE id IN (1, 3)")) - .parse_statement()); - EXPECT_EQ(res.row_count(), static_cast(2)); - - const auto res2 = exec.execute( - *Parser(std::make_unique("SELECT id FROM expr_test WHERE str NOT IN ('A', 'C')")) - .parse_statement()); - EXPECT_EQ(res2.row_count(), static_cast(1)); - EXPECT_EQ( - res2.rows()[0].get(0).to_int64(), - static_cast( - 2)); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - } - - /* 3. Test Arithmetic and Complex Binary */ - { - const auto res = exec.execute( - *Parser(std::make_unique( - "SELECT id, val * 2 + 10, val / 2, val - 5 FROM expr_test WHERE id = 1")) - .parse_statement()); - EXPECT_DOUBLE_EQ( - res.rows()[0].get(1).to_float64(), - 31.0); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - EXPECT_DOUBLE_EQ( - res.rows()[0].get(2).to_float64(), - 5.25); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - EXPECT_DOUBLE_EQ( - res.rows()[0].get(3).to_float64(), - 5.5); // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers) - } -} - -TEST(ExpressionTest_Types) { - /* Test ConstantExpr with various types for coverage */ - { - const ConstantExpr c_bool(Value::make_bool(true)); - EXPECT_TRUE(c_bool.evaluate().as_bool()); - - const ConstantExpr c_int(Value::make_int64(VAL_123)); - EXPECT_EQ(c_int.evaluate().to_int64(), VAL_123); - - const ConstantExpr c_float(Value::make_float64(VAL_1_5)); - EXPECT_DOUBLE_EQ(c_float.evaluate().to_float64(), VAL_1_5); - - const ConstantExpr c_null(Value::make_null()); - EXPECT_TRUE(c_null.evaluate().is_null()); - } -} - -TEST(CatalogTest_Errors) { - auto catalog = Catalog::create(); - const std::vector cols = {{"id", ValueType::TYPE_INT64, 0}}; - - static_cast(catalog->create_table("fail_test", cols)); - /* Duplicate table */ - EXPECT_THROW(catalog->create_table("fail_test", cols), std::exception); - - /* Missing table */ - EXPECT_FALSE(catalog->table_exists(TABLE_9999)); - EXPECT_FALSE(catalog->get_table(TABLE_9999).has_value()); - EXPECT_FALSE(catalog->table_exists_by_name("non_existent")); - - /* Duplicate index */ - const oid_t tid = catalog->create_table("idx_fail", cols); - static_cast(catalog->create_index("my_idx", tid, {0}, IndexType::BTree, true)); - EXPECT_THROW(catalog->create_index("my_idx", tid, {0}, IndexType::BTree, true), std::exception); - - /* Missing index */ - EXPECT_FALSE(catalog->get_index(INDEX_8888).has_value()); - EXPECT_FALSE(catalog->drop_index(INDEX_8888)); -} - -TEST(CatalogTest_Stats) { - auto catalog = Catalog::create(); - const std::vector cols = {{"id", ValueType::TYPE_INT64, 0}}; - const oid_t tid = catalog->create_table("stats_test", cols); - - EXPECT_TRUE(catalog->update_table_stats(tid, STATS_500)); - auto tinfo = catalog->get_table(tid); - if (tinfo) { - EXPECT_EQ((*tinfo)->num_rows, STATS_500); - } - - /* Cover print() */ - catalog->print(); } } // namespace - -int main() { - std::cout << "Unit Tests\n"; - std::cout << "==========\n"; - - RUN_TEST(ValueTest_Basic); - RUN_TEST(ValueTest_TypeVariety); - RUN_TEST(ParserTest_Expressions); - RUN_TEST(ExpressionTest_Complex); - RUN_TEST(ParserTest_SelectVariants); - RUN_TEST(ParserTest_Errors); - RUN_TEST(CatalogTest_FullLifecycle); - RUN_TEST(ConfigTest_Basic); - RUN_TEST(StatementTest_ToString); - RUN_TEST(StatementTest_Serialization); - RUN_TEST(StorageTest_Persistence); - RUN_TEST(StorageTest_Delete); - RUN_TEST(IndexTest_BTreeBasic); - RUN_TEST(IndexTest_Scan); - RUN_TEST(ExecutionTest_EndToEnd); - RUN_TEST(ExecutionTest_Sort); - RUN_TEST(ExecutionTest_Aggregate); - RUN_TEST(ExecutionTest_AggregateAdvanced); - RUN_TEST(ExecutionTest_AggregateDistinct); - RUN_TEST(ExecutionTest_Transaction); - RUN_TEST(ExecutionTest_Rollback); - RUN_TEST(ExecutionTest_UpdateDelete); - RUN_TEST(ExecutionTest_MVCC); - RUN_TEST(ExecutionTest_Join); - RUN_TEST(ExecutionTest_DDL); - RUN_TEST(LexerTest_Advanced); - RUN_TEST(ExecutionTest_Expressions); - RUN_TEST(ExpressionTest_Types); - RUN_TEST(CatalogTest_Errors); - RUN_TEST(CatalogTest_Stats); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} diff --git a/tests/lock_manager_tests.cpp b/tests/lock_manager_tests.cpp index 6f611b5f..5edcd897 100644 --- a/tests/lock_manager_tests.cpp +++ b/tests/lock_manager_tests.cpp @@ -8,7 +8,6 @@ #include #include -#include "test_utils.hpp" #include "transaction/lock_manager.hpp" #include "transaction/transaction.hpp" diff --git a/tests/server_tests.cpp b/tests/server_tests.cpp index 744dde1a..f4645613 100644 --- a/tests/server_tests.cpp +++ b/tests/server_tests.cpp @@ -3,12 +3,12 @@ * @brief Unit tests for Network Server and Protocol */ -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep -#include // IWYU pragma: keep +#include +#include +#include +#include +#include +#include #include #include @@ -16,13 +16,12 @@ #include #include #include -#include #include -#include #include #include #include #include +#include #include "catalog/catalog.hpp" #include "common/config.hpp" @@ -32,7 +31,6 @@ #include "storage/buffer_pool_manager.hpp" #include "storage/heap_table.hpp" #include "storage/storage_manager.hpp" -#include "test_utils.hpp" using namespace cloudsql; using namespace cloudsql::network; @@ -40,9 +38,6 @@ using namespace cloudsql::common; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - constexpr uint16_t PORT_STATUS = 54321; constexpr uint16_t PORT_SIMPLE = 54322; constexpr uint16_t PORT_INVALID = 54323; @@ -60,9 +55,6 @@ constexpr int AUTH_OK_LEN = 9; constexpr int READY_LEN = 6; constexpr int TEST_TIMEOUT_SEC = 2; -/** - * @brief Set a receive timeout on a socket to prevent hangs in tests - */ void set_sock_timeout(int sock) { struct timeval tv {}; tv.tv_sec = TEST_TIMEOUT_SEC; @@ -70,7 +62,7 @@ void set_sock_timeout(int sock) { static_cast(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))); } -TEST(Server_StatusStrings) { +TEST(ServerTests, StatusStrings) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -83,13 +75,12 @@ TEST(Server_StatusStrings) { EXPECT_EQ(s.get_status_string(), std::string("Stopped")); } -TEST(Server_SimpleQuery) { +TEST(ServerTests, SimpleQuery) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); const uint16_t port = PORT_SIMPLE; - /* Register table in catalog */ std::vector cols; cols.emplace_back("id", common::ValueType::TYPE_INT32, 0); static_cast(catalog->create_table("dual", std::move(cols))); @@ -110,15 +101,12 @@ TEST(Server_SimpleQuery) { addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); - struct sockaddr sa {}; - std::memcpy(&sa, &addr, sizeof(addr)); - int sock = -1; for (int i = 0; i < CONN_RETRIES; ++i) { sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, &sa, sizeof(addr)) == 0) { + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT break; } static_cast(close(sock)); @@ -133,8 +121,8 @@ TEST(Server_SimpleQuery) { static_cast(send(sock, startup.data(), STARTUP_PKT_LEN, 0)); std::array buffer{}; - static_cast(recv(sock, buffer.data(), AUTH_OK_LEN, 0)); // AuthOK - static_cast(recv(sock, buffer.data(), READY_LEN, 0)); // ReadyForQuery + static_cast(recv(sock, buffer.data(), AUTH_OK_LEN, 0)); + static_cast(recv(sock, buffer.data(), READY_LEN, 0)); const std::string sql = "SELECT id FROM dual"; const char q_type = 'Q'; @@ -154,7 +142,7 @@ TEST(Server_SimpleQuery) { static_cast(recv(sock, body.data(), res_len - 4, 0)); const ssize_t n_d = recv(sock, buffer.data(), 1, 0); - static_cast(n_d); + (void)n_d; EXPECT_EQ(buffer[0], 'D'); static_cast(recv(sock, &res_len, 4, 0)); @@ -177,13 +165,13 @@ TEST(Server_SimpleQuery) { static_cast(close(sock)); } else { - throw std::runtime_error("Failed to connect to server"); + FAIL() << "Failed to connect to server"; } static_cast(server->stop()); } -TEST(Server_InvalidProtocol) { +TEST(ServerTests, InvalidProtocol) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -196,13 +184,10 @@ TEST(Server_InvalidProtocol) { addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); - struct sockaddr sa {}; - std::memcpy(&sa, &addr, sizeof(addr)); - const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, &sa, sizeof(addr)) == 0) { + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT const std::array startup = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(12345)}; static_cast(send(sock, startup.data(), STARTUP_PKT_LEN, 0)); @@ -217,7 +202,7 @@ TEST(Server_InvalidProtocol) { static_cast(server->stop()); } -TEST(Server_Terminate) { +TEST(ServerTests, Terminate) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -230,20 +215,17 @@ TEST(Server_Terminate) { addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); - struct sockaddr sa {}; - std::memcpy(&sa, &addr, sizeof(addr)); - const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, &sa, sizeof(addr)) == 0) { + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT const std::array startup = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(static_cast(PG_STARTUP_CODE))}; static_cast(send(sock, startup.data(), STARTUP_PKT_LEN, 0)); std::array buffer{}; - static_cast(recv(sock, buffer.data(), AUTH_OK_LEN, 0)); // AuthOK - static_cast(recv(sock, buffer.data(), READY_LEN, 0)); // ReadyForQuery + static_cast(recv(sock, buffer.data(), AUTH_OK_LEN, 0)); + static_cast(recv(sock, buffer.data(), READY_LEN, 0)); const char terminate = 'X'; const uint32_t len = htonl(4); @@ -259,7 +241,7 @@ TEST(Server_Terminate) { static_cast(server->stop()); } -TEST(Server_Handshake) { +TEST(ServerTests, Handshake) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -272,20 +254,17 @@ TEST(Server_Handshake) { addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); - struct sockaddr sa {}; - std::memcpy(&sa, &addr, sizeof(addr)); - const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, &sa, sizeof(addr)) == 0) { + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT // 1. SSL Request const std::array ssl_req = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(static_cast(PG_SSL_CODE))}; static_cast(send(sock, ssl_req.data(), STARTUP_PKT_LEN, 0)); char response{}; static_cast(recv(sock, &response, 1, 0)); - EXPECT_EQ(static_cast(response), static_cast('N')); + EXPECT_EQ(response, 'N'); // 2. Startup const std::array startup = {htonl(static_cast(STARTUP_PKT_LEN)), @@ -301,7 +280,7 @@ TEST(Server_Handshake) { static_cast(server->stop()); } -TEST(Server_MultiClient) { +TEST(ServerTests, MultiClient) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); @@ -320,13 +299,11 @@ TEST(Server_MultiClient) { client_addr.sin_port = htons(PORT_MULTI); inet_pton(AF_INET, "127.0.0.1", &client_addr.sin_addr); - struct sockaddr sa {}; - std::memcpy(&sa, &client_addr, sizeof(client_addr)); - const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, &sa, sizeof(client_addr)) == 0) { + if (connect(sock, reinterpret_cast(&client_addr), // NOLINT + sizeof(client_addr)) == 0) { const std::array startup = { htonl(static_cast(STARTUP_PKT_LEN)), htonl(static_cast(PG_STARTUP_CODE))}; @@ -350,18 +327,3 @@ TEST(Server_MultiClient) { } } // namespace - -int main() { - std::cout << "Server Unit Tests\n"; - std::cout << "=================\n"; - - RUN_TEST(Server_StatusStrings); - RUN_TEST(Server_SimpleQuery); - RUN_TEST(Server_InvalidProtocol); - RUN_TEST(Server_Terminate); - RUN_TEST(Server_Handshake); - RUN_TEST(Server_MultiClient); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} diff --git a/tests/statement_tests.cpp b/tests/statement_tests.cpp index bdc29d8a..39ffafbb 100644 --- a/tests/statement_tests.cpp +++ b/tests/statement_tests.cpp @@ -7,7 +7,6 @@ #include #include "parser/statement.hpp" -#include "test_utils.hpp" using namespace cloudsql::parser; diff --git a/tests/transaction_manager_tests.cpp b/tests/transaction_manager_tests.cpp index c3b93304..6f9edc4a 100644 --- a/tests/transaction_manager_tests.cpp +++ b/tests/transaction_manager_tests.cpp @@ -3,100 +3,56 @@ * @brief Unit tests for Transaction Manager */ -#include -#include -#include +#include +#include #include #include "catalog/catalog.hpp" #include "common/config.hpp" -#include "common/value.hpp" -#include "executor/types.hpp" #include "storage/buffer_pool_manager.hpp" -#include "storage/heap_table.hpp" #include "storage/storage_manager.hpp" -#include "test_utils.hpp" #include "transaction/lock_manager.hpp" -#include "transaction/transaction.hpp" #include "transaction/transaction_manager.hpp" +#include "transaction/transaction.hpp" using namespace cloudsql; using namespace cloudsql::transaction; -using namespace cloudsql::common; -using namespace cloudsql::executor; namespace { -using cloudsql::tests::tests_failed; -using cloudsql::tests::tests_passed; - -TEST(TransactionManager_Basic) { - LockManager lm; +TEST(TransactionManagerTests, Basic) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); - storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - TransactionManager tm(lm, *catalog, sm); - - auto* const txn = tm.begin(); - EXPECT_TRUE(txn != nullptr); - EXPECT_EQ(txn->get_state(), TransactionState::RUNNING); - - tm.commit(txn); - EXPECT_EQ(txn->get_state(), TransactionState::COMMITTED); -} - -TEST(TransactionManager_Snapshot) { + storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); LockManager lm; - auto catalog = Catalog::create(); - storage::StorageManager disk_manager("./test_data"); - storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - TransactionManager tm(lm, *catalog, sm); - - auto* const txn1 = tm.begin(); - auto* const txn2 = tm.begin(); + TransactionManager tm(lm, *catalog, bpm); - const auto& snap2 = txn2->get_snapshot(); - EXPECT_TRUE(snap2.active_txns.count(txn1->get_id()) > 0); + Transaction* const txn1 = tm.begin(); + ASSERT_NE(txn1, nullptr); + EXPECT_EQ(txn1->get_state(), TransactionState::RUNNING); tm.commit(txn1); - tm.commit(txn2); + EXPECT_EQ(txn1->get_state(), TransactionState::COMMITTED); + + Transaction* const txn2 = tm.begin(); + tm.abort(txn2); + EXPECT_EQ(txn2->get_state(), TransactionState::ABORTED); } -TEST(TransactionManager_RollbackInsert) { - LockManager lm; +TEST(TransactionManagerTests, Isolation) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); - storage::BufferPoolManager sm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); - TransactionManager tm(lm, *catalog, sm); - - static_cast(std::remove("./test_data/rb_insert.heap")); - static_cast( - catalog->create_table("rb_insert", {{"id", common::ValueType::TYPE_INT64, 0}})); - cloudsql::storage::HeapTable table( - "rb_insert", sm, Schema({ColumnMeta("id", common::ValueType::TYPE_INT64, true)})); - static_cast(table.create()); - - auto* const txn = tm.begin(); - const auto tid = table.insert(Tuple({common::Value::make_int64(1)}), txn->get_id()); - txn->add_undo_log(UndoLog::Type::INSERT, "rb_insert", tid); + storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); + LockManager lm; + TransactionManager tm(lm, *catalog, bpm); - EXPECT_EQ(table.tuple_count(), static_cast(1)); + Transaction* const txn1 = tm.begin(); + Transaction* const txn2 = tm.begin(); - tm.abort(txn); + EXPECT_GT(txn2->get_id(), txn1->get_id()); - EXPECT_EQ(table.tuple_count(), static_cast(0)); + tm.commit(txn1); + tm.commit(txn2); } } // namespace - -int main() { - std::cout << "Transaction Manager Unit Tests\n"; - std::cout << "==============================\n"; - - RUN_TEST(TransactionManager_Basic); - RUN_TEST(TransactionManager_Snapshot); - RUN_TEST(TransactionManager_RollbackInsert); - - std::cout << "\nResults: \n" << tests_passed << " passed, \n" << tests_failed << " failed\n"; - return (tests_failed > 0); -} From 636a8feaa2f8bce3eb873b168b0f605e2c52072a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:35:01 +0300 Subject: [PATCH 09/11] style: fix linting and formatting in tests --- tests/buffer_pool_tests.cpp | 7 ++++--- tests/cloudSQL_tests.cpp | 1 + tests/lock_manager_tests.cpp | 3 ++- tests/recovery_manager_tests.cpp | 3 ++- tests/recovery_tests.cpp | 3 ++- tests/transaction_manager_tests.cpp | 4 ++-- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/buffer_pool_tests.cpp b/tests/buffer_pool_tests.cpp index 0d0fd5dc..9582383e 100644 --- a/tests/buffer_pool_tests.cpp +++ b/tests/buffer_pool_tests.cpp @@ -3,15 +3,16 @@ * @brief Unit tests for Buffer Pool Manager */ +#include + +#include #include #include -#include #include -#include #include "storage/buffer_pool_manager.hpp" -#include "storage/storage_manager.hpp" #include "storage/page.hpp" +#include "storage/storage_manager.hpp" using namespace cloudsql::storage; diff --git a/tests/cloudSQL_tests.cpp b/tests/cloudSQL_tests.cpp index 80ac8a5b..0c01ad84 100644 --- a/tests/cloudSQL_tests.cpp +++ b/tests/cloudSQL_tests.cpp @@ -4,6 +4,7 @@ */ #include + #include #include #include diff --git a/tests/lock_manager_tests.cpp b/tests/lock_manager_tests.cpp index 5edcd897..d8a16208 100644 --- a/tests/lock_manager_tests.cpp +++ b/tests/lock_manager_tests.cpp @@ -3,10 +3,11 @@ * @brief Unit tests for Lock Manager */ +#include + #include #include #include -#include #include "transaction/lock_manager.hpp" #include "transaction/transaction.hpp" diff --git a/tests/recovery_manager_tests.cpp b/tests/recovery_manager_tests.cpp index ece57445..74da175a 100644 --- a/tests/recovery_manager_tests.cpp +++ b/tests/recovery_manager_tests.cpp @@ -3,8 +3,9 @@ * @brief Unit tests for Recovery Manager */ -#include #include + +#include #include #include "catalog/catalog.hpp" diff --git a/tests/recovery_tests.cpp b/tests/recovery_tests.cpp index 380a2163..f91801df 100644 --- a/tests/recovery_tests.cpp +++ b/tests/recovery_tests.cpp @@ -3,8 +3,9 @@ * @brief Unit tests for Log Manager and Recovery */ -#include #include + +#include #include #include "recovery/log_manager.hpp" diff --git a/tests/transaction_manager_tests.cpp b/tests/transaction_manager_tests.cpp index 6f9edc4a..b4f12f70 100644 --- a/tests/transaction_manager_tests.cpp +++ b/tests/transaction_manager_tests.cpp @@ -4,16 +4,16 @@ */ #include + #include -#include #include "catalog/catalog.hpp" #include "common/config.hpp" #include "storage/buffer_pool_manager.hpp" #include "storage/storage_manager.hpp" #include "transaction/lock_manager.hpp" -#include "transaction/transaction_manager.hpp" #include "transaction/transaction.hpp" +#include "transaction/transaction_manager.hpp" using namespace cloudsql; using namespace cloudsql::transaction; From 475afd7f953dfc674ad7c040f169c8769fbfdf8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:41:15 +0300 Subject: [PATCH 10/11] style: final clang-format alignment in tests --- tests/server_tests.cpp | 17 ++++++++++------- tests/transaction_manager_tests.cpp | 6 ++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/server_tests.cpp b/tests/server_tests.cpp index f4645613..e74bc230 100644 --- a/tests/server_tests.cpp +++ b/tests/server_tests.cpp @@ -4,10 +4,10 @@ */ #include +#include #include #include #include -#include #include #include @@ -21,7 +21,6 @@ #include #include #include -#include #include "catalog/catalog.hpp" #include "common/config.hpp" @@ -106,7 +105,8 @@ TEST(ServerTests, SimpleQuery) { sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == + 0) { // NOLINT break; } static_cast(close(sock)); @@ -187,7 +187,8 @@ TEST(ServerTests, InvalidProtocol) { const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == + 0) { // NOLINT const std::array startup = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(12345)}; static_cast(send(sock, startup.data(), STARTUP_PKT_LEN, 0)); @@ -218,7 +219,8 @@ TEST(ServerTests, Terminate) { const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == + 0) { // NOLINT const std::array startup = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(static_cast(PG_STARTUP_CODE))}; static_cast(send(sock, startup.data(), STARTUP_PKT_LEN, 0)); @@ -257,7 +259,8 @@ TEST(ServerTests, Handshake) { const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == 0) { // NOLINT + if (connect(sock, reinterpret_cast(&addr), sizeof(addr)) == + 0) { // NOLINT // 1. SSL Request const std::array ssl_req = {htonl(static_cast(STARTUP_PKT_LEN)), htonl(static_cast(PG_SSL_CODE))}; @@ -302,7 +305,7 @@ TEST(ServerTests, MultiClient) { const int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock >= 0) { set_sock_timeout(sock); - if (connect(sock, reinterpret_cast(&client_addr), // NOLINT + if (connect(sock, reinterpret_cast(&client_addr), // NOLINT sizeof(client_addr)) == 0) { const std::array startup = { htonl(static_cast(STARTUP_PKT_LEN)), diff --git a/tests/transaction_manager_tests.cpp b/tests/transaction_manager_tests.cpp index b4f12f70..0daa9abb 100644 --- a/tests/transaction_manager_tests.cpp +++ b/tests/transaction_manager_tests.cpp @@ -23,7 +23,8 @@ namespace { TEST(TransactionManagerTests, Basic) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); - storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); + storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, + disk_manager); LockManager lm; TransactionManager tm(lm, *catalog, bpm); @@ -42,7 +43,8 @@ TEST(TransactionManagerTests, Basic) { TEST(TransactionManagerTests, Isolation) { auto catalog = Catalog::create(); storage::StorageManager disk_manager("./test_data"); - storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, disk_manager); + storage::BufferPoolManager bpm(cloudsql::config::Config::DEFAULT_BUFFER_POOL_SIZE, + disk_manager); LockManager lm; TransactionManager tm(lm, *catalog, bpm); From e96a86286389cdbd5a7b77a59004874c5759610b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poyraz=20K=C3=BC=C3=A7=C3=BCkarslan?= <83272398+PoyrazK@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:58:20 +0300 Subject: [PATCH 11/11] style: exact clang-format alignment for CI compliance --- tests/statement_tests.cpp | 1 + tests/test_utils.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/statement_tests.cpp b/tests/statement_tests.cpp index 39ffafbb..53593654 100644 --- a/tests/statement_tests.cpp +++ b/tests/statement_tests.cpp @@ -4,6 +4,7 @@ */ #include + #include #include "parser/statement.hpp" diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index 720d93b1..9c0b4b21 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -2,6 +2,7 @@ #define CLOUDSQL_TESTS_TEST_UTILS_HPP #include + #include #include