* Copyright (C) 2025-2026. Huawei Technologies Co., Ltd. All rights reserved.
*
* 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 <gtest/gtest.h>
#include <atomic>
#include <chrono>
#include <memory>
#include <thread>
#include "plugin/ipc_monitor/TimerTask.h"
using namespace dynolog_npu::ipc_monitor;
class TimerTaskSample : public TimerTask
{
public:
TimerTaskSample(const std::string& name, int interval)
: TimerTask(name, interval), executeCount(0), preTaskCount(0), postTaskCount(0)
{
}
void ExecuteTask() override { executeCount++; }
void RunPreTask() override { preTaskCount++; }
void RunPostTask() override { postTaskCount++; }
std::atomic_int executeCount;
std::atomic_int preTaskCount;
std::atomic_int postTaskCount;
};
class TimerTaskTest : public ::testing::Test
{
protected:
void SetUp() override {}
void TearDown() override {}
void waitFor(int milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); }
};
TEST_F(TimerTaskTest, ConstructorInitialization)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, StartAndStop)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 100;
waitFor(kWaitTime);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
EXPECT_EQ(task.preTaskCount, 1);
EXPECT_EQ(task.postTaskCount, 1);
}
TEST_F(TimerTaskTest, StartAlreadyRunning)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, StopNotRunning)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, TriggerExecution)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 100;
waitFor(kWaitTime);
EXPECT_EQ(task.executeCount, 0);
EXPECT_NO_THROW(task.Trigger());
waitFor(100);
EXPECT_EQ(task.executeCount, 1);
EXPECT_NO_THROW(task.Stop());
}
TEST_F(TimerTaskTest, MultipleTriggers)
{
constexpr int kInterval = 10;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 100;
EXPECT_NO_THROW(task.Trigger());
waitFor(kWaitTime);
EXPECT_NO_THROW(task.Trigger());
waitFor(kWaitTime);
EXPECT_NO_THROW(task.Trigger());
waitFor(kWaitTime);
EXPECT_EQ(task.executeCount, 3);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, IntervalExecution)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 2500;
waitFor(kWaitTime);
EXPECT_GE(task.executeCount, 2);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, SetInterval)
{
int kInterval = 5;
TimerTaskSample task("TestTask", kInterval);
kInterval = 1;
task.SetInterval(kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
int kWaitTime = 100;
waitFor(kWaitTime);
kWaitTime = 1500;
waitFor(kWaitTime);
EXPECT_GE(task.executeCount, 1);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, ZeroInterval)
{
constexpr int kInterval = 0;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 100;
waitFor(kWaitTime);
EXPECT_EQ(task.executeCount, 0);
EXPECT_NO_THROW(task.Trigger());
waitFor(kWaitTime);
EXPECT_EQ(task.executeCount, 1);
EXPECT_NO_THROW(task.Stop());
EXPECT_FALSE(task.IsRunning());
}
TEST_F(TimerTaskTest, DestructorStopsTask)
{
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 100;
waitFor(kWaitTime);
EXPECT_TRUE(task.IsRunning());
}
SUCCEED();
}
TEST_F(TimerTaskTest, PreAndPostTaskExecution)
{
constexpr int kInterval = 1;
TimerTaskSample task("TestTask", kInterval);
EXPECT_NO_THROW(task.Run());
EXPECT_TRUE(task.IsRunning());
constexpr int kWaitTime = 1500;
waitFor(kWaitTime);
EXPECT_NO_THROW(task.Stop());
EXPECT_EQ(task.preTaskCount, 1);
EXPECT_EQ(task.postTaskCount, 1);
EXPECT_GE(task.executeCount, 1);
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}