[tor-commits] [nyx/master] Class for Sampling rather than namedtuple

atagar at torproject.org atagar at torproject.org
Mon Apr 18 20:23:16 UTC 2016


commit da39c3fedd7e7345d4e587ba2fe571369c6d9add
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Apr 10 13:12:16 2016 -0700

    Class for Sampling rather than namedtuple
    
    As mentioned earlier I didn't like the sampling() and get_sampling() split we
    needed for our tests. On reflection this is actually nicer if we simply don't
    strive to make this a namedtuple.
---
 nyx/panel/header.py  | 166 +++++++++++++++++++++++++--------------------------
 test/panel/header.py |  14 ++---
 2 files changed, 89 insertions(+), 91 deletions(-)

diff --git a/nyx/panel/header.py b/nyx/panel/header.py
index 9288db9..01922ec 100644
--- a/nyx/panel/header.py
+++ b/nyx/panel/header.py
@@ -7,7 +7,6 @@ This expands the information it presents to two columns if there's room
 available.
 """
 
-import collections
 import os
 import time
 import threading
@@ -45,7 +44,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread):
     threading.Thread.__init__(self)
     self.setDaemon(True)
 
-    self._vals = _get_sampling()
+    self._vals = Sampling.create()
 
     self._last_width = 100
     self._pause_condition = threading.Condition()
@@ -248,7 +247,7 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread):
 
   def _update(self):
     previous_height = self.get_height()
-    self._vals = _get_sampling(self._vals)
+    self._vals = Sampling.create(self._vals)
 
     if self._vals.fd_used and self._vals.fd_limit != -1:
       fd_percent = 100 * self._vals.fd_used / self._vals.fd_limit
@@ -279,96 +278,95 @@ class HeaderPanel(nyx.panel.Panel, threading.Thread):
       self.redraw(True)  # just need to redraw ourselves
 
 
-def _sampling(**attr):
-  class Sampling(collections.namedtuple('Sampling', attr.keys())):
-    def __init__(self, **attr):
-      super(Sampling, self).__init__(**attr)
-      self._attr = attr
+class Sampling(object):
+  def __init__(self, **attr):
+    self._attr = attr
 
-    def format(self, message, crop_width = None):
-      formatted_msg = message.format(**self._attr)
+    for key, value in attr.items():
+      setattr(self, key, value)
 
-      if crop_width is not None:
-        formatted_msg = str_tools.crop(formatted_msg, crop_width)
-
-      return formatted_msg
-
-  return Sampling(**attr)
-
-
-def _get_sampling(last_sampling = None):
-  controller = tor_controller()
-  retrieved = time.time()
+  @staticmethod
+  def create(last_sampling = None):
+    controller = tor_controller()
+    retrieved = time.time()
 
-  pid = controller.get_pid('')
-  tor_resources = nyx.tracker.get_resource_tracker().get_value()
-  nyx_total_cpu_time = sum(os.times()[:3])
+    pid = controller.get_pid('')
+    tor_resources = nyx.tracker.get_resource_tracker().get_value()
+    nyx_total_cpu_time = sum(os.times()[:3])
 
-  or_listeners = controller.get_listeners(Listener.OR, [])
-  control_listeners = controller.get_listeners(Listener.CONTROL, [])
+    or_listeners = controller.get_listeners(Listener.OR, [])
+    control_listeners = controller.get_listeners(Listener.CONTROL, [])
 
-  if controller.get_conf('HashedControlPassword', None):
-    auth_type = 'password'
-  elif controller.get_conf('CookieAuthentication', None) == '1':
-    auth_type = 'cookie'
-  else:
-    auth_type = 'open'
+    if controller.get_conf('HashedControlPassword', None):
+      auth_type = 'password'
+    elif controller.get_conf('CookieAuthentication', None) == '1':
+      auth_type = 'cookie'
+    else:
+      auth_type = 'open'
 
-  try:
-    fd_used = proc.file_descriptors_used(pid)
-  except IOError:
-    fd_used = None
+    try:
+      fd_used = proc.file_descriptors_used(pid)
+    except IOError:
+      fd_used = None
 
-  if last_sampling:
-    nyx_cpu_delta = nyx_total_cpu_time - last_sampling.nyx_total_cpu_time
-    nyx_time_delta = retrieved - last_sampling.retrieved
+    if last_sampling:
+      nyx_cpu_delta = nyx_total_cpu_time - last_sampling.nyx_total_cpu_time
+      nyx_time_delta = retrieved - last_sampling.retrieved
 
-    python_cpu_time = nyx_cpu_delta / nyx_time_delta
-    sys_call_cpu_time = 0.0  # TODO: add a wrapper around call() to get this
+      python_cpu_time = nyx_cpu_delta / nyx_time_delta
+      sys_call_cpu_time = 0.0  # TODO: add a wrapper around call() to get this
 
-    nyx_cpu = python_cpu_time + sys_call_cpu_time
-  else:
-    nyx_cpu = 0.0
-
-  attr = {
-    'retrieved': retrieved,
-    'is_connected': controller.is_alive(),
-    'connection_time': controller.connection_time(),
-    'last_heartbeat': controller.get_latest_heartbeat(),
-
-    'fingerprint': controller.get_info('fingerprint', 'Unknown'),
-    'nickname': controller.get_conf('Nickname', ''),
-    'newnym_wait': controller.get_newnym_wait(),
-    'exit_policy': controller.get_exit_policy(None),
-    'flags': getattr(controller.get_network_status(default = None), 'flags', []),
-
-    'version': str(controller.get_version('Unknown')).split()[0],
-    'version_status': controller.get_info('status/version/current', 'Unknown'),
-
-    'address': or_listeners[0][0] if (or_listeners and or_listeners[0][0] != '0.0.0.0') else controller.get_info('address', 'Unknown'),
-    'or_port': or_listeners[0][1] if or_listeners else '',
-    'dir_port': controller.get_conf('DirPort', '0'),
-    'control_port': str(control_listeners[0][1]) if control_listeners else None,
-    'socket_path': controller.get_conf('ControlSocket', None),
-    'is_relay': bool(or_listeners),
-
-    'auth_type': auth_type,
-    'pid': pid,
-    'start_time': system.start_time(pid),
-    'fd_limit': int(controller.get_info('process/descriptor-limit', '-1')),
-    'fd_used': fd_used,
-
-    'nyx_total_cpu_time': nyx_total_cpu_time,
-    'tor_cpu': '%0.1f' % (100 * tor_resources.cpu_sample),
-    'nyx_cpu': '%0.1f' % (nyx_cpu),
-    'memory': str_tools.size_label(tor_resources.memory_bytes) if tor_resources.memory_bytes > 0 else 0,
-    'memory_percent': '%0.1f' % (100 * tor_resources.memory_percent),
-
-    'hostname': os.uname()[1],
-    'platform': '%s %s' % (os.uname()[0], os.uname()[2]),  # [platform name] [version]
-  }
-
-  return _sampling(**attr)
+      nyx_cpu = python_cpu_time + sys_call_cpu_time
+    else:
+      nyx_cpu = 0.0
+
+    attr = {
+      'retrieved': retrieved,
+      'is_connected': controller.is_alive(),
+      'connection_time': controller.connection_time(),
+      'last_heartbeat': controller.get_latest_heartbeat(),
+
+      'fingerprint': controller.get_info('fingerprint', 'Unknown'),
+      'nickname': controller.get_conf('Nickname', ''),
+      'newnym_wait': controller.get_newnym_wait(),
+      'exit_policy': controller.get_exit_policy(None),
+      'flags': getattr(controller.get_network_status(default = None), 'flags', []),
+
+      'version': str(controller.get_version('Unknown')).split()[0],
+      'version_status': controller.get_info('status/version/current', 'Unknown'),
+
+      'address': or_listeners[0][0] if (or_listeners and or_listeners[0][0] != '0.0.0.0') else controller.get_info('address', 'Unknown'),
+      'or_port': or_listeners[0][1] if or_listeners else '',
+      'dir_port': controller.get_conf('DirPort', '0'),
+      'control_port': str(control_listeners[0][1]) if control_listeners else None,
+      'socket_path': controller.get_conf('ControlSocket', None),
+      'is_relay': bool(or_listeners),
+
+      'auth_type': auth_type,
+      'pid': pid,
+      'start_time': system.start_time(pid),
+      'fd_limit': int(controller.get_info('process/descriptor-limit', '-1')),
+      'fd_used': fd_used,
+
+      'nyx_total_cpu_time': nyx_total_cpu_time,
+      'tor_cpu': '%0.1f' % (100 * tor_resources.cpu_sample),
+      'nyx_cpu': '%0.1f' % (nyx_cpu),
+      'memory': str_tools.size_label(tor_resources.memory_bytes) if tor_resources.memory_bytes > 0 else 0,
+      'memory_percent': '%0.1f' % (100 * tor_resources.memory_percent),
+
+      'hostname': os.uname()[1],
+      'platform': '%s %s' % (os.uname()[0], os.uname()[2]),  # [platform name] [version]
+    }
+
+    return Sampling(**attr)
+
+  def format(self, message, crop_width = None):
+    formatted_msg = message.format(**self._attr)
+
+    if crop_width is not None:
+      formatted_msg = str_tools.crop(formatted_msg, crop_width)
+
+    return formatted_msg
 
 
 def _draw_platform_section(subwindow, x, y, width, vals):
diff --git a/test/panel/header.py b/test/panel/header.py
index 209ce8b..57222b0 100644
--- a/test/panel/header.py
+++ b/test/panel/header.py
@@ -16,7 +16,7 @@ from mock import patch
 class TestHeader(unittest.TestCase):
   @require_curses
   def test_draw_platform_section(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       hostname = 'odin',
       platform = 'Linux 3.5.0-54-generic',
       version = '0.2.8.1-alpha-dev',
@@ -40,7 +40,7 @@ class TestHeader(unittest.TestCase):
 
   @require_curses
   def test_draw_platform_section_without_version(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       hostname = 'odin',
       platform = 'Linux 3.5.0-54-generic',
       version = 'Unknown',
@@ -51,7 +51,7 @@ class TestHeader(unittest.TestCase):
 
   @require_curses
   def test_draw_ports_section(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       nickname = 'Unnamed',
       address = '174.21.17.28',
       or_port = '7000',
@@ -72,7 +72,7 @@ class TestHeader(unittest.TestCase):
 
   @require_curses
   def test_draw_ports_section_with_relaying(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       control_port = None,
       socket_path = '/path/to/control/socket',
       is_relay = False,
@@ -88,7 +88,7 @@ class TestHeader(unittest.TestCase):
 
   @require_curses
   def test_draw_resource_usage(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       start_time = 1460166022.231895,
       connection_time = 1460267022.231895,
       is_connected = False,
@@ -116,7 +116,7 @@ class TestHeader(unittest.TestCase):
 
   @require_curses
   def test_draw_fingerprint_and_fd_usage(self):
-    vals = nyx.panel.header._sampling(
+    vals = nyx.panel.header.Sampling(
       fingerprint = '1A94D1A794FCB2F8B6CBC179EF8FDD4008A98D3B',
       fd_used = None,
     )
@@ -150,7 +150,7 @@ class TestHeader(unittest.TestCase):
     }
 
     for fd_used, expected in test_input.items():
-      vals = nyx.panel.header._sampling(
+      vals = nyx.panel.header.Sampling(
         fingerprint = '<stub>',
         fd_used = fd_used,
         fd_limit = 100,





More information about the tor-commits mailing list