OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_UNIT_TEST_H_ | 5 #ifndef RUNTIME_VM_UNIT_TEST_H_ |
6 #define RUNTIME_VM_UNIT_TEST_H_ | 6 #define RUNTIME_VM_UNIT_TEST_H_ |
7 | 7 |
8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
9 | 9 |
10 #include "platform/globals.h" | 10 #include "platform/globals.h" |
11 | 11 |
12 #include "vm/ast.h" | 12 #include "vm/ast.h" |
13 #include "vm/dart.h" | 13 #include "vm/dart.h" |
14 #include "vm/dart_api_state.h" | 14 #include "vm/dart_api_state.h" |
15 #include "vm/globals.h" | 15 #include "vm/globals.h" |
16 #include "vm/heap.h" | 16 #include "vm/heap.h" |
17 #include "vm/isolate.h" | 17 #include "vm/isolate.h" |
18 #include "vm/longjump.h" | 18 #include "vm/longjump.h" |
19 #include "vm/object.h" | 19 #include "vm/object.h" |
20 #include "vm/object_store.h" | 20 #include "vm/object_store.h" |
21 #include "vm/simulator.h" | 21 #include "vm/simulator.h" |
22 #include "vm/zone.h" | 22 #include "vm/zone.h" |
23 | 23 |
24 // The UNIT_TEST_CASE macro is used for tests that do not need any | 24 // The VM_UNIT_TEST_CASE macro is used for tests that do not need any |
25 // default isolate or zone functionality. | 25 // default isolate or zone functionality. |
26 #define UNIT_TEST_CASE(name) \ | 26 #define VM_UNIT_TEST_CASE(name) \ |
27 void Dart_Test##name(); \ | 27 void Dart_Test##name(); \ |
28 static const dart::TestCase kRegister##name(Dart_Test##name, #name); \ | 28 static const dart::TestCase kRegister##name(Dart_Test##name, #name); \ |
29 void Dart_Test##name() | 29 void Dart_Test##name() |
30 | 30 |
31 // The VM_TEST_CASE macro is used for tests that need an isolate and zone | 31 // The UNIT_TEST_CASE macro is used for tests that do not require any |
32 // in order to test its functionality. This macro is used for tests that | 32 // functionality provided by the VM. Tests declared using this macro will be run |
| 33 // after the VM is cleaned up. |
| 34 #define UNIT_TEST_CASE(name) \ |
| 35 void Dart_Test##name(); \ |
| 36 static const dart::RawTestCase kRegister##name(Dart_Test##name, #name); \ |
| 37 void Dart_Test##name() |
| 38 |
| 39 // The ISOLATE_UNIT_TEST_CASE macro is used for tests that need an isolate and |
| 40 // zone in order to test its functionality. This macro is used for tests that |
33 // are implemented using the VM code directly and do not use the Dart API | 41 // are implemented using the VM code directly and do not use the Dart API |
34 // for calling into the VM. The safepoint execution state of threads using | 42 // for calling into the VM. The safepoint execution state of threads using |
35 // this macro is transitioned from kThreadInNative to kThreadInVM. | 43 // this macro is transitioned from kThreadInNative to kThreadInVM. |
36 #define VM_TEST_CASE(name) \ | 44 #define ISOLATE_UNIT_TEST_CASE(name) \ |
37 static void Dart_TestHelper##name(Thread* thread); \ | 45 static void Dart_TestHelper##name(Thread* thread); \ |
38 UNIT_TEST_CASE(name) { \ | 46 VM_UNIT_TEST_CASE(name) { \ |
39 TestIsolateScope __test_isolate__; \ | 47 TestIsolateScope __test_isolate__; \ |
40 Thread* __thread__ = Thread::Current(); \ | 48 Thread* __thread__ = Thread::Current(); \ |
41 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ | 49 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ |
42 TransitionNativeToVM transition(__thread__); \ | 50 TransitionNativeToVM transition(__thread__); \ |
43 StackZone __zone__(__thread__); \ | 51 StackZone __zone__(__thread__); \ |
44 HandleScope __hs__(__thread__); \ | 52 HandleScope __hs__(__thread__); \ |
45 Dart_TestHelper##name(__thread__); \ | 53 Dart_TestHelper##name(__thread__); \ |
46 } \ | 54 } \ |
47 static void Dart_TestHelper##name(Thread* thread) | 55 static void Dart_TestHelper##name(Thread* thread) |
48 | 56 |
49 // The TEST_CASE macro is used for tests that need an isolate and zone | 57 // The TEST_CASE macro is used for tests that need an isolate and zone |
50 // in order to test its functionality. This macro is used for tests that | 58 // in order to test its functionality. This macro is used for tests that |
51 // are implemented using the Dart API for calling into the VM. The safepoint | 59 // are implemented using the Dart API for calling into the VM. The safepoint |
52 // execution state of threads using this macro remains kThreadNative. | 60 // execution state of threads using this macro remains kThreadNative. |
53 #define TEST_CASE(name) \ | 61 #define TEST_CASE(name) \ |
54 static void Dart_TestHelper##name(Thread* thread); \ | 62 static void Dart_TestHelper##name(Thread* thread); \ |
55 UNIT_TEST_CASE(name) { \ | 63 VM_UNIT_TEST_CASE(name) { \ |
56 TestIsolateScope __test_isolate__; \ | 64 TestIsolateScope __test_isolate__; \ |
57 Thread* __thread__ = Thread::Current(); \ | 65 Thread* __thread__ = Thread::Current(); \ |
58 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ | 66 ASSERT(__thread__->isolate() == __test_isolate__.isolate()); \ |
59 StackZone __zone__(__thread__); \ | 67 StackZone __zone__(__thread__); \ |
60 HandleScope __hs__(__thread__); \ | 68 HandleScope __hs__(__thread__); \ |
61 Dart_TestHelper##name(__thread__); \ | 69 Dart_TestHelper##name(__thread__); \ |
62 } \ | 70 } \ |
63 static void Dart_TestHelper##name(Thread* thread) | 71 static void Dart_TestHelper##name(Thread* thread) |
64 | 72 |
65 // The ASSEMBLER_TEST_GENERATE macro is used to generate a unit test | 73 // The ASSEMBLER_TEST_GENERATE macro is used to generate a unit test |
66 // for the assembler. | 74 // for the assembler. |
67 #define ASSEMBLER_TEST_GENERATE(name, assembler) \ | 75 #define ASSEMBLER_TEST_GENERATE(name, assembler) \ |
68 void AssemblerTestGenerate##name(Assembler* assembler) | 76 void AssemblerTestGenerate##name(Assembler* assembler) |
69 | 77 |
70 // The ASSEMBLER_TEST_EXTERN macro is used to declare a unit test | 78 // The ASSEMBLER_TEST_EXTERN macro is used to declare a unit test |
71 // for the assembler. | 79 // for the assembler. |
72 #define ASSEMBLER_TEST_EXTERN(name) \ | 80 #define ASSEMBLER_TEST_EXTERN(name) \ |
73 extern void AssemblerTestGenerate##name(Assembler* assembler); | 81 extern void AssemblerTestGenerate##name(Assembler* assembler); |
74 | 82 |
75 // The ASSEMBLER_TEST_RUN macro is used to execute the assembler unit | 83 // The ASSEMBLER_TEST_RUN macro is used to execute the assembler unit |
76 // test generated using the ASSEMBLER_TEST_GENERATE macro. | 84 // test generated using the ASSEMBLER_TEST_GENERATE macro. |
77 // C++ callee-saved registers are not preserved. Arguments may be passed in. | 85 // C++ callee-saved registers are not preserved. Arguments may be passed in. |
78 #define ASSEMBLER_TEST_RUN(name, test) \ | 86 #define ASSEMBLER_TEST_RUN(name, test) \ |
79 static void AssemblerTestRun##name(AssemblerTest* test); \ | 87 static void AssemblerTestRun##name(AssemblerTest* test); \ |
80 VM_TEST_CASE(name) { \ | 88 ISOLATE_UNIT_TEST_CASE(name) { \ |
81 Assembler __assembler__; \ | 89 Assembler __assembler__; \ |
82 AssemblerTest test("" #name, &__assembler__); \ | 90 AssemblerTest test("" #name, &__assembler__); \ |
83 AssemblerTestGenerate##name(test.assembler()); \ | 91 AssemblerTestGenerate##name(test.assembler()); \ |
84 test.Assemble(); \ | 92 test.Assemble(); \ |
85 AssemblerTestRun##name(&test); \ | 93 AssemblerTestRun##name(&test); \ |
86 } \ | 94 } \ |
87 static void AssemblerTestRun##name(AssemblerTest* test) | 95 static void AssemblerTestRun##name(AssemblerTest* test) |
88 | 96 |
89 // Populate node list with AST nodes. | 97 // Populate node list with AST nodes. |
90 #define CODEGEN_TEST_GENERATE(name, test) \ | 98 #define CODEGEN_TEST_GENERATE(name, test) \ |
91 static void CodeGenTestGenerate##name(CodeGenTest* test) | 99 static void CodeGenTestGenerate##name(CodeGenTest* test) |
92 | 100 |
93 // Populate node list with AST nodes, possibly using the provided function | 101 // Populate node list with AST nodes, possibly using the provided function |
94 // object built by a previous CODEGEN_TEST_GENERATE. | 102 // object built by a previous CODEGEN_TEST_GENERATE. |
95 #define CODEGEN_TEST2_GENERATE(name, function, test) \ | 103 #define CODEGEN_TEST2_GENERATE(name, function, test) \ |
96 static void CodeGenTestGenerate##name(const Function& function, \ | 104 static void CodeGenTestGenerate##name(const Function& function, \ |
97 CodeGenTest* test) | 105 CodeGenTest* test) |
98 | 106 |
99 | 107 |
100 // Pass the name of test and the expected results as RawObject. | 108 // Pass the name of test and the expected results as RawObject. |
101 #define CODEGEN_TEST_RUN(name, expected) \ | 109 #define CODEGEN_TEST_RUN(name, expected) \ |
102 static void CodeGenTestRun##name(const Function& function); \ | 110 static void CodeGenTestRun##name(const Function& function); \ |
103 VM_TEST_CASE(name) { \ | 111 ISOLATE_UNIT_TEST_CASE(name) { \ |
104 CodeGenTest __test__("" #name); \ | 112 CodeGenTest __test__("" #name); \ |
105 CodeGenTestGenerate##name(&__test__); \ | 113 CodeGenTestGenerate##name(&__test__); \ |
106 __test__.Compile(); \ | 114 __test__.Compile(); \ |
107 CodeGenTestRun##name(__test__.function()); \ | 115 CodeGenTestRun##name(__test__.function()); \ |
108 } \ | 116 } \ |
109 static void CodeGenTestRun##name(const Function& function) { \ | 117 static void CodeGenTestRun##name(const Function& function) { \ |
110 Object& result = Object::Handle(); \ | 118 Object& result = Object::Handle(); \ |
111 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ | 119 result = DartEntry::InvokeFunction(function, Object::empty_array()); \ |
112 EXPECT(!result.IsError()); \ | 120 EXPECT(!result.IsError()); \ |
113 Instance& actual = Instance::Handle(); \ | 121 Instance& actual = Instance::Handle(); \ |
114 actual ^= result.raw(); \ | 122 actual ^= result.raw(); \ |
115 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ | 123 EXPECT(actual.CanonicalizeEquals(Instance::Handle(expected))); \ |
116 } | 124 } |
117 | 125 |
118 | 126 |
119 // Pass the name of test, and use the generated function to call it | 127 // Pass the name of test, and use the generated function to call it |
120 // and evaluate its result. | 128 // and evaluate its result. |
121 #define CODEGEN_TEST_RAW_RUN(name, function) \ | 129 #define CODEGEN_TEST_RAW_RUN(name, function) \ |
122 static void CodeGenTestRun##name(const Function& function); \ | 130 static void CodeGenTestRun##name(const Function& function); \ |
123 VM_TEST_CASE(name) { \ | 131 ISOLATE_UNIT_TEST_CASE(name) { \ |
124 CodeGenTest __test__("" #name); \ | 132 CodeGenTest __test__("" #name); \ |
125 CodeGenTestGenerate##name(&__test__); \ | 133 CodeGenTestGenerate##name(&__test__); \ |
126 __test__.Compile(); \ | 134 __test__.Compile(); \ |
127 CodeGenTestRun##name(__test__.function()); \ | 135 CodeGenTestRun##name(__test__.function()); \ |
128 } \ | 136 } \ |
129 static void CodeGenTestRun##name(const Function& function) | 137 static void CodeGenTestRun##name(const Function& function) |
130 | 138 |
131 | 139 |
132 // Generate code for two sequences of AST nodes and execute the first one. | 140 // Generate code for two sequences of AST nodes and execute the first one. |
133 // The first one may reference the Function object generated by the second one. | 141 // The first one may reference the Function object generated by the second one. |
134 #define CODEGEN_TEST2_RUN(name1, name2, expected) \ | 142 #define CODEGEN_TEST2_RUN(name1, name2, expected) \ |
135 static void CodeGenTestRun##name1(const Function& function); \ | 143 static void CodeGenTestRun##name1(const Function& function); \ |
136 VM_TEST_CASE(name1) { \ | 144 ISOLATE_UNIT_TEST_CASE(name1) { \ |
137 /* Generate code for name2 */ \ | 145 /* Generate code for name2 */ \ |
138 CodeGenTest __test2__("" #name2); \ | 146 CodeGenTest __test2__("" #name2); \ |
139 CodeGenTestGenerate##name2(&__test2__); \ | 147 CodeGenTestGenerate##name2(&__test2__); \ |
140 __test2__.Compile(); \ | 148 __test2__.Compile(); \ |
141 /* Generate code for name1, providing function2 */ \ | 149 /* Generate code for name1, providing function2 */ \ |
142 CodeGenTest __test1__("" #name1); \ | 150 CodeGenTest __test1__("" #name1); \ |
143 CodeGenTestGenerate##name1(__test2__.function(), &__test1__); \ | 151 CodeGenTestGenerate##name1(__test2__.function(), &__test1__); \ |
144 __test1__.Compile(); \ | 152 __test1__.Compile(); \ |
145 CodeGenTestRun##name1(__test1__.function()); \ | 153 CodeGenTestRun##name1(__test1__.function()); \ |
146 } \ | 154 } \ |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 public: | 262 public: |
255 explicit TestCaseBase(const char* name); | 263 explicit TestCaseBase(const char* name); |
256 virtual ~TestCaseBase() {} | 264 virtual ~TestCaseBase() {} |
257 | 265 |
258 const char* name() const { return name_; } | 266 const char* name() const { return name_; } |
259 | 267 |
260 virtual void Run() = 0; | 268 virtual void Run() = 0; |
261 void RunTest(); | 269 void RunTest(); |
262 | 270 |
263 static void RunAll(); | 271 static void RunAll(); |
| 272 static void RunAllRaw(); |
| 273 |
| 274 protected: |
| 275 bool raw_test_; |
264 | 276 |
265 private: | 277 private: |
266 static TestCaseBase* first_; | 278 static TestCaseBase* first_; |
267 static TestCaseBase* tail_; | 279 static TestCaseBase* tail_; |
268 | 280 |
269 TestCaseBase* next_; | 281 TestCaseBase* next_; |
270 const char* name_; | 282 const char* name_; |
271 | 283 |
272 DISALLOW_COPY_AND_ASSIGN(TestCaseBase); | 284 DISALLOW_COPY_AND_ASSIGN(TestCaseBase); |
273 }; | 285 }; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 static void AddTestLib(const char* url, const char* source); | 328 static void AddTestLib(const char* url, const char* source); |
317 static const char* GetTestLib(const char* url); | 329 static const char* GetTestLib(const char* url); |
318 | 330 |
319 private: | 331 private: |
320 static Dart_Isolate CreateIsolate(const uint8_t* buffer, const char* name); | 332 static Dart_Isolate CreateIsolate(const uint8_t* buffer, const char* name); |
321 | 333 |
322 RunEntry* const run_; | 334 RunEntry* const run_; |
323 }; | 335 }; |
324 | 336 |
325 | 337 |
| 338 class RawTestCase : TestCaseBase { |
| 339 public: |
| 340 typedef void(RunEntry)(); |
| 341 |
| 342 RawTestCase(RunEntry* run, const char* name) : TestCaseBase(name), run_(run) { |
| 343 raw_test_ = true; |
| 344 } |
| 345 virtual void Run(); |
| 346 |
| 347 private: |
| 348 RunEntry* const run_; |
| 349 }; |
| 350 |
| 351 |
326 class TestIsolateScope { | 352 class TestIsolateScope { |
327 public: | 353 public: |
328 TestIsolateScope() { | 354 TestIsolateScope() { |
329 isolate_ = reinterpret_cast<Isolate*>(TestCase::CreateTestIsolate()); | 355 isolate_ = reinterpret_cast<Isolate*>(TestCase::CreateTestIsolate()); |
330 Dart_EnterScope(); // Create a Dart API scope for unit tests. | 356 Dart_EnterScope(); // Create a Dart API scope for unit tests. |
331 } | 357 } |
332 ~TestIsolateScope() { | 358 ~TestIsolateScope() { |
333 Dart_ExitScope(); // Exit the Dart API scope created for unit tests. | 359 Dart_ExitScope(); // Exit the Dart API scope created for unit tests. |
334 ASSERT(isolate_ == Isolate::Current()); | 360 ASSERT(isolate_ == Isolate::Current()); |
335 Dart_ShutdownIsolate(); | 361 Dart_ShutdownIsolate(); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 ~SetFlagScope() { *flag_ = original_value_; } | 640 ~SetFlagScope() { *flag_ = original_value_; } |
615 | 641 |
616 private: | 642 private: |
617 T* flag_; | 643 T* flag_; |
618 T original_value_; | 644 T original_value_; |
619 }; | 645 }; |
620 | 646 |
621 } // namespace dart | 647 } // namespace dart |
622 | 648 |
623 #endif // RUNTIME_VM_UNIT_TEST_H_ | 649 #endif // RUNTIME_VM_UNIT_TEST_H_ |
OLD | NEW |