1/*
2 * Copyright (C) 2024 HiHope Open Source Organization.
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
16#include <csignal>
17#include <ctime>
18#include <iostream>
19#include <unistd.h>
20#include <gtest/gtest.h>
21#include "securec.h"
22
23using namespace testing::ext;
24static bool g_timerExpired = false;
25static bool g_sigalRm = false;
26static const int DELAY_TIME = 100;
27
28void TimeHandler(union sigval sv)
29{
30    g_timerExpired = true;
31}
32void SigalrmHandler(int sig)
33{
34    g_sigalRm = true;
35}
36
37class TimerCreateApiTest : public testing::Test {
38public:
39static void SetUpTestCase();
40static void TearDownTestCase();
41void SetUp();
42void TearDown();
43private:
44};
45void TimerCreateApiTest::SetUp()
46{
47    g_timerExpired = false;
48    g_sigalRm = false;
49}
50void TimerCreateApiTest::TearDown()
51{
52    sighandler_t oldHandler = signal(SIGRTMIN, SIG_DFL);
53    EXPECT_NE(oldHandler, SIG_ERR);
54}
55void TimerCreateApiTest::SetUpTestCase()
56{
57}
58void TimerCreateApiTest::TearDownTestCase()
59{
60}
61
62/*
63 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_CREATE_0100
64 * @tc.name   : TimerCreateRealtimeAndGetoverrunSuccess_0001
65 * @tc.desc   : Test the timer_create and timer_getoverrun with CLOCK_REALTIME.
66 * @tc.size   : MediumTest
67 * @tc.type   : Function
68 * @tc.level  : Level 1
69 */
70HWTEST_F(TimerCreateApiTest, TimerCreateRealtimeAndGetoverrunSuccess_0001, Function | MediumTest | Level1)
71{
72    timer_t timerId;
73    struct sigevent sev;
74    const clockid_t CLOCK_ID = CLOCK_REALTIME;
75    struct itimerspec its = {
76        .it_interval = {
77            .tv_sec = 0,
78            .tv_nsec = 4000,
79        },
80        .it_value = {
81            .tv_sec = 0,
82            .tv_nsec = 5000,
83        },
84    };
85
86    sev.sigev_notify = SIGEV_THREAD;
87    sev.sigev_signo = SIGRTMIN;
88    sev.sigev_notify_function = TimeHandler;
89
90    EXPECT_EQ(timer_create(CLOCK_ID, &sev, &timerId), 0);
91    EXPECT_EQ(timer_settime(timerId, 0, &its, nullptr), 0);
92
93    usleep(DELAY_TIME);
94    EXPECT_TRUE(g_timerExpired);
95
96    int overruns = timer_getoverrun(timerId);
97    EXPECT_TRUE(overruns >= 0);
98
99    int timerRes = timer_delete(timerId);
100    EXPECT_EQ(timerRes, 0);
101}
102
103/*
104 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_CREATE_0200
105 * @tc.name   : TimerCreateMonotonicSuccess_0002
106 * @tc.desc   : Test the timer_create with CLOCK_MONOTONIC.
107 * @tc.size   : MediumTest
108 * @tc.type   : Function
109 * @tc.level  : Level 1
110 */
111HWTEST_F(TimerCreateApiTest, TimerCreateMonotonicSuccess_0002, Function | MediumTest | Level1)
112{
113    timer_t timerId;
114    struct itimerspec currValue;
115    const clockid_t CLOCK_ID = CLOCK_MONOTONIC;
116    signal(SIGALRM, SigalrmHandler);
117    struct itimerspec its = {
118        .it_interval = {
119            .tv_sec = 0,
120            .tv_nsec = 0,
121        },
122        .it_value = {
123            .tv_sec = 0,
124            .tv_nsec = 5000,
125        },
126    };
127
128    struct sigevent sev = {
129        .sigev_signo = SIGALRM,
130        .sigev_notify = SIGEV_SIGNAL,
131        .sigev_notify_function = TimeHandler,
132    };
133
134    EXPECT_EQ(timer_create(CLOCK_ID, &sev, &timerId), 0);
135    EXPECT_EQ(timer_settime(timerId, 0, &its, nullptr), 0);
136
137    usleep(DELAY_TIME);
138    EXPECT_EQ(timer_gettime(timerId, &currValue), 0);
139    EXPECT_TRUE(currValue.it_value.tv_sec < 1 && currValue.it_value.tv_nsec < 5000);
140
141    int timerRes = timer_delete(timerId);
142    EXPECT_EQ(timerRes, 0);
143}
144
145/*
146 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_CREATE_0300
147 * @tc.name   : TimerCreateRealTimeAlarmSuccess_0003
148 * @tc.desc   : Test the timer_create with CLOCK_REALTIME_ALARM.
149 * @tc.size   : MediumTest
150 * @tc.type   : Function
151 * @tc.level  : Level 1
152 */
153HWTEST_F(TimerCreateApiTest, TimerCreateRealTimeAlarmSuccess_0003, Function | MediumTest | Level1)
154{
155    timer_t timerId;
156    const clockid_t CLOCK_ID = CLOCK_REALTIME_ALARM;
157    sighandler_t oldHandler = signal(SIGALRM, SigalrmHandler);
158    EXPECT_NE(oldHandler, SIG_ERR);
159    struct sigevent sev = {
160        .sigev_signo = SIGALRM,
161        .sigev_notify = SIGEV_SIGNAL,
162        .sigev_notify_function = TimeHandler,
163    };
164    struct itimerspec its = {
165        .it_interval = {
166            .tv_sec = 0,
167            .tv_nsec = 0,
168        },
169        .it_value = {
170            .tv_sec = 0,
171            .tv_nsec = 50,
172        },
173    };
174
175    EXPECT_EQ(timer_create(CLOCK_ID, &sev, &timerId), 0);
176    EXPECT_EQ(timer_settime(timerId, 0, &its, nullptr), 0);
177
178    usleep(DELAY_TIME);
179
180    EXPECT_FALSE(g_timerExpired);
181    EXPECT_TRUE(g_sigalRm);
182
183    int timerRes = timer_delete(timerId);
184    EXPECT_EQ(timerRes, 0);
185}
186
187/*
188 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_CREATE_0400
189 * @tc.name   : TimeSetTimeOldValueSuccess_0004
190 * @tc.desc   : Test the timer_settime get the old value.
191 * @tc.size   : MediumTest
192 * @tc.type   : Function
193 * @tc.level  : Level 1
194 */
195HWTEST_F(TimerCreateApiTest, TimeSetTimeOldValueSuccess_0004, Function | MediumTest | Level1)
196{
197    timer_t timerId;
198    struct itimerspec oldValue;
199    struct itimerspec oldValue2;
200    struct itimerspec newValue = {
201        .it_interval = {
202            .tv_sec = 1,
203            .tv_nsec = 0,
204        },
205        .it_value = {
206            .tv_sec = 0,
207            .tv_nsec = 50,
208        },
209    };
210    EXPECT_EQ(timer_create(CLOCK_REALTIME, nullptr, &timerId), 0);
211
212    EXPECT_EQ(timer_settime(timerId, 0, &newValue, &oldValue), 0);
213    EXPECT_EQ(oldValue.it_value.tv_sec, 0);
214    EXPECT_EQ(oldValue.it_value.tv_nsec, 0);
215    EXPECT_EQ(oldValue.it_interval.tv_sec, 0);
216    EXPECT_EQ(oldValue.it_interval.tv_nsec, 0);
217
218    newValue.it_value.tv_sec = 0;
219    newValue.it_value.tv_nsec = 50;
220    newValue.it_interval.tv_sec = 1;
221    newValue.it_interval.tv_nsec = 0;
222    EXPECT_EQ(timer_settime(timerId, 0, &newValue, &oldValue2), 0);
223    EXPECT_EQ(oldValue2.it_interval.tv_sec, 1);
224    EXPECT_EQ(oldValue2.it_interval.tv_nsec, 0);
225
226    int timerRes = timer_delete(timerId);
227    EXPECT_EQ(timerRes, 0);
228}
229
230/*
231 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_SETTIME_0500
232 * @tc.name   : TimerSetTimeAbstimeSuccess_0005
233 * @tc.desc   : Test the timer_settime with TIMER_ABSTIME.
234 * @tc.size   : MediumTest
235 * @tc.type   : Function
236 * @tc.level  : Level 1
237 */
238HWTEST_F(TimerCreateApiTest, TimerSetTimeAbstimeSuccess_0005, Function | MediumTest | Level1)
239{
240    timer_t timerId;
241    struct itimerspec newValue;
242    struct itimerspec oldValue;
243    const clockid_t CLOCK_ID = CLOCK_REALTIME;
244
245    // Set the timer current time plus 50 nsec
246    struct timespec now;
247    clock_gettime(CLOCK_ID, &now);
248    newValue.it_value.tv_sec = now.tv_sec;
249    newValue.it_value.tv_nsec = now.tv_nsec + 50;
250    if (newValue.it_value.tv_nsec >= 1000000000) {
251        newValue.it_value.tv_nsec -= 1000000000;
252        newValue.it_value.tv_sec += 1;
253    }
254    newValue.it_interval.tv_sec = 0;
255    newValue.it_interval.tv_nsec = 0;
256
257    struct sigevent sev;
258    sev.sigev_notify = SIGEV_THREAD;
259    sev.sigev_notify_function = TimeHandler;
260    sev.sigev_value.sival_ptr = &g_timerExpired;
261
262    EXPECT_EQ(timer_create(CLOCK_ID, &sev, &timerId), 0);
263
264    EXPECT_EQ(timer_settime(timerId, TIMER_ABSTIME, &newValue, &oldValue), 0);
265
266    usleep(DELAY_TIME);
267    EXPECT_TRUE(g_timerExpired);
268
269    int timerRes = timer_delete(timerId);
270    EXPECT_EQ(timerRes, 0);
271}
272
273/*
274 * @tc.number : SUB_KERNEL_SYSCALL_TIMER_CREATE_0600
275 * @tc.name   : TimerCreateBoottimeAlarmSuccess_0006
276 * @tc.desc   : Test the timer_create with CLOCK_BOOTTIME_ALARM.
277 * @tc.size   : MediumTest
278 * @tc.type   : Function
279 * @tc.level  : Level 1
280 */
281HWTEST_F(TimerCreateApiTest, TimerCreateBoottimeAlarmSuccess_0006, Function | MediumTest | Level1)
282{
283    timer_t timerId;
284    const clockid_t CLOCK_ID = CLOCK_BOOTTIME_ALARM;
285    sighandler_t oldHandler = signal(SIGALRM, SigalrmHandler);
286    EXPECT_NE(oldHandler, SIG_ERR);
287    struct sigevent sev = {
288        .sigev_notify = SIGEV_SIGNAL,
289        .sigev_signo = SIGALRM,
290    };
291    struct itimerspec its = {
292        .it_interval = {
293            .tv_sec = 0,
294            .tv_nsec = 0,
295        },
296        .it_value = {
297            .tv_sec = 0,
298            .tv_nsec = 50,
299        },
300    };
301
302    EXPECT_EQ(timer_create(CLOCK_ID, &sev, &timerId), 0);
303    EXPECT_EQ(timer_settime(timerId, 0, &its, nullptr), 0);
304
305    usleep(DELAY_TIME);
306
307    EXPECT_TRUE(g_sigalRm);
308
309    int timerRes = timer_delete(timerId);
310    EXPECT_EQ(timerRes, 0);
311
312    signal(SIGALRM, oldHandler);
313}
314