commit 6417ffe9681138ac1fb9dbccd897df61ef358ae1
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sun May 10 23:59:42 2015 +0000
Move Main.updateBridgeHistory() → Stability.updateBridgeHistory().
Conflicts:
lib/bridgedb/Main.py
---
lib/bridgedb/Main.py | 42 ++--------------------------------------
lib/bridgedb/Stability.py | 40 ++++++++++++++++++++++++++++++++++++++
lib/bridgedb/test/test_Main.py | 28 ++++++++++++++-------------
3 files changed, 57 insertions(+), 53 deletions(-)
diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py
index 88b386b..4a00799 100644
--- a/lib/bridgedb/Main.py
+++ b/lib/bridgedb/Main.py
@@ -40,51 +40,13 @@ from bridgedb.configure import Conf
from bridgedb.parse import descriptors
from bridgedb.parse import options
from bridgedb.parse.addr import isIPAddress
-from bridgedb.schedule import toUnixSeconds
import bridgedb.Storage
from bridgedb import Bridges
from bridgedb import Dist
-from bridgedb.Stability import addOrUpdateBridgeHistory
-
-
-def updateBridgeHistory(bridges, timestamps):
- """Process all the timestamps and update the bridge stability statistics in
- the database.
-
- .. warning: This function is extremely expensive, and will keep getting
- more and more expensive, on a linearithmic scale, every time it is
- called. Blame the :mod:`bridgedb.Stability` module.
-
- :param dict bridges: All bridges from the descriptors, parsed into
- :class:`bridgedb.bridges.Bridge`s.
- :param dict timestamps: A dictionary whose keys are bridge fingerprints,
- and whose values are lists of integers, each integer being a timestamp
- (in seconds since Unix Epoch) for when a descriptor for that bridge
- was published.
- :rtype: dict
- :returns: The original **timestamps**, but which each list of integers
- (re)sorted.
- """
- logging.debug("Beginning bridge stability calculations")
- sortedTimestamps = {}
-
- for fingerprint, stamps in timestamps.items()[:]:
- stamps.sort()
- bridge = bridges[fingerprint]
- for timestamp in stamps:
- logging.debug(
- ("Adding/updating timestamps in BridgeHistory for %s in "
- "database: %s") % (fingerprint, timestamp))
- timestamp = toUnixSeconds(timestamp.timetuple())
- addOrUpdateBridgeHistory(bridge, timestamp)
- # Replace the timestamps so the next sort is (hopefully) less
- # expensive:
- sortedTimestamps[fingerprint] = stamps
-
- logging.debug("Stability calculations complete")
- return sortedTimestamps
+from bridgedb.Stability import updateBridgeHistory
+
def load(state, splitter, clear=False):
"""Read and parse all descriptors, and load into a bridge splitter.
diff --git a/lib/bridgedb/Stability.py b/lib/bridgedb/Stability.py
index ad6fd0c..fbc8e88 100644
--- a/lib/bridgedb/Stability.py
+++ b/lib/bridgedb/Stability.py
@@ -28,6 +28,9 @@ Bridge stability metrics are calculated using the model introduced in
import logging
import bridgedb.Storage
+from bridgedb.schedule import toUnixSeconds
+
+
# tunables
weighting_factor = float(19)/float(20)
discountIntervalMillis = long(60*60*12*1000)
@@ -253,3 +256,40 @@ def updateWeightedTime(statusPublicationMillis):
for bh in bhToUpdate:
db.updateIntoBridgeHistory(bh)
+
+def updateBridgeHistory(bridges, timestamps):
+ """Process all the timestamps and update the bridge stability statistics in
+ the database.
+
+ .. warning: This function is extremely expensive, and will keep getting
+ more and more expensive, on a linearithmic scale, every time it is
+ called. Blame the :mod:`bridgedb.Stability` module.
+
+ :param dict bridges: All bridges from the descriptors, parsed into
+ :class:`bridgedb.bridges.Bridge`s.
+ :param dict timestamps: A dictionary whose keys are bridge fingerprints,
+ and whose values are lists of integers, each integer being a timestamp
+ (in seconds since Unix Epoch) for when a descriptor for that bridge
+ was published.
+ :rtype: dict
+ :returns: The original **timestamps**, but which each list of integers
+ (re)sorted.
+ """
+ logging.debug("Beginning bridge stability calculations")
+ sortedTimestamps = {}
+
+ for fingerprint, stamps in timestamps.items()[:]:
+ stamps.sort()
+ bridge = bridges[fingerprint]
+ for timestamp in stamps:
+ logging.debug(
+ ("Adding/updating timestamps in BridgeHistory for %s in "
+ "database: %s") % (fingerprint, timestamp))
+ timestamp = toUnixSeconds(timestamp.timetuple())
+ addOrUpdateBridgeHistory(bridge, timestamp)
+ # Replace the timestamps so the next sort is (hopefully) less
+ # expensive:
+ sortedTimestamps[fingerprint] = stamps
+
+ logging.debug("Stability calculations complete")
+ return sortedTimestamps
diff --git a/lib/bridgedb/test/test_Main.py b/lib/bridgedb/test/test_Main.py
index 0b14319..5ae4025 100644
--- a/lib/bridgedb/test/test_Main.py
+++ b/lib/bridgedb/test/test_Main.py
@@ -48,13 +48,15 @@ w Bandwidth=2094050
p reject 1-65535
'''
-def mockAddOrUpdateBridgeHistory(bridge, timestamp):
- """A mocked version of :func:`bridgedb.Stability.addOrUpdateBridgeHistory`
+def mockUpdateBridgeHistory(bridges, timestamps):
+ """A mocked version of :func:`bridgedb.Stability.updateBridgeHistory`
which doesn't access the database (so that we can test functions which
- call it, like :func:`bridgedb.Main.updateBridgeHistory`).
+ call it, like :func:`bridgedb.Main.load`).
"""
- print("Pretending to update Bridge %s with timestamp %s..." %
- (bridge.fingerprint, timestamp))
+ for fingerprint, stamps in timestamps.items()[:]:
+ for timestamp in stamps:
+ print("Pretending to update Bridge %s with timestamp %s..." %
+ (fingerprint, timestamp))
class MockBridgeHolder(BridgeHolder):
@@ -170,23 +172,23 @@ class MainTests(unittest.TestCase):
# Functions which some tests mock, which we'll need to re-replace
# later in tearDown():
- self._orig_addOrUpdateBridgeHistory = Main.addOrUpdateBridgeHistory
+ self._orig_updateBridgeHistory = Main.updateBridgeHistory
self._orig_sys_argv = sys.argv
def tearDown(self):
- """Replace the mocked mockAddOrUpdateBridgeHistory() function with the
- real function, Stability.addOrUpdateBridgeHistory().
+ """Replace the mocked mockUpdateBridgeHistory() function with the
+ real function, Stability.updateBridgeHistory().
"""
- Main.addOrUpdateBridgeHistory = self._orig_addOrUpdateBridgeHistory
+ Main.updateBridgeHistory = self._orig_updateBridgeHistory
sys.argv = self._orig_sys_argv
def test_Main_updateBridgeHistory(self):
"""Main.updateBridgeHistory should update some timestamps for some
bridges.
"""
- # Mock the addOrUpdateBridgeHistory() function so that we don't try to
+ # Mock the updateBridgeHistory() function so that we don't try to
# access the database:
- Main.addOrUpdateBridgeHistory = mockAddOrUpdateBridgeHistory
+ Main.updateBridgeHistory = mockUpdateBridgeHistory
# Get the bridges into the mocked splitter
d = deferToThread(Main.load, self.state, self.splitter)
@@ -222,12 +224,12 @@ class MainTests(unittest.TestCase):
"""
# Mock the addOrUpdateBridgeHistory() function so that we don't try to
# access the database:
- Main.addOrUpdateBridgeHistory = mockAddOrUpdateBridgeHistory
+ Main.updateBridgeHistory = mockUpdateBridgeHistory
state = self.state
state.COLLECT_TIMESTAMPS = True
# The reactor is deferring this to a thread, so the test execution
- # here isn't actually covering the Main.updateBridgeHistory()
+ # here isn't actually covering the Storage.updateBridgeHistory()
# function:
Main.load(state, self.splitter)