[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [nyx/master] Track connection uptime
commit 40f5bb69cc3bf48871d92816888e5e7842a4e75c
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Wed Jul 15 09:49:48 2015 -0700
Track connection uptime
Our connection panel does some gross things to keep track of connection uptime.
Our tracker class can easily handle this, simplifying the panel and making this
functionality more testable.
---
nyx/util/tracker.py | 26 +++++++++++++----
test/util/tracker/connection_tracker.py | 48 ++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/nyx/util/tracker.py b/nyx/util/tracker.py
index 638768b..2471aff 100644
--- a/nyx/util/tracker.py
+++ b/nyx/util/tracker.py
@@ -68,6 +68,14 @@ RESOURCE_TRACKER = None
PORT_USAGE_TRACKER = None
CONSENSUS_TRACKER = None
+# Extending stem's Connection tuple with attributes for the uptime of the
+# connection.
+
+Connection = collections.namedtuple('Connection', [
+ 'start_time',
+ 'is_legacy', # boolean to indicate if the connection predated us
+] + list(stem.util.connection.Connection._fields))
+
Resources = collections.namedtuple('Resources', [
'cpu_sample',
'cpu_average',
@@ -441,8 +449,10 @@ class ConnectionTracker(Daemon):
super(ConnectionTracker, self).__init__(rate)
self._connections = []
+ self._start_times = {} # connection => (unix_timestamp, is_legacy)
self._resolvers = connection.system_resolvers()
self._custom_resolver = None
+ self._is_first_run = True
# Number of times in a row we've either failed with our current resolver or
# concluded that our rate is too low.
@@ -462,12 +472,16 @@ class ConnectionTracker(Daemon):
try:
start_time = time.time()
+ new_connections, new_start_times = [], {}
- self._connections = connection.get_connections(
- resolver,
- process_pid = process_pid,
- process_name = process_name,
- )
+ for conn in connection.get_connections(resolver, process_pid = process_pid, process_name = process_name):
+ conn_start_time, is_legacy = self._start_times.get(conn, (start_time, self._is_first_run))
+ new_start_times[conn] = (conn_start_time, is_legacy)
+ new_connections.append(Connection(conn_start_time, is_legacy, *conn))
+
+ self._connections = new_connections
+ self._start_times = new_start_times
+ self._is_first_run = False
runtime = time.time() - start_time
@@ -539,7 +553,7 @@ class ConnectionTracker(Daemon):
"""
Provides a listing of tor's latest connections.
- :returns: **list** of :class:`~stem.util.connection.Connection` we last
+ :returns: **list** of :class:`~nyx.util.tracker.Connection` we last
retrieved, an empty list if our tracker's been stopped
"""
diff --git a/test/util/tracker/connection_tracker.py b/test/util/tracker/connection_tracker.py
index 416a96b..0f3c93f 100644
--- a/test/util/tracker/connection_tracker.py
+++ b/test/util/tracker/connection_tracker.py
@@ -7,9 +7,9 @@ from stem.util import connection
from mock import Mock, patch
-CONNECTION_1 = connection.Connection('127.0.0.1', 3531, '75.119.206.243', 22, 'tcp')
-CONNECTION_2 = connection.Connection('127.0.0.1', 1766, '86.59.30.40', 443, 'tcp')
-CONNECTION_3 = connection.Connection('127.0.0.1', 1059, '74.125.28.106', 80, 'tcp')
+STEM_CONNECTION_1 = connection.Connection('127.0.0.1', 3531, '75.119.206.243', 22, 'tcp')
+STEM_CONNECTION_2 = connection.Connection('127.0.0.1', 1766, '86.59.30.40', 443, 'tcp')
+STEM_CONNECTION_3 = connection.Connection('127.0.0.1', 1059, '74.125.28.106', 80, 'tcp')
class TestConnectionTracker(unittest.TestCase):
@@ -19,7 +19,7 @@ class TestConnectionTracker(unittest.TestCase):
@patch('nyx.util.tracker.connection.system_resolvers', Mock(return_value = [connection.Resolver.NETSTAT]))
def test_fetching_connections(self, get_value_mock, tor_controller_mock):
tor_controller_mock().get_pid.return_value = 12345
- get_value_mock.return_value = [CONNECTION_1, CONNECTION_2, CONNECTION_3]
+ get_value_mock.return_value = [STEM_CONNECTION_1, STEM_CONNECTION_2, STEM_CONNECTION_3]
with ConnectionTracker(0.04) as daemon:
time.sleep(0.01)
@@ -27,7 +27,7 @@ class TestConnectionTracker(unittest.TestCase):
connections = daemon.get_value()
self.assertEqual(1, daemon.run_counter())
- self.assertEqual([CONNECTION_1, CONNECTION_2, CONNECTION_3], connections)
+ self.assertEqual(['75.119.206.243', '86.59.30.40', '74.125.28.106'], [conn.remote_address for conn in connections])
get_value_mock.return_value = [] # no connection results
time.sleep(0.05)
@@ -63,7 +63,7 @@ class TestConnectionTracker(unittest.TestCase):
# Now make connection resolution work. We still shouldn't provide any
# results since we stopped looking.
- get_value_mock.return_value = [CONNECTION_1, CONNECTION_2]
+ get_value_mock.return_value = [STEM_CONNECTION_1, STEM_CONNECTION_2]
get_value_mock.side_effect = None
time.sleep(0.05)
self.assertEqual([], daemon.get_value())
@@ -73,4 +73,38 @@ class TestConnectionTracker(unittest.TestCase):
daemon.set_custom_resolver(connection.Resolver.NETSTAT)
time.sleep(0.05)
- self.assertEqual([CONNECTION_1, CONNECTION_2], daemon.get_value())
+ self.assertEqual(['75.119.206.243', '86.59.30.40'], [conn.remote_address for conn in daemon.get_value()])
+
+ @patch('nyx.util.tracker.tor_controller')
+ @patch('nyx.util.tracker.connection.get_connections')
+ @patch('nyx.util.tracker.system', Mock(return_value = Mock()))
+ @patch('nyx.util.tracker.connection.system_resolvers', Mock(return_value = [connection.Resolver.NETSTAT]))
+ def test_tracking_uptime(self, get_value_mock, tor_controller_mock):
+ tor_controller_mock().get_pid.return_value = 12345
+ get_value_mock.return_value = [STEM_CONNECTION_1]
+ first_start_time = time.time()
+
+ with ConnectionTracker(0.04) as daemon:
+ time.sleep(0.01)
+
+ connections = daemon.get_value()
+ self.assertEqual(1, len(connections))
+
+ self.assertEqual('75.119.206.243', connections[0].remote_address)
+ self.assertTrue(first_start_time < connections[0].start_time < time.time())
+ self.assertTrue(connections[0].is_legacy)
+
+ second_start_time = time.time()
+ get_value_mock.return_value = [STEM_CONNECTION_1, STEM_CONNECTION_2]
+ time.sleep(0.05)
+
+ connections = daemon.get_value()
+ self.assertEqual(2, len(connections))
+
+ self.assertEqual('75.119.206.243', connections[0].remote_address)
+ self.assertTrue(first_start_time < connections[0].start_time < time.time())
+ self.assertTrue(connections[0].is_legacy)
+
+ self.assertEqual('86.59.30.40', connections[1].remote_address)
+ self.assertTrue(second_start_time < connections[1].start_time < time.time())
+ self.assertFalse(connections[1].is_legacy)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits