Skip to content

Commit cf1626e

Browse files
authored
Merge pull request rails#43550 from Shopify/as-test-case-executor-fix
Call Executor#wrap around each test
2 parents 6ab55ea + 7b50969 commit cf1626e

File tree

12 files changed

+71
-30
lines changed

12 files changed

+71
-30
lines changed

actionview/lib/action_view/cache_expiry.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module ActionView
44
class CacheExpiry
55
class Executor
66
def initialize(watcher:)
7-
@execution_lock = Concurrent::ReadWriteLock.new
7+
@execution_lock = Concurrent::ReentrantReadWriteLock.new
88
@cache_expiry = ViewModificationWatcher.new(watcher: watcher) do
99
clear_cache
1010
end

activerecord/lib/active_record/asynchronous_queries_tracker.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ class << self
77
def active?
88
true
99
end
10+
11+
def finalize
12+
end
1013
end
1114
end
1215

activerecord/lib/active_record/query_logs/test_helper.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.

activerecord/lib/active_record/railtie.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,6 @@ class Railtie < Rails::Railtie # :nodoc:
380380
app.reloader.before_class_unload { ActiveRecord::QueryLogs.clear_context }
381381
app.executor.to_run { ActiveRecord::QueryLogs.clear_context }
382382
app.executor.to_complete { ActiveRecord::QueryLogs.clear_context }
383-
384-
ActiveSupport.on_load(:active_support_test_case) do
385-
require "active_record/query_logs/test_helper"
386-
include ActiveRecord::QueryLogs::TestHelper
387-
end
388383
end
389384
end
390385
end

activerecord/test/cases/query_logs_test.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
require "cases/helper"
44
require "models/dashboard"
5-
require "active_record/query_logs/test_helper"
65

76
class QueryLogsTest < ActiveRecord::TestCase
8-
# Automatically included in Rails apps via railtie but that don't run here.
9-
include ActiveRecord::QueryLogs::TestHelper
10-
117
fixtures :dashboards
128

139
ActiveRecord::QueryLogs.taggings[:application] = -> {
1410
"active_record"
1511
}
1612

1713
def setup
14+
# QueryLogs context is automatically reset in Rails app via an executor hooks set in railtie
15+
# But not in Active Record's own test suite.
16+
ActiveRecord::QueryLogs.clear_context
17+
1818
# Enable the query tags logging
1919
@original_transformers = ActiveRecord.query_transformers
2020
@original_prepend = ActiveRecord::QueryLogs.prepend_comment
@@ -28,6 +28,9 @@ def teardown
2828
ActiveRecord.query_transformers = @original_transformers
2929
ActiveRecord::QueryLogs.prepend_comment = @original_prepend
3030
ActiveRecord::QueryLogs.tags = []
31+
# QueryLogs context is automatically reset in Rails app via an executor hooks set in railtie
32+
# But not in Active Record's own test suite.
33+
ActiveRecord::QueryLogs.clear_context
3134
end
3235

3336
def test_escaping_good_comment

activesupport/CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
* `Rails.application.executor` hooks are now called around every tests.
2+
3+
This helps to better simulate request or job local state being reset around tests and prevent state
4+
to leak from one test to another.
5+
6+
However it requires the executor hooks executed in the test environment to be re-entrant.
7+
8+
*Jean Boussier*
9+
110
* `ActiveSupport::DescendantsTracker` now mostly delegate to `Class#descendants` on Ruby 3.1
211

312
Ruby now provides a fast `Class#descendants` making `ActiveSupport::DescendantsTracker` mostly useless.
@@ -6,7 +15,6 @@
615

716
- `ActiveSupport::DescendantsTracker.direct_descendants`
817
- `ActiveSupport::DescendantsTracker#direct_descendants`
9-
1018
*Jean Boussier*
1119

1220
* Fix the `Digest::UUID.uuid_from_hash` behavior for namespace IDs that are different from the ones defined on `Digest::UUID`.

activesupport/lib/active_support/execution_wrapper.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ def self.wrap
9191
end
9292
end
9393

94+
def self.perform # :nodoc:
95+
instance = new
96+
instance.run
97+
begin
98+
yield
99+
ensure
100+
instance.complete
101+
end
102+
end
103+
94104
class << self # :nodoc:
95105
attr_accessor :active
96106
end
@@ -108,6 +118,10 @@ def self.active? # :nodoc:
108118

109119
def run! # :nodoc:
110120
self.class.active[Thread.current] = true
121+
run
122+
end
123+
124+
def run # :nodoc:
111125
run_callbacks(:run)
112126
end
113127

@@ -116,11 +130,15 @@ def run! # :nodoc:
116130
#
117131
# Where possible, prefer +wrap+.
118132
def complete!
119-
run_callbacks(:complete)
133+
complete
120134
ensure
121135
self.class.active.delete Thread.current
122136
end
123137

138+
def complete # :nodoc:
139+
run_callbacks(:complete)
140+
end
141+
124142
private
125143
def hook_state
126144
@_hook_state ||= {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module ActiveSupport::Executor::TestHelper # :nodoc:
4+
def run(...)
5+
Rails.application.executor.perform { super }
6+
end
7+
end

activesupport/lib/active_support/railtie.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,20 @@ class Railtie < Rails::Railtie # :nodoc:
2828
end
2929

3030
initializer "active_support.reset_all_current_attributes_instances" do |app|
31+
executor_around_test_case = app.config.active_support.delete(:executor_around_test_case)
32+
3133
app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
3234
app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
3335
app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
3436

3537
ActiveSupport.on_load(:active_support_test_case) do
36-
require "active_support/current_attributes/test_helper"
37-
include ActiveSupport::CurrentAttributes::TestHelper
38+
if executor_around_test_case
39+
require "active_support/executor/test_helper"
40+
include ActiveSupport::Executor::TestHelper
41+
else
42+
require "active_support/current_attributes/test_helper"
43+
include ActiveSupport::CurrentAttributes::TestHelper
44+
end
3845
end
3946
end
4047

activesupport/test/current_attributes_test.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
# frozen_string_literal: true
22

33
require_relative "abstract_unit"
4-
require "active_support/current_attributes/test_helper"
54

65
class CurrentAttributesTest < ActiveSupport::TestCase
7-
# Automatically included in Rails apps via railtie but that don't run here.
8-
include ActiveSupport::CurrentAttributes::TestHelper
6+
# CurrentAttributes is automatically reset in Rails app via executor hooks set in railtie
7+
# But not in Active Support's own test suite.
8+
setup do
9+
ActiveSupport::CurrentAttributes.reset_all
10+
end
11+
12+
teardown do
13+
ActiveSupport::CurrentAttributes.reset_all
14+
end
915

1016
Person = Struct.new(:id, :name, :time_zone)
1117

0 commit comments

Comments
 (0)