// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include using namespace IACore; IAT_BEGIN_BLOCK(Core, SocketOps) // ------------------------------------------------------------------------- // 1. Initialization Logic // ------------------------------------------------------------------------- auto test_initialization() -> bool { IAT_CHECK(SocketOps::is_initialized()); // Increment ref count const auto res = SocketOps::initialize(); IAT_CHECK(res.has_value()); // Decrement ref count SocketOps::terminate(); // Should still be initialized (ref count > 0) IAT_CHECK(SocketOps::is_initialized()); return true; } // ------------------------------------------------------------------------- // 2. Port Availability Checks // ------------------------------------------------------------------------- auto test_port_availability() -> bool { // We cannot easily guarantee a port is free or taken without binding it, // and SocketOps doesn't expose a generic TCP bind in its public API // (only Unix sockets). // However, we can verify the functions execute without crashing. const u16 port = 54321; // These return bools, we just ensure they run. (void)SocketOps::is_port_available_tcp(port); (void)SocketOps::is_port_available_udp(port); return true; } // ------------------------------------------------------------------------- // 3. Unix Domain Socket Lifecycle (Create, Bind, Listen, Connect) // ------------------------------------------------------------------------- auto test_unix_socket_lifecycle() -> bool { const String socket_path = "iatest_ipc.sock"; // Ensure clean state SocketOps::unlink_file(socket_path.c_str()); // 1. Create Server Socket auto server_res = SocketOps::create_unix_socket(); IAT_CHECK(server_res.has_value()); SocketHandle server = *server_res; // 2. Bind auto bind_res = SocketOps::bind_unix_socket(server, socket_path.c_str()); if (!bind_res) { // If bind fails (e.g. permissions), we clean up and fail the test SocketOps::close(server); return false; } // 3. Listen auto listen_res = SocketOps::listen(server); IAT_CHECK(listen_res.has_value()); // 4. Create Client Socket auto client_res = SocketOps::create_unix_socket(); IAT_CHECK(client_res.has_value()); SocketHandle client = *client_res; // 5. Connect // Note: This relies on the OS backlog. We aren't calling accept() on the // server, but connect() should succeed if the server is listening. auto connect_res = SocketOps::connect_unix_socket(client, socket_path.c_str()); IAT_CHECK(connect_res.has_value()); // 6. Cleanup SocketOps::close(client); SocketOps::close(server); SocketOps::unlink_file(socket_path.c_str()); return true; } // ------------------------------------------------------------------------- // 4. Unix Socket Error Handling // ------------------------------------------------------------------------- auto test_unix_socket_errors() -> bool { const String socket_path = "iatest_missing.sock"; // Ensure it doesn't exist SocketOps::unlink_file(socket_path.c_str()); auto client_res = SocketOps::create_unix_socket(); IAT_CHECK(client_res.has_value()); SocketHandle client = *client_res; // Should fail to connect to non-existent file auto connect_res = SocketOps::connect_unix_socket(client, socket_path.c_str()); IAT_CHECK_NOT(connect_res.has_value()); SocketOps::close(client); return true; } // ------------------------------------------------------------------------- // Registration // ------------------------------------------------------------------------- IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(test_initialization); IAT_ADD_TEST(test_port_availability); IAT_ADD_TEST(test_unix_socket_lifecycle); IAT_ADD_TEST(test_unix_socket_errors); IAT_END_TEST_LIST() IAT_END_BLOCK() IAT_REGISTER_ENTRY(Core, SocketOps)