commit cc343eb85f53095aceacd9ad2a22cb5dfebd0782 Author: juga0 juga@riseup.net Date: Mon Mar 1 19:02:04 2021 +0000
fix: scaling: round bandwidth filtered
because Torflow does it. --- docs/source/torflow_aggr.rst | 25 +++++++++++++++++++++++++ sbws/lib/scaling.py | 6 ++++-- tests/unit/lib/test_scaling.py | 29 ++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/docs/source/torflow_aggr.rst b/docs/source/torflow_aggr.rst index ee832cd..da1c328 100644 --- a/docs/source/torflow_aggr.rst +++ b/docs/source/torflow_aggr.rst @@ -203,6 +203,18 @@ From Torflow's `README.spec.txt`_ (section 1.6):: In the code, `SQLSupport.py`_, ``strm_bw`` is ``sbw`` and ``filt_bw`` is ``filt_sbws``::
+ for s in rs.router.streams: + if isinstance(s, ClosedStream): + tot_bytes += s.tot_bytes() + tot_duration += s.end_time - s.start_time + tot_bw += s.bandwidth() + s_cnt += 1 + # FIXME: Hrmm.. do we want to do weighted avg or pure avg here? + # If files are all the same size, it shouldn't matter.. + if s_cnt > 0: + rs.sbw = tot_bw/s_cnt + else: rs.sbw = None + for rs in RouterStats.query.filter(stats_clause).\ options(eagerload_all('router.streams.circuit.routers')).all(): tot_sbw = 0 @@ -224,6 +236,19 @@ In the code, `SQLSupport.py`_, ``strm_bw`` is ``sbw`` and if sbw_cnt: rs.filt_sbw = tot_sbw/sbw_cnt else: rs.filt_sbw = None
+When it is written to the file, it seem to write "None" string when +``filt_sbw`` or ``strm_bw`` are None. That would give an exception when +calculating the network average. So it never happen?:: + + def cvt(a,b,c=1): + if type(a) == float: return int(round(a/c,b)) + elif type(a) == int: return a + elif type(a) == type(None): return "None" + else: return type(a) + + f.write(" strm_bw="+str(cvt(s.sbw,0))) + f.write(" filt_bw="+str(cvt(s.filt_sbw,0))) + This is also expressed in pseudocode in the `bandwidth file spec`_, section B.4 step 1.
diff --git a/sbws/lib/scaling.py b/sbws/lib/scaling.py index 079f36b..6ec8185 100644 --- a/sbws/lib/scaling.py +++ b/sbws/lib/scaling.py @@ -16,8 +16,10 @@ def bw_filt(bw_measurements): """ mu = 1 if bw_measurements: - mu = mean(bw_measurements) + # Torflow is rounding to an integer, so is `bw_mean_from_results` in + # `v3bwfile.py` + mu = round(mean(bw_measurements)) bws_gte_mean = list(filter(lambda bw: bw >= mu, bw_measurements)) if bws_gte_mean: - return mean(bws_gte_mean) + return round(mean(bws_gte_mean)) return 1 diff --git a/tests/unit/lib/test_scaling.py b/tests/unit/lib/test_scaling.py index 06fb71b..2e4212c 100644 --- a/tests/unit/lib/test_scaling.py +++ b/tests/unit/lib/test_scaling.py @@ -1,4 +1,5 @@ """Unit tests for scaling.py.""" +from statistics import mean
from sbws.lib import scaling
@@ -10,4 +11,30 @@ def test_bw_filt(): ] fb = scaling.bw_filt(bw_measurements) # This is greater than the mean, that is 61422.73714139576 - assert fb == 83505.81986994506 + assert fb == 83506 + + # When there are no measurements what can not be the case for successful + # results. + bw_measurements = [] + assert 1 == scaling.bw_filt(bw_measurements) + + bw_measurements = [1, 0] + # Because rounded to int + assert 0 == round(mean(bw_measurements)) + # So the filtered bw will be also 0 + assert 0 == scaling.bw_filt(bw_measurements) + + bw_measurements = [1, 2, 3] + # Because rounded to int + assert 2 == round(mean(bw_measurements)) + assert 2 == scaling.bw_filt(bw_measurements) + + bw_measurements = [10, 0] + assert 5 == round(mean(bw_measurements)) + # Because the value 10 is bigger than the mean + assert 10 == scaling.bw_filt(bw_measurements) + + bw_measurements = [0, 10, 20] + assert 10 == round(mean(bw_measurements)) + # Because 10 and 20 are bigger or equal than the mean + assert 15 == scaling.bw_filt(bw_measurements)
tor-commits@lists.torproject.org