Switching from :transaction to :truncation for some tests doesn't work
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 45/100
調査の方向性
spec/rails_helper.rb から始め、Sidekiq が別プロセスとして実行されている状態で、truncate: true とマークされた RSpec の example を再現します。hook の後の DatabaseCleaner の strategy を調べ、PostgreSQL からの row visibility を確認します。完了条件は、マークされた example が truncation を使用して外部からレコードを参照でき、残りの suite はトランザクションのままであることです。
索引モデルが issue の本文から書いたものです。
説明
So, I have some tests that need truncation because I am testing the whole Sidekiq stack and as a separate process Sidekiq needs to be able to see the records created in the original process. I want to keep the suite in general as :transaction though as the rest of the tests are fine with that strategy.
To do this I add come config to the rspec config:
config.before(:each) do |example|
DatabaseCleaner.start
if example.metadata[:truncate]
DatabaseCleaner.strategy = :truncation
else
DatabaseCleaner.strategy = :transaction
end
end
Then add metadata to the test:
it 'should doit', truncate: true do
# create records then run the background worker
# wait for the background worker to finish
end
The problem is that Sidekiq gets ActiveRecord not found errors, and sure enough, there are no rows available to on a separate database (postgres) connection:
connector_test=# select count(*) from contacts;
count
-------
0
(1 row)
If I stick byebug in the test I can confirm that there are in fact records:
(byebug) Contact.count
3
but the strategey does seem to be truncation:
(byebug) DatabaseCleaner[:active_record].strategy.class
DatabaseCleaner::ActiveRecord::Truncation
(byebug) DatabaseCleaner[:active_record].strategy
#<DatabaseCleaner::ActiveRecord::Truncation:0x00007f95e600ff68 @only=nil, @tables_to_exclude=["schema_migrations"], @pre_count=nil, @reset_ids=nil, @cache_tables=true, @db=:default>
If I re-run the test after configuring truncation for all of the tests:
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
…
end
I can see that the strategy in the test is the same:
(byebug) DatabaseCleaner[:active_record].strategy
#<DatabaseCleaner::ActiveRecord::Truncation:0x00007f8faf0ccec0 @only=nil, @tables_to_exclude=["schema_migrations"], @pre_count=nil, @reset_ids=nil, @cache_tables=true, @db=:default>
and the records are available in the test:
(byebug) Contact.count
3
but this time the records are also available in the database:
connector_test=# select count(*) from contacts;
count
-------
3
(1 row)
and my test passes. These are the versions of relevant gems I am using
$ bundle info database_cleaner
* database_cleaner (1.7.0)
Summary: Strategies for cleaning databases. Can be used to ensure a clean state for testing.
Homepage: http://github.com/DatabaseCleaner/database_cleaner
Path: /Users/will/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/database_cleaner-1.7.0
$ bundle info rspec-rails
* rspec-rails (3.8.3)
Summary: RSpec for Rails
Homepage: https://github.com/rspec/rspec-rails
Path: /Users/will/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/rspec-rails-3.8.3
Upgrading database cleaner
So I noticed as I was gathering the version data that database_cleaner was out of date (I could have sworn that I updated it already!). Anyway, after upgrading database_cleaner it now looks like inside the test the reported strategy matches the observed behaviour:
(byebug) DatabaseCleaner[:active_record].strategy
#<DatabaseCleaner::ActiveRecord::Transaction:0x00007ff8ba938928 @db=:default>
This is despite my strategy switch seeming to work OK in the rspec config:
[57, 66] in /Users/will/clients/foo/repos/web-app/spec/rails_helper.rb
57: config.before(:each) do |example|
58: $redis.flushall
59: DatabaseCleaner.start
60:
61: byebug
=> 62: if example.metadata[:truncate]
63: DatabaseCleaner.strategy = :truncation
64: else
65: DatabaseCleaner.strategy = :transaction
66: end
(byebug) example.metadata[:truncate]
true
and as the test is using transactions not truncation the external process can't see the records and the test fails. Any ideas what's going on here?
- 主要言語
- Ruby
- スター
- 3k
- フォーク
- 485
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
DatabaseCleaner/database_cleaner のほかの issue
-
難易度 3/5 1〜2日 初心者へのやさしさ 67/100
-
Cleaning of dev DBオープン
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
-
Cannot truncate a table referenced in a foreign key constraint (ActiveRecord::StatementInvalid)オープン
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
DatabaseCleaner/database_cleaner#717 · コメント 5 件 · リアクション 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
DatabaseCleaner/database_cleaner#716 · コメント 2 件 ·
DatabaseCleaner/database_cleaner の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
eurosky-social/eu-haul#32 ·
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
benbalter/add-to-org#17 ·
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
benbalter/change_agent#11 ·
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
benbalter/count-org-loc#20 ·
-
good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
benbalter/sitemap-parser#33 ·