[tor-commits] [sbws/master] scanner: check that ResultDump queue is not full

juga at torproject.org juga at torproject.org
Sun Mar 3 12:44:39 UTC 2019


commit ada70d4f85ac7ce6f9847eeae832ec7620106470
Author: juga0 <juga at riseup.net>
Date:   Tue Jan 8 16:27:44 2019 +0000

    scanner: check that ResultDump queue is not full
    
    and put the result in the queue with a timeout.
    
    Fixes bug #28866. Bugfix v0.1.0.
---
 sbws/core/scanner.py            | 12 +++++++++++-
 tests/unit/conftest.py          | 20 ++++++++++++++++++++
 tests/unit/core/test_scanner.py | 28 ++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/sbws/core/scanner.py b/sbws/core/scanner.py
index 7246f12..4c85ee4 100644
--- a/sbws/core/scanner.py
+++ b/sbws/core/scanner.py
@@ -315,8 +315,18 @@ def _next_expected_amount(expected_amount, result_time, download_times,
 def result_putter(result_dump):
     ''' Create a function that takes a single argument -- the measurement
     result -- and return that function so it can be used by someone else '''
+
     def closure(measurement_result):
-        return result_dump.queue.put(measurement_result)
+        # in case the queue is full, wait until is not.
+        # Since result_dump thread is calling queue.get() every second,
+        # the queue should be full for only 1 second.
+        while result_dump.queue.full():
+            log.info('The results queue is full, after 1 second it should '
+                     'not be full.')
+            time.sleep(1)
+        # Non blocking, wait a maximum of 1 second if the queue is full.
+        # Because of the timeout, the previous while should not be needed.
+        result_dump.queue.put(measurement_result, timeout=1)
     return closure
 
 
diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
index 4dd442b..ada1b9b 100644
--- a/tests/unit/conftest.py
+++ b/tests/unit/conftest.py
@@ -267,3 +267,23 @@ def sbwshome_success_result_two_relays(sbwshome_only_datadir, conf):
     write_result_to_datadir(RESULT_SUCCESS2, dd)
     write_result_to_datadir(RESULT_SUCCESS2, dd)
     return sbwshome_only_datadir
+
+
+ at pytest.fixture(scope='function')
+def end_event():
+    import threading
+    return threading.Event()
+
+
+ at pytest.fixture(scope='function')
+def rd(args, conf, end_event):
+    from sbws.lib.resultdump import ResultDump
+    # in Travis the next line gives the error:
+    # TypeError: __init__() takes 3 positional arguments but 4 were given
+    # No idea why.
+    # Returning None to disable the test in case ResultDump can not be
+    # initialized.
+    try:
+        return ResultDump(args, conf, end_event)
+    except TypeError:
+        return None
diff --git a/tests/unit/core/test_scanner.py b/tests/unit/core/test_scanner.py
new file mode 100644
index 0000000..3f84472
--- /dev/null
+++ b/tests/unit/core/test_scanner.py
@@ -0,0 +1,28 @@
+"""Unit tests for scanner.py."""
+import pytest
+
+from sbws.core.scanner import result_putter
+
+
+def test_result_putter(sbwshome_only_datadir, result_success, rd, end_event):
+    if rd is None:
+        pytest.skip("ResultDump is None")
+    # Put one item in the queue
+    callback = result_putter(rd)
+    callback(result_success)
+    assert rd.queue.qsize() == 1
+
+    # Make queue maxsize 1, so that it'll be full after the first callback.
+    # The second callback will wait 1 second, then the queue will be empty
+    # again.
+    rd.queue.maxsize = 1
+    callback(result_success)
+    # after putting 1 result, the queue will be full
+    assert rd.queue.qsize() == 1
+    assert rd.queue.full()
+    # it's still possible to put another results, because the callback will
+    # wait 1 second and the queue will be empty again.
+    callback(result_success)
+    assert rd.queue.qsize() == 1
+    assert rd.queue.full()
+    end_event.set()





More information about the tor-commits mailing list