OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #include <fcntl.h> |
| 6 #include <magenta/syscalls.h> |
| 7 #include <mxio/util.h> |
| 8 #include <stdbool.h> |
| 9 #include <stdio.h> |
| 10 #include <stdlib.h> |
| 11 #include <string.h> |
| 12 #include <unistd.h> |
| 13 |
| 14 // This program runs Dart VM unit tests. The Dart VM unit tests are contained |
| 15 // in a separate binary whose location is defined in kRunVmTestsPath below. |
| 16 // That program accepts a command line argument --list to list all the available |
| 17 // tests, or the name of a single test to run. This program accepts a single |
| 18 // command line argument which is the path to a file containing a list of tests |
| 19 // to run, one per line. |
| 20 |
| 21 const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests"; |
| 22 |
| 23 // Tests that are invalid, wedge, or cause panics. |
| 24 const char* kSkip[] = { |
| 25 // These expect a file to exist that we aren't putting in the image. |
| 26 "Read", |
| 27 "FileLength", |
| 28 "FilePosition", |
| 29 // Wedges the system. |
| 30 "ArrayLengthMaxElements", |
| 31 "Int8ListLengthMaxElements", |
| 32 // Kernel panic. |
| 33 "ThreadBarrier", |
| 34 // Wedges. |
| 35 "ThreadPool_WorkerShutdown", |
| 36 "LargeMap", |
| 37 // The profiler is turned off. |
| 38 "Profiler_AllocationSampleTest", |
| 39 "Profiler_ArrayAllocation", |
| 40 "Profiler_BasicSourcePosition", |
| 41 "Profiler_BasicSourcePositionOptimized", |
| 42 "Profiler_BinaryOperatorSourcePosition", |
| 43 "Profiler_BinaryOperatorSourcePositionOptimized", |
| 44 "Profiler_ChainedSamples", |
| 45 "Profiler_ClosureAllocation", |
| 46 "Profiler_CodeTicks", |
| 47 "Profiler_ContextAllocation", |
| 48 "Profiler_FunctionInline", |
| 49 "Profiler_FunctionTicks", |
| 50 "Profiler_InliningIntervalBoundry", |
| 51 "Profiler_IntrinsicAllocation", |
| 52 "Profiler_SampleBufferIterateTest", |
| 53 "Profiler_SampleBufferWrapTest", |
| 54 "Profiler_SourcePosition", |
| 55 "Profiler_SourcePositionOptimized", |
| 56 "Profiler_StringAllocation", |
| 57 "Profiler_StringInterpolation", |
| 58 "Profiler_ToggleRecordAllocation", |
| 59 "Profiler_TrivialRecordAllocation", |
| 60 "Profiler_TypedArrayAllocation", |
| 61 "Profiler_GetSourceReport", |
| 62 "Service_Profile", |
| 63 // No realpath. |
| 64 "Dart2JSCompilerStats", |
| 65 "Dart2JSCompileAll", |
| 66 }; |
| 67 |
| 68 // Expected to fail/crash. |
| 69 const char* kExpectFail[] = { |
| 70 "Fail0", |
| 71 "Fail1", |
| 72 "Fail2", |
| 73 "IsolateReload_PendingUnqualifiedCall_InstanceToStatic", |
| 74 "IsolateReload_PendingUnqualifiedCall_StaticToInstance", |
| 75 "IsolateReload_PendingConstructorCall_AbstractToConcrete", |
| 76 "IsolateReload_PendingConstructorCall_ConcreteToAbstract", |
| 77 "IsolateReload_PendingStaticCall_DefinedToNSM", |
| 78 "IsolateReload_PendingStaticCall_NSMToDefined", |
| 79 "ArrayNew_Overflow_Crash", |
| 80 "AllocGeneric_Overflow", |
| 81 "CodeImmutability", |
| 82 "SNPrint_BadArgs", |
| 83 }; |
| 84 |
| 85 // Bugs to fix, or things that are not yet impelemnted. |
| 86 const char* kBugs[] = { |
| 87 // pthreads not using specified stack size. |
| 88 "StackOverflowStacktraceInfo", |
| 89 // Needs OS::GetCurrentThreadCPUMicros. |
| 90 "Timeline_Dart_TimelineDuration", |
| 91 "Timeline_Dart_TimelineInstant" |
| 92 "Timeline_Dart_TimelineAsyncDisabled", |
| 93 "Timeline_Dart_TimelineAsync", |
| 94 "Timeline_Dart_TimelineGetTrace", |
| 95 "Timeline_Dart_TimelineGetTraceOnlyDartEvents", |
| 96 "Timeline_Dart_TimelineGetTraceWithDartEvents", |
| 97 "Timeline_Dart_TimelineGetTraceGlobalOverride", |
| 98 "Timeline_Dart_GlobalTimelineGetTrace", |
| 99 "Timeline_Dart_GlobalTimelineGetTrace_Threaded", |
| 100 "TimelineEventDuration", |
| 101 "TimelineEventDurationPrintJSON", |
| 102 "TimelineEventArguments", |
| 103 "TimelineEventArgumentsPrintJSON", |
| 104 "TimelineEventBufferPrintJSON", |
| 105 "TimelineEventCallbackRecorderBasic", |
| 106 "TimelineAnalysis_ThreadBlockCount", |
| 107 "TimelineRingRecorderJSONOrder", |
| 108 "TimelinePauses_BeginEnd", |
| 109 // Crash. |
| 110 "FindCodeObject", |
| 111 // Needs OS::Sleep. |
| 112 "MessageHandler_Run", |
| 113 "Sleep", |
| 114 // Calls VirtualMemory::FreeSubSegment. |
| 115 "GrowableObjectArray", |
| 116 "PrintJSON", |
| 117 "GenerateSource", |
| 118 "FreeVirtualMemory", |
| 119 // Several missing calls. |
| 120 "OsFuncs", |
| 121 // OS::AlignedAllocate. |
| 122 "OSAlignedAllocate", |
| 123 // Needs NativeSymbolResolver |
| 124 "Service_PersistentHandles", |
| 125 // Need to investigate: |
| 126 "ThreadPool_RunOne", |
| 127 "ThreadPool_WorkerTimeout", |
| 128 "Monitor", |
| 129 "ThreadIterator_AddFindRemove", |
| 130 // Needs Utils::HostToBigEndian16 |
| 131 "Endianity", |
| 132 }; |
| 133 |
| 134 |
| 135 static bool contains(const char** list, intptr_t len, const char* str) { |
| 136 for (intptr_t i = 0; i < len; i++) { |
| 137 if (strcmp(list[i], str) == 0) { |
| 138 return true; |
| 139 } |
| 140 } |
| 141 return false; |
| 142 } |
| 143 |
| 144 |
| 145 static bool isSkip(const char* test) { |
| 146 return contains( |
| 147 kSkip, sizeof(kSkip) / sizeof(kSkip[0]), test); |
| 148 } |
| 149 |
| 150 |
| 151 static bool isExpectFail(const char* test) { |
| 152 return contains( |
| 153 kExpectFail, sizeof(kExpectFail) / sizeof(kExpectFail[0]), test); |
| 154 } |
| 155 |
| 156 |
| 157 static bool isBug(const char* test) { |
| 158 return contains(kBugs, sizeof(kBugs) / sizeof(kBugs[0]), test); |
| 159 } |
| 160 |
| 161 |
| 162 static int run_test(const char* test_name) { |
| 163 const intptr_t kArgc = 2; |
| 164 const char* argv[3]; |
| 165 argv[0] = kRunVmTestsPath; |
| 166 argv[1] = test_name; |
| 167 |
| 168 mx_handle_t p = mxio_start_process(argv[0], kArgc, argv); |
| 169 if (p < 0) { |
| 170 printf("process failed to start\n"); |
| 171 return -1; |
| 172 } |
| 173 |
| 174 mx_signals_state_t state; |
| 175 mx_status_t r = mx_handle_wait_one( |
| 176 p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state); |
| 177 if (r != NO_ERROR) { |
| 178 printf("[process(%x): wait failed? %d]\n", p, r); |
| 179 return -1; |
| 180 } |
| 181 |
| 182 mx_process_info_t proc_info; |
| 183 mx_ssize_t ret = mx_handle_get_info( |
| 184 p, MX_INFO_PROCESS, &proc_info, sizeof(proc_info)); |
| 185 if (ret != sizeof(proc_info)) { |
| 186 printf("[process(%x): handle_get_info failed? %ld]\n", p, ret); |
| 187 return -1; |
| 188 } |
| 189 |
| 190 mx_handle_close(p); |
| 191 return proc_info.return_code; |
| 192 } |
| 193 |
| 194 |
| 195 static void trim(char* line) { |
| 196 const intptr_t line_len = strlen(line); |
| 197 if (line[line_len - 1] == '\n') { |
| 198 line[line_len - 1] = '\0'; |
| 199 } |
| 200 } |
| 201 |
| 202 |
| 203 static bool should_run(const char* test) { |
| 204 return !(test[0] == '#') && !isSkip(test); |
| 205 } |
| 206 |
| 207 |
| 208 static void handle_result(intptr_t result, const char* test) { |
| 209 if (result != 0) { |
| 210 if (!isExpectFail(test) && !isBug(test)) { |
| 211 printf("******** Test %s FAILED\n", test); |
| 212 } |
| 213 } else { |
| 214 if (isExpectFail(test)) { |
| 215 printf("******** Test %s is expected to fail, but PASSED\n", test); |
| 216 } |
| 217 if (isBug(test)) { |
| 218 printf("******** Test %s is marked as a bug, but PASSED\n", test); |
| 219 } |
| 220 } |
| 221 } |
| 222 |
| 223 |
| 224 int main(int argc, char** argv) { |
| 225 if (argc <= 1) { |
| 226 fprintf(stderr, "Pass the path to a file containing the list of tests\n"); |
| 227 return -1; |
| 228 } |
| 229 const char* tests_path = argv[1]; |
| 230 |
| 231 FILE* fp = fopen(tests_path, "r"); |
| 232 if (fp == NULL) { |
| 233 fprintf(stderr, "Failed to read the file: %s\n", tests_path); |
| 234 return -1; |
| 235 } |
| 236 |
| 237 char* test = NULL; |
| 238 size_t len = 0; |
| 239 ssize_t read; |
| 240 while ((read = getline(&test, &len, fp)) != -1) { |
| 241 trim(test); |
| 242 if (!should_run(test)) { |
| 243 continue; |
| 244 } |
| 245 intptr_t result = run_test(test); |
| 246 handle_result(result, test); |
| 247 } |
| 248 |
| 249 fclose(fp); |
| 250 if (test != NULL) { |
| 251 free(test); |
| 252 } |
| 253 return 0; |
| 254 } |
| 255 |
OLD | NEW |