[tor-commits] [arm/master] Testing the ResourceTracker class

atagar at torproject.org atagar at torproject.org
Mon Jan 6 01:54:14 UTC 2014


commit 0cede13371c0796a5a819ef65466b9d2aaf0b806
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Jan 5 16:15:20 2014 -0800

    Testing the ResourceTracker class
    
    Unit tests for our daemon that tracks the resource usage of tor.
---
 arm/util/tracker.py                   |   20 ++---
 test/util/tracker/resource_tracker.py |  142 +++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 10 deletions(-)

diff --git a/arm/util/tracker.py b/arm/util/tracker.py
index 1a716d3..b0f99b2 100644
--- a/arm/util/tracker.py
+++ b/arm/util/tracker.py
@@ -31,7 +31,7 @@ Background tasks for gathering information about the tor process.
   :var float cpu_average: average cpu usage since we first started tracking the process
   :var float cpu_total: total cpu time the process has used since starting
   :var int memory_bytes: memory usage of the process in bytes
-  :var float memory_precent: percentage of our memory used by this process
+  :var float memory_percent: percentage of our memory used by this process
   :var float timestamp: unix timestamp for when this information was fetched
 """
 
@@ -70,7 +70,7 @@ def get_connection_tracker():
   global CONNECTION_TRACKER
 
   if CONNECTION_TRACKER is None:
-    CONNECTION_TRACKER = ConnectionTracker()
+    CONNECTION_TRACKER = ConnectionTracker(CONFIG['queries.connections.rate'])
 
   return CONNECTION_TRACKER
 
@@ -83,7 +83,7 @@ def get_resource_tracker():
   global RESOURCE_TRACKER
 
   if RESOURCE_TRACKER is None:
-    RESOURCE_TRACKER = ResourceTracker()
+    RESOURCE_TRACKER = ResourceTracker(CONFIG['queries.resources.rate'])
 
   return RESOURCE_TRACKER
 
@@ -147,9 +147,9 @@ def _resources_via_ps(pid):
         total_cpu_time = str_tools.parse_short_time_label(stats[0])
         uptime = str_tools.parse_short_time_label(stats[1])
         memory_bytes = int(stats[2]) * 1024  # ps size is in kb
-        memory_precent = float(stats[3]) / 100.0
+        memory_percent = float(stats[3]) / 100.0
 
-        return (total_cpu_time, uptime, memory_bytes, memory_precent)
+        return (total_cpu_time, uptime, memory_bytes, memory_percent)
       except ValueError:
         pass
 
@@ -320,8 +320,8 @@ class ConnectionTracker(Daemon):
   Periodically retrieves the connections established by tor.
   """
 
-  def __init__(self):
-    super(ConnectionTracker, self).__init__(CONFIG['queries.connections.rate'])
+  def __init__(self, rate):
+    super(ConnectionTracker, self).__init__(rate)
 
     self._connections = []
     self._resolvers = connection.get_system_resolvers()
