[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [sbws/maint-1.1] chg: relayprioritizer: Count priorities with timestamps
commit c7c91370f5008aa4757340799e880e175d3b8830
Author: juga0 <juga@xxxxxxxxxx>
Date: Sat Mar 21 14:49:50 2020 +0000
chg: relayprioritizer: Count priorities with timestamps
in RelayPrioritizer:
- Rename recent_priority_list_count to recent_priority_list when
there is no counting
- Rename recent_priority_relay_count to recent_priority_relay
when there is no counting
- Use the timestamps class to manage/count priority lists/relays
---
sbws/lib/relayprioritizer.py | 38 +++++++++++------
sbws/lib/v3bwfile.py | 4 +-
tests/conftest.py | 30 +++++++++++++
tests/unit/conftest.py | 11 +++++
tests/unit/lib/test_relayprioritizer.py | 76 +++++++++++++++++++++++++++++++++
tests/unit/lib/test_v3bwfile.py | 20 +++++++++
6 files changed, 163 insertions(+), 16 deletions(-)
diff --git a/sbws/lib/relayprioritizer.py b/sbws/lib/relayprioritizer.py
index 4932ea8..3647a8b 100644
--- a/sbws/lib/relayprioritizer.py
+++ b/sbws/lib/relayprioritizer.py
@@ -6,7 +6,8 @@ import copy
import time
import logging
-from ..util import state
+from ..globals import MAX_RECENT_PRIORITY_RELAY_COUNT
+from ..util import state, timestamps
log = logging.getLogger(__name__)
@@ -24,30 +25,39 @@ class RelayPrioritizer:
self.fraction_to_return = conf.getfloat(
'relayprioritizer', 'fraction_relays')
self._state = state.State(conf.getpath('paths', 'state_fname'))
- if self._state is not None:
- # If it was not in previous state versions, initialize it to 0
- if self._state.get('recent_priority_list_count', None) is None:
- self._state['recent_priority_list_count'] = 0
- if self._state.get('recent_priority_relay_count') is None:
- self._state['recent_priority_relay_count'] = 0
-
- def increment_priority_lists(self):
+ self._recent_priority_list = timestamps.DateTimeSeq(
+ [], 120, self._state, "recent_priority_list"
+ )
+ self._recent_priority_relay = timestamps.DateTimeIntSeq(
+ [], MAX_RECENT_PRIORITY_RELAY_COUNT, self._state,
+ "recent_priority_relay"
+ )
+
+ def increment_recent_priority_list(self):
"""
Increment the number of times that
:meth:`~sbws.lib.relayprioritizer.RelayPrioritizer.best_priority`
has been run.
"""
# NOTE: blocking, writes to file!
- self._state['recent_priority_list_count'] += 1
+ self._recent_priority_list.update()
- def increment_priority_relays(self, relays_count):
+ @property
+ def recent_priority_list_count(self):
+ return len(self._recent_priority_list)
+
+ def increment_recent_priority_relay(self, relays_count):
"""
Increment the number of relays that have been "prioritized" to be
measured in a
:meth:`~sbws.lib.relayprioritizer.RelayPrioritizer.best_priority`.
"""
# NOTE: blocking, writes to file!
- self._state['recent_priority_relay_count'] += relays_count
+ self._recent_priority_relay.update(number=relays_count)
+
+ @property
+ def recent_priority_relay_count(self):
+ return len(self._recent_priority_relay)
def best_priority(self, prioritize_result_error=False,
return_fraction=True):
@@ -141,11 +151,11 @@ class RelayPrioritizer:
upper_limit = cutoff if return_fraction else len(relays)
# NOTE: these two are blocking, write to disk
# Increment the number of times ``best_priority`` has been run.
- self.increment_priority_lists()
+ self.increment_recent_priority_list()
# Increment the number of relays that have been "prioritized".
# Because in a small testing network the upper limit could be smaller
# than the number of relays in the network, use the length of the list.
- self.increment_priority_relays(len(relays[0:upper_limit]))
+ self.increment_recent_priority_relay(len(relays[0:upper_limit]))
for relay in relays[0:upper_limit]:
log.debug('Returning next relay %s with priority %f',
relay.nickname, relay.priority)
diff --git a/sbws/lib/v3bwfile.py b/sbws/lib/v3bwfile.py
index f81ef82..ee9fd17 100644
--- a/sbws/lib/v3bwfile.py
+++ b/sbws/lib/v3bwfile.py
@@ -481,7 +481,7 @@ class V3BWHeader(object):
in the recent (by default 5) days from the state file.
"""
state = State(state_fpath)
- return state.get('recent_priority_list_count', None)
+ return state.count('recent_priority_list')
@staticmethod
def recent_priority_relay_count_from_file(state_fpath):
@@ -490,7 +490,7 @@ class V3BWHeader(object):
in the recent (by default 5) days from the state file.
"""
state = State(state_fpath)
- return state.get('recent_priority_relay_count', None)
+ return state.count('recent_priority_relay')
@staticmethod
def latest_bandwidth_from_results(results):
diff --git a/tests/conftest.py b/tests/conftest.py
index d968cac..b2b54d1 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -5,6 +5,10 @@ from unittest import mock
from stem import descriptor
+from sbws import settings
+from sbws.lib import relaylist
+from sbws.lib import relayprioritizer
+from sbws.lib import resultdump
from sbws.util.parser import create_parser
@@ -87,3 +91,29 @@ def controller_5days_later(router_statuses_5days_later):
controller = mock.Mock()
controller.get_network_statuses.return_value = router_statuses_5days_later
return controller
+
+
+# Because of the function scoped `args` in `tests.unit.conftest`, this has to
+# be function scoped too.
+@pytest.fixture(scope='function')
+def relay_list(args, conf, controller):
+ """Returns a RelayList containing the Relays in the controller"""
+ return relaylist.RelayList(args, conf, controller)
+
+
+@pytest.fixture(scope='function')
+def result_dump(args, conf):
+ """Returns a ResultDump without Results"""
+ # To stop the thread that would be waiting for new results
+ settings.set_end_event()
+ return resultdump.ResultDump(args, conf)
+
+
+@pytest.fixture(scope="function")
+def relay_prioritizer(args, conf_results, relay_list, result_dump):
+ """
+ Returns a RelayPrioritizer with a RelayList and a ResultDump.
+ """
+ return relayprioritizer.RelayPrioritizer(
+ args, conf_results, relay_list, result_dump
+ )
diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
index 295e777..bc812f0 100644
--- a/tests/unit/conftest.py
+++ b/tests/unit/conftest.py
@@ -187,6 +187,17 @@ def conf(sbwshome_empty, tmpdir):
return conf
+@pytest.fixture(scope='function')
+def conf_results(sbwshome_success_result_two_relays, conf):
+ """Minimal configuration having a datadir
+
+ So that `ResultDump` does not raise AssertionError.
+
+ """
+ conf['paths']['sbws_home'] = sbwshome_success_result_two_relays
+ return conf
+
+
@pytest.fixture()
def result():
return RESULT
diff --git a/tests/unit/lib/test_relayprioritizer.py b/tests/unit/lib/test_relayprioritizer.py
new file mode 100644
index 0000000..e692343
--- /dev/null
+++ b/tests/unit/lib/test_relayprioritizer.py
@@ -0,0 +1,76 @@
+"""relayprioritizer.py unit tests."""
+from freezegun import freeze_time
+
+
+def test_increment_recent_priority_list(relay_prioritizer):
+ """Test that incrementing the priority lists do not go on forever.
+
+ And instead it only counts the number of priority lists in the last days.
+ """
+
+ state = relay_prioritizer._state
+ assert 0 == relay_prioritizer.recent_priority_list_count
+ assert not state.get("recent_priority_list", None)
+
+ # Pretend that a priority list is made.
+ with freeze_time("2020-02-29 10:00:00"):
+ relay_prioritizer.increment_recent_priority_list()
+ assert 1 == relay_prioritizer.recent_priority_list_count
+ assert 1 == len(state["recent_priority_list"])
+
+ # And a second priority list is made 4 days later.
+ with freeze_time("2020-03-04 10:00:00"):
+ relay_prioritizer.increment_recent_priority_list()
+ assert 2 == relay_prioritizer.recent_priority_list_count
+ assert 2 == len(state["recent_priority_list"])
+
+ # And a third priority list is made 5 days later.
+ with freeze_time("2020-03-05 10:00:00"):
+ relay_prioritizer.increment_recent_priority_list()
+ assert 3 == relay_prioritizer.recent_priority_list_count
+ assert 3 == len(state["recent_priority_list"])
+
+ # And a fourth priority list is made 6 days later. The first one is
+ # now removed and not counted.
+ with freeze_time("2020-03-06 10:00:00"):
+ relay_prioritizer.increment_recent_priority_list()
+ assert 3 == relay_prioritizer.recent_priority_list_count
+ assert 3 == len(state["recent_priority_list"])
+
+
+def test_increment_priority_relay(relay_prioritizer):
+ """Test that incrementing the number of relays in the priority lists
+ do not go on forever.
+
+ And instead it only counts number of relays in priority lists in the last
+ days.
+ """
+
+ state = relay_prioritizer._state
+ assert 0 == relay_prioritizer.recent_priority_relay_count
+ assert not state.get("recent_priority_relay", None)
+
+ # Pretend that a priority list is made.
+ with freeze_time("2020-02-29 10:00:00"):
+ relay_prioritizer.increment_recent_priority_relay(2)
+ assert 2 == relay_prioritizer.recent_priority_relay_count
+ assert 2 == state.count("recent_priority_relay")
+
+ # And a second priority list is made 4 days later.
+ with freeze_time("2020-03-04 10:00:00"):
+ relay_prioritizer.increment_recent_priority_relay(2)
+ assert 4 == relay_prioritizer.recent_priority_relay_count
+ assert 4 == state.count("recent_priority_relay")
+
+ # And a third priority list is made 5 days later.
+ with freeze_time("2020-03-05 10:00:00"):
+ relay_prioritizer.increment_recent_priority_relay(2)
+ assert 6 == relay_prioritizer.recent_priority_relay_count
+ assert 6 == state.count("recent_priority_relay")
+
+ # And a fourth priority list is made 6 days later. The first one is
+ # now removed and the relays are not counted.
+ with freeze_time("2020-03-06 10:00:00"):
+ relay_prioritizer.increment_recent_priority_relay(2)
+ assert 6 == relay_prioritizer.recent_priority_relay_count
+ assert 6 == state.count("recent_priority_relay")
diff --git a/tests/unit/lib/test_v3bwfile.py b/tests/unit/lib/test_v3bwfile.py
index 2ce34ff..7d26b8d 100644
--- a/tests/unit/lib/test_v3bwfile.py
+++ b/tests/unit/lib/test_v3bwfile.py
@@ -551,3 +551,23 @@ def test_recent_measurement_attempt_count(root_data_path, datadir):
results = load_result_file(str(datadir.join("results.txt")))
header = V3BWHeader.from_results(results, '', '', state_fpath)
assert "15" == header.recent_measurement_attempt_count
+
+
+def test_recent_priority_list_count(root_data_path, datadir):
+ # This state has recent_priority_list
+ state_fpath = os.path.join(root_data_path, '.sbws/state.dat')
+ assert 1 == V3BWHeader.recent_priority_list_count_from_file(state_fpath)
+ # `results` does not matter here, using them to don't have an empty list.
+ results = load_result_file(str(datadir.join("results.txt")))
+ header = V3BWHeader.from_results(results, '', '', state_fpath)
+ assert "1" == header.recent_priority_list_count
+
+
+def test_recent_priority_relay_count(root_data_path, datadir):
+ # This state has recent_priority_relay_count
+ state_fpath = os.path.join(root_data_path, '.sbws/state.dat')
+ assert 15 == V3BWHeader.recent_priority_relay_count_from_file(state_fpath)
+ # `results` does not matter here, using them to don't have an empty list.
+ results = load_result_file(str(datadir.join("results.txt")))
+ header = V3BWHeader.from_results(results, '', '', state_fpath)
+ assert "15" == header.recent_priority_relay_count
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits