• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include "gtest/gtest.h"
16 
17 #define protected public
18 #define private public
19 
20 #include "test/mock/core/pipeline/mock_pipeline_context.h"
21 
22 #include "core/common/multi_thread_build_manager.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/base/ui_node.h"
25 #include "core/components_ng/pattern/pattern.h"
26 #include "frameworks/core/pipeline/base/element_register_multi_thread.h"
27 
28 using namespace testing;
29 using namespace testing::ext;
30 
31 namespace OHOS::Ace::NG {
32 class ThreadSafeNodeTestNg : public testing::Test {
33 public:
34     static void SetUpTestSuite();
35     static void TearDownTestSuite();
36 };
37 
SetUpTestSuite()38 void ThreadSafeNodeTestNg::SetUpTestSuite()
39 {
40     MockPipelineContext::SetUp();
41 }
42 
TearDownTestSuite()43 void ThreadSafeNodeTestNg::TearDownTestSuite()
44 {
45     MockPipelineContext::TearDown();
46 }
47 
48 /**
49  * @tc.name: ThreadSafeNodeTestNg001
50  * @tc.desc: Test AddUINodeMultiThread Repeated
51  * @tc.type: FUNC
52  */
53 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg001, TestSize.Level1)
54 {
55     /**
56      * @tc.steps: step1. create thread safe uinode
57      */
58     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
59     auto frameNode = AceType::MakeRefPtr<FrameNode>("main", 1, AceType::MakeRefPtr<Pattern>(), true);
60     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
61 
62     /**
63      * @tc.steps: step2. thread safe uinode add to ElementRegister
64      * @tc.expected: add success
65      */
66     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->AddUINodeMultiThread(frameNode), true);
67 
68     /**
69      * @tc.steps: step3. thread safe uinode add to ElementRegister again
70      * @tc.expected: add failed
71      */
72     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->AddUINodeMultiThread(frameNode), false);
73 }
74 
75 /**
76  * @tc.name: ThreadSafeNodeTestNg002
77  * @tc.desc: Test GetThreadSafeNodeById
78  * @tc.type: FUNC
79  */
80 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg002, TestSize.Level1)
81 {
82     /**
83      * @tc.steps: step1. create thread safe uinode
84      */
85     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
86     auto frameNode =
87         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
88     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
89     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->AddUINodeMultiThread(frameNode), true);
90 
91     /**
92      * @tc.steps: step2. get the thread safe node which id is 1 from ElementRegister
93      * @tc.expected: get success
94      */
95     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->GetThreadSafeNodeById(1), true);
96 
97     /**
98      * @tc.steps: step3. get the thread safe node which id is ElementRegister::UndefinedElementId from ElementRegister
99      * @tc.expected: get failed
100      */
101     EXPECT_EQ(
102          ElementRegisterMultiThread::GetInstance()->GetThreadSafeNodeById(ElementRegister::UndefinedElementId), false);
103 }
104 
105 /**
106  * @tc.name: ThreadSafeNodeTestNg003
107  * @tc.desc: Test RemoveThreadSafeNode
108  * @tc.type: FUNC
109  */
110 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg003, TestSize.Level1)
111 {
112     /**
113      * @tc.steps: step1. create thread safe uinode
114      */
115     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
116     auto frameNode =
117         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
118     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
119     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->AddUINodeMultiThread(frameNode), true);
120 
121     /**
122      * @tc.steps: step2. remove the thread safe node which id is 1 from ElementRegister
123      * @tc.expected: remove success
124      */
125     EXPECT_EQ(ElementRegisterMultiThread::GetInstance()->RemoveThreadSafeNode(1), true);
126 
127     /**
128      * @tc.steps: step3. remove the thread safe node which
129      * id is ElementRegister::UndefinedElementId from ElementRegister
130      * @tc.expected: remove failed
131      */
132     EXPECT_EQ(
133         ElementRegisterMultiThread::GetInstance()->RemoveThreadSafeNode(ElementRegister::UndefinedElementId), false);
134 }
135 
136 /**
137  * @tc.name: ThreadSafeNodeTestNg004
138  * @tc.desc: Test thread safe node RebuildRenderContextTree.
139  * @tc.type: FUNC
140  */
141 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg004, TestSize.Level1)
142 {
143     /**
144      * @tc.steps: step1. create thread safe uinode
145      */
146     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
147     auto frameNode =
148         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
149     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
150 
151     /**
152      * @tc.steps: step2. thread safe uinode RebuildRenderContextTree
153      * @tc.expected: rebuild success
154      */
155     int32_t taskSize = frameNode->afterAttachMainTreeTasks_.size();
156     frameNode->RebuildRenderContextTree();
157     EXPECT_EQ(frameNode->afterAttachMainTreeTasks_.size(), taskSize + 1);
158 }
159 
160 /**
161  * @tc.name: ThreadSafeNodeTestNg005
162  * @tc.desc: Test thread safe node MarkNeedRender.
163  * @tc.type: FUNC
164  */
165 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg005, TestSize.Level1)
166 {
167     /**
168      * @tc.steps: step1. create thread safe uinode
169      */
170     auto context = MockPipelineContext::GetCurrent();
171     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
172     auto frameNode =
173         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
174     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
175     frameNode->context_ = AceType::RawPtr(context);
176     frameNode->isRenderDirtyMarked_ = false;
177     frameNode->isLayoutDirtyMarked_ = false;
178 
179     /**
180      * @tc.steps: step2. thread safe uinode MarkNeedRender
181      * @tc.expected: mark success
182      */
183     int32_t taskSize = frameNode->afterAttachMainTreeTasks_.size();
184     frameNode->MarkNeedRender(true);
185     EXPECT_EQ(frameNode->afterAttachMainTreeTasks_.size(), taskSize + 1);
186 
187     /**
188      * @tc.steps: step3. create not thread safe uinode
189      */
190     auto frameNode2 =
191         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
192     frameNode2->context_ = AceType::RawPtr(context);
193     frameNode2->isRenderDirtyMarked_ = false;
194     frameNode2->isLayoutDirtyMarked_ = false;
195 
196     /**
197      * @tc.steps: step4. not thread safe uinode MarkNeedRender
198      * @tc.expected: mark success
199      */
200     taskSize = frameNode2->afterAttachMainTreeTasks_.size();
201     frameNode2->MarkNeedRender(true);
202     EXPECT_EQ(frameNode2 ->afterAttachMainTreeTasks_.size(), taskSize);
203 }
204 
205 /**
206  * @tc.name: ThreadSafeNodeTestNg006
207  * @tc.desc: Test thread safe uinode create.
208  * @tc.type: FUNC
209  */
210 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg006, TestSize.Level1)
211 {
212     /**
213      * @tc.steps: step1. create thread safe uinode
214      * @tc.expected: create success
215      */
216     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
217     auto frameNode =
218         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
219     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
220     EXPECT_EQ(frameNode->isThreadSafeNode_, true);
221     EXPECT_EQ(frameNode->isFree_, true);
222 }
223 
224 /**
225  * @tc.name: ThreadSafeNodeTestNg007
226  * @tc.desc: Test thread safe uinode release
227  * @tc.type: FUNC
228  */
229 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg007, TestSize.Level1)
230 {
231     bool isUIThread = MultiThreadBuildManager::isUIThread_;
232     {
233         /**
234          * @tc.steps: step1. create thread safe uinode
235          */
236         MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
237         auto frameNode =
238             FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
239         MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
240         /**
241          * @tc.steps: step2. release thread safe uinode not on ui thread
242          * @tc.expected: release success
243          */
244         MultiThreadBuildManager::isUIThread_ = false;
245         EXPECT_EQ(frameNode->isThreadSafeNode_, true);
246         EXPECT_EQ(frameNode->isFree_, true);
247     }
248     {
249         /**
250          * @tc.steps: step3. create thread safe uinode
251          */
252         MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
253         auto frameNode =
254             FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
255         MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
256         /**
257          * @tc.steps: step2. release thread safe uinode on ui thread
258          * @tc.expected: release success
259          */
260         MultiThreadBuildManager::isUIThread_ = true;
261         EXPECT_EQ(frameNode->isThreadSafeNode_, true);
262         EXPECT_EQ(frameNode->isFree_, true);
263     }
264     MultiThreadBuildManager::isUIThread_ = isUIThread;
265 }
266 
267 /**
268  * @tc.name: ThreadSafeNodeTestNg0088
269  * @tc.desc: Test uinode release
270  * @tc.type: FUNC
271  */
272 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg008, TestSize.Level1)
273 {
274     bool isUIThread = MultiThreadBuildManager::isUIThread_;
275     {
276         /**
277          * @tc.steps: step1. create not thread safe uinode
278          */
279         auto frameNode =
280             FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
281         /**
282          * @tc.steps: step2. release not thread safe uinode not on ui thread
283          * @tc.expected: release success
284          */
285         MultiThreadBuildManager::isUIThread_ = false;
286         EXPECT_EQ(frameNode->isThreadSafeNode_, false);
287         EXPECT_EQ(frameNode->isFree_, false);
288     }
289     {
290         /**
291          * @tc.steps: step3. create not thread safe uinode
292          */
293         auto frameNode =
294             FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
295         /**
296          * @tc.steps: step4. release not thread safe uinode on ui thread
297          * @tc.expected: release success
298          */
299         MultiThreadBuildManager::isUIThread_ = true;
300         EXPECT_EQ(frameNode->isThreadSafeNode_, false);
301         EXPECT_EQ(frameNode->isFree_, false);
302     }
303     MultiThreadBuildManager::isUIThread_ = isUIThread;
304 }
305 
306 /**
307  * @tc.name: ThreadSafeNodeTestNg009
308  * @tc.desc: Test thread safe uinode AttachToMainTree.
309  * @tc.type: FUNC
310  */
311 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg009, TestSize.Level1)
312 {
313     /**
314      * @tc.steps: step1. create thread safe uinode
315      */
316     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
317     auto frameNode =
318         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
319     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
320 
321     /**
322      * @tc.steps: step2. thread safe uinode AttachToMainTree and DetachFromMainTree
323      * @tc.expected: attach and detach success
324      */
325     PipelineContext* pipeline = frameNode->GetContextWithCheck();
326     frameNode->AttachToMainTree(false, pipeline);
327     EXPECT_EQ(frameNode->isFree_, false);
328     frameNode->DetachFromMainTree(false, false);
329     EXPECT_EQ(frameNode->isFree_, true);
330 }
331 
332 /**
333  * @tc.name: ThreadSafeNodeTestNg010
334  * @tc.desc: Test thread safe uinode DetachFromMainTree.
335  * @tc.type: FUNC
336  */
337 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg010, TestSize.Level1)
338 {
339     /**
340      * @tc.steps: step1. create thread safe uinode
341      */
342     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
343     auto frameNode =
344         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
345     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
346 
347     /**
348      * @tc.steps: step2. thread safe uinode AttachToMainTree and DetachFromMainTree
349      * @tc.expected: attach and detach success
350      */
351     PipelineContext* pipeline = frameNode->GetContextWithCheck();
352     frameNode->AttachToMainTree(false, pipeline);
353     EXPECT_EQ(frameNode->isFree_, false);
354     frameNode->DetachFromMainTree(false, true);
355     EXPECT_EQ(frameNode->isFree_, true);
356 }
357 
358 /**
359  * @tc.name: ThreadSafeNodeTestNg011
360  * @tc.desc: Test thread safe uinode tree DetachFromMainTree.
361  * @tc.type: FUNC
362  */
363 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg011, TestSize.Level1)
364 {
365     /**
366      * @tc.steps: step1. create thread safe uinode tree
367      */
368     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
369     auto frameNode =
370         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
371     auto child =
372         FrameNode::CreateFrameNode("main", 2, AceType::MakeRefPtr<Pattern>(), true);
373     frameNode->AddChild(child);
374     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
375 
376     /**
377      * @tc.steps: step2. thread safe uinode tree AttachToMainTree and DetachFromMainTree
378      * @tc.expected: attach and detach success
379      */
380     PipelineContext* pipeline = frameNode->GetContextWithCheck();
381     frameNode->AttachToMainTree(false, pipeline);
382     EXPECT_EQ(frameNode->isFree_, false);
383     frameNode->DetachFromMainTree(false, true);
384     EXPECT_EQ(frameNode->isFree_, true);
385 }
386 
387 /**
388  * @tc.name: ThreadSafeNodeTestNg012
389  * @tc.desc: Test not thread safe ui node tree DetachFromMainTree.
390  * @tc.type: FUNC
391  */
392 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg012, TestSize.Level1)
393 {
394     /**
395      * @tc.steps: step1. create thread safe uinode
396      */
397     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
398     auto frameNode =
399         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
400     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
401     /**
402      * @tc.steps: step2. create not thread safe uinode tree
403      */
404     auto child =
405         FrameNode::CreateFrameNode("main", 2, AceType::MakeRefPtr<Pattern>(), true);
406     frameNode->AddChild(child);
407     /**
408      * @tc.steps: step3. not thread safe uinode tree AttachToMainTree and DetachFromMainTree
409      * @tc.expected: attach and detach success
410      */
411     PipelineContext* pipeline = frameNode->GetContextWithCheck();
412     frameNode->AttachToMainTree(false, pipeline);
413     EXPECT_EQ(frameNode->isFree_, false);
414     frameNode->DetachFromMainTree(false, true);
415     EXPECT_EQ(frameNode->isFree_, true);
416 }
417 
418 /**
419  * @tc.name: ThreadSafeNodeTestNg013
420  * @tc.desc: Test thread safe node MarkModifyDone.
421  * @tc.type: FUNC
422  */
423 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg013, TestSize.Level1)
424 {
425     /**
426      * @tc.steps: step1. create thread safe uinode
427      */
428     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
429     auto frameNode =
430         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
431     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
432     /**
433      * @tc.steps: step2. thread safe uinode MarkModifyDone
434      * @tc.expected: MarkModifyDone success
435      */
436     int32_t taskSize = frameNode->afterAttachMainTreeTasks_.size();
437     frameNode->MarkModifyDone();
438     EXPECT_EQ(frameNode->afterAttachMainTreeTasks_.size(), taskSize + 1);
439 }
440 
441 /**
442  * @tc.name: ThreadSafeNodeTestNg014
443  * @tc.desc: Test thread safe node MarkDirtyNode.
444  * @tc.type: FUNC
445  */
446 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg014, TestSize.Level1)
447 {
448     /**
449      * @tc.steps: step1. create thread safe uinode
450      */
451     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
452     auto frameNode =
453         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
454     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
455     /**
456      * @tc.steps: step2. thread safe uinode MarkDirtyNode
457      * @tc.expected: MarkDirtyNode success
458      */
459     int32_t taskSize = frameNode->afterAttachMainTreeTasks_.size();
460     frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
461     EXPECT_EQ(frameNode->afterAttachMainTreeTasks_.size(), taskSize + 1);
462 }
463 
464 /**
465  * @tc.name: ThreadSafeNodeTestNg015
466  * @tc.desc: Test thread safe node CheckThreadSafeNodeTree.
467  * @tc.type: FUNC
468  */
469 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg015, TestSize.Level1)
470 {
471     /**
472      * @tc.steps: step1. create thread safe uinode
473      */
474     MultiThreadBuildManager::SetIsThreadSafeNodeScope(true);
475     auto frameNode =
476         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
477     MultiThreadBuildManager::SetIsThreadSafeNodeScope(false);
478     /**
479      * @tc.steps: step2. thread safe uinode CheckThreadSafeNodeTree
480      * @tc.expected: CheckThreadSafeNodeTree success
481      */
482     EXPECT_EQ(frameNode->CheckThreadSafeNodeTree(true), true);
483     EXPECT_EQ(frameNode->CheckThreadSafeNodeTree(false), true);
484 }
485 
486 /**
487  * @tc.name: ThreadSafeNodeTestNg016
488  * @tc.desc: Test thread unsafe node CheckThreadSafeNodeTree.
489  * @tc.type: FUNC
490  */
491 HWTEST_F(ThreadSafeNodeTestNg, ThreadSafeNodeTestNg016, TestSize.Level1)
492 {
493     /**
494      * @tc.steps: step1. create thread unsafe uinode
495      */
496     auto frameNode =
497         FrameNode::CreateFrameNode("main", 1, AceType::MakeRefPtr<Pattern>(), true);
498     /**
499      * @tc.steps: step2. thread unsafe uinode CheckThreadSafeNodeTree
500      * @tc.expected: CheckThreadSafeNodeTree success
501      */
502     EXPECT_EQ(frameNode->CheckThreadSafeNodeTree(true), false);
503     EXPECT_EQ(frameNode->CheckThreadSafeNodeTree(false), false);
504 }
505 } // namespace OHOS::Ace::NG