From efc2e4f94e655e9674cbf55cd1d770f9cf18a134 Mon Sep 17 00:00:00 2001 From: Tobias Witek Date: Fri, 6 Mar 2020 14:14:34 +0100 Subject: [PATCH] [modules] Separate modules into core & contrib Also, improve errors when importing a module fails. Also, add more tests. --- core/decorators.py | 1 + core/module.py | 19 +++++++++++++------ modules/{ => core}/__init__.py | 0 modules/{ => core}/__pulseaudio.py | 0 modules/{ => core}/date.py | 0 modules/{ => core}/datetime.py | 0 modules/{ => core}/kernel.py | 0 modules/{ => core}/load.py | 0 modules/{ => core}/nic.py | 0 modules/{ => core}/pasink.py | 0 modules/{ => core}/pasource.py | 0 modules/{ => core}/test.py | 0 modules/{ => core}/time.py | 0 tests/core/test_module.py | 22 +++++++++++++++++++++- tests/modules/test_kernel.py | 6 +++--- 15 files changed, 38 insertions(+), 10 deletions(-) rename modules/{ => core}/__init__.py (100%) rename modules/{ => core}/__pulseaudio.py (100%) rename modules/{ => core}/date.py (100%) rename modules/{ => core}/datetime.py (100%) rename modules/{ => core}/kernel.py (100%) rename modules/{ => core}/load.py (100%) rename modules/{ => core}/nic.py (100%) rename modules/{ => core}/pasink.py (100%) rename modules/{ => core}/pasource.py (100%) rename modules/{ => core}/test.py (100%) rename modules/{ => core}/time.py (100%) diff --git a/core/decorators.py b/core/decorators.py index e7b3b82..4c241a8 100644 --- a/core/decorators.py +++ b/core/decorators.py @@ -3,6 +3,7 @@ import util.format def scrollable(func): def wrapper(module, widget): text = func(module, widget) + widget.set('_raw', text) if not text: return text width = widget.get('theme.width', util.format.asint(module.parameter('width', 30))) diff --git a/core/module.py b/core/module.py index abf24d4..5979b8b 100644 --- a/core/module.py +++ b/core/module.py @@ -8,12 +8,19 @@ import core.decorators log = logging.getLogger(__name__) def load(module_name, config=None): - try: - mod = importlib.import_module('modules.{}'.format(module_name)) - except ImportError as error: - log.fatal('failed to import {}: {}'.format(module_name, error)) - return Error(config, module_name, error) - return getattr(mod, 'Module')(config) + error = None + for namespace in [ 'core', 'contrib' ]: + try: + mod = importlib.import_module('modules.{}.{}'.format(namespace, module_name)) + return getattr(mod, 'Module')(config) + except ModuleNotFoundError as e: + pass + except ImportError as e: + error = str(e) + if not error: + error = 'No such module' + log.fatal('failed to import {}: {}'.format(module_name, error)) + return Error(config, module_name, error) class Module(core.input.Object): def __init__(self, config=None, widgets=[]): diff --git a/modules/__init__.py b/modules/core/__init__.py similarity index 100% rename from modules/__init__.py rename to modules/core/__init__.py diff --git a/modules/__pulseaudio.py b/modules/core/__pulseaudio.py similarity index 100% rename from modules/__pulseaudio.py rename to modules/core/__pulseaudio.py diff --git a/modules/date.py b/modules/core/date.py similarity index 100% rename from modules/date.py rename to modules/core/date.py diff --git a/modules/datetime.py b/modules/core/datetime.py similarity index 100% rename from modules/datetime.py rename to modules/core/datetime.py diff --git a/modules/kernel.py b/modules/core/kernel.py similarity index 100% rename from modules/kernel.py rename to modules/core/kernel.py diff --git a/modules/load.py b/modules/core/load.py similarity index 100% rename from modules/load.py rename to modules/core/load.py diff --git a/modules/nic.py b/modules/core/nic.py similarity index 100% rename from modules/nic.py rename to modules/core/nic.py diff --git a/modules/pasink.py b/modules/core/pasink.py similarity index 100% rename from modules/pasink.py rename to modules/core/pasink.py diff --git a/modules/pasource.py b/modules/core/pasource.py similarity index 100% rename from modules/pasource.py rename to modules/core/pasource.py diff --git a/modules/test.py b/modules/core/test.py similarity index 100% rename from modules/test.py rename to modules/core/test.py diff --git a/modules/time.py b/modules/core/time.py similarity index 100% rename from modules/time.py rename to modules/core/time.py diff --git a/tests/core/test_module.py b/tests/core/test_module.py index cf8e387..5458ea3 100644 --- a/tests/core/test_module.py +++ b/tests/core/test_module.py @@ -26,9 +26,19 @@ class module(unittest.TestCase): self.assertEqual('core.module', module.__class__.__module__, 'module must be a module object') self.assertEqual('Error', module.__class__.__name__, 'an invalid module must be a core.module.Error') + def test_importerror(self): + with unittest.mock.patch('core.module.importlib') as importlib: + importlib.import_module.side_effect = ImportError('some-error') + + config = unittest.mock.MagicMock() + module = core.module.load(module_name=self.validModuleName, config=config) + module.widget().full_text() + self.assertEqual('Error', module.__class__.__name__, 'an invalid module must be a core.module.Error') + self.assertEqual(module.widget().get('_raw'), 'test: some-error') + def test_loadvalid_module(self): module = core.module.load(module_name=self.validModuleName) - self.assertEqual('modules.{}'.format(self.validModuleName), module.__class__.__module__, 'module must be a modules. object') + self.assertEqual('modules.core.{}'.format(self.validModuleName), module.__class__.__module__, 'module must be a modules.core. object') self.assertEqual('Module', module.__class__.__name__, 'a valid module must have a Module class') self.assertEqual([], module.state(None), 'default state of module is empty') @@ -90,4 +100,14 @@ class module(unittest.TestCase): self.assertEqual(None, module.widget(self.unusedWidgetName)) self.assertEqual(self.someWidget, module.widget()) + def test_default_thresholds(self): + cfg = core.config.Config([]) + module = TestModule(config=cfg, widgets=[self.someWidget, self.anotherWidget]) + + self.assertEqual('critical', module.threshold_state(100, 80, 99)) + self.assertEqual('warning', module.threshold_state(100, 80, 100)) + self.assertEqual('warning', module.threshold_state(81, 80, 100)) + self.assertEqual(None, module.threshold_state(80, 80, 100)) + self.assertEqual(None, module.threshold_state(10, 80, 100)) + # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/tests/modules/test_kernel.py b/tests/modules/test_kernel.py index 01d091d..db9d37d 100644 --- a/tests/modules/test_kernel.py +++ b/tests/modules/test_kernel.py @@ -1,13 +1,13 @@ import unittest -import modules.kernel +import modules.core.kernel class kernel(unittest.TestCase): def setUp(self): self.someKernel = 'this-is-my-kernel' - with unittest.mock.patch('modules.kernel.platform') as platform: + with unittest.mock.patch('modules.core.kernel.platform') as platform: platform.release.return_value = self.someKernel - self.module = modules.kernel.Module() + self.module = modules.core.kernel.Module() def test_full_text(self): self.assertEqual(1, len(self.module.widgets()))