aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-02-21 21:09:05 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-02-25 20:14:56 +0900
commit1d8fad6f903d5065911bea3409c7a9082f47d3f8 (patch)
tree8504ca8cc3a484cd32d46f133d578b45b3bc0206 /activerecord/test
parent67e20d1d4854d834e9e43e56486d37cd98983f0d (diff)
downloadrails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.tar.gz
rails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.tar.bz2
rails-1d8fad6f903d5065911bea3409c7a9082f47d3f8.zip
Ensure `update_all` series cares about optimistic locking
Incrementing the lock version invalidates any other process's optimistic lock, which is the desired outcome: the record no longer looks the same as it did when they loaded it.
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/dirty_test.rb2
-rw-r--r--activerecord/test/cases/relation/update_all_test.rb71
2 files changed, 64 insertions, 9 deletions
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index dfd74bfcb4..a2a501a794 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -352,7 +352,7 @@ class DirtyTest < ActiveRecord::TestCase
Person.where(id: person.id).update_all(first_name: "baz")
end
- old_lock_version = person.lock_version
+ old_lock_version = person.lock_version + 1
with_partial_writes Person, true do
assert_no_queries { 2.times { person.save! } }
diff --git a/activerecord/test/cases/relation/update_all_test.rb b/activerecord/test/cases/relation/update_all_test.rb
index bb6912148c..0500574f28 100644
--- a/activerecord/test/cases/relation/update_all_test.rb
+++ b/activerecord/test/cases/relation/update_all_test.rb
@@ -138,14 +138,6 @@ class UpdateAllTest < ActiveRecord::TestCase
assert_equal new_time, developer.updated_at
end
- def test_touch_all_updates_locking_column
- person = people(:david)
-
- assert_difference -> { person.reload.lock_version }, +1 do
- Person.where(first_name: "David").touch_all
- end
- end
-
def test_update_on_relation
topic1 = TopicWithCallbacks.create! title: "arel", author_name: nil
topic2 = TopicWithCallbacks.create! title: "activerecord", author_name: nil
@@ -186,6 +178,69 @@ class UpdateAllTest < ActiveRecord::TestCase
end
end
+ def test_update_all_cares_about_optimistic_locking
+ david = people(:david)
+
+ travel 5.seconds do
+ now = Time.now.utc
+ assert_not_equal now, david.updated_at
+
+ people = Person.where(id: people(:michael, :david, :susan))
+ expected = people.pluck(:lock_version)
+ expected.map! { |version| version + 1 }
+ people.update_all(updated_at: now)
+
+ assert_equal [now] * 3, people.pluck(:updated_at)
+ assert_equal expected, people.pluck(:lock_version)
+
+ assert_raises(ActiveRecord::StaleObjectError) do
+ david.touch(time: now)
+ end
+ end
+ end
+
+ def test_update_counters_cares_about_optimistic_locking
+ david = people(:david)
+
+ travel 5.seconds do
+ now = Time.now.utc
+ assert_not_equal now, david.updated_at
+
+ people = Person.where(id: people(:michael, :david, :susan))
+ expected = people.pluck(:lock_version)
+ expected.map! { |version| version + 1 }
+ people.update_counters(touch: [time: now])
+
+ assert_equal [now] * 3, people.pluck(:updated_at)
+ assert_equal expected, people.pluck(:lock_version)
+
+ assert_raises(ActiveRecord::StaleObjectError) do
+ david.touch(time: now)
+ end
+ end
+ end
+
+ def test_touch_all_cares_about_optimistic_locking
+ david = people(:david)
+
+ travel 5.seconds do
+ now = Time.now.utc
+ assert_not_equal now, david.updated_at
+
+ people = Person.where(id: people(:michael, :david, :susan))
+ expected = people.pluck(:lock_version)
+ expected.map! { |version| version + 1 }
+ people.touch_all(time: now)
+
+ assert_equal [now] * 3, people.pluck(:updated_at)
+ assert_equal expected, people.pluck(:lock_version)
+
+ assert_raises(ActiveRecord::StaleObjectError) do
+ david.touch(time: now)
+ end
+ end
+ end
+
# Oracle UPDATE does not support ORDER BY
unless current_adapter?(:OracleAdapter)
def test_update_all_ignores_order_without_limit_from_association