diff --git a/test/unit/issue_nested_set_concurrency_test.rb b/test/unit/issue_nested_set_concurrency_test.rb index dd02359..7467ae2 100644 --- a/test/unit/issue_nested_set_concurrency_test.rb +++ b/test/unit/issue_nested_set_concurrency_test.rb @@ -27,6 +27,7 @@ class IssueNestedSetConcurrencyTest < ActiveSupport::TestCase self.use_transactional_fixtures = false def setup + skip if sqlite? CustomField.delete_all end @@ -35,38 +36,60 @@ class IssueNestedSetConcurrencyTest < ActiveSupport::TestCase end def test_concurrency - skip if sqlite? - with_settings :notified_events => [] do - # Generates an issue and destroys it in order - # to load all needed classes before starting threads - i = Issue.generate! - i.destroy + # Generates an issue and destroys it in order + # to load all needed classes before starting threads + i = Issue.generate! + i.destroy - root = Issue.generate! - assert_difference 'Issue.count', 60 do - threads = [] - 3.times do |i| - threads << Thread.new(i) do - ActiveRecord::Base.connection_pool.with_connection do - begin - 10.times do - i = Issue.generate! :parent_issue_id => root.id - c1 = Issue.generate! :parent_issue_id => i.id - c2 = Issue.generate! :parent_issue_id => i.id - c3 = Issue.generate! :parent_issue_id => i.id - c2.reload.destroy - c1.reload.destroy - end - rescue Exception => e - Thread.current[:exception] = e.message - end + root = Issue.generate! + assert_difference 'Issue.count', 60 do + threaded(3) do + 10.times do + i = Issue.generate! :parent_issue_id => root.id + c1 = Issue.generate! :parent_issue_id => i.id + c2 = Issue.generate! :parent_issue_id => i.id + c3 = Issue.generate! :parent_issue_id => i.id + c2.reload.destroy + c1.reload.destroy + end + end + end + end + + def test_concurrent_subtasks_creation + root = Issue.generate! + assert_difference 'Issue.count', 30 do + threaded(3) do + 10.times do + Issue.generate! :parent_issue_id => root.id + end + end + end + root.reload + assert_equal [1, 62], [root.lft, root.rgt] + children_bounds = root.children.sort_by(&:lft).map {|c| [c.lft, c.rgt]}.flatten + assert_equal (2..61).to_a, children_bounds + end + + private + + def threaded(count, &block) + with_settings :notified_events => [] do + threads = [] + count.times do |i| + threads << Thread.new(i) do + ActiveRecord::Base.connection_pool.with_connection do + begin + yield + rescue Exception => e + Thread.current[:exception] = e.message end end end - threads.each do |thread| - thread.join - assert_nil thread[:exception] - end + end + threads.each do |thread| + thread.join + assert_nil thread[:exception] end end end