* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
* ubs-engine is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include "test_ubse_ipc_client.h"
#include <securec.h>
#include <mockcpp/mockcpp.hpp>
#include "ubse_error.h"
#include "ubse_ipc_client.h"
#include "ubse_ipc_common.h"
#include "ubse_ipc_message.h"
#include "ubse_ipc_utils.h"
#include "src/framework/ipc/client/ubse_uds_client.h"
#include "src/framework/ipc/ubse_ipc_message.h"
namespace ubse::ut::ipc {
using namespace ubse::ipc;
TestUbseIpcClient::TestUbseIpcClient() = default;
void TestUbseIpcClient::SetUp()
{
Test::SetUp();
}
void TestUbseIpcClient::TearDown()
{
GlobalMockObject::verify();
Test::TearDown();
}
int MockCopyResponseBody(const UbseResponseMessage&, ubse_api_buffer_t*)
{
return UBSE_OK;
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_Nullptr)
{
EXPECT_EQ(ubse_invoke_call(0, 0, nullptr, nullptr), UBSE_ERROR_INVAL);
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_ConnectFailed)
{
MOCKER_CPP(&UbseUDSClient::Connect).stubs().will(returnValue(UBSE_ERR_IPC_CONNECTION_FAILED));
ubse_api_buffer_t request_data = {nullptr, 0};
ubse_api_buffer_t response_data = {nullptr, 0};
EXPECT_EQ(ubse_invoke_call(0, 0, &request_data, &response_data), UBSE_ERR_IPC_CONNECTION_FAILED);
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_SendFailed)
{
MOCKER_CPP(&UbseUDSClient::Connect).stubs().will(returnValue(UBSE_OK));
MOCKER_CPP(&UbseUDSClient::Send).stubs().will(returnValue(UBSE_ERR_IPC_CONNECTION_FAILED));
ubse_api_buffer_t request_data = {nullptr, 0};
ubse_api_buffer_t response_data = {nullptr, 0};
EXPECT_EQ(ubse_invoke_call(0, 0, &request_data, &response_data), UBSE_ERR_IPC_CONNECTION_FAILED);
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_CopyResponseBodyEmpty)
{
MOCKER_CPP(&UbseUDSClient::Connect).stubs().will(returnValue(UBSE_OK));
UbseResponseMessage responseData{{0, 0}, nullptr};
MOCKER_CPP(&UbseUDSClient::Send).stubs().with(_, outBound(responseData)).will(returnValue(UBSE_OK));
ubse_api_buffer_t request_data = {nullptr, 0};
ubse_api_buffer_t response_data = {nullptr, 0};
EXPECT_EQ(ubse_invoke_call(0, 0, &request_data, &response_data), UBSE_OK);
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_CopyResponseBodyFailed)
{
MOCKER_CPP(&UbseUDSClient::Connect).stubs().will(returnValue(UBSE_OK));
auto buffer = new uint8_t[10];
UbseResponseMessage responseData{{0, 10}, buffer};
MOCKER_CPP(&UbseUDSClient::Send).stubs().with(_, outBound(responseData)).will(returnValue(UBSE_OK));
MOCKER(memcpy_s).stubs().will(returnValue(-1));
ubse_api_buffer_t request_data = {nullptr, 0};
ubse_api_buffer_t response_data = {nullptr, 0};
EXPECT_EQ(ubse_invoke_call(0, 0, &request_data, &response_data), UBSE_ERROR_DESERIALIZE_FAILED);
delete[] buffer;
}
TEST_F(TestUbseIpcClient, UbseInvokeCall_Success)
{
MOCKER_CPP(&UbseUDSClient::Connect).stubs().will(returnValue(UBSE_OK));
auto buffer = new uint8_t[10];
UbseResponseMessage responseData{{0, 10}, buffer};
MOCKER_CPP(&UbseUDSClient::Send).stubs().with(_, outBound(responseData)).will(returnValue(UBSE_OK));
ubse_api_buffer_t request_data = {nullptr, 0};
ubse_api_buffer_t response_data = {nullptr, 0};
EXPECT_EQ(ubse_invoke_call(0, 0, &request_data, &response_data), UBSE_OK);
ubse_api_buffer_free(&response_data);
delete[] buffer;
}
TEST_F(TestUbseIpcClient, LongLinkConnect_WhenConnectFailed)
{
MOCKER_CPP(&UbseUDSClient::PerSistentConnect).stubs().will(returnValue(UBSE_ERR_IPC_CONNECTION_FAILED));
EXPECT_EQ(ubse_long_link_connect(), UBSE_ERR_IPC_CONNECTION_FAILED);
}
TEST_F(TestUbseIpcClient, LongLinkConnect_WhenConnectSuccess)
{
MOCKER_CPP(&UbseUDSClient::PerSistentConnect).stubs().will(returnValue(UBSE_OK));
EXPECT_EQ(ubse_long_link_connect(), UBSE_OK);
}
TEST_F(TestUbseIpcClient, ShmFaultRegister_WhenRegisterLongLinkNotifyFailed)
{
MOCKER_CPP(&UbseUDSClient::RegisterLongLinkNotify).stubs().will(returnValue(UBSE_ERR_IPC_CONNECTION_FAILED));
ubs_mem_shm_fault_handler handler = nullptr;
EXPECT_EQ(ubse_shm_fault_register(handler), UBSE_ERR_IPC_CONNECTION_FAILED);
}
TEST_F(TestUbseIpcClient, ShmFaultRegister_WhenRegisterLongLinkNotifySuccess)
{
MOCKER_CPP(&UbseUDSClient::RegisterLongLinkNotify).stubs().will(returnValue(UBSE_OK));
ubs_mem_shm_fault_handler handler = nullptr;
EXPECT_EQ(ubse_shm_fault_register(handler), UBSE_OK);
}
TEST_F(TestUbseIpcClient, HandlerRequest_WhenInvalidHandler)
{
MOCKER_CPP(&UbseUDSClient::RegisterLongLinkNotify).stubs().will(returnValue(UBSE_OK));
ubs_mem_shm_fault_handler handler = nullptr;
EXPECT_EQ(ubse_shm_fault_register(handler), UBSE_OK);
UbseRequestMessage request;
request.header.moduleCode = 1;
request.header.opCode = 1;
UbseResponseMessage resp;
ubse::ipc::UbseUDSClient::GetInstance().requestHandler_(request, resp);
EXPECT_EQ(resp.header.statusCode, UBSE_ERR_DAEMON_UNREACHABLE);
}
TEST_F(TestUbseIpcClient, ShmFaultRegister_WhenRegisterSuccessfully)
{
MOCKER_CPP(&UbseUDSClient::RegisterLongLinkNotify).stubs().will(returnValue(UBSE_OK));
auto faultHandler = [](const char* shmName, uint64_t memId, ubs_mem_fault_type_t type) {
return static_cast<int32_t>(UBSE_OK);
};
uint32_t ret = ubse_shm_fault_register(faultHandler);
EXPECT_EQ(ret, UBSE_OK);
UbseRequestMessage request;
request.header.moduleCode = UBSE_LONG_LINK_REGISTER;
request.header.opCode = UBSE_LONGLINK_FAULT_SHM;
request.header.clientRequestId = 0;
request.header.bodyLen = 0;
request.body = nullptr;
UbseResponseMessage resp;
ubse::ipc::UbseUDSClient::GetInstance().requestHandler_(request, resp);
EXPECT_EQ(resp.header.statusCode, UBSE_ERROR_SERIALIZE_FAILED);
}
TEST_F(TestUbseIpcClient, ShmFaultRegister_WhenRegisterFailed)
{
MOCKER_CPP(&UbseUDSClient::RegisterLongLinkNotify).stubs().will(returnValue(UBSE_ERR_IPC_CONNECTION_FAILED));
auto faultHandler = [](const char* shmName, uint64_t memId, ubs_mem_fault_type_t type) {
return static_cast<int32_t>(UBSE_OK);
};
uint32_t ret = ubse_shm_fault_register(faultHandler);
EXPECT_EQ(ret, UBSE_ERR_IPC_CONNECTION_FAILED);
}
TEST_F(TestUbseIpcClient, SerializeShmFault_Normal)
{
uint8_t* buffer = nullptr;
size_t size = 0;
UbseMemFault shmFault{"name", 1, UbseIpcMemFaultType::UB_MEM_HEALTHY};
uint32_t result = SerializeMemFault(shmFault, buffer, size);
EXPECT_EQ(result, UBSE_OK);
EXPECT_NE(buffer, nullptr);
EXPECT_GT(size, 0);
if (buffer) {
delete[] buffer;
}
}
TEST_F(TestUbseIpcClient, DeSerializeShmFault_Normal)
{
uint8_t* buffer = nullptr;
size_t size = 0;
UbseMemFault shmFault{"name", 1, UbseIpcMemFaultType::UB_MEM_HEALTHY};
uint32_t serializeResult = SerializeMemFault(shmFault, buffer, size);
EXPECT_EQ(serializeResult, UBSE_OK);
EXPECT_NE(buffer, nullptr);
EXPECT_GT(size, 0);
UbseMemFault deserializedShmFault{};
uint32_t deserializeResult = DeSerializeMemFault(deserializedShmFault, buffer, size);
EXPECT_EQ(deserializeResult, UBSE_OK);
EXPECT_STREQ(deserializedShmFault.memName.c_str(), shmFault.memName.c_str());
EXPECT_EQ(deserializedShmFault.handleId, shmFault.handleId);
EXPECT_EQ(deserializedShmFault.type, shmFault.type);
if (buffer) {
delete[] buffer;
}
}
TEST_F(TestUbseIpcClient, DeSerializeShmFault_Failure)
{
uint8_t* buffer = nullptr;
size_t size = 0;
UbseMemFault deserializedShmFault;
size = 10;
uint32_t deserializeResult = DeSerializeMemFault(deserializedShmFault, buffer, size);
EXPECT_NE(deserializeResult, UBSE_OK);
}
TEST_F(TestUbseIpcClient, DeSerializeShmFault_NullBuffer)
{
uint8_t* buffer = nullptr;
size_t size = 0;
UbseMemFault deserializedShmFault;
uint32_t deserializeResult = DeSerializeMemFault(deserializedShmFault, buffer, size);
EXPECT_NE(deserializeResult, UBSE_OK);
}
TEST_F(TestUbseIpcClient, DeSerializeShmFault_ZeroSize)
{
uint8_t* buffer = new uint8_t[10]{};
size_t size = 0;
UbseMemFault deserializedShmFault;
uint32_t deserializeResult = DeSerializeMemFault(deserializedShmFault, buffer, size);
EXPECT_NE(deserializeResult, UBSE_OK);
delete[] buffer;
}
TEST_F(TestUbseIpcClient, RandomId_GeneratesValidId)
{
auto id1 = RandomId();
auto id2 = RandomId();
EXPECT_GE(id1, 1000000000000000ULL);
EXPECT_LE(id1, 9999999999999999ULL);
EXPECT_NE(id1, id2);
}
TEST_F(TestUbseIpcClient, SerializeRequestMessage_NullBody)
{
UbseRequestMessage msg{{1, 1, 0}, nullptr};
std::vector<uint8_t> buffer;
EXPECT_EQ(SerializeRequestMessage(msg, buffer), UBSE_OK);
EXPECT_EQ(buffer.size(), sizeof(bool) + sizeof(UbseRequestHeader));
}
TEST_F(TestUbseIpcClient, SerializeRequestMessage_WithBody)
{
uint8_t body[] = {1, 2, 3, 4, 5};
UbseRequestMessage msg{{1, 1, 5}, body};
std::vector<uint8_t> buffer;
EXPECT_EQ(SerializeRequestMessage(msg, buffer), UBSE_OK);
EXPECT_EQ(buffer.size(), sizeof(bool) + sizeof(UbseRequestHeader) + 5);
}
TEST_F(TestUbseIpcClient, SerializeResponseMessage_NullBody)
{
UbseResponseMessage msg{{0, 0}, nullptr};
std::vector<uint8_t> buffer;
EXPECT_EQ(SerializeResponseMessage(msg, buffer), UBSE_OK);
EXPECT_EQ(buffer.size(), sizeof(bool) + sizeof(UbseResponseHeader));
}
TEST_F(TestUbseIpcClient, SerializeResponseMessage_WithBody)
{
uint8_t body[] = {1, 2, 3, 4, 5};
UbseResponseMessage msg{{0, 5}, body};
std::vector<uint8_t> buffer;
EXPECT_EQ(SerializeResponseMessage(msg, buffer), UBSE_OK);
EXPECT_EQ(buffer.size(), sizeof(bool) + sizeof(UbseResponseHeader) + 5);
}
TEST_F(TestUbseIpcClient, UbseSocketPathSet_Nullptr)
{
ubse_socket_path_set(nullptr);
}
TEST_F(TestUbseIpcClient, UbseSocketPathSet_EmptyString)
{
ubse_socket_path_set("");
}
TEST_F(TestUbseIpcClient, UbseSocketPathSet_ValidPath)
{
ubse_socket_path_set("/tmp/test.sock");
}
TEST_F(TestUbseIpcClient, UbseApiBufferFree_Nullptr)
{
ubse_api_buffer_free(nullptr);
}
TEST_F(TestUbseIpcClient, UbseApiBufferFree_ValidBuffer)
{
auto buffer = static_cast<uint8_t*>(malloc(10));
ubse_api_buffer_t apiBuffer{buffer, 10};
ubse_api_buffer_free(&apiBuffer);
EXPECT_EQ(apiBuffer.buffer, nullptr);
EXPECT_EQ(apiBuffer.length, 0);
}
TEST_F(TestUbseIpcClient, UbseApiBufferDelete_Nullptr)
{
ubse_api_buffer_delete(nullptr);
}
TEST_F(TestUbseIpcClient, UbseApiBufferDelete_ValidBuffer)
{
auto buffer = new uint8_t[10];
ubse_api_buffer_t apiBuffer{buffer, 10};
ubse_api_buffer_delete(&apiBuffer);
EXPECT_EQ(apiBuffer.buffer, nullptr);
EXPECT_EQ(apiBuffer.length, 0);
}
}