Clean with transaction not working for 2 databases
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 35/100
- Issue 类型
- 缺陷
- 描述清晰度
- 需要澄清
- 活跃度
- 停滞
- 技术栈
- postgresql, ruby
- 领域
- databases, testing-qa
调研方向
从 lib/database_cleaner/active_record/transaction.rb 开始,重点关注事务策略的 start 和 clean 路径,并复现 issue 中描述的包含两个示例的 RSpec 设置。比较每个示例前后记录的事务数量和租户数据库状态。完成的标准是清理后租户数据库中不再有上一个示例留下的患者。
由索引模型根据 Issue 内容生成。
描述
I've used DatabaseCleaner for several years (thanks!) without issues. But my current setup seems to not work properly.
Basic setup:
- Grape 0.19.2
- ActiveRecord 5.1.3 (+ otr-activerecord 1.2.4)
- RSpec 3.6.0
- DatabaseCleaner 1.6.1
- Posgres 9.5
On noteworthy thing about the app here is that it's using multiple databases: One main database and several tenant databases. In the test environment, this currently means two databases in total (main + test tenant).
Here's the test setup:
TEST_TENANT = 'the_tenant'
TEST_TENANT_API_KEY = SecureRandom.uuid.gsub('-', '')
RSpec.configure do |config|
config.mock_with :rspec
config.expect_with :rspec
config.raise_errors_for_deprecations!
# config.order = 'random'
config.before(:suite) do
ApiApp.establish_connection # ApiApp is connected to the main DB
primary_cleaner.clean_with(:truncation)
tenant = ApiApp.where(identifier: TEST_TENANT).first_or_create!(
name: 'The tenant',
api_key: TEST_TENANT_API_KEY
)
# force full recreate of tenant DB
config = ActiveRecord::Base.configurations[tenant.identifier]
ActiveRecord::Tasks::DatabaseTasks.drop(config) rescue nil
ActiveRecord::Tasks::DatabaseTasks.create(config)
ActiveRecord::Tasks::DatabaseTasks.load_schema(config, :sql, 'db/structure.sql')
# seed it
AppSetter.with(TEST_TENANT) do
Dir["#{Dir.pwd}/spec/seeds/*.rb"].sort.each { |f| load f }
end
end
config.before(:each) do |example|
AppSetter.set(TEST_TENANT)
puts ['[RSpec] start before', "number of patients: #{Patient.count}", Patient.connection.instance_variable_get(:@config)[:database]].inspect
# primary_cleaner.start
tenant_cleaner.start
puts ['[RSpec] end before', "number of patients: #{Patient.count}", Patient.connection.instance_variable_get(:@config)[:database]].inspect
end
config.append_after(:each) do
puts ['[RSpec] start append_after', "number of patients: #{Patient.count}", Patient.connection.instance_variable_get(:@config)[:database]].inspect
# primary_cleaner.clean
tenant_cleaner.clean
puts ['[RSpec] end append_after', "number of patients: #{Patient.count}", Patient.connection.instance_variable_get(:@config)[:database]].inspect
puts '-' * 100
end
private
def primary_cleaner
@primary_cleaner ||= cleaner_for(connection: ENV['RACK_ENV'].to_sym)
end
def tenant_cleaner
@tenant_cleaner ||= cleaner_for(connection: TEST_TENANT.to_sym)
end
def cleaner_for(options)
DatabaseCleaner[:active_record, options].tap { |cleaner| cleaner.strategy = :transaction }
end
end
Now when I have 2 examples in RSpec which both use the same basic setup with a test patient (Patient.create!(email: '[email protected]', ...)), the uniqueness constraint on email fails because apparently the record exists already. The debugging code in the output (from the puts statements above) confirms this:
(1) ["[RSpec] start before", "number of patients: 0", "api_test_the_tenant"]
["[DatabaseCleaner] before start", "open transactions: 0", "api_test_the_tenant"]
(2) ["[DatabaseCleaner] after start", "open transactions: 1", "api_test_the_tenant"]
["[RSpec] end before", "number of patients: 0", "api_test_the_tenant"]
(3) ["[RSpec] start append_after", "number of patients: 1", "api_test_the_tenant"]
["[DatabaseCleaner] before clean", "open transactions: 1", "api_test_the_tenant"]
(4) ["[DatabaseCleaner] after clean", "open transactions: 0", "api_test_the_tenant"]
(5) ["[RSpec] end append_after", "number of patients: 1", "api_test_the_tenant"]
----------------------------------------------------------------------------------------------------
(6) ["[RSpec] start before", "number of patients: 1", "api_test_the_tenant"]
["[DatabaseCleaner] before start", "open transactions: 0", "api_test_the_tenant"]
["[DatabaseCleaner] after start", "open transactions: 1", "api_test_the_tenant"]
["[RSpec] end before", "number of patients: 1", "api_test_the_tenant"]
["[RSpec] start append_after", "number of patients: 1", "api_test_the_tenant"]
["[DatabaseCleaner] before clean", "open transactions: 1", "api_test_the_tenant"]
["[DatabaseCleaner] after clean", "open transactions: 0", "api_test_the_tenant"]
["[RSpec] end append_after", "number of patients: 1", "api_test_the_tenant"]
----------------------------------------------------------------------------------------------------
(I've numbered some lines to make it easier to follow. The [DatabaseCleaner] output comes from some puts statements I've put in the corresponding strategy in https://github.com/DatabaseCleaner/database_cleaner/blob/master/lib/database_cleaner/active_record/transaction.rb.)
(1) Before the first example (in the first before block), there are 0 patients in the tenant database => expected.
(2) tenant_cleaner.start has caused an open transaction in the tenant database => expected.
(3) Running the example has created a patient in the tenant database => expected.
(4) tenant_cleaner.clean rolls back the transaction => expected.
(5) There is still 1 patient in the tenant database => this is NOT expected.
(6) The before block of the next example confirms that 1 patient has remained in the tenant database => this is NOT expected.
Commenting in/out the cleaning of the primary database doesn't change anything (I wouldn't have expected it to either, but I tried it nonetheless).
Does anyone have any insights as to what's going wrong here?
Thanks a lot in advance.
- 主要语言
- Ruby
- 星标
- 76
- 派生
- 76
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
我们还没有检查这个项目的环境配置文件。先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
DatabaseCleaner/database_cleaner-active_record 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 62/100
-
难度 5/5 一周以上 新手友好度 30/100
DatabaseCleaner/database_cleaner-active_record#128 · 1 条评论 ·
-
难度 3/5 1-2 天 新手友好度 35/100
DatabaseCleaner/database_cleaner-active_record#127 · 3 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 45/100
-
难度 5/5 一周以上 新手友好度 25/100
查看 DatabaseCleaner/database_cleaner-active_record 的全部 Issue
相似的 Issue
-
security
难度 2/5 1-3 小时 新手友好度 68/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
solana-foundation/pay-kit#341 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 65/100
julienXX/terminal-notifier#333 ·
-
难度 1/5 1 小时以内 新手友好度 82/100
serhii-londar/open-source-mac-os-apps#1419 ·
维护者通常 5 天内回复