hunting/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp
2024-04-28 17:46:54 +08:00

138 lines
6.3 KiB
C++

/*
* Copyright (c) 2023 Fancy Code.
* 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 "LinuxTestImpl.h"
#include "ILog.h"
#include <thread>
/**
* @brief The simulated interface has been subjected to lock serial processing to ensure that the return value can be
* safely returned through multiple threads. However, this may affect the timing of the test code, which is not very
* reasonable. If the behavior of the simulated interface is redefined, the impact can be ignored.
* @param mock
*/
void LinuxTestImpl::ApiInit(std::shared_ptr<LinuxTest> &mock)
{
LogInfo("ApiInit\n");
static int openFd = -1;
auto api_open = [=](const char *pathname, int flags) {
LogInfo("Call __real_fx_open, pathname = %s.\n", pathname);
openFd = __real_fx_open(pathname, flags);
LogInfo("openFd = %d\n", openFd);
};
EXPECT_CALL(*mock.get(), fx_open(_, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1>(Invoke(api_open)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&openFd)));
static int resultTcgetattr = -1;
auto api_tcgetattr = [=](int fd, struct termios *termios_p) {
resultTcgetattr = __real_fx_tcgetattr(fd, termios_p);
LogInfo("resultTcgetattr = %d\n", resultTcgetattr);
};
EXPECT_CALL(*mock.get(), fx_tcgetattr(_, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1>(Invoke(api_tcgetattr)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&resultTcgetattr)));
static int resultTcsetattr = -1;
auto api_tcsetattr = [=](int fd, int optional_actions, const struct termios *termios_p) {
resultTcsetattr = __real_fx_tcsetattr(fd, optional_actions, termios_p);
LogInfo("resultTcsetattr = %d\n", resultTcsetattr);
};
EXPECT_CALL(*mock.get(), fx_tcsetattr(_, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_tcsetattr)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&resultTcsetattr)));
static int writeLength = -1;
auto api_write = [=](int fd, const void *buf, size_t count) {
writeLength = __real_fx_write(fd, buf, count);
LogInfo("writeLength = %d\n", writeLength);
};
EXPECT_CALL(*mock.get(), fx_write(_, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_write)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&writeLength)));
static int readLength = -1;
auto api_read = [=](int fd, void *buf, size_t count) {
readLength = __real_fx_read(fd, buf, count);
LogInfo("readLength = %d\n", readLength);
};
EXPECT_CALL(*mock.get(), fx_read(_, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_read)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&readLength)));
static int selectResult = -1;
auto api_select = [=](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
selectResult = __real_fx_select(nfds, readfds, writefds, exceptfds, timeout);
LogInfo("selectResult = %d\n", selectResult);
};
EXPECT_CALL(*mock.get(), fx_select(_, _, _, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2, 3, 4>(Invoke(api_select)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&selectResult)));
static int fstatResult = -1;
auto api_fstat = [=](int fd, struct stat *statbuf) {
LogInfo("Call __real_fx_fstat, fd = %d.\n", fd);
fstatResult = __real_fx_fstat(fd, statbuf);
LogInfo("fstatResult = %d\n", fstatResult);
};
EXPECT_CALL(*mock.get(), fx_fstat(_, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1>(Invoke(api_fstat)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&fstatResult)));
}
void LinuxTestImpl::Init()
{
}
void LinuxTestImpl::UnInit()
{
if (mApiThread.joinable()) {
mApiThread.join();
}
}
void LinuxTestImpl::ApiLock(void)
{
mApiMutex.lock();
LogInfo("lock api.\n");
}
void LinuxTestImpl::ApiUnlock(void)
{
mApiMutex.unlock();
LogInfo("unlock api.\n");
}
void LinuxTestImpl::ApiUnlockThread(void)
{
LogInfo("ApiUnlockThread\n");
if (mApiThread.joinable()) {
mApiThread.join();
}
auto api_unlock = [](std::shared_ptr<LinuxTestImpl> test) {
std::this_thread::sleep_for(std::chrono::milliseconds(API_LOCK_TIME_MS));
test->ApiUnlock();
};
std::shared_ptr<LinuxTestImpl> test = std::dynamic_pointer_cast<LinuxTestImpl>(LinuxTest::shared_from_this());
mApiThread = std::thread(api_unlock, test);
}