commit da39c3fedd7e7345d4e587ba2fe571369c6d9add Author: Damian Johnson atagar@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,