1 #include <chrono>
2 #include <errno.h>
3 #include <gtest/gtest.h>
4 #include <pthread.h>
5 #include <string.h>
6 #include <thread>
7 #include <time.h>
8
9 using namespace testing::ext;
10
11 class TimerTest : public testing::Test {
SetUp()12 void SetUp() override {}
TearDown()13 void TearDown() override {}
14 };
15 #define SLEEPTIME 100
16 class SignalProcessor {
17 public:
SignalProcessor(int signalNum,void (* handler)(int),int saFlags=0)18 SignalProcessor(int signalNum, void (*handler)(int), int saFlags = 0)
19 : signalNumber_(signalNum), oldAction_(new struct sigaction)
20 {
21 action_ = { .sa_flags = saFlags, .sa_handler = handler };
22 sigaction(signalNumber_, &action_, oldAction_);
23 }
24
SignalProcessor(int signalNum,void (* action)(int,siginfo_t *,void *),int saFlags=SA_SIGINFO)25 SignalProcessor(int signalNum, void (*action)(int, siginfo_t*, void*), int saFlags = SA_SIGINFO)
26 : signalNumber_(signalNum), oldAction_(new struct sigaction)
27 {
28 action_ = { .sa_flags = saFlags, .sa_sigaction = action };
29 sigaction(signalNumber_, &action_, oldAction_);
30 }
31
~SignalProcessor()32 ~SignalProcessor()
33 {
34 sigaction(signalNumber_, oldAction_, nullptr);
35 delete oldAction_;
36 }
37
38 private:
39 const int signalNumber_;
40 struct sigaction action_;
41 struct sigaction* oldAction_;
42 };
43
44 class Scaler {
45 private:
46 std::atomic<int> value_;
47 timer_t timerId_;
48 struct sigevent se_;
49 bool timerValid_;
50
CreateTimer()51 void CreateTimer()
52 {
53 if (!timerValid_) {
54 if (timer_create(CLOCK_REALTIME, &se_, &timerId_) == 0) {
55 timerValid_ = true;
56 }
57 }
58 }
59
60 public:
Scaler(void (* fn)(sigval))61 explicit Scaler(void (*fn)(sigval)) : value_(0), timerValid_(false)
62 {
63 memset(&se_, 0, sizeof(se_));
64 se_.sigev_notify = SIGEV_THREAD;
65 se_.sigev_notify_function = fn;
66 se_.sigev_value.sival_ptr = this;
67 CreateTimer();
68 }
69
~Scaler()70 ~Scaler()
71 {
72 if (timerValid_) {
73 if (timerValid_) {
74 if (timer_delete(timerId_) == 0) {
75 timerValid_ = false;
76 }
77 }
78 }
79 }
80
Value() const81 int Value() const
82 {
83 return value_.load();
84 }
85
GetTimerValid()86 bool GetTimerValid()
87 {
88 return timerValid_;
89 }
90
GetTimerid()91 timer_t GetTimerid()
92 {
93 return timerId_;
94 }
95
Change()96 void Change()
97 {
98 timerValid_ = false;
99 }
100
SetTimer(time_t valueS,time_t valueNs,time_t intervalS,time_t intervalNs)101 void SetTimer(time_t valueS, time_t valueNs, time_t intervalS, time_t intervalNs)
102 {
103 itimerspec newValue;
104 newValue.it_value.tv_sec = valueS;
105 newValue.it_value.tv_nsec = valueNs;
106 newValue.it_interval.tv_sec = intervalS;
107 newValue.it_interval.tv_nsec = intervalNs;
108 timer_settime(timerId_, 0, &newValue, nullptr);
109 }
110
ValUpdate()111 bool ValUpdate()
112 {
113 int currentValue = value_;
114 time_t start = time(nullptr);
115 while (currentValue == value_ && (time(nullptr) - start) < 5) {
116 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEPTIME));
117 }
118 return currentValue != value_;
119 }
120
ScalerFunc(sigval value_)121 static void ScalerFunc(sigval value_)
122 {
123 Scaler* cd = reinterpret_cast<Scaler*>(value_.sival_ptr);
124 ++cd->value_;
125 }
126
ScaNotifyFunc(sigval value_)127 static void ScaNotifyFunc(sigval value_)
128 {
129 Scaler* cd = reinterpret_cast<Scaler*>(value_.sival_ptr);
130 ++cd->value_;
131 cd->SetTimer(0, 0, 1, 0);
132 }
133 };
134
NotifyFunction(sigval)135 static void NotifyFunction(sigval) {}
136 static int g_count = 0;
Handler(int sig)137 void Handler(int sig)
138 {
139 g_count++;
140 return;
141 }
142
143 /**
144 * @tc.name: timer_create_001
145 * @tc.desc: Verify that the "timer_create" function correctly creates a timer with the specified attributes and
146 * that the "timer_delete" function successfully deletes the created timer.
147 * @tc.type: FUNC
148 **/
149 HWTEST_F(TimerTest, timer_create_001, TestSize.Level1)
150 {
151 struct sigevent sev;
152 timer_t timerid;
153
154 sev.sigev_notify = SIGEV_SIGNAL;
155 sev.sigev_signo = SIGUSR1;
156 sev.sigev_value.sival_ptr = &timerid;
157 signal(SIGUSR1, Handler);
158 int result = timer_create(CLOCK_REALTIME, &sev, &timerid);
159 EXPECT_EQ(result, 0);
160 EXPECT_EQ(0, timer_delete(timerid));
161 }
162
163 /**
164 * @tc.name: timer_create_002
165 * @tc.desc: Verify that the "timer_create" function properly handles invalid input arguments and returns the expected
166 * error code in the event of such errors.
167 * @tc.type: FUNC
168 **/
169 HWTEST_F(TimerTest, timer_create_002, TestSize.Level1)
170 {
171 clockid_t invalid = 13;
172 timer_t timer;
173 EXPECT_EQ(timer_create(invalid, nullptr, &timer), -1);
174 EXPECT_EQ(EINVAL, errno);
175
176 sigevent sev;
177 memset(&sev, 0, sizeof(sev));
178 sev.sigev_notify = SIGEV_THREAD;
179 sev.sigev_notify_function = NotifyFunction;
180 EXPECT_EQ(-1, timer_create(invalid, &sev, &timer));
181 EXPECT_EQ(EINVAL, errno);
182 }
183
184 /**
185 * @tc.name: timer_delete_001
186 * @tc.desc: Check if the timer is properly deleted and if the scaler's value remains unchanged after the
187 * timer is deleted.
188 * @tc.type: FUNC
189 **/
190 HWTEST_F(TimerTest, timer_delete_001, TestSize.Level1)
191 {
192 Scaler scaler(Scaler::ScalerFunc);
193 EXPECT_EQ(0, scaler.Value());
194
195 scaler.SetTimer(0, 2, 0, 2);
196
197 EXPECT_TRUE(scaler.ValUpdate());
198 EXPECT_TRUE(scaler.ValUpdate());
199 bool timerValid = scaler.GetTimerValid();
200 timer_t timerid = scaler.GetTimerid();
201 if (timerValid) {
202 if (timer_delete(timerid) == 0) {
203 scaler.Change();
204 }
205 }
206 std::chrono::nanoseconds duration1(500000);
207 std::this_thread::sleep_for(duration1);
208 int value = scaler.Value();
209 std::chrono::nanoseconds duration2(500000);
210 std::this_thread::sleep_for(duration2);
211 EXPECT_EQ(value, scaler.Value());
212 }
213
214 /**
215 * @tc.name: timer_settime_001
216 * @tc.desc: Verify that the "SetTimer" function of the "Scaler" object correctly sets the expiration time for a timer
217 * associated with the object, allowing for proper management and triggering of timers in the system.
218 * @tc.type: FUNC
219 **/
220 HWTEST_F(TimerTest, timer_settime_001, TestSize.Level1)
221 {
222 Scaler scaler(Scaler::ScaNotifyFunc);
223 EXPECT_EQ(0, scaler.Value());
224 scaler.SetTimer(0, 500000000, 1, 0);
225 sleep(1);
226 EXPECT_EQ(1, scaler.Value());
227 }
228
229 /**
230 * @tc.name: timer_settime_002
231 * @tc.desc: Verify that the "SetTimer" function of the "Scaler" object correctly sets a timer with a reload interval
232 * and that the timer can be successfully deleted.
233 * @tc.type: FUNC
234 **/
235 HWTEST_F(TimerTest, timer_settime_002, TestSize.Level1)
236 {
237 Scaler scaler(Scaler::ScalerFunc);
238 EXPECT_EQ(0, scaler.Value());
239
240 scaler.SetTimer(0, 1, 0, 10);
241 // Increase the probability of the timer reaching the set time
242 EXPECT_TRUE(scaler.ValUpdate());
243 EXPECT_TRUE(scaler.ValUpdate());
244 bool timerValid = scaler.GetTimerValid();
245 timer_t timerid = scaler.GetTimerid();
246 if (timerValid) {
247 if (timer_delete(timerid) == 0) {
248 scaler.Change();
249 }
250 }
251 std::chrono::nanoseconds duration(500000);
252 std::this_thread::sleep_for(duration);
253 }