33import math
44import multiprocessing
55import os
6+ import pathlib
67import re
78import signal
89import sys
910from functools import partial
1011from multiprocessing .dummy import Pool as ThreadPool
12+ import typing
1113
1214from python .lib .colors import red , green , yellow , blue , cyan
1315from python .lib .file_utils import search_php_bin
1416from python .lib .nocc_for_kphp_tester import nocc_start_daemon_in_background
1517from python .lib .kphp_run_once import KphpRunOnce
18+ from python .lib import std_function
1619from python .lib import tcp
1720
1821TCP_SERVER_TAG_PREFIX = "tcp_server:"
1922
23+ FILE = pathlib .Path (__file__ )
24+ TMP_DIR = FILE .with_name ("{}_tmp" .format (FILE .stem ))
25+
2026
2127class TestFile :
2228 def __init__ (self , file_path , test_tmp_dir , tags , env_vars : dict , out_regexps = None , forbidden_regexps = None ):
@@ -55,13 +61,16 @@ def is_php8(self):
5561 def is_available_for_k2 (self ):
5662 return "k2_skip" not in self .tags
5763
58- def make_kphp_once_runner (self , use_nocc , cxx_name , k2_bin ):
64+ def make_kphp_once_runner (
65+ self , use_nocc , cxx_name , k2_bin , std_function_invocations : typing .Optional [std_function .Invocations ]
66+ ):
5967 tester_dir = os .path .abspath (os .path .dirname (__file__ ))
6068 return KphpRunOnce (
6169 php_script_path = self .file_path ,
6270 working_dir = os .path .abspath (os .path .join (self .test_tmp_dir , "working_dir" )),
6371 artifacts_dir = os .path .abspath (os .path .join (self .test_tmp_dir , "artifacts" )),
6472 php_bin = search_php_bin (php_version = self .php_version ),
73+ std_function_invocations = std_function_invocations ,
6574 extra_include_dirs = [os .path .join (tester_dir , "php_include" )],
6675 vkext_dir = os .path .abspath (os .path .join (tester_dir , os .path .pardir , "objs" , "vkext" )),
6776 use_nocc = use_nocc ,
@@ -75,7 +84,6 @@ def set_up_env_for_k2(self):
7584 self .env_vars ["KPHP_ENABLE_GLOBAL_VARS_MEMORY_STATS" ] = "0"
7685 self .env_vars ["KPHP_PROFILER" ] = "0"
7786 self .env_vars ["KPHP_FORCE_LINK_RUNTIME" ] = "1"
78- self .env_vars ["KPHP_TRACKED_BUILTINS_LIST" ] = KphpRunOnce .K2_KPHP_TRACKED_BUILTINS_LIST
7987
8088
8189def make_test_file (file_path , test_tmp_dir , test_tags ):
@@ -152,12 +160,11 @@ def test_files_from_list(tests_dir, test_list):
152160
153161def collect_tests (tests_dir , test_tags , test_list ):
154162 tests = []
155- tmp_dir = "{}_tmp" .format (__file__ [:- 3 ])
156163 file_it = test_files_from_list (tests_dir , test_list ) if test_list else test_files_from_dir (tests_dir )
157164 for root , file in file_it :
158165 if file .endswith (".php" ) or file .endswith (".phpt" ):
159166 test_file_path = os .path .join (root , file )
160- test_tmp_dir = os .path .join (tmp_dir , os .path .relpath (test_file_path , os .path .dirname (tests_dir )))
167+ test_tmp_dir = os .path .join (TMP_DIR , os .path .relpath (test_file_path , os .path .dirname (tests_dir )))
161168 test_tmp_dir = test_tmp_dir [:- 4 ] if test_tmp_dir .endswith (".php" ) else test_tmp_dir [:- 5 ]
162169 test_file = make_test_file (test_file_path , test_tmp_dir , test_tags )
163170 if test_file :
@@ -350,11 +357,13 @@ def run_ok_test(test: TestFile, runner):
350357 return TestResult .passed (test , runner .artifacts )
351358
352359
353- def run_test (use_nocc , cxx_name , k2_bin , test : TestFile ):
360+ def run_test (
361+ use_nocc , cxx_name , k2_bin , std_function_invocations : typing .Optional [std_function .Invocations ], test : TestFile
362+ ):
354363 if not os .path .exists (test .file_path ):
355364 return TestResult .failed (test , None , "can't find test file" )
356365
357- runner = test .make_kphp_once_runner (use_nocc , cxx_name , k2_bin )
366+ runner = test .make_kphp_once_runner (use_nocc , cxx_name , k2_bin , std_function_invocations )
358367 runner .remove_artifacts_dir ()
359368 if k2_bin is not None :
360369 test .set_up_env_for_k2 ()
@@ -393,17 +402,32 @@ def run_all_tests(tests_dir, jobs, test_tags, no_report, passed_list, test_list,
393402 "tag" if len (test_tags ) == 1 else "tags" ))
394403 sys .exit (1 )
395404
405+ if "KPHP_TRACKED_BUILTINS_LIST" in os .environ :
406+ std_function_invocations = std_function .Invocations (os .environ ["KPHP_TRACKED_BUILTINS_LIST" ])
407+ else :
408+ std_function_invocations = None
409+
396410 results = []
397411 with ThreadPool (jobs ) as pool :
398412 tests_completed = 0
399- for test_result in pool .imap_unordered (partial (run_test , use_nocc , cxx_name , k2_bin ), tests ):
413+ for test_result in pool .imap_unordered (partial (run_test , use_nocc , cxx_name , k2_bin , std_function_invocations ), tests ):
400414 if hack_reference_exit :
401415 print (yellow ("Testing process was interrupted" ), flush = True )
402416 break
403417 tests_completed = tests_completed + 1
404418 test_result .print_short_report (len (tests ), tests_completed )
405419 results .append (test_result )
406420
421+ if std_function_invocations :
422+ std_function_invocations_output_dir = TMP_DIR / "artifacts"
423+ std_function_invocations_output_dir .mkdir (parents = True , exist_ok = True )
424+
425+ std_function_invocations_filename = "std_function_invocations.json"
426+ std_function_invocations_output_path = std_function_invocations_output_dir / std_function_invocations_filename
427+
428+ with open (std_function_invocations_output_path , "w" , encoding = "utf-8" ) as f :
429+ std_function_invocations .dump (f )
430+
407431 print ("\n Testing results:" , flush = True )
408432
409433 skipped = len (tests ) - len (results )
0 commit comments