Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call Executor#wrap around each test #43550

Merged
merged 1 commit into from Oct 28, 2021

Conversation

casperisfine
Copy link
Contributor

@casperisfine casperisfine commented Oct 27, 2021

Fix: #43546

We do want to run the executor callbacks because they do cleanup various global state at the end of an unit of work (CurrentAttributes, QueryLogs, QueryCache, etc).

However Executor#wrap has a safety to prevent being called recursively.

So we can't use it, otherwise all the integration test helpers such as get, post etc, won't properly cleanup after themselves.

So we introduce an alternative perform method, which is just like wrap, but don't prevent re-entrency.

cc @manuelpuyol @camertron, I tested this branch against https://github.com/github/view_component, I believe it fixes the bug you reported.

@camertron
Copy link
Contributor

I can confirm this fixes the view_component test suite. Thanks for the super quick fix @casperisfine !

@casperisfine
Copy link
Contributor Author

My pleasure, thanks for the quick error report :)

@casperisfine
Copy link
Contributor Author

One test in test/application/test_runner_test.rb seem stuck on CI, I'll have to debug that before I can merge.

@byroot
Copy link
Member

byroot commented Oct 27, 2021

I still have no clue why this test get stuck on CI and not on my machine, so I reverted #43546 for now.

@casperisfine
Copy link
Contributor Author

Ok, so I figured the cause of the stuck test, it's https://github.com/rails/rails/blob/6f30cc09a7ad21898d856059e498ab9ad2ae64a4/actionview/lib/action_view/cache_expiry.rb that isn't reentrant, and it end up dead locking itself with:

lock.with_read_lock { lock.with_write_lock {} }

@rails-bot rails-bot bot added the actionview label Oct 28, 2021
@casperisfine casperisfine force-pushed the as-test-case-executor-fix branch 2 times, most recently from 94e382f to 05e6e10 Compare October 28, 2021 10:58
@casperisfine casperisfine changed the title Do not mark the Executor as active when wraping TestCase Call Executor#wrap around each test Oct 28, 2021
@casperisfine casperisfine force-pushed the as-test-case-executor-fix branch 2 times, most recently from d7ab1ac to 7f8fe94 Compare October 28, 2021 12:11
It's `Rails.application.executor.wrap` that is responsible for
clearing request/job local state such as `CurrentAttributes`.

Instead of including an ad hoc helper to clear `CurrentAttributes` it's
better to run the executor so we properly clear other states as well.

However it means all executor hooks now need to be re-entrant.
@casperisfine
Copy link
Contributor Author

Since this has quite a large impact, I've put it behind a feature flag that's enabled by default for new Rails 7 apps.

@byroot byroot merged commit cf1626e into rails:main Oct 28, 2021
@casperisfine casperisfine deleted the as-test-case-executor-fix branch October 28, 2021 15:27
# This makes test cases behave closer to an actual request or job, several
# features that are normally disabled in test, such as Active Record query cache
# and asynchronous queries will then be enabled.
# Rails.application.config.active_support.executor_around_test_case = true
Copy link
Member

Choose a reason for hiding this comment

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

It is missing updating configuring.md to add to document this new options.

Copy link
Member

Choose a reason for hiding this comment

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

Fixed in fbd11ab

casperisfine pushed a commit to Shopify/rails that referenced this pull request Aug 19, 2022
Ref: rails#43550

If `executor_around_test_case` is enabled, all hooks must be
reentrant. However `allow_concurrency = false` register a
`MutexHook` that isn't reentrant.

So this commit replace it by a `Monitor` which does allow
reentrancy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants