1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <atomic>
16#include <chrono>
17#include <gtest/gtest.h>
18#include <sys/time.h>
19#include <thread>
20
21#include "schedule_task_manager.h"
22
23using namespace testing::ext;
24
25namespace {
26class ScheduleTaskManagerTest : public testing::Test {
27protected:
28    static void SetUpTestCase() {}
29    static void TearDownTestCase() {}
30};
31
32/**
33 * @tc.name: base
34 * @tc.desc: Single task processing.
35 * @tc.type: FUNC
36 */
37HWTEST_F(ScheduleTaskManagerTest, ScheduleTaskOneshot, TestSize.Level1)
38{
39    std::atomic<int> count = 0;
40    uint64_t initalDelay = 10; // 10ms
41
42    ScheduleTaskManager scheduleTaskManager;
43    EXPECT_NE(scheduleTaskManager.ScheduleTask([&]() { count++; }, initalDelay, true), -1);
44
45    std::this_thread::sleep_for(std::chrono::milliseconds(initalDelay + initalDelay));
46    EXPECT_EQ(count.load(), 1);
47}
48
49/**
50 * @tc.name: base
51 * @tc.desc: Repetitive task processing.
52 * @tc.type: FUNC
53 */
54HWTEST_F(ScheduleTaskManagerTest, ScheduleTaskRepeated, TestSize.Level1)
55{
56    std::atomic<int> count = 0;
57    constexpr int cnt = 5;
58    constexpr int thresh = 1;
59
60    uint64_t repeatInterval = 100;
61
62    ScheduleTaskManager scheduleTaskManager;
63    EXPECT_NE(scheduleTaskManager.ScheduleTask(
64        [&]() {
65            count++;
66            struct timeval tv;
67            gettimeofday(&tv, nullptr);
68        },
69    repeatInterval), -1);
70
71    int expected = 0;
72    std::this_thread::sleep_for(std::chrono::milliseconds(1));
73    for (int i = 0; i < cnt; i++) {
74        expected++;
75        struct timeval tv = { 0, 0 };
76        gettimeofday(&tv, nullptr);
77        std::this_thread::sleep_for(std::chrono::milliseconds(repeatInterval));
78    }
79    EXPECT_LE(abs(count.load() - expected), thresh);
80}
81
82/**
83 * @tc.name: base
84 * @tc.desc: Unschedule Task.
85 * @tc.type: FUNC
86 */
87HWTEST_F(ScheduleTaskManagerTest, UnscheduleTask, TestSize.Level1)
88{
89    std::atomic<int> count = 0;
90    constexpr int cnt = 5;
91    constexpr int thresh = 1;
92    int32_t taskFd = -1;
93    uint64_t repeatInterval = 100;
94    uint64_t initalDelay = 10;
95
96    ScheduleTaskManager scheduleTaskManager;
97    taskFd = scheduleTaskManager.ScheduleTask(
98        [&]() {
99            count++;
100            struct timeval tv;
101            gettimeofday(&tv, nullptr);
102        },
103        repeatInterval);
104    EXPECT_NE(taskFd, -1);
105
106    int expected = 0;
107    std::this_thread::sleep_for(std::chrono::milliseconds(initalDelay));
108    for (int i = 0; i < cnt; i++) {
109        expected++;
110        struct timeval tv = { 0, 0 };
111        gettimeofday(&tv, nullptr);
112        std::this_thread::sleep_for(std::chrono::milliseconds(repeatInterval));
113    }
114    EXPECT_LE(abs(count.load() - expected), thresh);
115    EXPECT_TRUE(scheduleTaskManager.UnscheduleTask(taskFd));
116}
117} // namespace