• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef PANDA_RUNTIME_TESTS_TOOLING_TEST_RUNNER_H
16 #define PANDA_RUNTIME_TESTS_TOOLING_TEST_RUNNER_H
17 
18 #include "test_util.h"
19 
20 namespace panda::tooling::test {
21 class TestRunner : public PtHooks {
22 public:
TestRunner(const char * test_name,DebugInterface * runtime_debug_interface)23     TestRunner(const char *test_name, DebugInterface *runtime_debug_interface)
24     {
25         debug_interface_ = runtime_debug_interface;
26         test_name_ = test_name;
27         test_ = TestUtil::GetTest(test_name);
28         test_->debug_interface = runtime_debug_interface;
29         TestUtil::Reset();
30         runtime_debug_interface->RegisterHooks(this);
31     }
32 
Run()33     void Run()
34     {
35         if (test_->scenario) {
36             test_->scenario();
37         }
38     }
39 
Breakpoint(PtThread thread,Method * method,const PtLocation & location)40     void Breakpoint(PtThread thread, Method *method, const PtLocation &location) override
41     {
42         if (test_->breakpoint) {
43             test_->breakpoint(thread, method, location);
44         }
45     }
46 
LoadModule(std::string_view panda_file_name)47     void LoadModule(std::string_view panda_file_name) override
48     {
49         if (test_->load_module) {
50             test_->load_module(panda_file_name);
51         }
52     }
53 
Paused(PauseReason reason)54     void Paused(PauseReason reason) override
55     {
56         if (test_->paused) {
57             test_->paused(reason);
58         }
59     };
60 
Exception(PtThread thread,Method * method,const PtLocation & location,ObjectHeader * object,Method * catch_method,const PtLocation & catch_location)61     void Exception(PtThread thread, Method *method, const PtLocation &location, ObjectHeader *object,
62                    Method *catch_method, const PtLocation &catch_location) override
63     {
64         if (test_->exception) {
65             test_->exception(thread, method, location, object, catch_method, catch_location);
66         }
67     }
68 
ExceptionCatch(PtThread thread,Method * method,const PtLocation & location,ObjectHeader * object)69     void ExceptionCatch(PtThread thread, Method *method, const PtLocation &location, ObjectHeader *object) override
70     {
71         if (test_->exception_catch) {
72             test_->exception_catch(thread, method, location, object);
73         }
74     }
75 
PropertyAccess(PtThread thread,Method * method,const PtLocation & location,ObjectHeader * object,PtProperty property)76     void PropertyAccess(PtThread thread, Method *method, const PtLocation &location, ObjectHeader *object,
77                         PtProperty property) override
78     {
79         if (test_->property_access) {
80             test_->property_access(thread, method, location, object, property);
81         }
82     }
83 
PropertyModification(PtThread thread,Method * method,const PtLocation & location,ObjectHeader * object,PtProperty property,VRegValue new_value)84     void PropertyModification(PtThread thread, Method *method, const PtLocation &location, ObjectHeader *object,
85                               PtProperty property, VRegValue new_value) override
86     {
87         if (test_->property_modification) {
88             test_->property_modification(thread, method, location, object, property, new_value);
89         }
90     }
91 
FramePop(PtThread thread,Method * method,bool was_popped_by_exception)92     void FramePop(PtThread thread, Method *method, bool was_popped_by_exception) override
93     {
94         if (test_->frame_pop) {
95             test_->frame_pop(thread, method, was_popped_by_exception);
96         }
97     }
98 
GarbageCollectionStart()99     void GarbageCollectionStart() override
100     {
101         if (test_->garbage_collection_start) {
102             test_->garbage_collection_start();
103         }
104     }
105 
GarbageCollectionFinish()106     void GarbageCollectionFinish() override
107     {
108         if (test_->garbage_collection_finish) {
109             test_->garbage_collection_finish();
110         }
111     }
112 
MethodEntry(PtThread thread,Method * method)113     void MethodEntry(PtThread thread, Method *method) override
114     {
115         if (test_->method_entry) {
116             test_->method_entry(thread, method);
117         }
118     }
119 
MethodExit(PtThread thread,Method * method,bool was_popped_by_exception,VRegValue return_value)120     void MethodExit(PtThread thread, Method *method, bool was_popped_by_exception, VRegValue return_value) override
121     {
122         if (test_->method_exit) {
123             test_->method_exit(thread, method, was_popped_by_exception, return_value);
124         }
125     }
126 
SingleStep(PtThread thread,Method * method,const PtLocation & location)127     void SingleStep(PtThread thread, Method *method, const PtLocation &location) override
128     {
129         if (test_->single_step) {
130             test_->single_step(thread, method, location);
131         }
132     }
133 
ThreadStart(PtThread thread)134     void ThreadStart(PtThread thread) override
135     {
136         if (test_->thread_start) {
137             test_->thread_start(thread);
138         }
139     }
140 
ThreadEnd(PtThread thread)141     void ThreadEnd(PtThread thread) override
142     {
143         if (test_->thread_end) {
144             test_->thread_end(thread);
145         }
146     }
147 
VmDeath()148     void VmDeath() override
149     {
150         if (test_->vm_death) {
151             test_->vm_death();
152         }
153         TestUtil::Event(DebugEvent::VM_DEATH);
154     }
155 
VmInitialization(PtThread thread)156     void VmInitialization(PtThread thread) override
157     {
158         if (test_->vm_init) {
159             test_->vm_init(thread);
160         }
161         TestUtil::Event(DebugEvent::VM_INITIALIZATION);
162     }
163 
VmStart()164     void VmStart() override
165     {
166         if (test_->vm_start) {
167             test_->vm_start();
168         }
169     }
170 
ExceptionRevoked(ExceptionWrapper reason,ExceptionID exception_id)171     void ExceptionRevoked(ExceptionWrapper reason, ExceptionID exception_id) override
172     {
173         if (test_->exception_revoked) {
174             test_->exception_revoked(reason, exception_id);
175         }
176     }
177 
ExecutionContextCreated(ExecutionContextWrapper context)178     void ExecutionContextCreated(ExecutionContextWrapper context) override
179     {
180         if (test_->execution_context_created) {
181             test_->execution_context_created(context);
182         }
183     }
184 
ExecutionContextDestroyed(ExecutionContextWrapper context)185     void ExecutionContextDestroyed(ExecutionContextWrapper context) override
186     {
187         if (test_->execution_context_destroyed) {
188             test_->execution_context_destroyed(context);
189         }
190     }
191 
ExecutionContextsCleared()192     void ExecutionContextsCleared() override
193     {
194         if (test_->execution_context_cleared) {
195             test_->execution_context_cleared();
196         }
197     }
198 
InspectRequested(PtObject object,PtObject hints)199     void InspectRequested(PtObject object, PtObject hints) override
200     {
201         if (test_->inspect_requested) {
202             test_->inspect_requested(object, hints);
203         }
204     }
205 
ClassLoad(PtThread thread,BaseClass * klass)206     void ClassLoad(PtThread thread, BaseClass *klass) override
207     {
208         if (test_->class_load) {
209             test_->class_load(thread, klass);
210         }
211     }
212 
ClassPrepare(PtThread thread,BaseClass * klass)213     void ClassPrepare(PtThread thread, BaseClass *klass) override
214     {
215         if (test_->class_prepare) {
216             test_->class_prepare(thread, klass);
217         }
218     }
219 
MonitorWait(PtThread thread,ObjectHeader * object,int64_t timeout)220     void MonitorWait(PtThread thread, ObjectHeader *object, int64_t timeout) override
221     {
222         if (test_->monitor_wait) {
223             test_->monitor_wait(thread, object, timeout);
224         }
225     }
226 
MonitorWaited(PtThread thread,ObjectHeader * object,bool timed_out)227     void MonitorWaited(PtThread thread, ObjectHeader *object, bool timed_out) override
228     {
229         if (test_->monitor_waited) {
230             test_->monitor_waited(thread, object, timed_out);
231         }
232     }
233 
MonitorContendedEnter(PtThread thread,ObjectHeader * object)234     void MonitorContendedEnter(PtThread thread, ObjectHeader *object) override
235     {
236         if (test_->monitor_contended_enter) {
237             test_->monitor_contended_enter(thread, object);
238         }
239     }
240 
MonitorContendedEntered(PtThread thread,ObjectHeader * object)241     void MonitorContendedEntered(PtThread thread, ObjectHeader *object) override
242     {
243         if (test_->monitor_contended_entered) {
244             test_->monitor_contended_entered(thread, object);
245         }
246     }
247 
ObjectAlloc(BaseClass * klass,ObjectHeader * object,PtThread thread,size_t size)248     void ObjectAlloc(BaseClass *klass, ObjectHeader *object, PtThread thread, size_t size) override
249     {
250         if (test_->object_alloc) {
251             test_->object_alloc(klass, object, thread, size);
252         }
253     }
254 
TerminateTest()255     void TerminateTest()
256     {
257         debug_interface_->UnregisterHooks();
258         if (TestUtil::IsTestFinished()) {
259             return;
260         }
261         LOG(FATAL, DEBUGGER) << "Test " << test_name_ << " failed";
262     }
263 
264 private:
265     DebugInterface *debug_interface_;
266     const char *test_name_;
267     ApiTest *test_;
268 };
269 }  // namespace panda::tooling::test
270 
271 #endif  // PANDA_RUNTIME_TESTS_TOOLING_TEST_RUNNER_H
272