1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
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 <gtest/gtest.h>
17 #include <ostream>
18 #include <securec.h>
19 #include <cstdint>
20
21 #include "refbase.h"
22 #include "sync_fence.h"
23 #include "sync_fence_timeline.h"
24 #include "sync_fence_tracker.h"
25
26 using namespace testing;
27 using namespace testing::ext;
28
29 namespace OHOS {
30 class SyncFenceTest : public testing::Test {
31 public:
32 static void SetUpTestCase();
33 static void TearDownTestCase();
34 };
35
SetUpTestCase()36 void SyncFenceTest::SetUpTestCase()
37 {
38 }
39
TearDownTestCase()40 void SyncFenceTest::TearDownTestCase()
41 {
42 }
43
44 /*
45 * Function: IsValid
46 * Type: Function
47 * Rank: Important(2)
48 * EnvConditions: N/A
49 * CaseDescription: 1. call IsValid
50 * 2. check ret
51 */
52 HWTEST_F(SyncFenceTest, IsValid001, Function | MediumTest | Level2)
53 {
54 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
55 bool valid = syncTimeline_->IsValid();
56 if (valid) {
57 ASSERT_EQ(valid, true);
58 } else {
59 ASSERT_EQ(valid, false);
60 }
61 }
62
63 /*
64 * Function: IsValid, GenerateFence
65 * Type: Function
66 * Rank: Important(2)
67 * EnvConditions: N/A
68 * CaseDescription: 1. call GenerateFence
69 * 2. check ret
70 */
71 HWTEST_F(SyncFenceTest, GenerateFence001, Function | MediumTest | Level2)
72 {
73 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
74 bool valid = syncTimeline_->IsValid();
75 if (valid) {
76 ASSERT_EQ(valid, true);
77 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
78 SyncFence syncFence(fd);
79 ASSERT_GE(fd, 0);
80 } else {
81 ASSERT_EQ(valid, false);
82 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
83 ASSERT_EQ(fd, -1);
84 int32_t ret = syncTimeline_->IncreaseSyncPoint(1);
85 ASSERT_EQ(ret, -1);
86 }
87 }
88
89 /*
90 * Function: IsValid, GenerateFence, SyncFileReadTimestamp
91 * Type: Function
92 * Rank: Important(2)
93 * EnvConditions: N/A
94 * CaseDescription: 1. call GenerateFence
95 * 2. check ret
96 */
97 HWTEST_F(SyncFenceTest, GetFenceInfo001, Function | MediumTest | Level2)
98 {
99 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
100 bool valid = syncTimeline_->IsValid();
101 if (valid) {
102 ASSERT_EQ(valid, true);
103 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
104 SyncFence syncFence(fd);
105 ASSERT_GE(fd, 0);
106 int64_t timestamp = syncFence.SyncFileReadTimestamp();
107 ASSERT_EQ(timestamp, SyncFence::FENCE_PENDING_TIMESTAMP);
108 auto ret = syncTimeline_->IncreaseSyncPoint(1);
109 ASSERT_EQ(ret, 0);
110 timestamp = syncFence.SyncFileReadTimestamp();
111 ASSERT_GT(timestamp, 0);
112 } else {
113 ASSERT_EQ(valid, false);
114 }
115 }
116
117 /*
118 * Function: IsValid, GenerateFence, IncreaseSyncPoint, GetStatus
119 * Type: Function
120 * Rank: Important(2)
121 * EnvConditions: N/A
122 * CaseDescription: 1. call IsValid, GenerateFence, IncreaseSyncPoint, GetStatus
123 * 2. check ret
124 */
125 HWTEST_F(SyncFenceTest, OneTimeLineGetStatus001, Function | MediumTest | Level2)
126 {
127 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
128 bool valid = syncTimeline_->IsValid();
129 if (valid) {
130 ASSERT_EQ(valid, true);
131 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
132 SyncFence syncFence(fd);
133 ASSERT_GE(fd, 0);
134 FenceStatus st = syncFence.GetStatus();
135 ASSERT_EQ(st, FenceStatus::ACTIVE);
136 auto ret = syncTimeline_->IncreaseSyncPoint(1);
137 ASSERT_EQ(ret, 0);
138 st = syncFence.GetStatus();
139 ASSERT_EQ(st, FenceStatus::SIGNALED);
140 // go 2 even futher, still signal status
141 syncTimeline_->IncreaseSyncPoint(2);
142 ASSERT_EQ(ret, 0);
143 st = syncFence.GetStatus();
144 ASSERT_EQ(st, FenceStatus::SIGNALED);
145 } else {
146 ASSERT_EQ(valid, false);
147 }
148 }
149
150 /*
151 * Function: IsValid, GenerateFence, Wait, GetStatus
152 * Type: Function
153 * Rank: Important(2)
154 * EnvConditions: N/A
155 * CaseDescription: 1. call IsValid, GenerateFence, Wait, GetStatus
156 * 2. check ret
157 */
158 HWTEST_F(SyncFenceTest, OneTimeLineWait001, Function | MediumTest | Level2)
159 {
160 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
161 bool valid = syncTimeline_->IsValid();
162 if (valid) {
163 ASSERT_EQ(valid, true);
164 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 3);
165 SyncFence syncFence(fd);
166 ASSERT_GE(fd, 0);
167
168 // increase timeline from 0 -> 1
169 auto ret = syncTimeline_->IncreaseSyncPoint(1);
170 ASSERT_EQ(ret, 0);
171 // wait on fence until timeout
172 ret = syncFence.Wait(0);
173 ASSERT_LT(ret, 0);
174 ASSERT_EQ(errno, ETIME);
175 auto st = syncFence.GetStatus();
176 ASSERT_EQ(st, FenceStatus::ACTIVE);
177 // increase 2 timeline from 1 -> 3, signal the fence
178 ret = syncTimeline_->IncreaseSyncPoint(2);
179 ASSERT_EQ(ret, 0);
180 // wait succ
181 ret = syncFence.Wait(0);
182 ASSERT_EQ(ret, 0);
183 st = syncFence.GetStatus();
184 ASSERT_EQ(st, FenceStatus::SIGNALED);
185 // go 5 even futher, still signal status
186 ret = syncTimeline_->IncreaseSyncPoint(5);
187 ASSERT_EQ(ret, 0);
188 ret = syncFence.Wait(0);
189 ASSERT_EQ(ret, 0);
190 st = syncFence.GetStatus();
191 ASSERT_EQ(st, FenceStatus::SIGNALED);
192 } else {
193 ASSERT_EQ(valid, false);
194 }
195 }
196
197 /*
198 * Function: IsValid, GenerateFence, MergeFence
199 * Type: Function
200 * Rank: Important(2)
201 * EnvConditions: N/A
202 * CaseDescription: 1. call IsValid, GenerateFence, MergeFence
203 * 2. check ret
204 */
205 HWTEST_F(SyncFenceTest, OneTimeLineMerge001, Function | MediumTest | Level2)
206 {
207 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
208 bool valid = syncTimeline_->IsValid();
209 if (valid) {
210 ASSERT_EQ(valid, true);
211 int32_t fd1 = syncTimeline_->GenerateFence("test sw_sync_fence1", 1);
212 sptr<SyncFence> syncFence1 = new SyncFence(fd1);
213 ASSERT_GE(fd1, 0);
214 // timeline generate fence2 target 5 seq.no
215 int32_t fd2 = syncTimeline_->GenerateFence("test sw_sync_fence2", 5);
216 sptr<SyncFence> syncFence2 = new SyncFence(fd2);
217 ASSERT_GE(fd2, 0);
218
219 sptr<SyncFence> fdMerged = SyncFence::MergeFence("merged sw_fence", syncFence1, syncFence2);
220 ASSERT_GE(fdMerged->Get(), 0);
221 auto st = fdMerged->GetStatus();
222 ASSERT_EQ(st, FenceStatus::ACTIVE);
223
224 // increase 1 timeline from 0 -> 1
225 auto ret = syncTimeline_->IncreaseSyncPoint(1);
226 ASSERT_EQ(ret, 0);
227 st = fdMerged->GetStatus();
228 ASSERT_EQ(st, FenceStatus::ACTIVE);
229 // increase 4 timeline from 1 -> 5, signal fence
230 ret = syncTimeline_->IncreaseSyncPoint(4);
231 ASSERT_EQ(ret, 0);
232 st = fdMerged->GetStatus();
233 ASSERT_EQ(st, FenceStatus::SIGNALED);
234 } else {
235 ASSERT_EQ(valid, false);
236 }
237 }
238
239 /*
240 * Function: IsValid, GenerateFence, MergeFence
241 * Type: Function
242 * Rank: Important(2)
243 * EnvConditions: N/A
244 * CaseDescription: 1. call IsValid, GenerateFence, MergeFence
245 * 2. check ret
246 */
247 HWTEST_F(SyncFenceTest, MultiTimeLineMerge001, Function | MediumTest | Level2)
248 {
249 sptr<SyncTimeline> syncTimeline1_ = new SyncTimeline();
250 bool valid = syncTimeline1_->IsValid();
251 if (!valid) {
252 ASSERT_EQ(valid, false);
253 return;
254 }
255 sptr<SyncTimeline> syncTimeline2_ = new SyncTimeline();
256 valid = syncTimeline2_->IsValid();
257 if (valid) {
258 ASSERT_EQ(valid, true);
259 // timeline1 generate fence1 target 1 seq.no
260 int32_t fd1 = syncTimeline1_->GenerateFence("test sw_sync_fence1", 1);
261 sptr<SyncFence> syncFence1 = new SyncFence(fd1);
262 ASSERT_GE(fd1, 0);
263 // timeline2 generate fence2 target 5 seq.no
264 int32_t fd2 = syncTimeline2_->GenerateFence("test sw_sync_fence2", 5);
265 sptr<SyncFence> syncFence2 = new SyncFence(fd2);
266 ASSERT_GE(fd2, 0);
267
268 sptr<SyncFence> fdMerged = SyncFence::MergeFence("merged sw_fence", syncFence1, syncFence2);
269 ASSERT_GE(fdMerged->Get(), 0);
270 auto st = fdMerged->GetStatus();
271 ASSERT_EQ(st, FenceStatus::ACTIVE);
272 // timeline1 increase 1 timeline from 0 -> 1, signal fence fence1
273 auto ret = syncTimeline1_->IncreaseSyncPoint(1);
274 ASSERT_EQ(ret, 0);
275 st = fdMerged->GetStatus();
276 ASSERT_EQ(st, FenceStatus::ACTIVE);
277 // timeline2 increase 5 timeline from 0 -> 5, signal fence fence2
278 ret = syncTimeline2_->IncreaseSyncPoint(5);
279 ASSERT_EQ(ret, 0);
280 st = fdMerged->GetStatus();
281 ASSERT_EQ(st, FenceStatus::SIGNALED);
282 } else {
283 ASSERT_EQ(valid, false);
284 }
285 }
286
287 /*
288 * Function: IsValid, Dup, Get
289 * Type: Function
290 * Rank: Important(2)
291 * EnvConditions: N/A
292 * CaseDescription: 1. call GenerateFence, IsValid, Dup, Get
293 * 2. check ret
294 */
295 HWTEST_F(SyncFenceTest, IsValidGetDup001, Function | MediumTest | Level2)
296 {
297 sptr<SyncTimeline> syncTimeline = new SyncTimeline();
298 bool valid = syncTimeline->IsValid();
299 if (valid) {
300 ASSERT_EQ(valid, true);
301 int32_t fd = syncTimeline->GenerateFence("test sw_sync_fence", 1);
302 SyncFence syncFence(fd);
303 ASSERT_GE(fd, 0);
304 bool fenceValid = syncFence.IsValid();
305 ASSERT_EQ(fenceValid, true);
306 int32_t getFd = syncFence.Get();
307 ASSERT_EQ(getFd, fd);
308 int32_t dupFenceFd = syncFence.Dup();
309 ASSERT_GE(dupFenceFd, 0);
310 } else {
311 ASSERT_EQ(valid, false);
312 }
313 }
314
315 /*
316 * Function: IsValid
317 * Type: Function
318 * Rank: Important(2)
319 * EnvConditions: N/A
320 * CaseDescription: 1. call IsValid
321 * 2. check ret
322 */
323 HWTEST_F(SyncFenceTest, IsValid002, Function | MediumTest | Level2)
324 {
325 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
326 bool valid = syncTimeline_->IsValid();
327 if (valid) {
328 ASSERT_EQ(valid, true);
329 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
330 sptr<SyncFence> syncFence_ = new SyncFence(fd);
331 ASSERT_GE(fd, 0);
332 auto syncFenceTime_ = std::make_shared<SyncFenceTime>(syncFence_);
333 ASSERT_EQ(true, syncFenceTime_->IsValid());
334 } else {
335 ASSERT_EQ(valid, false);
336 }
337 }
338
339 /*
340 * Function: IsValid, GetSignalTimestamp
341 * Type: Function
342 * Rank: Important(2)
343 * EnvConditions: N/A
344 * CaseDescription: 1. call GetSignalTimestamp
345 * 2. check ret
346 */
347 HWTEST_F(SyncFenceTest, GetSignalTimestamp001, Function | MediumTest | Level2)
348 {
349 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
350 bool valid = syncTimeline_->IsValid();
351 if (valid) {
352 ASSERT_EQ(valid, true);
353 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
354 sptr<SyncFence> syncFence_ = new SyncFence(fd);
355 ASSERT_GE(fd, 0);
356 auto syncFenceTime_ = std::make_shared<SyncFenceTime>(syncFence_);
357 ns_sec_t timestamp = syncFenceTime_->GetSignalTimestamp();
358 ASSERT_EQ(syncFenceTime_->GetCachedSignalTimestamp(), timestamp);
359 } else {
360 ASSERT_EQ(valid, false);
361 }
362 }
363
364 /*
365 * Function: Push
366 * Type: Function
367 * Rank: Important(2)
368 * EnvConditions: N/A
369 * CaseDescription: 1. call Push
370 * 2. check ret
371 */
372 HWTEST_F(SyncFenceTest, Push001, Function | MediumTest | Level2)
373 {
374 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
375 bool valid = syncTimeline_->IsValid();
376 if (valid) {
377 ASSERT_EQ(valid, true);
378 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
379 sptr<SyncFence> syncFence_ = new SyncFence(fd);
380 ASSERT_GE(fd, 0);
381 auto syncFenceTime_ = std::make_shared<SyncFenceTime>(syncFence_);
382 auto syncFenceTimeline_ = std::make_shared<SyncFenceTimeline>();
383 syncFenceTimeline_->Push(syncFenceTime_);
384 } else {
385 ASSERT_EQ(valid, false);
386 }
387 }
388
389 /*
390 * Function: UpdateFenceTimeline
391 * Type: Function
392 * Rank: Important(2)
393 * EnvConditions: N/A
394 * CaseDescription: 1. call UpdateFenceTimeline
395 * 2. check ret
396 */
397 HWTEST_F(SyncFenceTest, UpdateFenceTimeline001, Function | MediumTest | Level2)
398 {
399 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
400 bool valid = syncTimeline_->IsValid();
401 if (valid) {
402 ASSERT_EQ(valid, true);
403 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence", 1);
404 sptr<SyncFence> syncFence_ = new SyncFence(fd);
405 ASSERT_GE(fd, 0);
406 auto syncFenceTime_ = std::make_shared<SyncFenceTime>(syncFence_);
407 auto syncFenceTimeline_ = std::make_shared<SyncFenceTimeline>();
408 syncFenceTimeline_->UpdateFenceTimeline();
409 syncFenceTimeline_->Push(syncFenceTime_);
410 syncFenceTimeline_->UpdateFenceTimeline();
411
412 } else {
413 ASSERT_EQ(valid, false);
414 }
415 }
416
417 /*
418 * Function: SyncFenceTracker
419 * Type: Function
420 * Rank: Important(2)
421 * EnvConditions: N/A
422 * CaseDescription: 1. call SyncFenceTracker
423 * 2. check ret
424 */
425 HWTEST_F(SyncFenceTest, SyncFenceTrackerTest, Function | MediumTest | Level2)
426 {
427 auto tracker = std::make_shared<SyncFenceTracker>("test sw_sync_fence1");
428 }
429
430 /*
431 * Function: TrackFence
432 * Type: Function
433 * Rank: Important(2)
434 * EnvConditions: N/A
435 * CaseDescription: 1. call TrackFence, call Loop
436 * 2. check ret
437 */
438 HWTEST_F(SyncFenceTest, TrackFenceTest, Function | MediumTest | Level2)
439 {
440 sptr<SyncTimeline> syncTimeline_ = new SyncTimeline();
441 bool valid = syncTimeline_->IsValid();
442 ASSERT_EQ(true, valid);
443 int32_t fd = syncTimeline_->GenerateFence("test sw_sync_fence_timeline", 1);
444 sptr<SyncFence> syncFence = new SyncFence(fd);
445 ASSERT_GE(fd, 0);
446
447 auto tracker = std::make_shared<SyncFenceTracker>("test sw_sync_fence");
448 tracker->TrackFence(syncFence);
449
450 // increase timeline from 0 -> 1
451 auto ret = syncTimeline_->IncreaseSyncPoint(1);
452 ASSERT_EQ(ret, 0);
453 tracker->TrackFence(syncFence);
454 }
455 } // namespace OHOS