Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Side by Side Diff: runtime/bin/run_vm_tests_fuchsia.cc

Issue 2197773004: Fuchsia: Paralellize VM test wrapper. Update statuses for Fuchsia update (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/os_fuchsia.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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 #include <fcntl.h> 5 #include <fcntl.h>
6 #include <launchpad/launchpad.h> 6 #include <launchpad/launchpad.h>
7 #include <magenta/syscalls.h> 7 #include <magenta/syscalls.h>
8 #include <mxio/util.h> 8 #include <mxio/util.h>
9 #include <pthread.h>
10 #include <runtime/sysinfo.h>
9 #include <stdbool.h> 11 #include <stdbool.h>
10 #include <stdio.h> 12 #include <stdio.h>
11 #include <stdlib.h> 13 #include <stdlib.h>
12 #include <string.h> 14 #include <string.h>
13 #include <unistd.h> 15 #include <unistd.h>
14 16
15 // This program runs Dart VM unit tests. The Dart VM unit tests are contained 17 // This program runs Dart VM unit tests. The Dart VM unit tests are contained
16 // in a separate binary whose location is defined in kRunVmTestsPath below. 18 // in a separate binary whose location is defined in kRunVmTestsPath below.
17 // That program accepts a command line argument --list to list all the available 19 // That program accepts a command line argument --list to list all the available
18 // tests, or the name of a single test to run. This program accepts a single 20 // tests, or the name of a single test to run. This program accepts a single
19 // command line argument which is the path to a file containing a list of tests 21 // command line argument which is the path to a file containing a list of tests
20 // to run, one per line. 22 // to run, one per line.
21 23
22 const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests"; 24 const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests";
23 25
24 // Tests that are invalid, wedge, or cause panics. 26 // Tests that are invalid, wedge, or cause panics.
25 const char* kSkip[] = { 27 const char* kSkip[] = {
26 // These expect a file to exist that we aren't putting in the image. 28 // These expect a file to exist that we aren't putting in the image.
27 "Read", 29 "Read",
28 "FileLength", 30 "FileLength",
29 "FilePosition", 31 "FilePosition",
30 // Hangs. 32 // Hangs.
31 "ArrayLengthMaxElements", 33 "ArrayLengthMaxElements",
32 "Int8ListLengthMaxElements", 34 "Int8ListLengthMaxElements",
33 "ThreadPool_WorkerShutdown",
34 "LargeMap", 35 "LargeMap",
35 "CompileFunctionOnHelperThread", 36 "CompileFunctionOnHelperThread",
36 // The profiler is turned off. 37 // The profiler is turned off.
37 "Profiler_AllocationSampleTest", 38 "Profiler_AllocationSampleTest",
38 "Profiler_ArrayAllocation", 39 "Profiler_ArrayAllocation",
39 "Profiler_BasicSourcePosition", 40 "Profiler_BasicSourcePosition",
40 "Profiler_BasicSourcePositionOptimized", 41 "Profiler_BasicSourcePositionOptimized",
41 "Profiler_BinaryOperatorSourcePosition", 42 "Profiler_BinaryOperatorSourcePosition",
42 "Profiler_BinaryOperatorSourcePositionOptimized", 43 "Profiler_BinaryOperatorSourcePositionOptimized",
43 "Profiler_ChainedSamples", 44 "Profiler_ChainedSamples",
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 "IsolateReload_PendingStaticCall_DefinedToNSM", 77 "IsolateReload_PendingStaticCall_DefinedToNSM",
77 "IsolateReload_PendingStaticCall_NSMToDefined", 78 "IsolateReload_PendingStaticCall_NSMToDefined",
78 "ArrayNew_Overflow_Crash", 79 "ArrayNew_Overflow_Crash",
79 "AllocGeneric_Overflow", 80 "AllocGeneric_Overflow",
80 "CodeImmutability", 81 "CodeImmutability",
81 "SNPrint_BadArgs", 82 "SNPrint_BadArgs",
82 }; 83 };
83 84
84 // Bugs to fix, or things that are not yet impelemnted. 85 // Bugs to fix, or things that are not yet impelemnted.
85 const char* kBugs[] = { 86 const char* kBugs[] = {
86 // pthreads not using specified stack size. 87 // pthreads not using specified stack size?
87 "StackOverflowStacktraceInfo", 88 "StackOverflowStacktraceInfo",
88 // Needs OS::GetCurrentThreadCPUMicros. 89 // Needs OS::GetCurrentThreadCPUMicros.
89 "Timeline_Dart_TimelineDuration",
90 "Timeline_Dart_TimelineInstant"
91 "Timeline_Dart_TimelineAsyncDisabled",
92 "Timeline_Dart_TimelineAsync",
93 "Timeline_Dart_TimelineGetTrace", 90 "Timeline_Dart_TimelineGetTrace",
94 "Timeline_Dart_TimelineGetTraceOnlyDartEvents", 91 "Timeline_Dart_TimelineGetTraceOnlyDartEvents",
95 "Timeline_Dart_TimelineGetTraceWithDartEvents", 92 "Timeline_Dart_TimelineGetTraceWithDartEvents",
96 "Timeline_Dart_TimelineGetTraceGlobalOverride", 93 "Timeline_Dart_TimelineGetTraceGlobalOverride",
97 "Timeline_Dart_GlobalTimelineGetTrace", 94 "Timeline_Dart_GlobalTimelineGetTrace",
98 "Timeline_Dart_GlobalTimelineGetTrace_Threaded", 95 "Timeline_Dart_GlobalTimelineGetTrace_Threaded",
99 "TimelineEventDuration", 96 "TimelineEventDuration",
100 "TimelineEventDurationPrintJSON", 97 "TimelineEventDurationPrintJSON",
101 "TimelineEventArguments", 98 "TimelineEventArguments",
102 "TimelineEventArgumentsPrintJSON", 99 "TimelineEventArgumentsPrintJSON",
103 "TimelineEventBufferPrintJSON",
104 "TimelineEventCallbackRecorderBasic", 100 "TimelineEventCallbackRecorderBasic",
105 "TimelineAnalysis_ThreadBlockCount", 101 "TimelineAnalysis_ThreadBlockCount",
106 "TimelineRingRecorderJSONOrder", 102 "TimelineRingRecorderJSONOrder",
107 "TimelinePauses_BeginEnd", 103 "TimelinePauses_BeginEnd",
108 // Crash.
109 "FindCodeObject",
110 // Needs NativeSymbolResolver 104 // Needs NativeSymbolResolver
111 "Service_PersistentHandles", 105 "Service_PersistentHandles",
112 // Need to investigate: 106 // Need to investigate:
107 "FindCodeObject",
113 "ThreadIterator_AddFindRemove", 108 "ThreadIterator_AddFindRemove",
109 "PrintJSON",
110 "SourceReport_Coverage_AllFunctions_ForceCompile",
114 }; 111 };
115 112
116 113
117 static bool contains(const char** list, intptr_t len, const char* str) { 114 static bool contains(const char** list, intptr_t len, const char* str) {
118 for (intptr_t i = 0; i < len; i++) { 115 for (intptr_t i = 0; i < len; i++) {
119 if (strcmp(list[i], str) == 0) { 116 if (strcmp(list[i], str) == 0) {
120 return true; 117 return true;
121 } 118 }
122 } 119 }
123 return false; 120 return false;
(...skipping 18 matching lines...) Expand all
142 139
143 140
144 static int run_test(const char* test_name) { 141 static int run_test(const char* test_name) {
145 const intptr_t kArgc = 2; 142 const intptr_t kArgc = 2;
146 const char* argv[3]; 143 const char* argv[3];
147 argv[0] = kRunVmTestsPath; 144 argv[0] = kRunVmTestsPath;
148 argv[1] = test_name; 145 argv[1] = test_name;
149 146
150 mx_handle_t p = launchpad_launch(argv[0], kArgc, argv); 147 mx_handle_t p = launchpad_launch(argv[0], kArgc, argv);
151 if (p < 0) { 148 if (p < 0) {
152 printf("process failed to start\n"); 149 fprintf(stderr, "process failed to start\n");
153 return -1; 150 return -1;
154 } 151 }
155 152
156 mx_signals_state_t state; 153 mx_signals_state_t state;
157 mx_status_t r = mx_handle_wait_one( 154 mx_status_t r = mx_handle_wait_one(
158 p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state); 155 p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state);
159 if (r != NO_ERROR) { 156 if (r != NO_ERROR) {
160 printf("[process(%x): wait failed? %d]\n", p, r); 157 fprintf(stderr, "[process(%x): wait failed? %d]\n", p, r);
161 return -1; 158 return -1;
162 } 159 }
163 160
164 mx_process_info_t proc_info; 161 mx_process_info_t proc_info;
165 mx_ssize_t ret = mx_handle_get_info( 162 mx_ssize_t ret = mx_handle_get_info(
166 p, MX_INFO_PROCESS, &proc_info, sizeof(proc_info)); 163 p, MX_INFO_PROCESS, &proc_info, sizeof(proc_info));
167 if (ret != sizeof(proc_info)) { 164 if (ret != sizeof(proc_info)) {
168 printf("[process(%x): handle_get_info failed? %ld]\n", p, ret); 165 fprintf(stderr, "[process(%x): handle_get_info failed? %ld]\n", p, ret);
169 return -1; 166 return -1;
170 } 167 }
171 168
172 mx_handle_close(p); 169 mx_handle_close(p);
173 return proc_info.return_code; 170 return proc_info.return_code;
174 } 171 }
175 172
176 173
174 static void handle_result(intptr_t result, const char* test) {
175 if (result != 0) {
176 if (!isExpectFail(test) && !isBug(test)) {
177 printf("******** Test %s FAILED\n", test);
178 }
179 } else {
180 if (isExpectFail(test)) {
181 printf("******** Test %s is expected to fail, but PASSED\n", test);
182 }
183 if (isBug(test)) {
184 printf("******** Test %s is marked as a bug, but PASSED\n", test);
185 }
186 }
187 }
188
189
190 typedef struct {
191 pthread_mutex_t* test_list_lock;
192 char** test_list;
193 intptr_t test_list_length;
194 intptr_t* test_list_index;
195 } runner_args_t;
196
197
198 static void* test_runner_thread(void* arg) {
199 runner_args_t* args = reinterpret_cast<runner_args_t*>(arg);
200
201 pthread_mutex_lock(args->test_list_lock);
202 while (*args->test_list_index < args->test_list_length) {
203 const intptr_t index = *args->test_list_index;
204 *args->test_list_index = index + 1;
205 pthread_mutex_unlock(args->test_list_lock);
206 const char* test = args->test_list[index];
207 handle_result(run_test(test), test);
208 pthread_mutex_lock(args->test_list_lock);
209 }
210 pthread_mutex_unlock(args->test_list_lock);
211
212 return NULL;
213 }
214
215
177 static void trim(char* line) { 216 static void trim(char* line) {
178 const intptr_t line_len = strlen(line); 217 const intptr_t line_len = strlen(line);
179 if (line[line_len - 1] == '\n') { 218 if (line[line_len - 1] == '\n') {
180 line[line_len - 1] = '\0'; 219 line[line_len - 1] = '\0';
181 } 220 }
182 } 221 }
183 222
184 223
185 static bool should_run(const char* test) { 224 static bool should_run(const char* test) {
186 return !(test[0] == '#') && !isSkip(test); 225 return !(test[0] == '#') && !isSkip(test);
187 } 226 }
188 227
189 228
190 static void handle_result(intptr_t result, const char* test) { 229 static intptr_t count_lines(FILE* fp) {
191 if (result != 0) { 230 intptr_t lines = 0;
192 if (!isExpectFail(test) && !isBug(test)) { 231
193 printf("******** Test %s FAILED\n", test); 232 // Make sure we're at the beginning of the file.
194 } 233 rewind(fp);
195 } else { 234
196 if (isExpectFail(test)) { 235 intptr_t ch;
197 printf("******** Test %s is expected to fail, but PASSED\n", test); 236 while ((ch = fgetc(fp)) != EOF) {
198 } 237 if (ch == '\n') {
199 if (isBug(test)) { 238 lines++;
200 printf("******** Test %s is marked as a bug, but PASSED\n", test);
201 } 239 }
202 } 240 }
241
242 rewind(fp);
243 return lines;
203 } 244 }
204 245
205 246
247 static intptr_t read_lines(FILE* fp, char** lines, intptr_t lines_length) {
248 char* test = NULL;
249 size_t len = 0;
250 ssize_t read;
251 intptr_t i = 0;
252 while (((read = getline(&test, &len, fp)) != -1) && (i < lines_length)) {
253 trim(test);
254 if (!should_run(test)) {
255 continue;
256 }
257 lines[i] = strdup(test);
258 i++;
259 }
260
261 if (test != NULL) {
262 free(test);
263 }
264 return i;
265 }
266
267
206 int main(int argc, char** argv) { 268 int main(int argc, char** argv) {
207 if (argc <= 1) { 269 if (argc <= 1) {
208 fprintf(stderr, "Pass the path to a file containing the list of tests\n"); 270 fprintf(stderr, "Pass the path to a file containing the list of tests\n");
209 return -1; 271 return -1;
210 } 272 }
211 const char* tests_path = argv[1]; 273 const char* tests_path = argv[1];
212 274
213 FILE* fp = fopen(tests_path, "r"); 275 FILE* fp = fopen(tests_path, "r");
214 if (fp == NULL) { 276 if (fp == NULL) {
215 fprintf(stderr, "Failed to read the file: %s\n", tests_path); 277 fprintf(stderr, "Failed to read the file: %s\n", tests_path);
216 return -1; 278 return -1;
217 } 279 }
218 280
219 char* test = NULL; 281 intptr_t lines_count = count_lines(fp);
220 size_t len = 0; 282 char** test_list =
221 ssize_t read; 283 reinterpret_cast<char**>(malloc(sizeof(*test_list) * lines_count));
222 while ((read = getline(&test, &len, fp)) != -1) { 284 lines_count = read_lines(fp, test_list, lines_count);
223 trim(test); 285 fclose(fp);
224 if (!should_run(test)) { 286
225 continue; 287 pthread_mutex_t args_mutex;
226 } 288 pthread_mutex_init(&args_mutex, NULL);
227 intptr_t result = run_test(test); 289 intptr_t test_list_index = 0;
228 handle_result(result, test); 290 runner_args_t args;
291 args.test_list_lock = &args_mutex;
292 args.test_list = test_list;
293 args.test_list_length = lines_count;
294 args.test_list_index = &test_list_index;
295
296 const intptr_t num_cpus = mxr_get_nprocs_conf();
297 pthread_t* threads =
298 reinterpret_cast<pthread_t*>(malloc(num_cpus * sizeof(pthread_t)));
299 for (int i = 0; i < num_cpus; i++) {
300 pthread_create(&threads[i], NULL, test_runner_thread, &args);
229 } 301 }
230 302
231 fclose(fp); 303 for (int i = 0; i < num_cpus; i++) {
232 if (test != NULL) { 304 pthread_join(threads[i], NULL);
233 free(test);
234 } 305 }
306
307 free(threads);
308 for (int i = 0; i < lines_count; i++) {
309 free(test_list[i]);
310 }
311 free(test_list);
312 pthread_mutex_destroy(&args_mutex);
313
314 if (test_list_index != lines_count) {
315 fprintf(stderr, "Failed to attempt all the tests!\n");
316 return -1;
317 }
318
235 return 0; 319 return 0;
236 } 320 }
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/os_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698