@@ -437,8 +437,8 @@ class ResourceTracker(Daemon):
   Periodically retrieves the resource usage of tor.
   """
 
-  def __init__(self):
-    super(ResourceTracker, self).__init__(CONFIG['queries.resources.rate'])
+  def __init__(self, rate):
+    super(ResourceTracker, self).__init__(rate)
 
     self._resources = None
     self._use_proc = proc.is_available()  # determines if we use proc or ps for lookups
@@ -469,7 +469,7 @@ class ResourceTracker(Daemon):
         cpu_average = total_cpu_time / uptime,
         cpu_total = total_cpu_time,
         memory_bytes = memory_in_bytes,
-        memory_precent = memory_in_percent,
+        memory_percent = memory_in_percent,
         timestamp = time.time(),
       )
 
diff --git a/test/util/tracker/resource_tracker.py b/test/util/tracker/resource_tracker.py
new file mode 100644
index 0000000..70cdf27
--- /dev/null
+++ b/test/util/tracker/resource_tracker.py
@@ -0,0 +1,142 @@
+import time
+import unittest
+
+from arm.util.tracker import ResourceTracker, _resources_via_ps, _resources_via_proc
+
+from mock import Mock, patch
+
+PS_OUTPUT = """\
+    TIME     ELAPSED   RSS %MEM
+00:00:02       00:18 18848  0.4
+"""
+
+
+class TestResourceTracker(unittest.TestCase):
+  @patch('arm.util.tracker.tor_controller')
+  @patch('arm.util.tracker._resources_via_proc')
+  @patch('arm.util.tracker.system', Mock(return_value = Mock()))
+  @patch('arm.util.tracker.proc.is_available', Mock(return_value = True))
+  def test_fetching_samplings(self, resources_via_proc_mock, tor_controller_mock):
+    tor_controller_mock().get_pid.return_value = 12345
+    resources_via_proc_mock.return_value = (105.3, 2.4, 8072, 0.3)
+
+    with ResourceTracker(0.04) as daemon:
+      time.sleep(0.01)
+
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(1, daemon.run_counter())
+      self.assertEqual(0.0, resources.cpu_sample)
+      self.assertEqual(43.875, resources.cpu_average)
+      self.assertEqual(105.3, resources.cpu_total)
+      self.assertEqual(8072, resources.memory_bytes)
+      self.assertEqual(0.3, resources.memory_percent)
+      self.assertTrue((time.time() - resources.timestamp) < 0.5)
+
+      resources_via_proc_mock.return_value = (800.3, 3.2, 6020, 0.26)
+      time.sleep(0.05)
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(2, daemon.run_counter())
+      self.assertEqual(6.600189933523267, resources.cpu_sample)
+      self.assertEqual(250.09374999999997, resources.cpu_average)
+      self.assertEqual(800.3, resources.cpu_total)
+      self.assertEqual(6020, resources.memory_bytes)
+      self.assertEqual(0.26, resources.memory_percent)
+      self.assertTrue((time.time() - resources.timestamp) < 0.5)
+
+    resources_via_proc_mock.assert_called_with(12345)
+
+  @patch('arm.util.tracker.tor_controller')
+  @patch('arm.util.tracker.proc.is_available')
+  @patch('arm.util.tracker._resources_via_ps', Mock(return_value = (105.3, 2.4, 8072, 0.3)))
+  @patch('arm.util.tracker._resources_via_proc', Mock(return_value = (340.3, 3.2, 6020, 0.26)))
+  @patch('arm.util.tracker.system', Mock(return_value = Mock()))
+  def test_picking_proc_or_ps(self, is_proc_available_mock, tor_controller_mock):
+    tor_controller_mock().get_pid.return_value = 12345
+
+    is_proc_available_mock.return_value = True
+
+    with ResourceTracker(0.04) as daemon:
+      time.sleep(0.01)
+
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(1, daemon.run_counter())
+      self.assertEqual(0.0, resources.cpu_sample)
+      self.assertEqual(106.34375, resources.cpu_average)
+      self.assertEqual(340.3, resources.cpu_total)
+      self.assertEqual(6020, resources.memory_bytes)
+      self.assertEqual(0.26, resources.memory_percent)
+      self.assertTrue((time.time() - resources.timestamp) < 0.5)
+
+    is_proc_available_mock.return_value = False
+
+    with ResourceTracker(0.04) as daemon:
+      time.sleep(0.01)
+
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(1, daemon.run_counter())
+      self.assertEqual(0.0, resources.cpu_sample)
+      self.assertEqual(43.875, resources.cpu_average)
+      self.assertEqual(105.3, resources.cpu_total)
+      self.assertEqual(8072, resources.memory_bytes)
+      self.assertEqual(0.3, resources.memory_percent)
+      self.assertTrue((time.time() - resources.timestamp) < 0.5)
+
+  @patch('arm.util.tracker.tor_controller')
+  @patch('arm.util.tracker._resources_via_ps', Mock(return_value = (105.3, 2.4, 8072, 0.3)))
+  @patch('arm.util.tracker._resources_via_proc', Mock(side_effect = IOError()))
+  @patch('arm.util.tracker.system', Mock(return_value = Mock()))
+  @patch('arm.util.tracker.proc.is_available', Mock(return_value = True))
+  def test_failing_over_to_ps(self, tor_controller_mock):
+    tor_controller_mock().get_pid.return_value = 12345
+
+    with ResourceTracker(0.01) as daemon:
+      time.sleep(0.03)
+
+      self.assertEqual(True, daemon._use_proc)
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(0, daemon.run_counter())
+      self.assertEqual(0.0, resources.cpu_sample)
+      self.assertEqual(0.0, resources.cpu_average)
+      self.assertEqual(0, resources.cpu_total)
+      self.assertEqual(0, resources.memory_bytes)
+      self.assertEqual(0.0, resources.memory_percent)
+      self.assertEqual(0.0, resources.timestamp)
+
+      time.sleep(0.05)
+      self.assertEqual(False, daemon._use_proc)
+
+      resources = daemon.get_resource_usage()
+
+      self.assertEqual(1, daemon.run_counter())
+      self.assertEqual(0.0, resources.cpu_sample)
+      self.assertEqual(43.875, resources.cpu_average)
+      self.assertEqual(105.3, resources.cpu_total)
+      self.assertEqual(8072, resources.memory_bytes)
+      self.assertEqual(0.3, resources.memory_percent)
+      self.assertTrue((time.time() - resources.timestamp) < 0.5)
+
+  @patch('arm.util.tracker.system.call', Mock(return_value = PS_OUTPUT.split('\n')))
+  def test_resources_via_ps(self):
+    total_cpu_time, uptime, memory_in_bytes, memory_in_percent = _resources_via_ps(12345)
+
+    self.assertEqual(2.0, total_cpu_time)
+    self.assertEqual(18, uptime)
+    self.assertEqual(19300352, memory_in_bytes)
+    self.assertEqual(0.004, memory_in_percent)
+
+  @patch('time.time', Mock(return_value = 1388967218.973117))
+  @patch('arm.util.tracker.proc.get_stats', Mock(return_value = (1.5, 0.5, 1388967200.9)))
+  @patch('arm.util.tracker.proc.get_memory_usage', Mock(return_value = (19300352, 6432)))
+  @patch('arm.util.tracker.proc.get_physical_memory', Mock(return_value = 4825088000))
+  def test_resources_via_proc(self):
+    total_cpu_time, uptime, memory_in_bytes, memory_in_percent = _resources_via_proc(12345)
+
+    self.assertEqual(2.0, total_cpu_time)
+    self.assertEqual(18, int(uptime))
+    self.assertEqual(19300352, memory_in_bytes)
+    self.assertEqual(0.004, memory_in_percent)





More information about the tor-commits mailing list