Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion codeflash/languages/javascript/mocha_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,9 @@ def run_mocha_benchmarking_tests(
)
mocha_env["CODEFLASH_TEST_MODULE"] = test_module_path

total_timeout = max(120, (target_duration_ms // 1000) + 60, timeout or 120)
# Subprocess timeout: target_duration + 120s headroom for Mocha startup.
# capturePerf's time budget governs actual looping.
total_timeout = max(120, (target_duration_ms // 1000) + 120)

logger.debug(f"Running Mocha benchmarking tests: {' '.join(mocha_cmd)}")
logger.debug(
Expand Down
11 changes: 7 additions & 4 deletions codeflash/languages/javascript/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -2372,9 +2372,12 @@ def run_behavioral_tests(
candidate_index=candidate_index,
)

# JavaScript/TypeScript benchmarking uses high max_loops like Python (100,000)
# The actual loop count is limited by target_duration_seconds, not max_loops
JS_BENCHMARKING_MAX_LOOPS = 100_000
# Max iterations per capturePerf call site. Each iteration writes a ~200-byte
# timing marker to stdout. The actual loop count is governed by the 10s time
# budget (CODEFLASH_PERF_TARGET_DURATION_MS) — this constant is just a ceiling.
# Python uses max_loops=250; JS iterations are lighter (no pytest overhead) so
# 1000 gives comparable statistical power while keeping stdout under 200 KB.
JS_BENCHMARKING_MAX_LOOPS = 1_000

def run_benchmarking_tests(
self,
Expand All @@ -2384,7 +2387,7 @@ def run_benchmarking_tests(
timeout: int | None = None,
project_root: Path | None = None,
min_loops: int = 5,
max_loops: int = 100_000,
max_loops: int = 1_000,
target_duration_seconds: float = 10.0,
test_framework: str | None = None,
) -> tuple[Path, Any]:
Expand Down
6 changes: 3 additions & 3 deletions codeflash/languages/javascript/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1025,9 +1025,9 @@ def run_jest_benchmarking_tests(
if "--max-old-space-size" not in existing_node_options:
jest_env["NODE_OPTIONS"] = f"{existing_node_options} --max-old-space-size=4096".strip()

# Total timeout for the entire benchmark run (longer than single-loop timeout)
# Account for startup overhead + target duration + buffer
total_timeout = max(120, (target_duration_ms // 1000) + 60, timeout or 120)
# Subprocess timeout: target_duration + 120s headroom for Jest startup
# and TS compilation. capturePerf's time budget governs actual looping.
total_timeout = max(120, (target_duration_ms // 1000) + 120)

logger.debug(f"Running Jest benchmarking tests with in-process loop runner: {' '.join(jest_cmd)}")
logger.debug(
Expand Down
6 changes: 4 additions & 2 deletions codeflash/languages/javascript/vitest_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,10 @@ def run_vitest_benchmarking_tests(
vitest_env["CODEFLASH_TEST_MODULE"] = test_module_path
logger.debug(f"[VITEST-BENCH] Set CODEFLASH_TEST_MODULE={test_module_path}")

# Total timeout for the entire benchmark run
total_timeout = max(120, (target_duration_ms // 1000) + 60, timeout or 120)
# Subprocess timeout: target_duration + 120s headroom for Vitest startup
# (TS compilation, module resolution). The capturePerf time budget (10s default)
# governs actual looping; this is just a safety net for process-level hangs.
total_timeout = max(120, (target_duration_ms // 1000) + 120)

logger.debug(f"[VITEST-BENCH] Running Vitest benchmarking tests: {' '.join(vitest_cmd)}")
logger.debug(
Expand Down
8 changes: 7 additions & 1 deletion codeflash/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,13 @@ def get_src_code(self, test_path: Path) -> Optional[str]:
test_src = test_path.read_text(encoding="utf-8")
module_node = cst.parse_module(test_src)
except Exception:
return None
# libcst can't parse non-Python files (JS/TS) — return a descriptive string
# so the code repair API receives a non-None test_src_code.
return (
f"// Test: {self.test_function_name}\n"
f"// File: {test_path.name}\n"
f"// Testing function: {self.function_getting_tested}"
)

if self.test_class_name:
for stmt in module_node.body:
Expand Down
4 changes: 2 additions & 2 deletions tests/languages/javascript/test_support_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ def test_passes_loop_parameters(self, mock_vitest_runner: MagicMock, js_support:

call_kwargs = mock_vitest_runner.call_args.kwargs
assert call_kwargs["min_loops"] == 10
# JS/TS always uses high max_loops (100_000) regardless of passed value
# JS/TS uses JS_BENCHMARKING_MAX_LOOPS (5_000) regardless of passed value
# Actual loop count is limited by target_duration, not max_loops
assert call_kwargs["max_loops"] == 100_000
assert call_kwargs["max_loops"] == 5_000
assert call_kwargs["target_duration_ms"] == 5000


Expand Down
Loading