競合状態のコードの一部をテストしようとしています。私が持っていた問題は、レール内の競合状態から安全ではないことが判明した一意性検証に関連していました。私は問題を解決することができると信じていますが、自分のソリューションをテストする方法がわかりません。競合状態のテストとその後のクリーニング
私は(に触発さ:http://blog.arkency.com/2015/09/testing-race-conditions/):次のようである来て最も近い
test "Can't create duplicate keys with same value and keyboard" do
assert_equal(5, ActiveRecord::Base.connection.pool.size)
begin
concurrency_level = 4
keyboard = create :keyboard
should_wait = true
statuses = {}
threads = Array.new(concurrency_level) do |i|
Thread.new do
true while should_wait
begin
# Unique validation for key values exists scoped to keyboard
key = keyboard.keys.new(value: 'a')
statuses[i] = key.save
rescue ActiveRecord::RecordNotUnique
statuses[i] = false
end
end
end
should_wait = false
threads.each(&:join)
assert_equal(1, keyboard.keys.count)
assert_equal(1, statuses.count { |_k, v| v })
assert_equal(3, statuses.count { |_k, v| !v })
ensure
ActiveRecord::Base.connection_pool.disconnect!
end
end
上記のコードは、まさに私のように構成されているが、モデルは、より一般的になるように変更しました。
テスト自体は問題なく動作しているようです。ただし、テストで作成されたキーはその後削除されません。私はDatabaseCleanerを使用しています。私はすべての異なる戦略を試しました。また、時には、定数キーの循環依存関係の問題が発生することがあります。理由は分かりませんが、私はルビのスレッドセーフではないことを要求しています。
私の問題には良い方法がありますか?上記で指定したように、私はこれにいくつかの異なる問題を抱えており、良いテスト標準が存在するはずの共通の問題であると感じています。
1)ループは、すべてのスレッドが同時に起動することを確認するためにちょっと醜いハックです。あなたは "pod.save"に関して正しいと思っていました。私はそれを私の例に合うように編集しました。 2)私はそれを試してみる必要があります。私は各テストの後にそれをきれいにするように設定したと思ったが、あなたは正しいかもしれない。 3)ええ、それは私が使っている解決策です。そして、あなたは正しく、それを正しく処理するためにDBを信頼することができます。私はもう少し解決するのが難しいかもしれないいくつかのシナリオを持っているので、競合状態をテストするための一般的な方法はまだ素晴らしいでしょう。 –