4 Copies all the Zend tests to a temporary directory, runs them in interp mode,
5 then copies the good ones to test/zend/good and the bad ones to test/zend/bad.
18 # SESSION is bused on husdon
22 # unpredictable numbers - we need param matching
25 'gettimeofday_basic.php',
26 'localtime_basic.php',
28 'posix_getpgid_basic.php',
29 'posix_getpgid_basic.php',
30 'posix_getpgrp_basic.php',
31 'posix_getpid_basic.php',
32 'posix_getppid_basic.php',
33 'posix_getsid_basic.php',
34 'posix_times_basic.php',
35 'socket_getsockname.php',
36 'fileinode_variation1.php',
41 'openssl_random_pseudo_bytes.php',
42 'pcntl_fork_basic.php',
44 'array_diff_assoc_variation6.php',
47 'getrusage_basic.php',
49 # not implemented extensions
50 'phar', # this appears in filenames
52 # works in interp but not others
58 # line number is inconsistent on stack overflow
70 'array_pad_variation2.phpt',
80 'socket_select-wrongparams-1.phpt',
86 'date/tests/bug50055.phpt',
87 'operators/divide_basiclong_64bit.phpt',
88 'operators/modulus_basiclong_64bit.phpt',
90 'lang/func_get_arg.003.phpt',
91 'lang/func_num_args.003.phpt',
92 'lang/func_get_args.003.phpt',
94 'Zend/tests/020.phpt',
95 'Zend/tests/bug35239.phpt',
96 'Zend/tests/bug54265.phpt',
97 'Zend/tests/bug55705.phpt',
98 'Zend/tests/callable_type_hint_001.phpt',
99 'Zend/tests/callable_type_hint_003.phpt',
100 'Zend/tests/jump13.phpt',
101 'Zend/tests/heredoc_005.phpt',
102 'gd/tests/crafted_gd2.phpt',
103 'pcntl/tests/pcntl_exec.phpt',
104 'pcntl/tests/pcntl_exec_2.phpt',
105 'pcntl/tests/pcntl_exec_3.phpt',
106 'session/tests/bug61728.phpt',
107 'session/tests/session_module_name_variation2.phpt',
109 # not imported yet, but will be
125 # not implemented extensions
169 # Random other files that zend wants
171 'curl_testdata1.txt',
172 'curl_testdata2.txt',
174 'autoload_derived.p5c',
175 'autoload_implements.p5c',
176 'autoload_interface.p5c',
177 'constants_basic_003.inc',
178 'interface_optional_arg_003.inc',
193 '/ext-exif/bug48378.jpeg',
195 '/ext-gd/bug37346.gif',
196 '/ext-gd/bug38112.gif',
197 '/ext-gd/bug43121.gif',
198 '/ext-gd/conv_test.gif',
199 '/ext-gd/conv_test.jpeg',
200 '/ext-gd/conv_test.png',
201 '/ext-gd/conv_test.xbm',
205 '/ext-gd/test8859.ttf',
206 '/ext-gd/test_gif.gif',
207 '/ext-intl/ut_common.inc',
208 '/ext-ldap/connect.inc',
209 '/ext-mbstring/common.inc',
210 '/ext-mcrypt/vectors.txt',
211 '/ext-openssl/005_crt.txt',
212 '/ext-openssl/bug37820cert.pem',
213 '/ext-openssl/bug37820key.pem',
214 '/ext-openssl/bug39217cert1.txt',
215 '/ext-openssl/bug39217cert2.txt',
216 '/ext-openssl/cert.crt',
217 '/ext-openssl/openssl.cnf',
218 '/ext-openssl/private.key',
219 '/ext-openssl/public.key',
220 '/ext-session/save_handler.inc',
221 '/ext-simplexml/bug24392.xml',
222 '/tests/quicktester.inc',
226 # generic inconsistencies
227 ('Variable passed to ([^\s]+)\(\) is not an array or object', 'Invalid operand type was used: expecting an array'),
229 ('bcsqrt\(\): ', ''),
230 ('bcpowmod\(\): ', ''),
233 parser
= argparse
.ArgumentParser()
238 help="zend path to import tests from."
245 help="only import tests whose path matches this regex."
250 help="leave around test/zend/all directory."
256 help="print out extra stuff."
258 args
= parser
.parse_args()
264 except OSError as exc
: # Python >2.5
267 def walk(filename
, source
):
268 dest_filename
= os
.path
.basename(filename
).replace('.phpt', '.php')
269 source_dir
= source
.lower().replace('/tests', '').replace('/', '-')
271 cur_dir
= os
.path
.dirname(__file__
)
272 dest_subdir
= os
.path
.join(cur_dir
, '../test/zend/all', source_dir
)
274 full_dest_filename
= os
.path
.join(dest_subdir
, dest_filename
)
276 if not '.phpt' in filename
:
277 shutil
.copyfile(filename
, full_dest_filename
)
280 print "Importing %s" % filename
282 def split(pattern
, str):
283 return re
.split(r
'\n\s*--'+pattern
+'--\s*\n', str, 1)
285 def parse_headers(zend
):
288 for line
in zend
.split('\n'):
289 header
= re
.match('--([_A-Z]+)--', line
)
291 cur_header
= header
.group(1)
292 sections
[cur_header
] = []
294 sections
[cur_header
].append(line
)
297 sections
= parse_headers(file(filename
).read())
298 for i
in sections
.keys():
299 sections
[i
] = '\n'.join(sections
[i
])
301 unsupported_sections
= ('INI', 'POST_RAW')
302 for name
in unsupported_sections
:
303 if sections
.has_key(name
):
304 print "Unsupported test with section --%s--: " % name
, filename
307 if not sections
.has_key('FILE'):
308 print "Malformed test, no --FILE--: ", filename
311 for key
in ('EXPECT', 'EXPECTF', 'EXPECTREGEX'):
312 if sections
.has_key(key
):
315 # tests are really inconsistent about whitespace
316 exp
= re
.sub(r
'(\r\n|\r|\n)', '\n', exp
.strip())
318 exp
= exp
.replace('in %s on', 'in %s/%s/%s on' % ('hphp/test/zend/all', source_dir
, dest_filename
))
320 # PHP puts a newline in that we don't
321 exp
= exp
.replace('\n\nFatal error:', '\nFatal error:')
322 exp
= exp
.replace('\n\nWarning:', '\nWarning:')
323 exp
= exp
.replace('\n\nNotice:', '\nNotice:')
325 match_rest_of_line
= '%a'
326 if key
== 'EXPECTREGEX':
327 match_rest_of_line
= '.+'
329 exp
= re
.sub(r
'Fatal\\? error\\?:.*', 'HipHop Fatal error: '+match_rest_of_line
, exp
)
330 exp
= re
.sub(r
'Warning\\?:.*', 'HipHop Warning: '+match_rest_of_line
, exp
)
331 exp
= re
.sub(r
'Notice\\?:.*', 'HipHop Notice: '+match_rest_of_line
, exp
)
334 exp
= re
.sub(error
[0], error
[1], exp
)
338 if sections
.has_key('EXPECT'):
339 exp
= sections
['EXPECT']
340 # we use %a for error messages so always write expectf
341 file(full_dest_filename
+'.expectf', 'w').write(exp
)
342 elif sections
.has_key('EXPECTREGEX'):
343 exp
= sections
['EXPECTREGEX']
344 file(full_dest_filename
+'.expectregex', 'w').write(exp
)
345 elif sections
.has_key('EXPECTF'):
346 exp
= sections
['EXPECTF']
347 file(full_dest_filename
+'.expectf', 'w').write(exp
)
349 print "Malformed test, no --EXPECT-- or --EXPECTF-- or --EXPECTREGEX--: ", filename
352 test
= sections
['FILE']
354 if sections
.has_key('POST'):
357 '<?php\nparse_str("' + sections
['POST'] + '", $_POST);\n'
359 if sections
.has_key('GET'):
362 '<?php\nparse_str("' + sections
['GET'] + '", $_GET);\n'
364 if sections
.has_key('COOKIE'):
367 '<?php\n$_COOKIE = http_parse_cookie("' + sections
['COOKIE'] + '");\n'
369 if sections
.has_key('ENV'):
370 for line
in sections
['ENV'].split('\n'):
371 boom
= line
.split('=')
372 if len(boom
) == 2 and boom
[0] and boom
[1]:
375 '<?php\n$_ENV[%s] = %s;\n' % (boom
[0], boom
[1])
377 if sections
.has_key('CLEAN'):
378 test
+= sections
['CLEAN']
380 if 'bug60771.php' in full_dest_filename
:
381 test
= test
.replace("?>", "unlink('test.php');\n?>")
382 if 'bug44805.php' in full_dest_filename
:
383 test
= test
.replace("1)) {\n\tunlink($file2", "2)) {\n\tunlink($file2")
384 if 'bug24054.php' in full_dest_filename
:
385 test
= test
.replace("quicktester.inc", "tests/quicktester.inc")
386 if 'ext-bz2/with_strings.php' in full_dest_filename
:
387 test
= test
.replace("../..", "")
388 if 'ext-bz2/bug51997.php' in full_dest_filename
:
389 test
= test
.replace("testfile.bz2", "bug51997.bz2")
390 if 'ext-bz2/with_files.php' in full_dest_filename
:
391 test
= test
.replace("testfile.bz2", "with_files.bz2")
393 file(full_dest_filename
, 'w').write(test
)
396 test_dirs
= (('Zend/tests'), ('tests'), ('sapi'), ('ext'))
397 def should_import(filename
):
398 for bad
in no_import
:
403 for source
in test_dirs
:
404 for root
, dirs
, files
in os
.walk(os
.path
.join(args
.zend_path
, source
)):
405 for filename
in files
:
406 full_file
= os
.path
.join(root
, filename
)
408 def matches(regexes
):
411 for regex
in regexes
:
412 if re
.search(regex
, full_file
):
416 if matches(args
.only
) and should_import(full_file
):
417 walk(full_file
, root
.replace(args
.zend_path
, ''))
419 if not os
.path
.isdir('test/zend/all'):
421 print "No test/zend/all. Maybe no tests were imported?"
424 print "Running all tests from test/zend/bad"
425 shutil
.copytree('test/zend/bad', 'test/zend/all')
427 print "Running all tests from zend/all"
429 stdout
= subprocess
.Popen(
431 'tools/verify_to_json.php',
438 stdout
=subprocess
.PIPE
,
439 stderr
=subprocess
.STDOUT
442 # segfaults also print on stderr
443 stdout
= re
.sub('\nsh: line 1:.*', '', stdout
)
444 # fbmake, you are crazy
446 results
= json
.loads('['+stdout
.strip().replace("\n", ",\n")+']')[-1]['results']
452 filename
= test
['name']
453 good_file
= filename
.replace('all', 'good', 1)
454 bad_file
= filename
.replace('all', 'bad', 1)
455 mkdir_p(os
.path
.dirname(good_file
))
456 mkdir_p(os
.path
.dirname(bad_file
))
458 good
= (test
['status'] == 'passed')
459 for test
in bad_tests
:
464 dest_file
= good_file
465 delete_file
= bad_file
469 delete_file
= good_file
472 exps
= glob
.glob(filename
+'.expect*')
474 # this file is probably generated while running tests :(
477 source_file_exp
= exps
[0]
478 _
, dest_ext
= os
.path
.splitext(source_file_exp
)
479 os
.rename(filename
, dest_file
)
480 file(dest_file
+dest_ext
, 'w').write(
481 file(source_file_exp
).read().replace('/all', '/' + subpath
)
483 os
.unlink(source_file_exp
)
484 for f
in glob
.glob(delete_file
+"*"):
487 # extra random files needed for tests...
488 for root
, dirs
, files
in os
.walk('test/zend/all'):
489 for filename
in files
:
490 filename
= os
.path
.join(root
, filename
)
492 for name
in other_files
:
494 dest
= filename
.replace('all', 'good', 1)
495 dir = os
.path
.dirname(dest
)
497 shutil
.copyfile(filename
, dest
)
500 shutil
.rmtree('test/zend/all')