Skip to content

Commit 6f68b2c

Browse files
authored
[k2] dump k2 built-in invocations (#1554)
1 parent 81bffa6 commit 6f68b2c

13 files changed

Lines changed: 378 additions & 92 deletions

runtime-light/stdlib/diagnostics/functions-call-stats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66

77
#include "runtime-light/stdlib/diagnostics/logs.h"
88

9-
#define DUMP_BUILTIN_CALL_STATS(builtin_name, builtin_call) (kphp::log::debug("built-in called: " builtin_name), builtin_call)
9+
#define DUMP_BUILTIN_CALL_STATS(builtin_name, builtin_call) (kphp::log::debug("std function called: " builtin_name), builtin_call)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import json
2+
import csv
3+
import argparse
4+
import pathlib
5+
import collections
6+
7+
SCRIPT_DIR = pathlib.Path(__file__).parent
8+
DEFAULT_OUTPUT = SCRIPT_DIR / 'tmp' / 'std_function_invocations.csv'
9+
10+
def main():
11+
parser = argparse.ArgumentParser(
12+
description="Aggregates std function invocations from multiple JSON files into a single CSV report."
13+
)
14+
15+
parser.add_argument(
16+
'inputs',
17+
nargs='+',
18+
type=pathlib.Path,
19+
help='Paths to the JSON files generated by test groups',
20+
)
21+
22+
parser.add_argument(
23+
'--output', '-o',
24+
type=pathlib.Path,
25+
default=DEFAULT_OUTPUT,
26+
help=f'Path to the output CSV file (default: {DEFAULT_OUTPUT})',
27+
)
28+
29+
args = parser.parse_args()
30+
total_counts = collections.defaultdict(int)
31+
32+
for file_path in args.inputs:
33+
if file_path.exists():
34+
try:
35+
data = json.loads(file_path.read_text(encoding='utf-8'))
36+
if isinstance(data, dict):
37+
for func_name, count in data.items():
38+
total_counts[func_name] += count
39+
else:
40+
print(f"Warning: {file_path} content is not a dictionary. Skipping.")
41+
except json.JSONDecodeError:
42+
print(f"Error: {file_path} is not a valid JSON file. Skipping.")
43+
else:
44+
print(f"Info: {file_path} not found. It might have been disabled.")
45+
46+
args.output.parent.mkdir(parents=True, exist_ok=True)
47+
48+
try:
49+
with args.output.open('w', newline='', encoding='utf-8') as f:
50+
writer = csv.writer(f)
51+
writer.writerow(['Built-in', 'Call count'])
52+
53+
sorted_results = sorted(total_counts.items(), key=lambda item: (item[1], item[0]))
54+
55+
for func, count in sorted_results:
56+
writer.writerow([func, count])
57+
58+
print(f"Success! Aggregated report saved to: {args.output.absolute()}")
59+
except Exception as e:
60+
print(f"Error saving report: {e}")
61+
62+
if __name__ == "__main__":
63+
main()

tests/python/lib/k2_kphp_tracked_builtins_list.txt renamed to tests/k2_kphp_tracked_builtins_list.txt

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,11 @@ rpc_queue_next
353353
rpc_server_fetch_request
354354
rpc_server_store_response
355355
rpc_tl_pending_queries_count
356-
rpc_tl_query
357-
rpc_tl_query_result
358-
rpc_tl_query_result_synchronously
359356
rsort
360357
rtrim
361358
sched_yield
362359
sched_yield_sleep
363360
serialize
364-
set_detect_incorrect_encoding_names_warning
365361
set_fail_rpc_on_int32_overflow
366362
set_json_log_on_timeout_mode
367363
set_migration_php8_warning
@@ -413,9 +409,6 @@ tan
413409
time
414410
to_array_debug
415411
trim
416-
typed_rpc_tl_query
417-
typed_rpc_tl_query_result
418-
typed_rpc_tl_query_result_synchronously
419412
uasort
420413
UberH3$$geoToH3
421414
UberH3$$h3ToParent
@@ -454,3 +447,81 @@ warning
454447
wordwrap
455448
zstd_compress
456449
zstd_uncompress
450+
flush
451+
getopt
452+
is_readable
453+
kphp_extended_instance_cache_metrics_init
454+
md5_file
455+
fgetcsv
456+
fgets
457+
file_exists
458+
file_put_contents
459+
prepare_search_query
460+
set_json_log_demangle_stacktrace
461+
strftime
462+
ini_set
463+
get_webserver_stats
464+
thread_pool_test_load
465+
chmod
466+
getimagesize
467+
copy
468+
dirname
469+
feof
470+
filemtime
471+
fputcsv
472+
fseek
473+
ftell
474+
is_dir
475+
mkdir
476+
rename
477+
rewind
478+
scandir
479+
tempnam
480+
stream_context_create
481+
kphp_job_worker_fetch_request
482+
kphp_job_worker_start
483+
kphp_job_worker_start_multi
484+
kphp_job_worker_start_no_reply
485+
kphp_job_worker_store_response
486+
kphp_backtrace
487+
kphp_turn_on_host_tag_in_inner_statshouse_metrics_toggle
488+
memory_get_static_usage
489+
openssl_x509_checkpurpose
490+
openssl_x509_verify
491+
preg_last_error
492+
new_rpc_connection
493+
store_finish
494+
fetch_lookup_int
495+
gethostbynamel
496+
localtime
497+
system
498+
kphp_tracing_func_enter_branch
499+
kphp_tracing_get_current_active_span
500+
kphp_tracing_get_level
501+
kphp_tracing_get_root_span
502+
kphp_tracing_init
503+
kphp_tracing_register_enums_provider
504+
kphp_tracing_register_on_finish
505+
kphp_tracing_register_rpc_details_provider
506+
msgpack_deserialize_safe
507+
kphp_tracing_set_level
508+
kphp_tracing_start_span
509+
KphpDiv$$assignTraceCtx
510+
KphpDiv$$generateTraceCtxForChild
511+
preg_split
512+
KphpSpan$$addAttributeBool
513+
KphpSpan$$addAttributeFloat
514+
KphpSpan$$addAttributeInt
515+
KphpSpan$$addAttributeString
516+
KphpSpan$$addEvent
517+
KphpSpan$$exclude
518+
KphpSpan$$finish
519+
KphpSpan$$finishWithError
520+
KphpSpan$$updateName
521+
KphpSpanEvent$$addAttributeInt
522+
KphpSpanEvent$$addAttributeString
523+
ignore_user_abort
524+
send_http_103_early_hints
525+
profiler_set_function_label
526+
vk_dot_product
527+
vk_flex

tests/kphp_ci_pipeline_runner.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import math
55
import multiprocessing
66
import os
7+
import pathlib
8+
import shlex
79
import signal
810
import subprocess
911
import sys
@@ -13,6 +15,10 @@
1315
from python.lib.nocc_for_kphp_tester import nocc_env
1416

1517

18+
K2_KPHP_TRACKED_BUILTINS_LIST_PATH = pathlib.Path(__file__).parent / "k2_kphp_tracked_builtins_list.txt"
19+
K2_KPHP_TRACKED_BUILTINS_LIST = K2_KPHP_TRACKED_BUILTINS_LIST_PATH.read_text()
20+
21+
1622
class TestStatus(Enum):
1723
FAILED = red("failed")
1824
PASSED = green("passed")
@@ -348,9 +354,11 @@ def _calculate_pytest_jobs_count(default_percent: int = 95) -> int:
348354
name="k2-kphp-tests",
349355
description="run k2-kphp tests with cxx={}".format(args.cxx_name),
350356
cmd="KPHP_TESTS_POLYFILLS_REPO={kphp_polyfills_repo} "
357+
"KPHP_TRACKED_BUILTINS_LIST={K2_KPHP_TRACKED_BUILTINS_LIST} "
351358
"{kphp_runner} -j{jobs} --cxx-name {cxx_name} --k2-bin {k2_bin}".format(
352359
jobs=n_cpu,
353360
kphp_polyfills_repo=kphp_polyfills_repo,
361+
K2_KPHP_TRACKED_BUILTINS_LIST=shlex.quote(K2_KPHP_TRACKED_BUILTINS_LIST),
354362
kphp_runner=kphp_test_runner,
355363
cxx_name=args.cxx_name,
356364
k2_bin=args.k2_bin,
@@ -427,10 +435,17 @@ def _calculate_pytest_jobs_count(default_percent: int = 95) -> int:
427435
runner.add_test_group(
428436
name="k2-functional-tests",
429437
description="run k2-kphp functional tests with cxx={}".format(args.cxx_name),
430-
cmd="KPHP_TESTS_POLYFILLS_REPO={kphp_polyfills_repo} KPHP_CXX={cxx_name} K2_BIN={k2_bin} K2_MONITORING_ABORT_HANGING_GLOBAL_TASK=false K2_MONITORING_ABORT_HANGING_REQUEST_TASK=false python3 -m pytest --basetemp={base_tempdir} --tb=native -n{jobs} {functional_tests_dir}".format(
438+
cmd="KPHP_TESTS_POLYFILLS_REPO={kphp_polyfills_repo} "
439+
"KPHP_CXX={cxx_name} "
440+
"K2_BIN={k2_bin} "
441+
"K2_MONITORING_ABORT_HANGING_GLOBAL_TASK=false "
442+
"K2_MONITORING_ABORT_HANGING_REQUEST_TASK=false "
443+
"KPHP_TRACKED_BUILTINS_LIST={K2_KPHP_TRACKED_BUILTINS_LIST} "
444+
"python3 -m pytest --basetemp={base_tempdir} --tb=native -n{jobs} {functional_tests_dir}".format(
431445
kphp_polyfills_repo=kphp_polyfills_repo,
432446
cxx_name=args.cxx_name,
433447
k2_bin=args.k2_bin,
448+
K2_KPHP_TRACKED_BUILTINS_LIST=shlex.quote(K2_KPHP_TRACKED_BUILTINS_LIST),
434449
jobs=n_cpu,
435450
functional_tests_dir=functional_tests_dir,
436451
base_tempdir=os.path.expanduser(
@@ -474,6 +489,7 @@ def _calculate_pytest_jobs_count(default_percent: int = 95) -> int:
474489
"KPHP_TESTS_INTERGRATION_TESTS_ENABLED=1 "
475490
"KPHP_CXX={cxx_name} "
476491
"K2_BIN={k2_bin} "
492+
"KPHP_TRACKED_BUILTINS_LIST={K2_KPHP_TRACKED_BUILTINS_LIST} "
477493
"python3 -m pytest --tb=native -n{jobs} {tests_dir}".format(
478494
jobs=n_cpu,
479495
lib_dir=os.path.join(runner_dir, "python"),
@@ -482,6 +498,7 @@ def _calculate_pytest_jobs_count(default_percent: int = 95) -> int:
482498
kphp_polyfills_repo=kphp_polyfills_repo,
483499
cxx_name=args.cxx_name,
484500
k2_bin=args.k2_bin,
501+
K2_KPHP_TRACKED_BUILTINS_LIST=shlex.quote(K2_KPHP_TRACKED_BUILTINS_LIST),
485502
tests_dir=" ".join([
486503
os.path.join(args.kphp_tests_repo, "python/tests/k2_rpc_client/"),
487504
os.path.join(args.kphp_tests_repo, "python/tests/k2_rpc_server/"),

tests/kphp_tester.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@
33
import math
44
import multiprocessing
55
import os
6+
import pathlib
67
import re
78
import signal
89
import sys
910
from functools import partial
1011
from multiprocessing.dummy import Pool as ThreadPool
12+
import typing
1113

1214
from python.lib.colors import red, green, yellow, blue, cyan
1315
from python.lib.file_utils import search_php_bin
1416
from python.lib.nocc_for_kphp_tester import nocc_start_daemon_in_background
1517
from python.lib.kphp_run_once import KphpRunOnce
18+
from python.lib import std_function
1619
from python.lib import tcp
1720

1821
TCP_SERVER_TAG_PREFIX = "tcp_server:"
1922

23+
FILE = pathlib.Path(__file__)
24+
TMP_DIR = FILE.with_name("{}_tmp".format(FILE.stem))
25+
2026

2127
class 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

8189
def make_test_file(file_path, test_tmp_dir, test_tags):
@@ -152,12 +160,11 @@ def test_files_from_list(tests_dir, test_list):
152160

153161
def 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("\nTesting results:", flush=True)
408432

409433
skipped = len(tests) - len(results)

0 commit comments

Comments
 (0)