]> git.saurik.com Git - apple/javascriptcore.git/blob - tests/mozilla/runtests.pl
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / tests / mozilla / runtests.pl
1 #!/tools/ns/bin/perl5
2 #
3 # simple script that executes JavaScript tests. you have to build the
4 # stand-alone, js shell executable (which is not the same as the dll that gets
5 # built for mozilla). see the readme at
6 # http://lxr.mozilla.org/mozilla/source/js/src/README.html for instructions on
7 # how to build the jsshell.
8 #
9 # this is just a quick-n-dirty script. for full reporting, you need to run
10 # the test driver, which requires java and is currently not available on
11 # mozilla.org.
12 #
13 # this test looks for an executable JavaScript shell in
14 # %MOZ_SRC/mozilla/js/src/[platform]-[platform-version]-OPT.OBJ/js,
15 # which is the default build location when you build using the instructions
16 # at http://lxr.mozilla.org/mozilla/source/js/src/README.html
17 #
18 #
19 # christine@netscape.com
20 #
21
22 &parse_args;
23 &setup_env;
24 &main_test_loop;
25 &cleanup_env;
26
27 #
28 # given a main directory, assume that there is a file called 'shell.js'
29 # in it. then, open all the subdirectories, and look for js files.
30 # for each test.js that is found, execute the shell, and pass shell.js
31 # and the test.js as file arguments. redirect all process output to a
32 # file.
33 #
34 sub main_test_loop {
35 foreach $suite ( &get_subdirs( $test_dir )) {
36 foreach $subdir (&get_subdirs( $suite, $test_dir )) {
37 @jsfiles = &get_js_files($subdir);
38 execute_js_tests(@jsfiles);
39 }
40 }
41 }
42
43 #
44 # given a directory, return an array of all subdirectories
45 #
46 sub get_subdirs{
47 local ($dir, $path) = @_;
48 local @subdirs;
49
50 local $dir_path = $path . $dir;
51 chdir $dir_path;
52
53 opendir ( DIR, ${dir_path} );
54 local @testdir_contents = readdir( DIR );
55 closedir( DIR );
56
57 foreach (@testdir_contents) {
58 if ( (-d $_) && ($_ !~ 'CVS') && ( $_ ne '.') && ($_ ne '..')) {
59 @subdirs[$#subdirs+1] = $_;
60 }
61 }
62 chdir $path;
63 return @subdirs;
64 }
65
66 #
67 # given a directory, return an array of all the js files that are in it.
68 #
69 sub get_js_files {
70 ( $test_subdir ) = @_;
71 local @js_file_array;
72
73 $current_test_dir = $test_dir ."/". $suite . "/" .$test_subdir;
74 chdir $current_test_dir;
75
76 opendir ( TEST_SUBDIR, ${current_test_dir} );
77 @subdir_files = readdir( TEST_SUBDIR );
78 closedir( TOP_LEVEL_BUILD_DIR );
79
80 foreach ( @subdir_files ) {
81 if ( $_ =~ /\.js$/ ) {
82 $js_file_array[$#js_file_array+1] = $_;
83 }
84 }
85
86 return @js_file_array;
87 }
88
89 #
90 # given an array of test.js files, execute the shell command and pass
91 # the shell.js and test.js files as file arguments. redirect process
92 # output to a file. if $js_verbose is set (not recommended), write all
93 # testcase output to the output file. if $js_quiet is set, only write
94 # failed test case information to the output file. the default setting
95 # is to write a line for each test file, and whether each file passed
96 # or failed.
97 #
98 sub execute_js_tests {
99 (@js_file_array) = @_;
100
101 $js_printed_suitename = 0;
102 if ( !$js_quiet ) {
103 &js_print_suitename;
104 }
105
106 foreach $js_test (@js_file_array) {
107 $js_printed_filename = 0;
108 $js_test_bugnumber = 0;
109 $runtime_error = "";
110
111 local $passed = -1;
112
113 # create the test command
114 $test_command =
115 $shell_command .
116 " -f $test_dir/$suite/shell.js " .
117 " -f $test_dir/$suite/$subdir/$js_test";
118
119 if ( !$js_quiet ) {
120 &js_print_filename;
121 } else {
122 print '.';
123 }
124
125 $test_path = $test_dir ."/" . $suite ."/". $test_subdir ."/". $js_test;
126
127
128 if ( !-e $test_path ) {
129 &js_print( " FAILED! file not found\n",
130 "<font color=#990000>", "</font><br>\n");
131 } else {
132 open( RUNNING_TEST, "$test_command" . ' 2>&1 |');
133
134
135 # this is where we want the tests to provide a lot more information
136 # that this script must parse so that we can
137
138 while( <RUNNING_TEST> ){
139 if ( $js_verbose && !$js_quiet ) {
140 &js_print ($_ ."\n", "", "<br>\n");
141 }
142 if ( $_ =~ /BUGNUMBER/ ) {
143 $js_test_bugnumber = $_;
144 }
145 if ( $_ =~ /PASSED/ && $passed == -1 ) {
146 $passed = 1;
147 }
148 if ( $_ =~ /FAILED/ && $_ =~ /expected/) {
149 &js_print_suitename;
150 &js_print_filename;
151 &js_print_bugnumber;
152
153 local @msg = split ( "FAILED", $_ );
154 &js_print ( $passed ? "\n" : "" );
155 &js_print( " " . $msg[0], "&nbsp;&nbsp;<tt>" );
156 &js_print( "FAILED", "<font color=#990000>", "</font>");
157 &js_print( $msg[1], "", "</tt><br>\n" );
158 $passed = 0;
159 }
160 if ( $_ =~ /$js_test/ ) {
161 $runtime_error .= $_;
162 }
163 }
164 close( RUNNING_TEST );
165
166 #
167 # figure out whether the test passed or failed. print out an
168 # appropriate level of output based on the value of $js_quiet
169 #
170 if ( $js_test =~ /-n\.js$/ ) {
171 if ( $runtime_error ) {
172 if ( !$js_quiet ) {
173 &js_print( " PASSED!\n ",
174 "<font color=#009900>&nbsp;&nbsp",
175 "</font><br>" );
176 if ( $js_errors ) {
177 &js_print( $runtime_error, "<pre>", "</pre>");
178 }
179 }
180 } else {
181 &js_print_suitename;
182 &js_print_filename;
183 &js_print_bugnumber;
184 &js_print( " FAILED! ", "&nbsp;&nbsp;<font color=#990000>",
185 "</font>");
186 &js_print( " Should have resulted in an error\n",
187 "","<br>" );
188 }
189 } else {
190 if ( $passed == 1 && !$js_quiet) {
191 &js_print( " PASSED!\n " , "&nbsp;&nbsp;<font color=#009900>",
192 "</font><br>" );
193 } else {
194 if ($passed == -1) {
195 &js_print_suitename;
196 &js_print_filename;
197 &js_print_bugnumber;
198 &js_print( " FAILED!\n " , "&nbsp;&nbsp;<font color=#990000>",
199 "</font><br>" );
200 &js_print( " Missing 'PASSED' in output\n", "","<br>" );
201 &js_print( $log, "output:<br><pre>", "</pre>" );
202 }
203 }
204
205 }
206 }
207 }
208 }
209
210 #
211 # figure out what os we're on, the default name of the object directory
212 #
213 sub setup_env {
214 # MOZ_SRC must be set, so we can figure out where the
215 # JavaScript executable is
216 $moz_src = $ENV{"MOZ_SRC"}
217 || die( "You need to set your MOZ_SRC environment variable.\n" );
218 $src_dir = $moz_src . '/mozilla/js/src/';
219
220 # JS_TEST_DIR must be set so we can figure out where the tests are.
221 $test_dir = $ENV{"JS_TEST_DIR"};
222
223 # if it's not set, look for it relative to $moz_src
224 if ( !$test_dir ) {
225 $test_dir = $moz_src . '/mozilla/js/tests/';
226 }
227
228 # make sure that the test dir exists
229 if ( ! -e $test_dir ) {
230 die "The JavaScript Test Library could not be found at $test_dir.\n" .
231 "Check the tests out from /mozilla/js/tests or\n" .
232 "Set the value of your JS_TEST_DIR environment variable\n " .
233 "to the location of the test library.\n";
234 }
235
236 # make sure that the test dir ends with a trailing slash
237 $test_dir .= '/';
238
239 chdir $src_dir;
240
241 # figure out which platform we're on, and figure out where the object
242 # directory is
243
244 $machine_os = `uname -s`;
245
246 if ( $machine_os =~ /WIN/ ) {
247 $machine_os = 'WIN';
248 $object_dir = ($js_debug) ? 'Debug' : 'Release';
249 $js_exe = 'jsshell.exe';
250 } else {
251 chop $machine_os;
252 $js_exe = 'js';
253
254 # figure out what the object directory is. on all platforms,
255 # it's the directory that ends in OBJ. if $js_debug is set,
256 # look the directory that ends with or DBG.OBJ; otherwise
257 # look for the directory that ends with OPT.OBJ
258
259 opendir ( SRC_DIR_FILES, $src_dir );
260 @src_dir_files = readdir( SRC_DIR_FILES );
261 closedir ( SRC_DIR_FILES );
262
263 $object_pattern = $js_debug ? 'DBG.OBJ' : 'OPT.OBJ';
264
265 foreach (@src_dir_files) {
266 if ( $_ =~ /$object_pattern/ && $_ =~ $machine_os) {
267 $object_dir = $_;
268 }
269 }
270 }
271 if ( ! $object_dir ) {
272 die( "Couldn't find an object directory in $src_dir.\n" );
273 }
274
275 # figure out what the name of the javascript executable should be, and
276 # make sure it's there. if it's not there, give a helpful message so
277 # the user can figure out what they need to do next.
278
279
280 if ( ! $js_exe_full_path ) {
281 $shell_command = $src_dir . $object_dir .'/'. $js_exe;
282 } else {
283 $shell_command = $js_exe_full_path;
284 }
285
286 if ( !-e $shell_command ) {
287 die ("Could not find JavaScript shell executable $shell_command.\n" .
288 "Check the value of your MOZ_SRC environment variable.\n" .
289 "Currently, MOZ_SRC is set to $ENV{\"MOZ_SRC\"}\n".
290 "See the readme at http://lxr.mozilla.org/mozilla/src/js/src/ " .
291 "for instructions on building the JavaScript shell.\n" );
292 }
293
294 # set the output file name. let's base its name on the date and platform,
295 # and give it a sequence number.
296
297 if ( $get_output ) {
298 $js_output = &get_output;
299 }
300 if ($js_output) {
301 print( "Writing results to $js_output\n" );
302 chdir $test_dir;
303 open( JS_OUTPUT, "> ${js_output}" ) ||
304 die "Can't open log file $js_output\n";
305 close JS_OUTPUT;
306 }
307
308 # get the start time
309 $start_time = time;
310
311 # print out some nice stuff
312 $start_date = &get_date;
313 &js_print( "JavaScript tests started: " . $start_date, "<p><tt>", "</tt></p>" );
314
315 &js_print ("Executing all the tests under $test_dir\n against " .
316 "$shell_command\n", "<p><tt>", "</tt></p>" );
317 }
318
319 #
320 # parse arguments. see usage for what arguments are expected.
321 #
322 sub parse_args {
323 $i = 0;
324 while( $i < @ARGV ){
325 if ( $ARGV[$i] eq '--threaded' ) {
326 $js_threaded = 1;
327 } elsif ( $ARGV[$i] eq '--d' ) {
328 $js_debug = 1;
329 } elsif ( $ARGV[$i] eq '--14' ) {
330 $js_version = '14';
331 } elsif ( $ARGV[$i] eq '--v' ) {
332 $js_verbose = 1;
333 } elsif ( $ARGV[$i] eq '-f' ) {
334 $js_output = $ARGV[++$i];
335 } elsif ( $ARGV[$i] eq '--o' ) {
336 $get_output = 1;
337 } elsif ($ARGV[$i] eq '--e' ) {
338 $js_errors = 1;
339 } elsif ($ARGV[$i] eq '--q' ) {
340 $js_quiet = 1;
341 } elsif ($ARGV[$i] eq '--h' ) {
342 die &usage;
343 } elsif ( $ARGV[$i] eq '-E' ) {
344 $js_exe_full_path = $ARGV[$i+1];
345 $i++;
346 } else {
347 die &usage;
348 }
349 $i++;
350 }
351
352 #
353 # if no output options are provided, show some output and write to file
354 #
355 if ( !$js_verbose && !$js_output && !$get_output ) {
356 $get_output = 1;
357 }
358 }
359
360 #
361 # print the arguments that this script expects
362 #
363 sub usage {
364 die ("usage: $0\n" .
365 "--q Quiet mode -- only show information for tests that failed\n".
366 "--e Show runtime error messages for negative tests\n" .
367 "--v Verbose output -- show all test cases (not recommended)\n" .
368 "--o Send output to file whose generated name is based on date\n".
369 "--d Look for a debug JavaScript executable (default is optimized)\n" .
370 "-f <file> Redirect output to file named <file>\n"
371 );
372 }
373
374 #
375 # if $js_output is set, print to file as well as stdout
376 #
377 sub js_print {
378 ($string, $start_tag, $end_tag) = @_;
379
380 if ($js_output) {
381 open( JS_OUTPUT, ">> ${js_output}" ) ||
382 die "Can't open log file $js_output\n";
383
384 print JS_OUTPUT "$start_tag $string $end_tag";
385 close JS_OUTPUT;
386 }
387 print $string;
388 }
389
390 #
391 # close open files
392 #
393 sub cleanup_env {
394 # print out some nice stuff
395 $end_date = &get_date;
396 &js_print( "\nTests complete at $end_date", "<hr><tt>", "</tt>" );
397
398 # print out how long it took to complete
399 $end_time = time;
400
401 $test_seconds = ( $end_time - $start_time );
402
403 &js_print( "Start Date: $start_date\n", "<tt><br>" );
404 &js_print( "End Date: $end_date\n", "<br>" );
405 &js_print( "Test Time: $test_seconds seconds\n", "<br>" );
406
407 if ($js_output ) {
408 if ( !$js_verbose) {
409 &js_print( "Results were written to " . $js_output ."\n",
410 "<br>", "</tt>" );
411 }
412 close JS_OUTPUT;
413 }
414 }
415
416
417 #
418 # get the current date and time
419 #
420 sub get_date {
421 &get_localtime;
422 $now = $year ."/". $mon ."/". $mday ." ". $hour .":".
423 $min .":". $sec ."\n";
424 return $now;
425
426 }
427 sub get_localtime {
428 ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
429 localtime;
430 $mon++;
431 $mon = &zero_pad($mon);
432 $year= ($year < 2000) ? "19" . $year : $year;
433 $mday= &zero_pad($mday);
434 $sec = &zero_pad($sec);
435 $min = &zero_pad($min);
436 $hour = &zero_pad($hour);
437 }
438 sub zero_pad {
439 local ($string) = @_;
440 $string = ($string < 10) ? "0" . $string : $string;
441 return $string;
442 }
443
444 #
445 # generate an output file name based on the date
446 #
447 sub get_output {
448 &get_localtime;
449
450 chdir $test_dir;
451
452 $js_output = $test_dir ."/". $year .'-'. $mon .'-'. $mday ."\.1.html";
453
454 $output_file_found = 0;
455
456 while ( !$output_file_found ) {
457 if ( -e $js_output ) {
458 # get the last sequence number - everything after the dot
459 @seq_no = split( /\./, $js_output, 2 );
460 $js_output = $seq_no[0] .".". (++$seq_no[1]) . "\.html";
461 } else {
462 $output_file_found = 1;
463 }
464 }
465 return $js_output;
466 }
467
468 sub js_print_suitename {
469 if ( !$js_printed_suitename ) {
470 &js_print( "$suite\\$subdir\n", "<hr><font size+=1><b>",
471 "</font></b><br>" );
472 }
473 $js_printed_suitename = 1;
474 }
475
476 sub js_print_filename {
477 if ( !$js_printed_filename ) {
478 &js_print( "$js_test\n", "<b>", "</b><br>" );
479 $js_printed_filename = 1;
480 }
481 }
482
483 sub js_print_bugnumber {
484 if ( !$js_printed_bugnumber ) {
485 if ( $js_bugnumber =~ /^http/ ) {
486 &js_print( "$js_bugnumber", "<a href=$js_bugnumber>", "</a>" );
487 } else {
488 &js_print( "$js_bugnumber",
489 "<a href=http://scopus.mcom.com/bugsplat/show_bug.cgi?id=" .
490 $js_bugnumber .">",
491 "</a>" );
492 }
493 $js_printed_bugnumber = 1;
494 }
495 }