[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] connection_time() method for the BaseController
commit d220b901851db31758e4f38703b31e090cbb471b
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Mon Sep 1 14:34:11 2014 -0700
connection_time() method for the BaseController
Adding a connection_time() to our ControlSocket and BaseController to provide
when we either connected or disconnected from the socket.
---
docs/change_log.rst | 4 ++++
run_tests.py | 2 ++
stem/control.py | 12 ++++++++++++
stem/socket.py | 16 +++++++++++++++
test/integ/socket/control_socket.py | 37 +++++++++++++++++++++++++++++++++++
5 files changed, 71 insertions(+)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 0e605ca..2b6964c 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -40,6 +40,10 @@ Unreleased
The following are only available within Stem's `git repository
<download.html>`_.
+ * **Controller**
+
+ * Added :func:`~stem.control.BaseController.connection_time` to the :class:`~stem.control.BaseController`
+
* **Descriptors**
* Improved speed for parsing consensus documents by around 30% (:trac:`12859`)
diff --git a/run_tests.py b/run_tests.py
index 3c91513..2d73457 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -279,7 +279,9 @@ def main():
except OSError:
error_tracker.register_error()
finally:
+ println()
integ_runner.stop()
+ println()
if skipped_targets:
println()
diff --git a/stem/control.py b/stem/control.py
index e2f133d..8571a7f 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -478,6 +478,18 @@ class BaseController(object):
return self._socket.is_alive()
+ def connection_time(self):
+ """
+ Provides the unix timestamp for when our socket was either connected or
+ disconnected. That is to say, the time we connected if we're presently
+ connected and the time we disconnected if we're not connected.
+
+ :returns: **float** for when we last connected or disconnected, zero if
+ we've never connected
+ """
+
+ return self._socket.connection_time()
+
def is_authenticated(self):
"""
Checks if our socket is both connected and authenticated.
diff --git a/stem/socket.py b/stem/socket.py
index 1d664c0..e25f385 100644
--- a/stem/socket.py
+++ b/stem/socket.py
@@ -72,6 +72,7 @@ from __future__ import absolute_import
import re
import socket
import threading
+import time
import stem.prereq
import stem.response
@@ -93,6 +94,7 @@ class ControlSocket(object):
def __init__(self):
self._socket, self._socket_file = None, None
self._is_alive = False
+ self._connection_time = 0.0 # time when we last connected or disconnected
# Tracks sending and receiving separately. This should be safe, and doing
# so prevents deadlock where we block writes because we're waiting to read
@@ -203,6 +205,18 @@ class ControlSocket(object):
return False
+ def connection_time(self):
+ """
+ Provides the unix timestamp for when our socket was either connected or
+ disconnected. That is to say, the time we connected if we're presently
+ connected and the time we disconnected if we're not connected.
+
+ :returns: **float** for when we last connected or disconnected, zero if
+ we've never connected
+ """
+
+ return self._connection_time
+
def connect(self):
"""
Connects to a new socket, closing our previous one if we're already
@@ -223,6 +237,7 @@ class ControlSocket(object):
self._socket = self._make_socket()
self._socket_file = self._socket.makefile(mode = 'rwb')
self._is_alive = True
+ self._connection_time = time.time()
# It's possible for this to have a transient failure...
# SocketError: [Errno 4] Interrupted system call
@@ -273,6 +288,7 @@ class ControlSocket(object):
self._socket = None
self._socket_file = None
self._is_alive = False
+ self._connection_time = time.time()
if is_change:
self._close()
diff --git a/test/integ/socket/control_socket.py b/test/integ/socket/control_socket.py
index 7d7b84f..f0f2e40 100644
--- a/test/integ/socket/control_socket.py
+++ b/test/integ/socket/control_socket.py
@@ -8,6 +8,7 @@ those focus on parsing and correctness of the content these are more concerned
with the behavior of the socket itself.
"""
+import time
import unittest
import stem.connection
@@ -17,6 +18,42 @@ import test.runner
class TestControlSocket(unittest.TestCase):
+ def test_connection_time(self):
+ """
+ Checks that our connection_time method tracks when our state's changed.
+ """
+
+ if test.runner.require_control(self):
+ return
+
+ test_start = time.time()
+ runner = test.runner.get_runner()
+
+ with runner.get_tor_socket() as control_socket:
+ connection_time = control_socket.connection_time()
+
+ # connection time should be between our tests start and now
+
+ self.assertTrue(test_start <= connection_time <= time.time())
+
+ # connection time should be absolute (shouldn't change as time goes on)
+
+ time.sleep(0.1)
+ self.assertEqual(connection_time, control_socket.connection_time())
+
+ # should change to the disconnection time if we detactch
+
+ control_socket.close()
+ disconnection_time = control_socket.connection_time()
+ self.assertTrue(connection_time < disconnection_time <= time.time())
+
+ # then change again if we reconnect
+
+ time.sleep(0.1)
+ control_socket.connect()
+ reconnection_time = control_socket.connection_time()
+ self.assertTrue(disconnection_time < reconnection_time <= time.time())
+
def test_send_buffered(self):
"""
Sends multiple requests before receiving back any of the replies.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits