Switch GitHub CI to C++ test runner (#1963)#1963
Open
lavenzg wants to merge 13 commits intofacebook:static_hfrom
Open
Switch GitHub CI to C++ test runner (#1963)#1963lavenzg wants to merge 13 commits intofacebook:static_hfrom
lavenzg wants to merge 13 commits intofacebook:static_hfrom
Conversation
lavenzg
added a commit
to lavenzg/hermes
that referenced
this pull request
Mar 27, 2026
Summary: Pull Request resolved: facebook#1963 Replace the Python test_runner.py invocation with the C++ test-runner binary in the GitHub Actions CI workflow for macOS, Linux, and Linux ARMv7 jobs. The C++ runner is ~8x faster and runs tests in-process. Key changes: - macOS/Linux: use build/bin/test-runner with --test-intl and --skiplist - JIT matrix variant: replace --vm-args='-Xjit=force' with --jit=force - ARMv7: same as Linux, no JIT variant - Windows: kept on Python runner (C++ runner uses POSIX signal APIs for crash isolation that aren't available on Windows) Differential Revision: D98531546
5b340a2 to
41e1b4c
Compare
lavenzg
added a commit
to lavenzg/hermes
that referenced
this pull request
Mar 27, 2026
Summary: Pull Request resolved: facebook#1963 Replace the Python test_runner.py invocation with the C++ test-runner binary in the GitHub Actions CI workflow for macOS, Linux, and Linux ARMv7 jobs. The C++ runner is ~8x faster and runs tests in-process. Key changes: - macOS/Linux: use build/bin/test-runner with --test-intl and --skiplist - JIT matrix variant: replace --vm-args='-Xjit=force' with --jit=force - ARMv7: same as Linux, no JIT variant - Windows: kept on Python runner (C++ runner uses POSIX signal APIs for crash isolation that aren't available on Windows) Differential Revision: D98531546
41e1b4c to
96fe60d
Compare
lavenzg
added a commit
to lavenzg/hermes
that referenced
this pull request
Mar 27, 2026
Summary: Pull Request resolved: facebook#1963 Replace the Python test_runner.py invocation with the C++ test-runner binary in the GitHub Actions CI workflow for macOS, Linux, and Linux ARMv7 jobs. The C++ runner is ~8x faster and runs tests in-process. Key changes: - macOS/Linux: use build/bin/test-runner with --test-intl and --skiplist - JIT matrix variant: replace --vm-args='-Xjit=force' with --jit=force - ARMv7: same as Linux, no JIT variant - Windows: kept on Python runner (C++ runner uses POSIX signal APIs for crash isolation that aren't available on Windows) Differential Revision: D98531546
96fe60d to
01f8062
Compare
Summary: Add C++ test runner project that links hermesvm_a for in-process execution. CLI supports -j, --timeout, --show-slowest-tests, --dump-source flags. Build: ninja test-runner in cmake-build-release. Differential Revision: D98522855
Summary:
Add test file discovery and skiplist filtering:
TestDiscovery.h:
- Recursive directory traversal finding .js files
- Suite detection (test262, mjsunit, CVEs, esprima, flow) via rfind markers
- Excludes test262 _FIXTURE.js files
- Sorted output for deterministic ordering
Skiplist.h:
- Parses utils/testsuite/skiplist.json using Hermes JSONParser
- Supports all categories: manual_skip_list, skip_list, lazy_skip_list,
permanent_skip_list, handlesan_skip_list, intl_tests, platform_skip_list
- Supports unsupported_features and permanent_unsupported_features
- Handles both bare string and {paths, comment} entry formats
- Substring matching for path-based skipping (matches Python/Rust behavior)
main.cpp:
- Wires discovery and skiplist into CLI pipeline
- Auto-detects skiplist.json by walking up from test paths
- Prints Python-compatible output: "-- Testing: N tests, max J concurrent tasks --"
Differential Revision: D98522850
Summary: Add YAML frontmatter parser (Frontmatter.h) that extracts test262 metadata (flags, features, includes, negative expectations) and strips frontmatter + license headers from test source. Add harness file cache (HarnessCache.h) that loads all .js files from test262/harness/ into memory once, then assembles complete test source by prepending harness includes with optional 'use strict;' prefix. Implement --dump-source mode in main.cpp: parses frontmatter, loads harness, assembles source with correct strict/non-strict variants (onlyStrict, noStrict, raw, module flags), and prints to stdout. Auto-detects test262 suite root from test paths for harness loading. Feature-based skiplist filtering applied during dump-source. Differential Revision: D98522852
Summary: Add the core test execution engine (Executor.h/cpp) and integrate it into main.cpp with result tallying and failure reporting. Executor.h: Public API declarations: - ResultCode enum with granular failure categories: CompileFailed, CompileTimeout, ExecuteFailed, ExecuteTimeout, PermanentlySkipped - resultCodeName() for display strings - TestResult struct with test name, result code, message, and duration - ExecConfig struct for thread count and timeout configuration - compileSource(): compile JS to bytecode via BCProviderFromSrc - executeTestVariant(): compile + run a single test variant - WorkQueue: thread-safe FIFO work queue (std::deque) with mutex+condvar for distributing tests to a configurable thread pool - runAllTests(): orchestrate parallel test execution Executor.cpp: Implementation with extracted static helpers: - captureException(): capture and clear thrown exception from runtime - createTestRuntime(): create configured HermesRuntime with ES6Proxy, MicrotaskQueue, Test262, HermesInternal, AsyncGenerators, Eval, and TimeLimitMonitor for timeout enforcement - drainTaskQueue(): process queued setTimeout callbacks with microtask draining after each one - executeCompiledTest(): run bytecode in fresh runtime, install console bindings ($262, setTimeout), handle negative expectations (parse, runtime, resolution phases), drain microtasks and task queue - processTestEntry(): read test file, parse frontmatter, determine strict/non-strict/raw variants, skip by feature and testIntl.js, short-circuit on first variant failure, thread-safe result collection - reportProgress(): periodic progress display (every 100 tests) main.cpp: Integrates executor with: - shouldSkipByFeature() and filterBySkiplist() for path-based skipping - Result tallying by category with failure detail reporting - Slowest test display (--show-slowest-tests) - Summary statistics with pass/fail/skip/timeout counts CMakeLists.txt: Added Executor.cpp and hermesConsoleHost_obj link dependency. Differential Revision: D98522849
Summary: Refactor result reporting into structured helpers and add permanent skip tracking, wall-clock timing, and formatted summary table. Executor changes: - Add permanentFeatureSkipped atomic counter to processTestEntry() and runAllTests(), tracking PermanentUnsupportedFeature skips separately from regular feature skips. main.cpp reporting helpers (extracted from inline Phase 4 code): - ResultTally struct: per-category counters (compileFail, compileTimeout, executeFail, executeTimeout) with failures vector and totalFailed() accessor. - tallyResults(): categorize results by ResultCode, leveraging the executor's one-result-per-file short-circuit behavior. - printSlowestTests(): display N slowest tests sorted by duration, with seconds format (e.g., "0.10s") and dashed borders. - printResults(): formatted summary table matching Python/Rust runner output with Total, Passes, Failures, Skipped, Permanently Skipped, Pass Rate, and failure breakdown rows. Pass Rate computed over executed tests only (excludes skipped). Assert guards unsigned subtraction invariant for skip accounting. main.cpp integration: - FilterResult gains permanentlySkippedCount, tracked via PermanentSkipList SkipReason in filterBySkiplist(). - Wall-clock timing via steady_clock around runAllTests(). - Removed inline result tallying and "Skipped N tests via skiplist" message, replaced by printResults() call. Differential Revision: D98522847
Summary: Add enableTDZ (Temporal Dead Zone) flag to hbc::CompileFlags and wire it through BCProviderFromSrc to CodeGenerationSettings. This allows callers like the test runner to enable TDZ checking for let/const when compiling test262 tests. Differential Revision: D98821643
Summary: Harden the test runner for full test262 suite verification. Executor changes: - Enable ES6 block scoping and TDZ in both RuntimeConfig and CompileFlags for full let/const semantics. - Suppress print/alert output by installing no-op overrides before running test bytecode, preventing stdout noise from test output. - Move expectRuntimeError computation into executeCompiledTest(), removing it from executeTestVariant() parameter list. - Remove negative.errorType matching for expected compile errors (too fragile against Hermes-specific error messages). - Skip module tests early (Hermes doesn't support ES module execution) instead of forcing them to non-strict mode. - Extract buildTestIncludes() as public API (moved from main.cpp buildIncludes), now skips harness includes for raw tests. - Swap drainTaskQueue parameter order (ctx before scope) for consistency. - Rename hermesRuntime -> jsiRuntime in TestRuntimeEnv. - Use std::move for timeLimitMonitor in createTestRuntime return. Progress display: - Replace "N/total tests complete" with percentage-based milestones "Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.." - Thread-safe via atomic compare_exchange_strong, each milestone printed exactly once. Move reportProgress() call to lambda in runAllTests() instead of inside processTestEntry(). Frontmatter changes: - Defer license header stripping and blank line trimming until after YAML parsing, so raw tests preserve their source exactly. main.cpp changes: - Remove buildIncludes() (moved to Executor as buildTestIncludes). - Skip module tests in dumpTestSource() instead of forcing non-strict. - Minor comment and doc string cleanups. Differential Revision: D98823646
Summary: Integrate the skip list system with the C++ test runner. Adds handle sanitizer disable support (matching the Python runner's handlesan_skip_list), supported feature detection (compile-time via ifdefs), non-intl path skipping, and the --test-intl CLI flag. Key changes: - Skiplist: add handlesanPaths_, supportedFeatures_, shouldDisableHandleSan(), shouldSkipPathNonIntl(), and compile-time feature detection - Executor: thread disableHandleSan through createTestRuntime/executeCompiledTest/ executeTestVariant/processTestEntry - main: add --test-intl flag, extend filterBySkiplist() with testIntl and lazy params Differential Revision: D98824412
Differential Revision: D98522853
Summary: Add support for enabling compiler optimization passes via the -O CLI flag, matching the Python runner's behavior. When -O is passed, the full optimization pipeline (runFullOptimizationPasses) is invoked during compilation via BCProviderFromSrc::create(). Default is no optimization (-O0), matching the Python runner's default behavior (--opt flag with store_true, defaulting to False). Verified: 38,418 passes, 0 failures with -O on full test262 suite. Differential Revision: D98522851
Summary: Add support for lazy compilation in the C++ test runner, matching the Python runner's --lazy flag behavior. When --lazy is passed: - CompileFlags.lazy = true is set, enabling lazy compilation in BCProviderFromSrc - RuntimeModuleFlags.persistent is set to false (incompatible with lazy) - Tests in lazy_skip_list are skipped (matching Python runner's conditional: if lazy: skip_categories.append(LAZY_SKIP_LIST)) When --lazy is not passed (default): - Tests in lazy_skip_list run normally and are not skipped, matching the Python runner's behavior where LAZY_SKIP_LIST is only appended when the lazy flag is set Differential Revision: D98522848
Summary: Adds a `--jit` flag with three modes: off (default), on, and force. This maps directly to RuntimeConfig's EnableJIT and ForceJIT settings, matching the Python runner's `--vm-args='-Xjit=force'` behavior. The flag is threaded through ExecConfig → processTestEntry → executeTestVariant → executeCompiledTest → createTestRuntime, where it configures the RuntimeConfig builder with .withEnableJIT() and .withForceJIT(). Differential Revision: D98858012
Summary: Pull Request resolved: facebook#1963 Replace the Python test_runner.py invocation with the C++ test-runner binary in the GitHub Actions CI workflow for macOS, Linux, and Linux ARMv7 jobs. The C++ runner is ~8x faster and runs tests in-process. Key changes: - macOS/Linux: use build/bin/test-runner with --test-intl and --skiplist - JIT matrix variant: replace --vm-args='-Xjit=force' with --jit=force - ARMv7: same as Linux, no JIT variant - Windows: kept on Python runner (C++ runner uses POSIX signal APIs for crash isolation that aren't available on Windows) Differential Revision: D98531546
01f8062 to
b874810
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Replace the Python test_runner.py invocation with the C++ test-runner
binary in the GitHub Actions CI workflow for macOS, Linux, and Linux
ARMv7 jobs. The C++ runner is ~8x faster and runs tests in-process.
Key changes:
for crash isolation that aren't available on Windows)
Differential Revision: D98531546