diff options
author | Marius Balteanu <marius.balteanu@zitec.com> | 2023-11-18 22:27:35 +0000 |
---|---|---|
committer | Marius Balteanu <marius.balteanu@zitec.com> | 2023-11-18 22:27:35 +0000 |
commit | 92e779cafab1407f79206c89b8e8934b1ea1fe6e (patch) | |
tree | 3a315a8962ad111035b5936075ad8f7ff34d0b99 /test | |
parent | a2c203cca02a5eed685d30b02131a243d7635239 (diff) | |
download | redmine-92e779cafab1407f79206c89b8e8934b1ea1fe6e.tar.gz redmine-92e779cafab1407f79206c89b8e8934b1ea1fe6e.zip |
Add concurrent subtask removal test to cover corrupted nested sets (#39437).
Patch by Jens Krämer.
git-svn-id: https://svn.redmine.org/redmine/trunk@22461 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'test')
-rw-r--r-- | test/unit/issue_nested_set_concurrency_test.rb | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/test/unit/issue_nested_set_concurrency_test.rb b/test/unit/issue_nested_set_concurrency_test.rb index 0c3f9e6a8..93027c490 100644 --- a/test/unit/issue_nested_set_concurrency_test.rb +++ b/test/unit/issue_nested_set_concurrency_test.rb @@ -74,6 +74,49 @@ class IssueNestedSetConcurrencyTest < ActiveSupport::TestCase assert_equal (2..61).to_a, children_bounds end + def test_concurrent_subtask_removal + with_settings :notified_events => [] do + root = Issue.generate! + 60.times do + Issue.generate! :parent_issue_id => root.id + end + # pick 40 random subtask ids + child_ids = Issue.where(root_id: root.id, parent_id: root.id).pluck(:id) + ids_to_remove = child_ids.sample(40).shuffle + ids_to_keep = child_ids - ids_to_remove + # remove these from the set, using four parallel threads + threads = [] + ids_to_remove.each_slice(10) do |ids| + threads << Thread.new do + ActiveRecord::Base.connection_pool.with_connection do + begin + ids.each do |id| + Issue.find(id).update(parent_id: nil) + end + rescue => e + Thread.current[:exception] = e.message + end + end + end + end + threads.each do |thread| + thread.join + assert_nil thread[:exception] + end + assert_equal 20, Issue.where(parent_id: root.id).count + Issue.where(id: ids_to_remove).each do |issue| + assert_nil issue.parent_id + assert_equal issue.id, issue.root_id + assert_equal 1, issue.lft + assert_equal 2, issue.rgt + end + root.reload + assert_equal [1, 42], [root.lft, root.rgt] + children_bounds = root.children.sort_by(&:lft).map {|c| [c.lft, c.rgt]}.flatten + assert_equal (2..41).to_a, children_bounds + end + end + private def threaded(count, &block) |