* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* MindIE 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 <gtest/gtest.h>
#include <mockcpp/mockcpp.hpp>
#include <thread>
#include "ipc_communicator.h"
#include "shared_memory.h"
#define MOCKER_CPP(api, TT) (MOCKCPP_NS::mockAPI((#api), (reinterpret_cast<TT>(api))))
namespace mindie_llm {
class IPCCommunicatorTest : public ::testing::Test {
protected:
void SetUp() override
{
MOCKER_CPP(&SharedMemorySizeCheck, bool (*)(const uint32_t &)).stubs().will(returnValue(true));
MOCKER_CPP(&SharedMemory::Create, bool (*)(const std::string &, uint32_t)).stubs().will(returnValue(true));
prefix_ = "/gtest_ipc_" + std::to_string(reinterpret_cast<std::uintptr_t>(this));
semConfig_ = SemaphoreConfig{2, 2};
iPCCommunicator_ = std::make_unique<IPCCommunicator>(prefix_, semConfig_);
}
void TearDown() override
{
if (didSetup_) {
iPCCommunicator_->CleanUp();
}
MOCKCPP_NS::GlobalMockObject::reset();
}
std::shared_ptr<IPCCommunicator> iPCCommunicator_;
std::string prefix_;
SemaphoreConfig semConfig_;
bool didSetup_ = false;
};
TEST_F(IPCCommunicatorTest, SerializeExecuteMessageReturnsTrue)
{
std::string buf;
ExecuteRequest request;
ASSERT_TRUE(SerializeExecuteMessage(request, buf));
size_t msgSize = request.ByteSizeLong();
EXPECT_EQ(buf.size(), msgSize + sizeof(uint32_t));
}
TEST_F(IPCCommunicatorTest, SetupChannelReturnsTrue)
{
ShmSizeConfig shmConfig{DEFAULT_SHARED_MEMORY_SIZE, DEFAULT_SHARED_MEMORY_SIZE};
bool ok = iPCCommunicator_->SetupChannel(shmConfig);
EXPECT_TRUE(ok);
didSetup_ = ok;
}
TEST_F(IPCCommunicatorTest, RegisterResponseHandler_DuplicateFails)
{
ShmSizeConfig shmConfig{DEFAULT_SHARED_MEMORY_SIZE, DEFAULT_SHARED_MEMORY_SIZE};
ASSERT_TRUE(iPCCommunicator_->SetupChannel(shmConfig));
didSetup_ = true;
bool first = iPCCommunicator_->RegisterResponseHandler([](ExecuteResponse &) {});
EXPECT_TRUE(first);
bool second = iPCCommunicator_->RegisterResponseHandler([](ExecuteResponse &) {});
EXPECT_FALSE(second);
}
TEST_F(IPCCommunicatorTest, StartHandleResponseThread_NoHandlerFails)
{
ShmSizeConfig shmConfig{DEFAULT_SHARED_MEMORY_SIZE, DEFAULT_SHARED_MEMORY_SIZE};
ASSERT_TRUE(iPCCommunicator_->SetupChannel(shmConfig));
didSetup_ = true;
EXPECT_FALSE(iPCCommunicator_->StartHandleResponseThread());
}
TEST_F(IPCCommunicatorTest, StartHandleResponseThread_AfterRegisterSucceeds)
{
MOCKER_CPP(&IPCCommunicator::ParseResponse, bool (*)(ExecuteResponse &, char *)).stubs().will(returnValue(true));
ShmSizeConfig shmConfig{DEFAULT_SHARED_MEMORY_SIZE, DEFAULT_SHARED_MEMORY_SIZE};
ASSERT_TRUE(iPCCommunicator_->SetupChannel(shmConfig));
didSetup_ = true;
bool reg = iPCCommunicator_->RegisterResponseHandler([](ExecuteResponse &) {});
ASSERT_TRUE(reg);
bool started = iPCCommunicator_->StartHandleResponseThread();
EXPECT_TRUE(started);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
TEST_F(IPCCommunicatorTest, SendMessageViaSM_ReturnsTrueAfterSetup)
{
MOCKER_CPP(&IPCCommunicator::WriteMessage, bool (*)(const char *, uint32_t)).stubs().will(returnValue(true));
ShmSizeConfig shmConfig{DEFAULT_SHARED_MEMORY_SIZE, DEFAULT_SHARED_MEMORY_SIZE};
ASSERT_TRUE(iPCCommunicator_->SetupChannel(shmConfig));
didSetup_ = true;
ExecuteRequest request;
EXPECT_TRUE(iPCCommunicator_->SendMessageViaSM(request));
}
}