[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Add a get_start_time() method
commit 9b1897578aca4a8befda999efcc5ad64aaf646ed
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Tue Apr 2 11:05:22 2019 -0700
Add a get_start_time() method
On reflection, process initialization time is cachable whereas uptime is not.
Adding a get_start_time() method, not only for its own usefulness but because
it inherrantly lets us make get_uptime() a cached method.
---
docs/change_log.rst | 1 +
stem/control.py | 72 +++++++++++++++++++++++++++++------------
test/unit/control/controller.py | 7 ++--
3 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 5c0208cb..f188c885 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -47,6 +47,7 @@ The following are only available within Stem's `git repository
* **Controller**
+ * Added :func:`~stem.control.Controller.get_start_time` method to the :class:`~stem.control.Controller`
* Added :func:`~stem.control.Controller.get_uptime` method to the :class:`~stem.control.Controller`
* Controller events could fail to be delivered in a timely fashion (:trac:`27173`)
* Adjusted :func:`~stem.control.Controller.get_microdescriptors` fallback to also use '.new' cache files (:trac:`28508`)
diff --git a/stem/control.py b/stem/control.py
index b4436af0..3ea3752f 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -84,6 +84,7 @@ If you're fine with allowing your script to raise exceptions then this can be mo
|- get_protocolinfo - information about the controller interface
|- get_user - provides the user tor is running as
|- get_pid - provides the pid of our tor process
+ |- get_start_time - timestamp when the tor process began
|- get_uptime - duration tor has been running
|- is_user_traffic_allowed - checks if we send or receive direct user traffic
|
@@ -1582,8 +1583,10 @@ class Controller(BaseController):
user = self._get_cache('user')
- if not user:
- user = self.get_info('process/user', None)
+ if user:
+ return user
+
+ user = self.get_info('process/user', None)
if not user and self.is_localhost():
pid = self.get_pid(None)
@@ -1618,11 +1621,13 @@ class Controller(BaseController):
pid = self._get_cache('pid')
- if not pid:
- getinfo_pid = self.get_info('process/pid', None)
+ if pid:
+ return pid
- if getinfo_pid and getinfo_pid.isdigit():
- pid = int(getinfo_pid)
+ getinfo_pid = self.get_info('process/pid', None)
+
+ if getinfo_pid and getinfo_pid.isdigit():
+ pid = int(getinfo_pid)
if not pid and self.is_localhost():
pid_file_path = self.get_conf('PidFile', None)
@@ -1652,30 +1657,37 @@ class Controller(BaseController):
raise ValueError("Unable to resolve tor's pid" if self.is_localhost() else "Tor isn't running locally")
@with_default()
- def get_uptime(self, default = UNDEFINED):
+ def get_start_time(self, default = UNDEFINED):
"""
- get_uptime(default = UNDEFINED)
+ get_start_time(default = UNDEFINED)
- Provides the duration in seconds that tor has been running.
+ Provides when the tor process began.
.. versionadded:: 1.8.0
:param object default: response if the query fails
- :returns: **int** for the number of seconds tor has been running
+ :returns: **float** for the unix timestamp of when the tor process began
- :raises: **ValueError** if unable to determine the uptime and no default
- was provided
+ :raises: **ValueError** if unable to determine when the process began and
+ no default was provided
"""
+ start_time = self._get_cache('start_time')
+
+ if start_time:
+ return start_time
+
if self.get_version() >= stem.version.Requirement.GETINFO_UPTIME:
uptime = self.get_info('uptime', None)
- if uptime and uptime.isdigit():
- return int(uptime)
- else:
- raise ValueError("'GETINFO uptime' did not provide a valid numeric response: %s" % uptime)
- else:
+ if uptime:
+ if not uptime.isdigit():
+ raise ValueError("'GETINFO uptime' did not provide a valid numeric response: %s" % uptime)
+
+ start_time = time.time() - float(uptime)
+
+ if not start_time and self.is_localhost():
# Tor doesn't yet support this GETINFO option, attempt to determine the
# uptime of the process ourselves.
@@ -1689,10 +1701,30 @@ class Controller(BaseController):
start_time = stem.util.system.start_time(pid)
- if not start_time:
- raise ValueError('Unable to determine when the tor process began')
+ if start_time:
+ self._set_cache({'start_time': start_time})
+ return start_time
+ else:
+ raise ValueError("Unable to resolve when tor began" if self.is_localhost() else "Tor isn't running locally")
+
+ @with_default()
+ def get_uptime(self, default = UNDEFINED):
+ """
+ get_uptime(default = UNDEFINED)
+
+ Provides the duration in seconds that tor has been running.
+
+ .. versionadded:: 1.8.0
+
+ :param object default: response if the query fails
+
+ :returns: **float** for the number of seconds tor has been running
+
+ :raises: **ValueError** if unable to determine the uptime and no default
+ was provided
+ """
- return time.time() - start_time
+ return time.time() - self.get_start_time()
def is_user_traffic_allowed(self):
"""
diff --git a/test/unit/control/controller.py b/test/unit/control/controller.py
index f5e63771..94c1b65f 100644
--- a/test/unit/control/controller.py
+++ b/test/unit/control/controller.py
@@ -563,14 +563,17 @@ class TestControl(unittest.TestCase):
self.assertEqual(432, self.controller.get_pid())
@patch('stem.control.Controller.get_version', Mock(return_value = stem.version.Version('0.5.0.14')))
+ @patch('stem.socket.ControlSocket.is_localhost', Mock(return_value = False))
@patch('stem.control.Controller.get_info')
+ @patch('time.time', Mock(return_value = 1000.0))
def test_get_uptime_by_getinfo(self, getinfo_mock):
"""
Exercise the get_uptime() resolution via a GETINFO query.
"""
getinfo_mock.return_value = '321'
- self.assertEqual(321, self.controller.get_uptime())
+ self.assertEqual(321.0, self.controller.get_uptime())
+ self.controller.clear_cache()
getinfo_mock.return_value = 'abc'
self.assertRaisesWith(ValueError, "'GETINFO uptime' did not provide a valid numeric response: abc", self.controller.get_uptime)
@@ -585,7 +588,7 @@ class TestControl(unittest.TestCase):
Exercise the get_uptime() resolution via process age.
"""
- self.assertEqual(200, self.controller.get_uptime())
+ self.assertEqual(200.0, self.controller.get_uptime())
@patch('stem.control.Controller.get_info')
def test_get_network_status_for_ourselves(self, get_info_mock):
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits