Parallelized generator tests fail in race condition because destination is not worker aware
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
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 do you have a preferred approach?
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.
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.
For parallel tests, I think you can store the destination dir in IsolatedExecutionState which is a per-thread or per-fiber storage.