E54B Change test-all suite to enable running each test in separate ractors. by luke-gruber · Pull Request #14672 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

Conversation

luke-gruber
Copy link
Contributor

This tests for ractor safety issues as well as concurrency issues.

You can enable these tests with RUBY_TESTS_WITH_RACTORS=X when running make test-all TESTS=test/ruby. Running tests with ractors is currently only working for tests under the "test/ruby" directory. You should also use the .excludes-ractor excludes directory.

For example:

EXCLUDES=test/.excludes-ractor RUBY_TESTS_WITH_RACTORS=3 TESTS=test/ruby make test-all

This will create 3 ractors for each test method, run the test method inside each ractor and then call join on the ractors. Then, it's ready to process the next test. The reason we do this instead of taking all the tests and dividing them between the number of ractors is:

  • We want to run each test under concurrency load to test whether or not it is safe under ractors. If it isn't safe, we know it's something to do with this specific test.

  • If we get a segfault or error, we know the error is coming from this test alone, not interactions with other tests.

The disadvantage of this approach is:

  • It's slower than dividing the tests between the number of ractors running.

  • This might not uncover ractor scheduling issues that would show up when you have long-running ractors.

@luke-gruber luke-gruber marked this pull request as draft September 29, 2025 17:52
@matzbot matzbot requested a review from a team September 29, 2025 17:52
@luke-gruber luke-gruber force-pushed the test_all_ractors_multi_ractor branch 2 times, most recently from 330d4fe to c32acb5 Compare September 30, 2025 16:35
Copy link
launchable-app bot commented Sep 30, 2025

2/67574 Tests Failed

test/json/ractor_test.rb#test_generate
Failure:
JSONInRactorTest#test_generate [/home/runner/work/ruby/ruby/src/test/json/ractor_test.rb:53]:
Expected #<Process::Status: pid 133212 SIGSEGV (signal 11) (core dumped)> to be success?.

test/rubygems/test_gem_remote_fetcher_local_ssl_server.rb#test_do_not_allow_insecure_ssl_connection_by_default

[-> View Test suite health in main branch]

@luke-gruber luke-gruber force-pushed the test_all_ractors_multi_ractor branch 16 times, most recently from 25804c4 to d641b1f Compare October 3, 2025 15:16
@luke-gruber
Copy link
Contributor Author

This branch is ready to be merged @ko1 . When you run the make command listed in the first commit, don't add the -j as this option is not supported with ractors enabled yet.

def after_teardown
super
assert_empty(Process.waitall)
assert_empty(Process.waitall) unless multiple_ractors?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it disabled?

Copy link
Contributor Author
@luke-gruber luke-gruber Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since after_teardown runs after each test, other ractors could still have processes running.

@__io__ = nil
@__passed__ = nil
@@__current__ = self # FIX: make thread local
Ractor.current[:__test_current__] = self
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removed comment said it should be thread local. is it okay to use Ractor local?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's okay 👍

RUN_TEST_TRACE = "#{__FILE__}:#{__LINE__+3}:in `run_test'".freeze
def run_test(name)
progname, $0 = $0, "#{$0}: #{self.class}##{name}"
progname, $0 = $0, "#{$0}: #{self.class}##{name}" if main_ractor?
Copy link
Contributor
@ko1 ko1 Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO:
if we make main Ractor as a manager Ractor (and other Ractors run tests, a manager Ractor knows which tests are running), we can set the progname with running test names by the main Ractor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good idea. For future work 😆

end

def multiple_ractors?
ENV["RUBY_TESTS_WITH_RACTORS"].to_i > 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cache the value or define different methods with the envval?
some tests can remove ENVVAL.

Ractor.receive
end
end
dir = r.take
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it work...??

Copy link
Contributor Author
@luke-gruber luke-gruber Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll investigate 🤷 Edit: There was a shim in assert_ractor method. I removed it.

This tests for ractor safety issues as well as concurrency issues.

You can enable these tests with RUBY_TESTS_WITH_RACTORS=X when running
`make test-all TESTS=test/ruby`. Running tests with ractors is currently only
working for tests under the "test/ruby" directory. You should also use
the `.excludes-ractor` excludes directory.

For example:

```
EXCLUDES=test/.excludes-ractor RUBY_TESTS_WITH_RACTORS=3 TESTS=test/ruby make test-all
```

This will create 3 ractors for each test method, run the test method
inside each ractor and then call `join` on the ractors. Then, it's ready
to process the next test. The reason we do this instead of taking all the
tests and dividing them between the number of ractors is:

* We want to run each test under concurrency load to test whether
  or not it is safe under ractors. If it isn't safe, we know it's
  something to do with this specific test.

* If we get a segfault or error, we know the error is coming from this
  test alone, not interactions with other tests.

The disadvantage of this approach is:

* It's slower than dividing the tests between the number of ractors
  running.

* This might not uncover ractor scheduling issues that would show up when
  you have long-running ractors.
As per ko1's comment, tests can mess with ENV. Add a couple more
excludes too after running into issues.
@luke-gruber luke-gruber force-pushed the test_all_ractors_multi_ractor branch from d86bda5 to 680c924 Compare October 10, 2025 17:22
@luke-gruber
Copy link
Contributor Author

MMTK CI failed but we found out why. We're waiting on #14811 to be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0