1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Eagerly materialize the fixtures transaction

The transaction used to restore fixtures is an implementation detail
that should be abstracted away. Idealy a test should behave the same
wether or not transactional fixtures are enabled.

However since transactions have been made lazy, the fixture
transaction started leaking into tests case. e.g. consider the
following (oversimplified) test:

```ruby
class SQLSubscriber
  attr_accessor :sql

  def initialize
    @sql = []
  end

  def call(*, event)
    sql << event[:sql]
  end
end

subscriber = SQLSubscriber.new
ActiveSupport::Notifications.subscribe("sql.active_record", subscriber)

User.connection.execute('SELECT 1', 'Generic name')
assert_equal ['SELECT 1'], subscriber.sql
```

On Rails 6 it starts to break because the `sql` array will be `['BEGIN', 'SELECT 1']`.

Several things are wrong here:

  - That transaction is not generated by the tested code, so it shouldn't be visible.
  - The transaction is not even closed yet, which again doesn't reflect the reality.
This commit is contained in:
Jean Boussier 2019-01-29 13:29:27 +01:00
parent 8309cd2c68
commit 74dbce0fca
3 changed files with 8 additions and 5 deletions

View file

@ -205,9 +205,12 @@ module ActiveRecord
run_commit_callbacks: run_commit_callbacks)
end
transaction.materialize! unless @connection.supports_lazy_transactions? && lazy_transactions_enabled?
if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && options[:_lazy] != false
@has_unmaterialized_transactions = true
else
transaction.materialize!
end
@stack.push(transaction)
@has_unmaterialized_transactions = true if @connection.supports_lazy_transactions?
transaction
end
end

View file

@ -122,7 +122,7 @@ module ActiveRecord
# Begin transactions for connections already established
@fixture_connections = enlist_fixture_connections
@fixture_connections.each do |connection|
connection.begin_transaction joinable: false
connection.begin_transaction joinable: false, _lazy: false
connection.pool.lock_thread = true if lock_threads
end
@ -138,7 +138,7 @@ module ActiveRecord
end
if connection && !@fixture_connections.include?(connection)
connection.begin_transaction joinable: false
connection.begin_transaction joinable: false, _lazy: false
connection.pool.lock_thread = true if lock_threads
@fixture_connections << connection
end

View file

@ -924,7 +924,7 @@ class TransactionalFixturesOnConnectionNotification < ActiveRecord::TestCase
def lock_thread=(lock_thread); end
end.new
assert_called_with(connection, :begin_transaction, [joinable: false]) do
assert_called_with(connection, :begin_transaction, [joinable: false, _lazy: false]) do
fire_connection_notification(connection)
end
end