diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 6376aff5a6..c1abd1798e 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -56,27 +56,6 @@ class TestDB(FrappeTestCase): frappe.db.rollback(save_point=savepoint) self.fail("Long running queries not timing out") - def test_skip_locking(self): - with self.primary_connection(): - name = frappe.db.get_value("User", "Administrator", for_update=True, skip_locked=True) - self.assertEqual(name, "Administrator") - - with self.secondary_connection(): - name = frappe.db.get_value("User", "Administrator", for_update=True, skip_locked=True) - self.assertFalse(name) - - @timeout(5, "Lock timeout should have been 0") - def test_no_wait(self): - with self.primary_connection(): - name = frappe.db.get_value("User", "Administrator", for_update=True) - self.assertEqual(name, "Administrator") - - with self.secondary_connection(): - self.assertRaises( - frappe.QueryTimeoutError, - lambda: frappe.db.get_value("User", "Administrator", for_update=True, wait=False), - ) - @patch.dict(frappe.conf, {"http_timeout": 20, "enable_db_statement_timeout": 1}) def test_db_timeout_computation(self): set_request(method="GET", path="/") @@ -990,6 +969,44 @@ class TestReplicaConnections(FrappeTestCase): self.assertEqual(write_connection, db_id()) +class TestConcurrency(FrappeTestCase): + @timeout(5, "There shouldn't be any lock wait") + def test_skip_locking(self): + with self.primary_connection(): + name = frappe.db.get_value("User", "Administrator", for_update=True, skip_locked=True) + self.assertEqual(name, "Administrator") + + with self.secondary_connection(): + name = frappe.db.get_value("User", "Administrator", for_update=True, skip_locked=True) + self.assertFalse(name) + + @timeout(5, "Lock timeout should have been 0") + def test_no_wait(self): + with self.primary_connection(): + name = frappe.db.get_value("User", "Administrator", for_update=True) + self.assertEqual(name, "Administrator") + + with self.secondary_connection(): + self.assertRaises( + frappe.QueryTimeoutError, + lambda: frappe.db.get_value("User", "Administrator", for_update=True, wait=False), + ) + + @timeout(5, "Deletion stuck on lock timeout") + def test_delete_race_condition(self): + note = frappe.new_doc("Note") + note.title = note.content = frappe.generate_hash() + note.insert() + frappe.db.commit() # ensure that second connection can see the document + + with self.primary_connection(): + n1 = frappe.get_doc(note.doctype, note.name) + n1.save() + + with self.secondary_connection(): + self.assertRaises(frappe.QueryTimeoutError, frappe.delete_doc, note.doctype, note.name) + + class TestSqlIterator(FrappeTestCase): def test_db_sql_iterator(self): test_queries = [ diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py index 2201949fe0..a707312103 100644 --- a/frappe/tests/test_document.py +++ b/frappe/tests/test_document.py @@ -492,20 +492,6 @@ class TestDocument(FrappeTestCase): changed_val = frappe.db.get_single_value(c.doctype, key) self.assertEqual(val, changed_val) - @timeout(5, "Deletion stuck on lock timeout") - def test_delete_race_condition(self): - note = frappe.new_doc("Note") - note.title = note.content = frappe.generate_hash() - note.insert() - frappe.db.commit() # ensure that second connection can see the document - - with self.primary_connection(): - n1 = frappe.get_doc(note.doctype, note.name) - n1.save() - - with self.secondary_connection(): - self.assertRaises(frappe.QueryTimeoutError, frappe.delete_doc, note.doctype, note.name) - class TestDocumentWebView(FrappeTestCase): def get(self, path, user="Guest"):