jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1326010?usp=email )

Change subject: tests: Synchronize page locking test
......................................................................

tests: Synchronize page locking test

Hold the page lock while all worker threads enter the condition wait, then
release it immediately. This exercises lock contention without random sleeps.

Bug: T434934
Change-Id: I6f86d7d6ca537158aa7eff42a2de3faeb2343b91
---
M tests/site_tests.py
1 file changed, 38 insertions(+), 17 deletions(-)

Approvals:
  jenkins-bot: Verified
  Xqt: Looks good to me, approved




diff --git a/tests/site_tests.py b/tests/site_tests.py
index dac3333..e830e33 100755
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -10,10 +10,10 @@
 import pickle
 import random
 import threading
-import time
 import unittest
 from collections.abc import Iterable, Mapping
 from contextlib import suppress
+from unittest.mock import patch

 import pywikibot
 from pywikibot import config
@@ -284,30 +284,51 @@
     cached = True

     def worker(self) -> None:
-        """Lock a page, wait few seconds and unlock the page."""
+        """Lock and unlock a page."""
         page = pywikibot.Page(self.site, 'Foo')
         page.site.lock_page(page=page, block=True)
-        wait = random.randint(1, 25) / 10
-        time.sleep(wait)
         page.site.unlock_page(page=page)

     def test_threads_locking_page(self) -> None:
         """Test lock_page and unlock_page methods for multiple threads."""
-        # Start few threads
-        threads = []
-        for _ in range(5):
-            thread = threading.Thread(target=self.worker, daemon=True)
-            thread.start()
-            threads.append(thread)
+        page = pywikibot.Page(self.site, 'Foo')
+        worker_count = 5
+        waiting_workers = 0
+        all_waiting = threading.Event()
+        original_wait = self.site._pagemutex.wait

-        for thread in threads:
-            thread.join(15)  # maximum wait time for all threads
+        def track_waiting_workers() -> None:
+            nonlocal waiting_workers
+            waiting_workers += 1
+            if waiting_workers == worker_count:
+                all_waiting.set()
+            original_wait()

-            with self.subTest(name=thread.name):
-                # Check whether a timeout happened.
-                # In that case is_alive() is True
-                self.assertFalse(thread.is_alive(),
-                                 'test page is still locked')
+        # Hold the page lock until every worker is blocked on it.
+        with patch.object(self.site._pagemutex,
+                          'wait', track_waiting_workers):
+            self.site.lock_page(page)
+            # Start few threads
+            threads = []
+            for _ in range(worker_count):
+                thread = threading.Thread(target=self.worker, daemon=True)
+                thread.start()
+                threads.append(thread)
+
+            try:
+                self.assertTrue(all_waiting.wait(5),
+                                'workers did not wait for the page lock')
+            finally:
+                self.site.unlock_page(page)
+
+            for thread in threads:
+                thread.join(15)  # maximum wait time for all threads
+
+                with self.subTest(name=thread.name):
+                    # Check whether a timeout happened.
+                    # In that case is_alive() is True
+                    self.assertFalse(thread.is_alive(),
+                                     'test page is still locked')

     def test_lock_page(self) -> None:
         """Test the site.lock_page() and site.unlock_page() method."""

--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1326010?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I6f86d7d6ca537158aa7eff42a2de3faeb2343b91
Gerrit-Change-Number: 1326010
Gerrit-PatchSet: 2
Gerrit-Owner: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to