611 Commits
Author SHA1 Message Date
William T. NelsonandClaude Opus 5.5 b77c9f32dc [ruby/test-unit-ruby-core] Close stdin before terminating a
timed-out memory leak child
(https://github.com/ruby/test-unit-ruby-core/pull/37)

* Close stdin before terminating a timed-out memory leak child

With a sample range, assert_no_memory_leak keeps the child's stdin open,
and the child's ensure clause reads a "continue" line from it after each
sample. When the timeout fires while the child is running the sampled
code, EnvUtil.terminate sends SIGTERM, and the child's ensure clause
then blocks reading stdin, which was closed only after terminate
returned. SIGTERM cannot end the child, so terminate escalates to
SIGABRT and then waits for the aborted child without a time limit. On
ruby/ruby's YJIT macOS CI jobs the child sometimes did not exit after
the RUBY_ON_BUG core dump, and the test worker hung until the runner
killed it 20 minutes later. In other runs the test passed but left a
crash report for the child.

Close stdin first. The child's read then returns nil, and its ensure
clause breaks out of the sample loop. The break discards the
SignalException raised by SIGTERM, so the child exits with status 0. If
SIGTERM arrives before the child reaches the sample loop, the child
still dies from SIGTERM.

The existing timeout test now also checks that the child exited
normally or by SIGTERM.

https://github.com/ruby/test-unit-ruby-core/commit/ce7a92e724

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 00:23:25 +00:00
Yusuke EndohandClaude Opus 5.5 fd77a0a2a0 leakchecker.rb: Ignore lsof that does not print the expected header
busybox lsof ignores the options and prints no header line, so the
FD/TYPE/NODE columns cannot be found and check_fd_leak crashed with
NoMethodError, which killed the test worker. Treat such lsof as
unavailable; leaked fds are still reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:05:30 +09:00
Nobuyoshi Nakada d60c0505be [ruby/test-unit-ruby-core] Wait indefinitely for dumped child processes
On macOS, it sometimes takes a little while for a process attached to
the debugger to be ready for `waitpid`.

https://github.com/ruby/test-unit-ruby-core/commit/c1f817fdad
2026-10-19 05:29:00 +00:00
Nobuyoshi Nakada 2ea459b156 [ruby/test-unit-ruby-core] Support adaptive memory leak samples
Allow memory leak assertions to stop sampling when memory growth
settles.  This helps avoid failures from transient memory use.

https://github.com/ruby/test-unit-ruby-core/commit/ab24a357a4
2026-10-19 05:29:00 +00:00
Nobuyoshi Nakada ef4d6d7c7d [ruby/test-unit-ruby-core] Sample memory usage trends in leak assertions
Repeated sampling avoids false leak reports from transient RSS growth.

https://github.com/ruby/test-unit-ruby-core/commit/55320e5dae
2026-10-19 05:29:00 +00:00
Yusuke EndohandClaude Opus 5.5 a1efb9ae6b Promote prism to a bundled gem
prism is no longer a default gem (the built-in parser is Ruby::Prism
now), so add the prism gem to gems/bundled_gems.  `require "prism"`
keeps providing the gem, which can be any version.  lib/bundled_gems.rb
warns when it is required under bundler without a Gemfile entry, like
other gems promoted to bundled gems.

The gem is pinned to the upstream revision that ruby/ruby is synced
with, because the tests of the released 1.9.0 compare with the parser
of the running Ruby, whose grammar has moved on in 4.1.

prism does not keep its templated files in git, so BundledGem.build
(used by both common.mk and defs/gmake.mk) generates them before
building the gem from the checkout.  Since the gem built from the
revision has the same version as the released one, BundledGem.unpack
now clears the target directory first; otherwise files removed upstream
(ext/prism/api_pack.c) remain from the released gem and break the
build.

tool/test-bundled-gems.rb: several bundled gems (irb, rdoc, rbs,
typeprof, ...) require prism, and their tests spawn ruby with
--disable=gems, where the prism gem is not loadable anymore.  Preset its
load paths in RUBYLIB, as is already done for debug.

[Bug #22379]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:27:15 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 03ec621e90 Pick the pid to kill in one place
Worker#kill and quit_workers both need the test process rather than the runruby.rb process on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:12:22 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 162ce2fee8 Kill the test processes left after waiting for workers on Windows
The KILL sent when Process.waitall times out in quit_workers also hit only the runruby.rb process on Windows, leaving the test process running. It now targets only the workers still running, since the pids of the test processes that have exited may already be reused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:12:22 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 16d7abf963 Kill the hung worker itself on Windows
On Windows, exec in runruby.rb spawns the worker as another process and waits for it, so killing the launched pid left the worker running with the inherited stderr open, and GitHub Actions waited on it until the step timed out. The worker now reports its own pid, which is also the process the debugger should dump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:12:22 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 047430f81c vcs.rb: Pass /dev/null to git instead of IO::NULL
Git for Windows 2.56.0 dies with "unable to access 'NUL': Invalid argument" when GIT_CONFIG_SYSTEM or GIT_CONFIG_GLOBAL is `NUL`, which stops the revision.h generation on mswin. `/dev/null` is the value git documents for them, and Git for Windows has accepted it since 2.32, the first version that reads them.

https://github.com/git-for-windows/git/issues/6449

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:38:08 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 fa6ffde024 Read RUBY_TEST_TIMEOUT_SCALE in EnvUtil
test-bundled-gems runs the tests with the test-unit gem, which loads EnvUtil through gems/lib but never goes through tool/lib/test/unit.rb, so the scale was ignored there. `--timeout-scale` still takes precedence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 06:21:58 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 0fef975dce Remove Solaris 9 and earlier support
Extended Support for Solaris 9 ended in 2014. Solaris 10 and later have setenv and unsetenv, and libumem is always available, so the version specific fallbacks are no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:00:26 +09:00
Peter Zhu 99d67b64a1 Add assert_in_ractor
This commit adds assert_in_ractor which runs code in a Ractor and allows
the use of assertions in the Ractor.
2026-10-01 20:07:00 +09:00
Peter Zhu 4898b7d4da [ruby/test-unit-ruby-core] Make core_assertions.rb Ractor-ready
These changes make core_assertions.rb ready for changes in
https://github.com/ruby/ruby/pull/19141.

https://github.com/ruby/test-unit-ruby-core/commit/1c3f62cd4c
2026-09-30 23:59:07 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 708492952c [ruby/test-unit-ruby-core] Pass a message to Timeout.timeout only when given
Timeout.timeout in Ruby 2.3 takes at most two arguments, so EnvUtil.timeout always raised ArgumentError there. EnvUtil.terminate reaches it through Debugger#dump on Windows when gdb is installed, which broke test_terminate_reaps_exited_child on windows-latest 2.3.

https://github.com/ruby/test-unit-ruby-core/commit/42d15562b2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:53:18 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 9fe613e94b Reap an exited child in EnvUtil.terminate
On Windows, Process.kill raises Errno::ESRCH for a child that has exited but has not been reaped, so terminate returned a stale $? and left the child to ZombieHunter. TestIO#test_write_32bit_boundary hit this on Windows 11-arm, where the child finished writing after its timeout expired and before it was killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:23:31 +09:00
Nobuyoshi Nakada 9cbb4e67ef Disable repeat counts for parallel tests
Ignore `--repeat-count` during parallel tests because fresh workers
cannot expose state carried over between repetitions.
2026-09-24 21:51:13 +09:00
Nobuyoshi Nakada 28ae8099dc Preserve jobserver limits across repeated test runs
Keep the jobserver connection until all repetitions finish so that
later runs do not launch up to 256 workers without token limits.
2026-09-24 21:51:13 +09:00
Nobuyoshi Nakada 1f11ffaee4 Run GC in test workers before running suites
Run `GC.start` in the process executing tests because collecting the
parent heap does not reclaim objects in parallel workers.
2026-09-24 21:51:12 +09:00
Nobuyoshi Nakada c02373fb32 win32: Now mklink is run through cmd.exe\n\nIt is included at 213b1add1f. 2026-09-24 16:39:22 +09:00
Jeremy Evans 3ee17ab904 Make Test::Unit stop aliasing method in prepended module
Ruby will be emitting a deprecation warning for this shortly. Switch
to using super instead of an alias.
2026-09-17 18:29:51 -07:00
Hiroshi SHIBATAandClaude Opus 5 b6e284dcdf Keep the message of a Timeout::Error raised in a test
A subprocess that expires its timeout reports which assertion it was and
the output it did manage to produce.  Dropping that left nothing to go on
for the crash report timeouts on macOS CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 11:59:54 +09:00
Hiroshi SHIBATAandClaude Opus 5 f21fbbd029 Remove obsolete GC compaction skip guards for s390x
Compaction has been suppressed on s390x since 2021 because the tests
randomly stalled past the 1800s output timeout. That no longer happens:
on s390x.rubyci.org these all pass individually, inside a full serial
test-all, and across a 100-run soak under CPU saturation, with GC.compact
and GC.verify_compaction_references both behaving correctly.

https://github.com/ruby/ruby/pull/5077

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 11:03:57 +09:00
Koichi SasadaandClaude Opus 5 0e06087548 Do not measure with a per-thread CPU clock under the M:N scheduler
assert_linear_performance() picks CLOCK_THREAD_CPUTIME_ID when it is
available.  That clock belongs to the native thread that reads it, and an
M:N thread moves between native threads, so two reads around one
measurement can come from different native threads and the elapsed time
comes out negative:

    Expected 0 to be <= -2.2150775009999997.

Reproduced with RUBY_MN_THREADS=2, 1500 fork/waitpid pairs per run: the
Ruby thread changed native thread 1, 9 and 10 times over three runs, and
the clock went backwards 1, 5 and 6 times, by as much as 0.38s.  The
default, =1 and =-1 never moved the main thread and never went backwards.
CLOCK_PROCESS_CPUTIME_ID stayed monotonic across 15 such migrations.

Prefer process CPU time when the M:N scheduler is on.  This only changes
which clock the assertion uses; it does not relax the assertion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 22:54:47 +09:00
Hiroshi SHIBATAandClaude Opus 5 97f63a8385 Strip the Ruby::Box experimental warning from captured child output
With RUBY_BOX=1 inherited from the environment, a child that clears or
overrides RUBYOPT, or that passes its own warning flags, prints the
experimental warning into the captured output and fails the assertions
on it.  Tests that hand RUBY_BOX to the child themselves still see the
warning.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 16:10:29 +09:00
Hiroshi SHIBATAandClaude Opus 5 fd1b7d2448 Keep assert_separately's -w from re-enabling the experimental category
The -w it hands every child turns all the categories back on, so the
RUBYOPT setting test-all passes down never reaches them and a Ruby::Box
startup warning lands in output the assertions compare verbatim.  The
switch is 2.7 or later, and this file is copied verbatim into
ruby/test-unit-ruby-core, which still runs on older rubies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 14:07:00 +09:00
Nobuyoshi Nakada f76b9efac9 [ruby/test-unit-ruby-core] Fix for rubies older than 2.7
https://github.com/ruby/test-unit-ruby-core/commit/c53dddaa9c
2026-08-20 15:52:45 +09:00
Nobuyoshi Nakada 2951d70c90 [ruby/test-unit-ruby-core] Use Regexp#=~ for ruby 2.3
`Regexp#match?` was introduced at ruby 2.4.

https://github.com/ruby/test-unit-ruby-core/commit/11c19e865b
2026-08-20 15:52:45 +09:00
Nobuyoshi Nakada d9ce287556 [ruby/test-unit-ruby-core] Fix errors on ruby 2.6 or earliers
https://github.com/ruby/test-unit-ruby-core/commit/434734d9bb
2026-08-20 15:52:44 +09:00
Taketo Takashima 1ca45d5580 [ruby/test-unit-ruby-core] Fix SyntaxError: unexpected keyword_rescue, expecting keyword_end in Ruby 2.4 and earlier
https://github.com/ruby/test-unit-ruby-core/commit/15d209a002
2026-08-20 15:52:44 +09:00
Nobuyoshi Nakada 8f228934f8 [ruby/test-unit-ruby-core] Unset PAGER environment variables when reading the help message
Workaround for jruby/jruby#9026.  JRuby attempts to call the entire
`ENV[“PAGER”]` (or `ENV["RUBY_PAGER"]`) as the program name instead
of splitting it into a program name and options, even if stdout and
stderr are redirected to a non-tty.

https://github.com/ruby/test-unit-ruby-core/commit/ccd86da00f
2026-08-10 10:42:45 +09:00
Hiroshi SHIBATAandClaude Fable 5 34f041ca05 Silence debugger availability probes in EnvUtil
`EnvUtil::Debugger.search` runs each debugger to test whether it is
usable, and the probe output goes straight to the test output. On
Windows, the lldb bundled with Visual Studio BuildTools fails to
delay-load python311.dll and dumps an LLVM crash report over the test
progress line. Also cache a nil result so the failing probe does not
repeat on every timeout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-01 17:07:08 +09:00
Hiroshi SHIBATA f7462782e3 Split -I option with File::PATH_SEPARATOR in test runner
The test runner split -Idirectory on a hardcoded ":", so on Windows an
absolute path such as -IV:/foo/lib was broken into "V" and "/foo/lib".
The tail only resolved by accident when the current drive matched.
File::PATH_SEPARATOR is the right delimiter, matching ruby -I itself.
This is the same class of bug as the test-syntax-suggest -I fix in
commit 3c7a4c174f, which replaced ":" with $(PATH_SEPARATOR) in
common.mk. Makefiles only pass relative paths, so this stayed latent.
2026-07-13 14:19:42 +09:00
Hiroshi SHIBATAandClaude Fable 5 508b486c38 Group test-bundler-parallel workers by recorded runtime (#17647)
* Group test-bundler-parallel workers by recorded runtime

turbo_tests balances workers by a recorded runtime log only when invoked
as a bare `spec`; this build passes an absolute spec/bundler path, so it
grouped by file size and let the single heaviest file dominate the
wall-clock. A tool/ patch loaded from the recipe records per-file
runtimes and reorders the size-based grouper to use the previous run's
data, leaving the synced spec/bin/parallel_rspec untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix stale reference in runtime recorder comment

The launcher script it pointed at was replaced by the recipe calling
BundlerRuntimeGrouping.install! directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Rescue LoadError when installing runtime grouping

install! is meant to degrade to filesize grouping on any failure, but
LoadError from the parallel_tests require is a ScriptError and escaped
the StandardError rescue, killing the whole recipe instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 14:32:29 +09:00
Koichi SasadaandClaude Opus 4.8 6819e80a07 test/unit: optionally verify GC consistency after each test
Set RUBY_TEST_GC_VERIFY to call GC.verify_internal_consistency after each
test. An integer >= 2 samples once every N tests; any other non-empty value
verifies every test. Useful for pinning down which test corrupts the heap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 06:55:37 +09:00
Nobuyoshi Nakada 821b84b525 Create the parent directory if the target does not exist
The `target_directory` option does not make sense unless the target is
not a directory.
2026-07-01 17:40:58 +09:00
Nobuyoshi Nakada 13b5af444b Add target_directory option to ln_relative / ln_dir_relative
As well as `FileUtils.ln_sr`.
2026-07-01 15:56:29 +09:00
Nobuyoshi Nakada e2a743242a Separate test-spec tmpdir
spec/mspec/lib/mspec/helpers/tmp.rb also tries to remove SPEC_TEMP_DIR
at exit, before this `END`.  At that time, the "tmp" marker directory
causes an ENOTEMPTY.
2026-06-30 14:29:24 +09:00
Hiroshi SHIBATAandClaude Opus 4.8 1bcc15d1d8 Remove the tmp marker before removing the temp root
The sandbox marker created at the temp root is ours, so the END block
must remove it before Dir.rmdir(tmpdir); otherwise that call always
fails with ENOTEMPTY and a clean run looks like it left files behind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 11:45:53 +09:00
Hiroshi SHIBATAandClaude Opus 4.8 888f6e07f2 Keep bundler specs in their sandbox when temp is under the user home
Bundler's spec helpers walk up from the working directory looking for a
`.bundle` directory, stopping at the first ancestor that contains a `tmp`
directory (Bundler::SharedHelpers#search_up). On Windows the test temp dir
lives under the user home (%LOCALAPPDATA%\Temp), so the search escaped the
sandbox and picked up the real ~/.bundle, breaking config, cache and other
specs. Create a `tmp` marker at the temp root so the search stops there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 11:45:53 +09:00
Nobuyoshi Nakada 16c70c4ad0 LeakChecker: skip AF_SYSTEM sockets on macOS
Socket used for kernel events and kernel control that cannot be
closed while the process is running.
2026-06-28 18:25:32 +09:00
Nobuyoshi Nakada 7bd3079262 LeakChecker: skip CLOSED sockets as well as CLOSE_WAIT 2026-06-24 20:23:36 +09:00
XrXr 5eb78494be Copyedit test-all -j crash message. Add hints about RUBY_CRASH_REPORT
The GitHub Actions part particularly is for ZJIT and YJIT jobs which
have a separate "Dump crash logs" fold. There doesn't seem to be a way
to ask for the web UI to unfold on loading of the logs.
2026-06-17 17:01:49 -04:00
Nobuyoshi Nakada 0a7564be12 Add a custom gemspec loader to suppress external commands
Do not execute `git` command which won't work when building from a
tarball, to avoid the error message "fatal: not a git repository".
The default gemspecs do not need these file lists anyway.
2026-05-22 20:00:16 +09:00
Nobuyoshi Nakada d9242cab17 Skip generating gemspec if the newer target exists
Because of difference of rubygems versions, between baseruby and the
bundled source, the generated gemspec may differ even equivalent
actually.
2026-05-13 11:55:57 +09:00
Nobuyoshi Nakada 68e768391a Move update-default-gemspecs code to bundled_gem.rb 2026-05-13 11:55:57 +09:00
Benoit Daloze 27af8317b9 Fix timeout_scale= call to use the correct receiver
* See https://github.com/ruby/test-unit-ruby-core/pull/23
2026-04-17 12:00:54 +02:00
Benoit Daloze 9c682d3d56 Set a default EnvUtil.timeout_scale for TruffleRuby to help avoid transient failures 2026-04-16 21:24:56 +02:00
Nobuyoshi Nakada a3c372a6da Fix error when lsof did not work 2026-04-05 22:58:03 +09:00
Nobuyoshi Nakada 21d360981c Fix error when lsof did not work 2026-04-05 22:37:10 +09:00