• 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 
16 #include "common_components/heap/heap_manager.h"
17 #include "common_components/mutator/mutator.h"
18 #include "common_components/mutator/mutator_manager.h"
19 #include "common_components/tests/test_helper.h"
20 #include "common_interfaces/base_runtime.h"
21 #include "common_interfaces/objects/base_object.h"
22 
23 using namespace common;
24 
25 namespace common::test {
26 class TestMutator : public Mutator {
27 public:
28     using Mutator::VisitRawObjects;
29 };
30 class MutatorTest : public BaseTestWithScope {
31 protected:
SetUpTestCase()32     static void SetUpTestCase()
33     {
34         BaseRuntime::GetInstance()->Init();
35     }
TearDownTestCase()36     static void TearDownTestCase() {}
37 };
38 
HWTEST_F_L0(MutatorTest,GetThreadLocalData_Test1)39 HWTEST_F_L0(MutatorTest, GetThreadLocalData_Test1)
40 {
41     ThreadLocalData *ret = GetThreadLocalData();
42     ASSERT_TRUE(ret != nullptr);
43 }
44 
HWTEST_F_L0(MutatorTest,TransitionGCPhase_Test1)45 HWTEST_F_L0(MutatorTest, TransitionGCPhase_Test1)
46 {
47     MutatorBase mutatorBase;
48     mutatorBase.Init();
49     bool ret = mutatorBase.TransitionGCPhase(false);
50     EXPECT_TRUE(ret == true);
51 
52     MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE;
53     mutatorBase.SetSuspensionFlag(flag);
54 
55     ret = mutatorBase.TransitionGCPhase(false);
56     EXPECT_TRUE(ret == true);
57 
58     ret = mutatorBase.TransitionGCPhase(true);
59     EXPECT_TRUE(ret == true);
60     ret = mutatorBase.TransitionGCPhase(false);
61     EXPECT_TRUE(ret == true);
62 }
63 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test0)64 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test0)
65 {
66     MutatorBase mutatorBase;
67     mutatorBase.Init();
68 
69     MutatorBase::SuspensionType  flag = MutatorBase::SuspensionType::SUSPENSION_FOR_STW;
70     mutatorBase.SetSuspensionFlag(flag);
71 
72     mutatorBase.HandleSuspensionRequest();
73     EXPECT_TRUE(mutatorBase.InSaferegion() == false);
74 
75     flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE;
76     mutatorBase.SetSuspensionFlag(flag);
77     mutatorBase.HandleSuspensionRequest();
78     EXPECT_TRUE(mutatorBase.InSaferegion() == false);
79 }
80 
HWTEST_F_L0(MutatorTest,SuspendForStw_Test0)81 HWTEST_F_L0(MutatorTest, SuspendForStw_Test0)
82 {
83     MutatorBase mutatorBase;
84     mutatorBase.Init();
85 
86     mutatorBase.SuspendForStw();
87     EXPECT_TRUE(mutatorBase.InSaferegion() == false);
88 }
89 
HWTEST_F_L0(MutatorTest,VisitRawObjects_Nullptr_NoCall)90 HWTEST_F_L0(MutatorTest, VisitRawObjects_Nullptr_NoCall)
91 {
92     TestMutator mutator;
93     mutator.Init();
94     mutator.PushRawObject(nullptr);
95 
96     bool called = false;
97     RootVisitor func = [&called](const ObjectRef& obj) {
98         called = true;
99     };
100     mutator.VisitRawObjects(func);
101     EXPECT_FALSE(called);
102 }
103 
HWTEST_F_L0(MutatorTest,VisitRawObjects_NonNull_Call)104 HWTEST_F_L0(MutatorTest, VisitRawObjects_NonNull_Call)
105 {
106     TestMutator mutator;
107     mutator.Init();
108     BaseObject mockObj;
109     mutator.PushRawObject(&mockObj);
110 
111     bool called = false;
112     RootVisitor func = [&called, &mockObj](const ObjectRef& obj) {
113         called = true;
114         EXPECT_EQ(obj.object, &mockObj);
115     };
116 
117     mutator.VisitRawObjects(func);
118     EXPECT_TRUE(called);
119 }
120 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test1)121 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test1)
122 {
123     MutatorBase mutatorBase;
124     mutatorBase.Init();
125     MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_STW;
126     mutatorBase.SetSuspensionFlag(flag);
127     flag = MutatorBase::SuspensionType::SUSPENSION_FOR_GC_PHASE;
128     mutatorBase.SetSuspensionFlag(flag);
129     mutatorBase.HandleSuspensionRequest();
130     EXPECT_FALSE(mutatorBase.InSaferegion());
131     EXPECT_TRUE(mutatorBase.FinishedTransition());
132 }
133 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test2)134 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test2)
135 {
136     MutatorBase mutatorBase;
137     mutatorBase.Init();
138     MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_CPU_PROFILE;
139     mutatorBase.SetSuspensionFlag(flag);
140     mutatorBase.SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE);
141     std::thread t([&]() {
142         std::this_thread::sleep_for(std::chrono::nanoseconds(1));
143         mutatorBase.ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE);
144     });
145     mutatorBase.HandleSuspensionRequest();
146     t.join();
147     EXPECT_FALSE(mutatorBase.InSaferegion());
148     EXPECT_TRUE(mutatorBase.FinishedCpuProfile());
149 }
150 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test3)151 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test3)
152 {
153     MutatorBase mutatorBase;
154     mutatorBase.Init();
155     mutatorBase.SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_STW);
156     mutatorBase.SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE);
157     mutatorBase.SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE);
158     std::thread t([&]() {
159         std::this_thread::sleep_for(std::chrono::nanoseconds(1));
160         mutatorBase.ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE);
161     });
162     mutatorBase.HandleSuspensionRequest();
163     t.join();
164     EXPECT_FALSE(mutatorBase.InSaferegion());
165     EXPECT_TRUE(mutatorBase.FinishedCpuProfile());
166 }
167 
HWTEST_F_L0(MutatorTest,HandleGCPhase_SatbNodeNotNull)168 HWTEST_F_L0(MutatorTest, HandleGCPhase_SatbNodeNotNull)
169 {
170     Mutator* mutator = MutatorManager::Instance().CreateRuntimeMutator(ThreadType::ARK_PROCESSOR);
171     HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true);
172     BaseObject *mockObj = reinterpret_cast<BaseObject*>(addr);
173     new (mockObj) BaseObject();
174     mutator->RememberObjectInSatbBuffer(mockObj);
175     EXPECT_NE(mutator->GetSatbBufferNode(), nullptr);
176     MutatorBase* base = static_cast<MutatorBase*>(mutator->GetMutatorBasePtr());
177     base->TransitionToGCPhaseExclusive(GCPhase::GC_PHASE_REMARK_SATB);
178     EXPECT_EQ(mutator->GetSatbBufferNode(), nullptr);
179     MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::ARK_PROCESSOR);
180 }
181 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_LeaveSaferegion1)182 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_LeaveSaferegion1)
183 {
184     MutatorBase mutatorBase;
185     mutatorBase.Init();
186     mutatorBase.IncObserver();
187     std::thread t([&]() {
188         std::this_thread::sleep_for(std::chrono::nanoseconds(1));
189         mutatorBase.DecObserver();
190     });
191     mutatorBase.HandleSuspensionRequest();
192     t.join();
193     EXPECT_FALSE(mutatorBase.InSaferegion());
194 }
195 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_LeaveSaferegion2)196 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_LeaveSaferegion2)
197 {
198     MutatorBase mutatorBase;
199     mutatorBase.Init();
200     MutatorBase::SuspensionType flag = MutatorBase::SuspensionType::SUSPENSION_FOR_CPU_PROFILE;
201     mutatorBase.SetSuspensionFlag(flag);
202     mutatorBase.SetCpuProfileState(MutatorBase::CpuProfileState::FINISH_CPUPROFILE);
203     mutatorBase.IncObserver();
204     std::thread t([&]() {
205         std::this_thread::sleep_for(std::chrono::nanoseconds(1));
206         mutatorBase.ClearSuspensionFlag(MutatorBase::SUSPENSION_FOR_CPU_PROFILE);
207         mutatorBase.DecObserver();
208     });
209     mutatorBase.HandleSuspensionRequest();
210     t.join();
211     EXPECT_FALSE(mutatorBase.InSaferegion());
212 }
213 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test4)214 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test4)
215 {
216     MutatorBase mutatorBase;
217     mutatorBase.Init();
218     mutatorBase.SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_STW);
219     EXPECT_NO_FATAL_FAILURE(mutatorBase.HandleSuspensionRequest());
220 }
221 
HWTEST_F_L0(MutatorTest,HandleSuspensionRequest_Test5)222 HWTEST_F_L0(MutatorTest, HandleSuspensionRequest_Test5)
223 {
224     MutatorBase mutatorBase;
225     mutatorBase.Init();
226     mutatorBase.SetSuspensionFlag(MutatorBase::SUSPENSION_FOR_GC_PHASE);
227     EXPECT_NO_FATAL_FAILURE(mutatorBase.HandleSuspensionRequest());
228 }
229 
HWTEST_F_L0(MutatorTest,TransitionToGCPhaseExclusive_TestEnum)230 HWTEST_F_L0(MutatorTest, TransitionToGCPhaseExclusive_TestEnum)
231 {
232     MutatorBase mutatorBase;
233     mutatorBase.Init();
234 
235     GCPhase phase = GCPhase::GC_PHASE_ENUM;
236     EXPECT_NO_FATAL_FAILURE(mutatorBase.TransitionToGCPhaseExclusive(phase));
237 }
238 
HWTEST_F_L0(MutatorTest,TransitionToGCPhaseExclusive_TestPrecopy)239 HWTEST_F_L0(MutatorTest, TransitionToGCPhaseExclusive_TestPrecopy)
240 {
241     MutatorBase mutatorBase;
242     mutatorBase.Init();
243 
244     GCPhase phase = GCPhase::GC_PHASE_PRECOPY;
245     EXPECT_NO_FATAL_FAILURE(mutatorBase.TransitionToGCPhaseExclusive(phase));
246 }
247 
HWTEST_F_L0(MutatorTest,TransitionToGCPhaseExclusive_TestIdle)248 HWTEST_F_L0(MutatorTest, TransitionToGCPhaseExclusive_TestIdle)
249 {
250     MutatorBase mutatorBase;
251     mutatorBase.Init();
252 
253     GCPhase phase = GCPhase::GC_PHASE_IDLE;
254     EXPECT_NO_FATAL_FAILURE(mutatorBase.TransitionToGCPhaseExclusive(phase));
255 }
256 }  // namespace common::test
257