rails icon indicating copy to clipboard operation
rails copied to clipboard

Parallelized generator tests fail in race condition because destination is not worker aware

Open jprosevear opened this issue 1 year ago • 3 comments

Steps to reproduce

Write generator tests and turn on parallel testing.

Rails::Generators::TestCase expects a class level destination https://github.com/rails/rails/blob/main/railties/lib/rails/generators/testing/behavior.rb#L46 but inherits from ActiveSupport::TestCase so if parallel testing is on https://guides.rubyonrails.org/testing.html#parallel-testing-with-processes the test cases can race creating/destroying the directory

Expected behavior

Per parallel executor destinations

My hack to get around this for now in the test case:

    def prepare_destination
      self.destination_root = File.expand_path("../tmp", __dir__) + "-#{Process.pid}"
      super
    end

Maybe destination should use the after fork hook like https://github.com/rails/rails/blob/main/activerecord/lib/active_record/test_databases.rb#L7 ? Or maybe a cleaned up version of my workaround would suffice?

System configuration

Rails version: 7.1.8.4

Ruby version: 3.1.6

jprosevear avatar Jun 21 '24 19:06 jprosevear

The workaround and even the after_fork only works if the parallel processor is using processes and not threads. Unfortunately Rails::Generator::TestCase don't support parallel tests at the moment. We should probably disallow setting it at short-term and fix it to support parallel tests long term.

rafaelfranca avatar Jun 21 '24 20:06 rafaelfranca

@rafaelfranca do you have a preferred approach?

jprosevear avatar Jun 21 '24 21:06 jprosevear

If we can fix it, I'd prefer to try that first. Now, how we are going to make sure the destination dir is different for each test worker I don't know.

rafaelfranca avatar Jun 21 '24 21:06 rafaelfranca

This issue has been automatically marked as stale because it has not been commented on for at least three months. The resources of the Rails team are limited, and so we are asking for your help. If you can still reproduce this error on the 7-2-stable branch or on main, please reply with all of the information you have about it in order to keep the issue open. Thank you for all your contributions.

rails-bot[bot] avatar Sep 19 '24 21:09 rails-bot[bot]

For parallel tests, I think you can store the destination dir in IsolatedExecutionState which is a per-thread or per-fiber storage.

zzak avatar Oct 03 '24 07:10 zzak