[modules/cpu] Add initial version of CPU utilization module

Re-enable the CPU utilization module as proof-of-concept for the new
core engine.

see #23
This commit is contained in:
Tobi-wan Kenobi 2016-12-04 17:45:42 +01:00
parent 8855f1155b
commit aacc56a4e2
9 changed files with 85 additions and 10 deletions

View file

@ -55,10 +55,12 @@ class Engine(object):
while self.running(): while self.running():
widgets = [] widgets = []
for module in self._modules: for module in self._modules:
widgets += module.widgets() module_widgets = module.widgets()
self._output.draw(widgets) widgets += module_widgets if isinstance(module_widgets, list) else [module_widgets]
self._output.draw(widgets=widgets, engine=self)
self._output.flush() self._output.flush()
time.sleep(1) if self.running():
time.sleep(1)
self._output.stop() self._output.stop()

18
bumblebee/modules/cpu.py Normal file
View file

@ -0,0 +1,18 @@
# pylint: disable=C0111,R0903
"""Displays CPU utilization across all CPUs."""
import psutil
import bumblebee.engine
class Module(bumblebee.engine.Module):
def __init__(self, engine):
super(Module, self).__init__(engine)
self._utilization = psutil.cpu_percent(percpu=False)
def widgets(self):
self._utilization = psutil.cpu_percent(percpu=False)
return bumblebee.output.Widget(full_text="{:05.02f}%".format(self._utilization))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -9,6 +9,6 @@ class Module(bumblebee.engine.Module):
super(Module, self).__init__(engine) super(Module, self).__init__(engine)
def widgets(self): def widgets(self):
return [] return bumblebee.output.Widget(full_text="test")
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -5,6 +5,15 @@
import sys import sys
import json import json
class Widget(object):
"""Represents a single visible block in the status bar"""
def __init__(self, full_text):
self._full_text = full_text
def full_text(self):
"""Retrieve the full text to display in the widget"""
return self._full_text
class I3BarOutput(object): class I3BarOutput(object):
"""Manage output according to the i3bar protocol""" """Manage output according to the i3bar protocol"""
def __init__(self): def __init__(self):
@ -18,14 +27,14 @@ class I3BarOutput(object):
"""Finish i3bar protocol""" """Finish i3bar protocol"""
sys.stdout.write("]\n") sys.stdout.write("]\n")
def draw(self, widgets): def draw(self, widgets, engine=None):
"""Draw a number of widgets""" """Draw a number of widgets"""
if not isinstance(widgets, list): if not isinstance(widgets, list):
widgets = [widgets] widgets = [widgets]
result = [] result = []
for widget in widgets: for widget in widgets:
result.append({ result.append({
u"full_text": widget.text() u"full_text": widget.full_text()
}) })
sys.stdout.write(json.dumps(result)) sys.stdout.write(json.dumps(result))

View file

16
tests/modules/test_cpu.py Normal file
View file

@ -0,0 +1,16 @@
# pylint: disable=C0103,C0111
import unittest
from bumblebee.modules.cpu import Module
from tests.util import assertWidgetAttributes
class TestCPUModule(unittest.TestCase):
def setUp(self):
self.module = Module(None)
def test_widgets(self):
widget = self.module.widgets()
assertWidgetAttributes(self, widget)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,13 +1,17 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import unittest import unittest
from bumblebee.error import ModuleLoadError from bumblebee.error import ModuleLoadError
from bumblebee.engine import Engine from bumblebee.engine import Engine
from bumblebee.config import Config from bumblebee.config import Config
from tests.util import MockOutput
class TestEngine(unittest.TestCase): class TestEngine(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = Engine(Config()) self.engine = Engine(config=Config(), output=MockOutput())
self.singleWidgetModule = [{"module": "test"}]
self.testModule = "test" self.testModule = "test"
self.invalidModule = "no-such-module" self.invalidModule = "no-such-module"
self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule) self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule)
@ -41,4 +45,11 @@ class TestEngine(unittest.TestCase):
[self.testModuleSpec for module in modules] [self.testModuleSpec for module in modules]
) )
def test_run(self):
self.engine.load_modules(self.singleWidgetModule)
try:
self.engine.run()
except Exception as e:
self.fail(e)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -32,14 +32,14 @@ class TestI3BarOutput(unittest.TestCase):
def test_draw_single_widget(self, stdout): def test_draw_single_widget(self, stdout):
self.output.draw(self.someWidget) self.output.draw(self.someWidget)
result = json.loads(stdout.getvalue())[0] result = json.loads(stdout.getvalue())[0]
self.assertEquals(result["full_text"], self.someWidget.text()) self.assertEquals(result["full_text"], self.someWidget.full_text())
@mock.patch("sys.stdout", new_callable=StringIO) @mock.patch("sys.stdout", new_callable=StringIO)
def test_draw_multiple_widgets(self, stdout): def test_draw_multiple_widgets(self, stdout):
self.output.draw([self.someWidget, self.someWidget]) self.output.draw([self.someWidget, self.someWidget])
result = json.loads(stdout.getvalue()) result = json.loads(stdout.getvalue())
for res in result: for res in result:
self.assertEquals(res["full_text"], self.someWidget.text()) self.assertEquals(res["full_text"], self.someWidget.full_text())
@mock.patch("sys.stdout", new_callable=StringIO) @mock.patch("sys.stdout", new_callable=StringIO)
def test_flush(self, stdout): def test_flush(self, stdout):

View file

@ -1,10 +1,29 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
from bumblebee.output import Widget
def assertWidgetAttributes(test, widget):
test.assertTrue(isinstance(widget, Widget))
test.assertTrue(hasattr(widget, "full_text"))
class MockOutput(object):
def start(self):
pass
def stop(self):
pass
def draw(self, widgets, engine):
engine.stop()
def flush(self):
pass
class MockWidget(object): class MockWidget(object):
def __init__(self, text): def __init__(self, text):
self._text = text self._text = text
def text(self): def full_text(self):
return self._text return self._text
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4