diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1b3dccb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: generic +sudo: required +services: + - docker +matrix: + include: + - name: "fedora 28 python 2 test suite" + env: + - python=2 + - os=fedora:28 + - package_manager=dnf + - name: "fedora 28 python 3 test suite" + env: + - python=3 + - os=fedora:28 + - package_manager=dnf + - name: "centos 7 test suite" + env: + - python=2 + - os=centos:7 + - package_manager=yum +script: + - docker build --build-arg PYTHON=${python} --build-arg OS=${os} --build-arg PACKAGE_MANAGER=${package_manager} -t tuned_image -f tests/Dockerfile . + - docker run tuned_image /bin/sh -c "make test PYTHON=/usr/bin/python${python}" diff --git a/tests/Dockerfile b/tests/Dockerfile new file mode 100644 index 0000000..2e4e258 --- /dev/null +++ b/tests/Dockerfile @@ -0,0 +1,27 @@ +ARG OS + +FROM $OS + +WORKDIR /test_dir + +ADD ./ /test_dir + +ARG PACKAGE_MANAGER=dnf + +ENV PKM=$PACKAGE_MANAGER + +ARG OS +RUN if [[ $OS == "centos:7" ]]; then yum install -y epel-release; fi; + +RUN ${PKM} install -y virt-what ethtool gawk hdparm util-linux dbus polkit make +ARG PYTHON +RUN ${PKM} install -y python$PYTHON-flexmock + +ARG OS +ARG PYTHON +RUN if [[ $OS == "centos:7" ]]; then export py=python; \ + else export py=python$PYTHON; fi; \ + ${PKM} install -y ${py}-dbus \ + ${py}-decorator ${py}-pyudev ${py}-configobj ${py}-schedutils \ + ${py}-linux-procfs ${py}-perf ${py}-unittest2 ${py}-gobject-base; + diff --git a/tests/exports/__init__.py b/tests/exports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/exports/test_controller.py b/tests/exports/test_controller.py new file mode 100644 index 0000000..ce1def9 --- /dev/null +++ b/tests/exports/test_controller.py @@ -0,0 +1,88 @@ +import unittest2 +import flexmock + +from tuned.exports.controller import ExportsController +import tuned.exports as exports + +class ControllerTestCase(unittest2.TestCase): + @classmethod + def setUpClass(cls): + cls._controller = ExportsController() + + def test_is_exportable_method(self): + self.assertFalse(self._controller._is_exportable_method( \ + MockClass().NonExportableObject)) + + self.assertTrue(self._controller._is_exportable_method( \ + MockClass().ExportableMethod)) + + def test_is_exportable_signal(self): + self.assertFalse(self._controller._is_exportable_signal( \ + MockClass().NonExportableObject)) + + self.assertTrue(self._controller._is_exportable_signal( \ + MockClass().ExportableSignal)) + + def test_initialize_exports(self): + local_controller = ExportsController() + exporter = MockExporter() + instance = MockClass() + local_controller.register_exporter(exporter) + local_controller.register_object(instance) + local_controller._initialize_exports() + self.assertEqual(exporter.exported_methods[0].method,\ + instance.ExportableMethod) + self.assertEqual(exporter.exported_methods[0].args[0],\ + "method_param1") + self.assertEqual(exporter.exported_methods[0].kwargs['kword'],\ + "method_param2") + self.assertEqual(exporter.exported_signals[0].method,\ + instance.ExportableSignal) + self.assertEqual(exporter.exported_signals[0].args[0],\ + "signal_param1") + self.assertEqual(exporter.exported_signals[0].kwargs['kword'],\ + "signal_param2") + + def test_start_stop(self): + local_controller = ExportsController() + exporter = MockExporter() + local_controller.register_exporter(exporter) + local_controller.start() + self.assertTrue(exporter.is_running) + local_controller.stop() + self.assertFalse(exporter.is_running) + + +class MockExporter(object): + def __init__(self): + self.exported_methods = [] + self.exported_signals = [] + self.is_running = False + + def export(self,method,*args,**kwargs): + object_to_export = flexmock.flexmock(\ + method = method, args = args, kwargs = kwargs) + self.exported_methods.append(object_to_export) + + def signal(self,method,*args,**kwargs): + object_to_export = flexmock.flexmock(\ + method = method, args = args, kwargs = kwargs) + self.exported_signals.append(object_to_export) + + def start(self): + self.is_running = True + + def stop(self): + self.is_running = False + +class MockClass(object): + @exports.export('method_param1', kword = 'method_param2') + def ExportableMethod(self): + return True + + def NonExportableObject(self): + pass + + @exports.signal('signal_param1', kword = 'signal_param2') + def ExportableSignal(self): + return True diff --git a/tests/hardware/test_device_matcher.py b/tests/hardware/test_device_matcher.py index d3e879f..1987eb6 100644 --- a/tests/hardware/test_device_matcher.py +++ b/tests/hardware/test_device_matcher.py @@ -1,7 +1,7 @@ -import unittest +import unittest2 from tuned.hardware.device_matcher import DeviceMatcher -class DeviceMatcherTestCase(unittest.TestCase): +class DeviceMatcherTestCase(unittest2.TestCase): @classmethod def setUpClass(cls): cls.matcher = DeviceMatcher() diff --git a/tests/hardware/test_device_matcher_udev.py b/tests/hardware/test_device_matcher_udev.py new file mode 100644 index 0000000..8e93428 --- /dev/null +++ b/tests/hardware/test_device_matcher_udev.py @@ -0,0 +1,36 @@ +import unittest2 +import pyudev + +from tuned.hardware.device_matcher_udev import DeviceMatcherUdev + +class DeviceMatcherUdevTestCase(unittest2.TestCase): + @classmethod + def setUpClass(cls): + cls.udev_context = pyudev.Context() + cls.matcher = DeviceMatcherUdev() + + def test_simple_search(self): + try: + device = pyudev.Devices.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty0") + except AttributeError: + device = pyudev.Device.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty0") + self.assertTrue(self.matcher.match("tty0", device)) + try: + device = pyudev.Devices.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty1") + except AttributeError: + device = pyudev.Device.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty1") + self.assertFalse(self.matcher.match("tty0", device)) + + def test_regex_search(self): + try: + device = pyudev.Devices.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty0") + except AttributeError: + device = pyudev.Device.from_sys_path(self.udev_context, + "/sys/devices/virtual/tty/tty0") + self.assertTrue(self.matcher.match("tty.", device)) + self.assertFalse(self.matcher.match("tty[1-9]", device)) diff --git a/tests/hardware/test_inventory.py b/tests/hardware/test_inventory.py new file mode 100644 index 0000000..83a02dd --- /dev/null +++ b/tests/hardware/test_inventory.py @@ -0,0 +1,60 @@ +import unittest2 +from flexmock import flexmock +import pyudev + +from tuned.hardware.inventory import Inventory + +subsystem_name = "test subsystem" + +class InventoryTestCase(unittest2.TestCase): + @classmethod + def setUpClass(cls): + cls._context = pyudev.Context() + cls._inventory = Inventory(set_receive_buffer_size=False) + cls._dummy = DummyPlugin() + cls._dummier = DummyPlugin() + + def test_get_device(self): + try: + device1 = pyudev.Devices.from_name(self._context, "tty", "tty0") + except AttributeError: + device1 = pyudev.Device.from_name(self._context, "tty", "tty0") + device2 = self._inventory.get_device("tty", "tty0") + self.assertEqual(device1,device2) + + def test_get_devices(self): + device_list1 = self._context.list_devices(subsystem = "tty") + device_list2 = self._inventory.get_devices("tty") + self.assertItemsEqual(device_list1,device_list2) + + def test_subscribe(self): + self._inventory.subscribe(self._dummy,subsystem_name, + self._dummy.TestCallback) + self._inventory.subscribe(self._dummier,subsystem_name, + self._dummier.TestCallback) + device = flexmock(subsystem = subsystem_name) + self._inventory._handle_udev_event("test event", device) + self.assertTrue(self._dummy.CallbackWasCalled) + self.assertTrue(self._dummier.CallbackWasCalled) + + def test_unsubscribe(self): + self._dummy.CallbackWasCalled = False + self._dummier.CallbackWasCalled = False + self._inventory.unsubscribe(self._dummy) + device = flexmock(subsystem = subsystem_name) + self._inventory._handle_udev_event("test event", device) + self.assertFalse(self._dummy.CallbackWasCalled) + self.assertTrue(self._dummier.CallbackWasCalled) + self._dummier.CallbackWasCalled = False + self._inventory.unsubscribe(self._dummier) + self._inventory._handle_udev_event("test event", device) + self.assertFalse(self._dummy.CallbackWasCalled) + self.assertFalse(self._dummier.CallbackWasCalled) + self.assertIsNone(self._inventory._monitor_observer) + +class DummyPlugin(): + def __init__(self): + self.CallbackWasCalled = False + + def TestCallback(self, event, device): + self.CallbackWasCalled = True diff --git a/tests/monitors/test_base.py b/tests/monitors/test_base.py index eac1d6f..64fd59e 100644 --- a/tests/monitors/test_base.py +++ b/tests/monitors/test_base.py @@ -1,4 +1,4 @@ -import unittest +import unittest2 import tests.globals import tuned.monitors.base @@ -13,7 +13,7 @@ class MockMonitor(tuned.monitors.base.Monitor): cls._load.setdefault(device, 0) cls._load[device] += 1 -class MonitorBaseClassTestCase(unittest.TestCase): +class MonitorBaseClassTestCase(unittest2.TestCase): def test_fail_base_class_init(self): with self.assertRaises(NotImplementedError): tuned.monitors.base.Monitor() diff --git a/tests/plugins/test_base.py b/tests/plugins/test_base.py index 66a71d7..eef4827 100644 --- a/tests/plugins/test_base.py +++ b/tests/plugins/test_base.py @@ -1,122 +1,243 @@ -import unittest -import tests.globals -from flexmock import flexmock -from tuned.plugins.base import Plugin as PluginBase -import tuned.plugins.decorators +from collections import Mapping +import tempfile +import unittest2 +import flexmock + +from tuned.monitors.repository import Repository +import tuned.plugins.decorators as decorators +from tuned.plugins.base import Plugin +import tuned.hardware as hardware +import tuned.monitors as monitors +import tuned.profiles as profiles +import tuned.plugins as plugins +import tuned.consts as consts +from tuned import storage +import tuned.plugins.base + +tuned.plugins.base.log = flexmock.flexmock(info = lambda *args: None,\ + error = lambda *args: None,debug = lambda *args: None,\ + warn = lambda *args: None) + +temp_storage_file = tempfile.TemporaryFile(mode = 'r') +consts.DEFAULT_STORAGE_FILE = temp_storage_file.name +monitors_repository = monitors.Repository() +hardware_inventory = hardware.Inventory(set_receive_buffer_size=False) +device_matcher = hardware.DeviceMatcher() +device_matcher_udev = hardware.DeviceMatcherUdev() +plugin_instance_factory = plugins.instance.Factory() +storage_provider = storage.PickleProvider() +storage_factory = storage.Factory(storage_provider) + +class PluginBaseTestCase(unittest2.TestCase): + def setUp(self): + self._plugin = DummyPlugin(monitors_repository,storage_factory,\ + hardware_inventory,device_matcher,device_matcher_udev,\ + plugin_instance_factory,None,None) + + self._commands_plugin = CommandsPlugin(monitors_repository,\ + storage_factory,hardware_inventory,device_matcher,\ + device_matcher_udev,plugin_instance_factory,None,\ + profiles.variables.Variables()) + + def test_get_effective_options(self): + self.assertEqual(self._plugin._get_effective_options(\ + {'default_option1':'default_value2'}),\ + {'default_option1': 'default_value2',\ + 'default_option2': 'default_value2'}) + + def test_option_bool(self): + self.assertTrue(self._plugin._option_bool(True)) + self.assertTrue(self._plugin._option_bool('true')) + self.assertFalse(self._plugin._option_bool('false')) + + def test_create_instance(self): + instance = self._plugin.create_instance(\ + 'first_instance','test','test','test','test',\ + {'default_option1':'default_value2'}) + self.assertIsNotNone(instance) + + def test_destroy_instance(self): + instance = self._plugin.create_instance(\ + 'first_instance','test','test','test','test',\ + {'default_option1':'default_value2'}) + + self._plugin.destroy_instance(instance) + self.assertIn(instance,self._plugin.cleaned_instances) + + def test_get_matching_devices(self): + """ without udev regex """ + instance = self._plugin.create_instance(\ + 'first_instance','right_device*',None,'test','test',\ + {'default_option1':'default_value2'}) + + self.assertEqual(self._plugin._get_matching_devices(\ + instance,['bad_device','right_device1','right_device2']),\ + set(['right_device1','right_device2'])) + + """ with udev regex """ + instance = self._plugin.create_instance(\ + 'second_instance','right_device*','device[1-2]','test','test',\ + {'default_option1':'default_value2'}) + + device1 = DummyDevice('device1',{'name':'device1'}) + device2 = DummyDevice('device2',{'name':'device2'}) + device3 = DummyDevice('device3',{'name':'device3'}) + + self.assertEqual(self._plugin._get_matching_devices(\ + instance,[device1,device2,device3]),set(['device1','device2'])) + + def test_autoregister_commands(self): + self._commands_plugin._autoregister_commands() + self.assertEqual(self._commands_plugin._commands['size']['set'],\ + self._commands_plugin._set_size) + self.assertEqual(self._commands_plugin._commands['size']['get'],\ + self._commands_plugin._get_size) + self.assertEqual(\ + self._commands_plugin._commands['custom_name']['custom'], + self._commands_plugin.the_most_custom_command) + + def test_check_commands(self): + self._commands_plugin._check_commands() + + with self.assertRaises(TypeError): + bad_plugin = BadCommandsPlugin(monitors_repository,storage_factory,\ + hardware_inventory,device_matcher,device_matcher_udev,\ + plugin_instance_factory,None,None) + + def test_execute_all_non_device_commands(self): + instance = self._commands_plugin.create_instance('test_instance','',\ + '','','',{'size':'XXL'}) + + self._commands_plugin._execute_all_non_device_commands(instance) + + self.assertEqual(self._commands_plugin._size,'XXL') + + def test_execute_all_device_commands(self): + instance = self._commands_plugin.create_instance('test_instance','',\ + '','','',{'device_setting':'010'}) + + device1 = DummyDevice('device1',{}) + device2 = DummyDevice('device2',{}) + + self._commands_plugin._execute_all_device_commands(instance,\ + [device1,device2]) + + self.assertEqual(device1.setting,'010') + self.assertEqual(device2.setting,'010') + + def test_process_assignment_modifiers(self): + self.assertEqual(self._plugin._process_assignment_modifiers('100',None)\ + ,'100') + self.assertEqual(self._plugin._process_assignment_modifiers(\ + '>100','200'),None) + self.assertEqual(self._plugin._process_assignment_modifiers(\ + '<100','200'),'100') + + def test_get_current_value(self): + instance = self._commands_plugin.create_instance('test_instance','',\ + '','','',{}) + + command = [com for com in self._commands_plugin._commands.values()\ + if com['name'] == 'size'][0] + + self.assertEqual(self._commands_plugin._get_current_value(command),'S') + + def test_norm_value(self): + self.assertEqual(self._plugin._norm_value('"000000021"'),'21') + + def test_verify_value(self): + self.assertEqual(self._plugin._verify_value(\ + 'test_value','1',None,True),True) + + self.assertEqual(self._plugin._verify_value(\ + 'test_value','1',None,False),False) + + self.assertEqual(self._plugin._verify_value(\ + 'test_value','00001','001',False),True) + + self.assertEqual(self._plugin._verify_value(\ + 'test_value','0x1a','0x1a',False),True) + + self.assertEqual(self._plugin._verify_value(\ + 'test_value','0x1a','0x1b',False),False) -class MockPlugin(PluginBase): @classmethod - def _get_default_options(cls): - return { 'color': 'blue', 'size': 'XXL' } + def tearDownClass(cls): + temp_storage_file.close() -class InvalidCommandPlugin(MockPlugin): - @tuned.plugins.decorators.command_set('color') - def _set_color(self, new_color): - pass +class DummyPlugin(Plugin): + def __init__(self,*args,**kwargs): + super(DummyPlugin,self).__init__(*args,**kwargs) + self.cleaned_instances = [] -class CommandPlugin(MockPlugin): @classmethod - def tunable_devices(cls): - return ['a', 'b'] + def _get_config_options(self): + return {'default_option1':'default_value1',\ + 'default_option2':'default_value2'} - def _post_init(self): - self._size = 'M' - self._color = { 'a': 'green', 'b': 'pink' } + def _instance_cleanup(self, instance): + self.cleaned_instances.append(instance) - @tuned.plugins.decorators.command_set('size') - def _set_size(self, new_size): + def _get_device_objects(self, devices): + objects = [] + for device in devices: + objects.append({'name':device}) + return devices + +class DummyDevice(Mapping): + def __init__(self,sysname,dictionary,*args,**kwargs): + super(DummyDevice,self).__init__(*args,**kwargs) + self.dictionary = dictionary + self.properties = dictionary + self.sys_name = sysname + self.setting = '101' + + def __getitem__(self,prop): + return self.dictionary.__getitem__(prop) + + def __len__(self): + return self.dictionary.__len__() + + def __iter__(self): + return self.dictionary.__iter__() + +class CommandsPlugin(Plugin): + def __init__(self,*args,**kwargs): + super(CommandsPlugin,self).__init__(*args,**kwargs) + self._size = 'S' + + @classmethod + def _get_config_options(self): + """Default configuration options for the plugin.""" + return {'size':'S','device_setting':'101'} + + @decorators.command_set('size') + def _set_size(self, new_size, sim): self._size = new_size + return new_size - @tuned.plugins.decorators.command_get('size') + @decorators.command_get('size') def _get_size(self): return self._size - @tuned.plugins.decorators.command_set('color', per_device=True) - def _set_color(self, device, new_color): - self._color[device] = new_color + @decorators.command_set('device_setting',per_device = True) + def _set_device_setting(self,value,device,sim): + device.setting = value + return device.setting - @tuned.plugins.decorators.command_get('color') - def _get_color(self, device): - return self._color[device] + @decorators.command_get('device_setting') + def _get_device_setting(self,device,ignore_missing = False): + return device.setting -class PluginBaseClassTestCase(unittest.TestCase): - def setUp(self): - self.storage_factory = flexmock(create = lambda name: None) - self.monitor_repository = None - self.plugin = MockPlugin(self.monitor_repository, self.storage_factory) + @decorators.command_custom('custom_name') + def the_most_custom_command(self): + return True - def test_init(self): - self.storage_factory.should_receive('create').and_return(None).times(2) - plugin = MockPlugin(self.monitor_repository, self.storage_factory, None, None) - plugin = MockPlugin(self.monitor_repository, self.storage_factory) +class BadCommandsPlugin(Plugin): + def __init__(self,*args,**kwargs): + super(BadCommandsPlugin,self).__init__(*args,**kwargs) + self._size = 'S' - def test_cleanup(self): - self.plugin.cleanup() - - def test_update_tuning_not_implemented(self): - with self.assertRaises(NotImplementedError): - self.plugin.update_tuning() - - def test_class_properties(self): - self.assertIs(PluginBase.tunable_devices(), None) - self.assertTrue(PluginBase.is_supported()) - - def test_instance_properties(self): - self.assertTrue(self.plugin.dynamic_tuning) - - def test_merge_unknown_options(self): - plugin1 = PluginBase(self.monitor_repository, self.storage_factory, None, None) - plugin2 = PluginBase(self.monitor_repository, self.storage_factory, None, {}) - plugin3 = PluginBase(self.monitor_repository, self.storage_factory, None, {'unknown': 'test'}) - self.assertDictEqual(plugin1._options, {}) - self.assertDictEqual(plugin2._options, {}) - self.assertDictEqual(plugin3._options, {}) - - def test_merge_known_options(self): - plugin1 = MockPlugin(self.monitor_repository, self.storage_factory, None, None) - plugin2 = MockPlugin(self.monitor_repository, self.storage_factory, None, {'color': 'red'}) - plugin3 = MockPlugin(self.monitor_repository, self.storage_factory, None, {'size': 'S', 'fabric': 'cotton'}) - self.assertDictEqual(plugin1._options, {'size': 'XXL', 'color': 'blue'}) - self.assertDictEqual(plugin2._options, {'size': 'XXL', 'color': 'red'}) - self.assertDictEqual(plugin3._options, {'size': 'S', 'color': 'blue'}) - - def test_classs_with_invalid_commands(self): - with self.assertRaises(TypeError): - plugin = InvalidCommandPlugin(self.monitor_repository, self.storage_factory) - - def test_storage_with_device_independent_commands(self): - storage = flexmock() - storage_factory = flexmock() - storage_factory.should_receive('create').and_return(storage) - - storage.should_receive('set').with_args('size', 'M').once.ordered - storage.should_receive('get').with_args('size').and_return('M').once.ordered - storage.should_receive('unset').with_args('size').once.ordered - - plugin = CommandPlugin(self.monitor_repository, storage_factory, ['b'], {'size': 'XXS', 'color': None}) - plugin.execute_commands() - plugin.cleanup_commands() - - def test_storage_with_per_device_commands(self): - storage = flexmock() - storage_factory = flexmock() - storage_factory.should_receive('create').and_return(storage) - - storage.should_receive('set').with_args('color@b', 'pink').once.ordered - storage.should_receive('get').with_args('color@b').and_return('pink').once.ordered - storage.should_receive('unset').with_args('color@b').once.ordered - - plugin = CommandPlugin(self.monitor_repository, storage_factory, ['b'], {'size': None, 'color': 'white'}) - plugin.execute_commands() - plugin.cleanup_commands() - - def test_exception_with_per_device_commands_when_no_devices_specified(self): - storage = flexmock(set=lambda key: None, get=lambda key, value: None, unset=lambda key: None) - storage_factory = flexmock() - storage_factory.should_receive('create').and_return(storage) - - plugin = CommandPlugin(self.monitor_repository, storage_factory) - with self.assertRaises(TypeError): - plugin.execute_commands() - with self.assertRaises(TypeError): - plugin.cleanup_commands() + @decorators.command_set('size') + def _set_size(self, new_size): + self._size = new_size diff --git a/tests/profiles/test_loader.py b/tests/profiles/test_loader.py index 8187b57..c9c1810 100644 --- a/tests/profiles/test_loader.py +++ b/tests/profiles/test_loader.py @@ -1,111 +1,114 @@ -import unittest +import unittest2 +import flexmock import tempfile import shutil -import os.path -import tuned.profiles.exceptions -from tuned.profiles.loader import Loader -from flexmock import flexmock +import os -class MockProfile(object): - def __init__(self, name, config): - self.name = name - self.options = {} - self.units = {} - self.test_config = config - -class MockProfileFactory(object): - def create(self, name, config): - return MockProfile(name, config) - -class MockProfileMerger(object): - def merge(self, profiles): - new = MockProfile("merged", {}) - new.test_merged = profiles - return new - -class LoaderTestCase(unittest.TestCase): - def setUp(self): - self.factory = MockProfileFactory() - self.merger = MockProfileMerger() - self.loader = Loader(self._tmp_load_dirs, self.factory, self.merger) +import tuned.profiles as profiles +from tuned.profiles.exceptions import InvalidProfileException +class LoaderTestCase(unittest2.TestCase): @classmethod def setUpClass(cls): - tmpdir1 = tempfile.mkdtemp() - tmpdir2 = tempfile.mkdtemp() - cls._tmp_load_dirs = [tmpdir1, tmpdir2] + profiles.loader.log = flexmock.flexmock(info = lambda *args: None,\ + error = lambda *args: None,debug = lambda *args: None,\ + warn = lambda *args: None) + cls._test_dir = tempfile.mkdtemp() + cls._profiles_dir = cls._test_dir + '/test_profiles' + cls._dummy_profile_dir = cls._profiles_dir + '/dummy' + cls._dummy_profile_dir2 = cls._profiles_dir + '/dummy2' + cls._dummy_profile_dir3 = cls._profiles_dir + '/dummy3' + cls._dummy_profile_dir4 = cls._profiles_dir + '/dummy4' + try: + os.mkdir(cls._profiles_dir) + os.mkdir(cls._dummy_profile_dir) + os.mkdir(cls._dummy_profile_dir2) + os.mkdir(cls._dummy_profile_dir3) + os.mkdir(cls._dummy_profile_dir4) + except OSError: + pass - cls._create_profile(tmpdir1, "default", "[main]\n\n[network]\ntype=net\ndevices=em*\n\n[disk]\nenabled=false\n") - cls._create_profile(tmpdir1, "invalid", "INVALID") - cls._create_profile(tmpdir1, "expand", "[expand]\ntype=script\nscript=runme.sh\n") - cls._create_profile(tmpdir2, "empty", "") + with open(cls._dummy_profile_dir + '/tuned.conf','w') as f: + f.write('[main]\nsummary=dummy profile\n') + f.write('[test_unit]\ntest_option=hello\n') + f.write('random_option=random\n') - cls._create_profile(tmpdir1, "custom", "[custom]\ntype=one\n") - cls._create_profile(tmpdir2, "custom", "[custom]\ntype=two\n") + with open(cls._dummy_profile_dir2 + '/tuned.conf','w') as f: + f.write(\ + '[main]\nsummary=second dummy profile\n') + f.write('[test_unit]\ntest_option=hello world\n') + f.write('secondary_option=whatever\n') + + with open(cls._dummy_profile_dir3 + '/tuned.conf','w') as f: + f.write('[main]\nsummary=another profile\ninclude=dummy\n') + f.write('[test_unit]\ntest_option=bye bye\n') + f.write('new_option=add this\n') + + with open(cls._dummy_profile_dir4 + '/tuned.conf','w') as f: + f.write(\ + '[main]\nsummary=dummy profile for configuration read test\n') + f.write('file_path=${i:PROFILE_DIR}/whatever\n') + f.write('script=random_name.sh\n') + f.write('[test_unit]\ntest_option=hello world\n') + + def setUp(self): + locator = profiles.Locator([self._profiles_dir]) + factory = profiles.Factory() + merger = profiles.Merger() + self._loader = profiles.Loader(locator,factory,merger,None,\ + profiles.variables.Variables()) + + def test_safe_name(self): + self.assertFalse(self._loader.safe_name('*')) + self.assertFalse(self._loader.safe_name('$')) + self.assertTrue(self._loader.safe_name('Allowed_ch4rs.-')) + + def test_load_without_include(self): + merged_profile = self._loader.load(['dummy','dummy2']) + + self.assertEqual(merged_profile.name, 'dummy dummy2') + self.assertEqual(merged_profile.options['summary'],\ + 'second dummy profile') + self.assertEqual(merged_profile.units['test_unit'].\ + options['test_option'],'hello world') + self.assertEqual(merged_profile.units['test_unit'].\ + options['secondary_option'],'whatever') + + with self.assertRaises(InvalidProfileException): + self._loader.load([]) + + with self.assertRaises(InvalidProfileException): + self._loader.load(['invalid']) + + def test_load_with_include(self): + merged_profile = self._loader.load(['dummy3']) + + self.assertEqual(merged_profile.name,'dummy3') + self.assertEqual(merged_profile.options['summary'],'another profile') + self.assertEqual(merged_profile.units['test_unit'].\ + options['test_option'],'bye bye') + self.assertEqual(merged_profile.units['test_unit'].\ + options['new_option'],'add this') + self.assertEqual(merged_profile.units['test_unit'].\ + options['random_option'],'random') + + def test_expand_profile_dir(self): + self.assertEqual(self._loader._expand_profile_dir(\ + '/hello/world','${i:PROFILE_DIR}/file'),'/hello/world/file') + + def test_load_config_data(self): + config = self._loader._load_config_data(\ + self._dummy_profile_dir4 + '/tuned.conf') + + self.assertEqual(config['main']['script'][0],\ + self._dummy_profile_dir4 + '/random_name.sh') + + self.assertEqual(config['main']['file_path'],\ + self._dummy_profile_dir4 + '/whatever') + + self.assertEqual(config['test_unit']['test_option'],\ + 'hello world') @classmethod def tearDownClass(cls): - for tmp_dir in cls._tmp_load_dirs: - shutil.rmtree(tmp_dir, True) - - @classmethod - def _create_profile(cls, load_dir, profile_name, tuned_conf_content): - profile_dir = os.path.join(load_dir, profile_name) - conf_name = os.path.join(profile_dir, "tuned.conf") - os.mkdir(profile_dir) - with open(conf_name, "w") as conf_file: - conf_file.write(tuned_conf_content) - - def test_init(self): - Loader([], None, None) - Loader(["/tmp"], None, None) - Loader(["/foo", "/bar"], None, None) - - def test_init_wrong_type(self): - with self.assertRaises(TypeError): - Loader(False, self.factory, self.merger) - - def test_load(self): - profile = self.loader.load("default") - self.assertIn("main", profile.test_config) - self.assertIn("disk", profile.test_config) - self.assertEqual(profile.test_config["network"]["devices"], "em*") - - def test_load_empty(self): - profile = self.loader.load("empty") - self.assertDictEqual(profile.test_config, {}) - - def test_load_invalid(self): - with self.assertRaises(tuned.profiles.exceptions.InvalidProfileException): - invalid_config = self.loader.load("invalid") - - def test_load_nonexistent(self): - with self.assertRaises(tuned.profiles.exceptions.InvalidProfileException): - config = self.loader.load("nonexistent") - - def test_load_order(self): - profile = self.loader.load("custom") - self.assertEqual(profile.test_config["custom"]["type"], "two") - - def test_default_load(self): - profile = self.loader.load("empty") - self.assertIs(type(profile), MockProfile) - - def test_script_expand_names(self): - profile = self.loader.load("expand") - expected_name = os.path.join(self._tmp_load_dirs[0], "expand", "runme.sh") - self.assertEqual(profile.test_config["expand"]["script"], expected_name) - - def test_load_multiple_profiles(self): - profile = self.loader.load(["default", "expand"]) - self.assertEqual(len(profile.test_merged), 2) - - def test_include_directive(self): - profile1 = MockProfile("first", {}) - profile1.options = {"include": "default"} - profile2 = MockProfile("second", {}) - - flexmock(self.factory).should_receive("create").and_return(profile1).and_return(profile2).twice() - profile = self.loader.load("empty") - - self.assertEqual(len(profile.test_merged), 2) + shutil.rmtree(cls._test_dir) diff --git a/tests/profiles/test_locator.py b/tests/profiles/test_locator.py index 741abdc..6ab7c5e 100644 --- a/tests/profiles/test_locator.py +++ b/tests/profiles/test_locator.py @@ -1,10 +1,10 @@ -import unittest +import unittest2 import os import shutil import tempfile from tuned.profiles.locator import Locator -class LocatorTestCase(unittest.TestCase): +class LocatorTestCase(unittest2.TestCase): def setUp(self): self.locator = Locator(self._tmp_load_dirs) diff --git a/tests/profiles/test_merger.py b/tests/profiles/test_merger.py index 8e53745..6023b26 100644 --- a/tests/profiles/test_merger.py +++ b/tests/profiles/test_merger.py @@ -1,49 +1,62 @@ -import unittest +import unittest2 from tuned.profiles.merger import Merger +from tuned.profiles.profile import Profile from collections import OrderedDict -class MergerTestCase(unittest.TestCase): +class MergerTestCase(unittest2.TestCase): def test_merge_without_replace(self): merger = Merger() config1 = OrderedDict([ - ("main", OrderedDict()), - ("net", { "devices": "em0", "custom": "option"}), + ("main", {"test_option" : "test_value1"}), + ("net", { "devices": "em0", "custom": "custom_value"}), ]) + profile1 = Profile('test_profile1',config1) config2 = OrderedDict([ - ("main", OrderedDict()), - ("net", { "devices": "em1" }), + ('main', {'test_option' : 'test_value2'}), + ('net', { 'devices': 'em1' }), ]) - config = merger.merge([config1, config2]) + profile2 = Profile("test_profile2",config2) - self.assertIn("main", config) - self.assertIn("net", config) - self.assertEqual(config["net"]["custom"], "option") - self.assertEqual(config["net"]["devices"], "em1") + merged_profile = merger.merge([profile1, profile2]) + + self.assertEqual(merged_profile.options["test_option"],"test_value2") + self.assertIn("net", merged_profile.units) + self.assertEqual(merged_profile.units["net"].options["custom"],\ + "custom_value") + self.assertEqual(merged_profile.units["net"].devices, "em1") def test_merge_with_replace(self): merger = Merger() config1 = OrderedDict([ - ("main", OrderedDict()), + ("main", {"test_option" : "test_value1"}), ("net", { "devices": "em0", "custom": "option"}), ]) + profile1 = Profile('test_profile1',config1) config2 = OrderedDict([ - ("main", OrderedDict()), + ("main", {"test_option" : "test_value2"}), ("net", { "devices": "em1", "replace": True }), ]) - config = merger.merge([config1, config2]) + profile2 = Profile('test_profile2',config2) + merged_profile = merger.merge([profile1, profile2]) - self.assertIn("main", config) - self.assertIn("net", config) - self.assertNotIn("custom", config["net"]) - self.assertEqual(config["net"]["devices"], "em1") + self.assertEqual(merged_profile.options["test_option"],"test_value2") + self.assertIn("net", merged_profile.units) + self.assertNotIn("custom", merged_profile.units["net"].options) + self.assertEqual(merged_profile.units["net"].devices, "em1") def test_merge_multiple_order(self): merger = Merger() - config1 = OrderedDict([ ("main", OrderedDict()), ("net", { "devices": "em0" }) ]) - config2 = OrderedDict([ ("main", OrderedDict()), ("net", { "devices": "em1" }) ]) - config3 = OrderedDict([ ("main", OrderedDict()), ("net", { "devices": "em2" }) ]) - config = merger.merge([config1, config2, config3]) + config1 = OrderedDict([ ("main", {"test_option" : "test_value1"}),\ + ("net", { "devices": "em0" }) ]) + profile1 = Profile('test_profile1',config1) + config2 = OrderedDict([ ("main", {"test_option" : "test_value2"}),\ + ("net", { "devices": "em1" }) ]) + profile2 = Profile('test_profile2',config2) + config3 = OrderedDict([ ("main", {"test_option" : "test_value3"}),\ + ("net", { "devices": "em2" }) ]) + profile3 = Profile('test_profile3',config3) + merged_profile = merger.merge([profile1, profile2, profile3]) - self.assertIn("main", config) - self.assertIn("net", config) - self.assertEqual(config["net"]["devices"], "em2") + self.assertEqual(merged_profile.options["test_option"],"test_value3") + self.assertIn("net", merged_profile.units) + self.assertEqual(merged_profile.units["net"].devices, "em2") diff --git a/tests/profiles/test_profile.py b/tests/profiles/test_profile.py index 665642b..8f43e3d 100644 --- a/tests/profiles/test_profile.py +++ b/tests/profiles/test_profile.py @@ -1,4 +1,4 @@ -import unittest +import unittest2 import tuned.profiles import collections @@ -6,7 +6,7 @@ class MockProfile(tuned.profiles.profile.Profile): def _create_unit(self, name, config): return (name, config) -class ProfileTestCase(unittest.TestCase): +class ProfileTestCase(unittest2.TestCase): def test_init(self): MockProfile("test", {}) @@ -20,7 +20,7 @@ class ProfileTestCase(unittest.TestCase): self.assertIs(type(profile.units), collections.OrderedDict) self.assertEqual(len(profile.units), 2) - self.assertListEqual(sorted([name_config[0] for name_config in profile.units]), sorted(["network", "storage"])) + self.assertListEqual(sorted([name_config for name_config in profile.units]), sorted(["network", "storage"])) def test_create_units_empty(self): profile = MockProfile("test", {"main":{}}) diff --git a/tests/profiles/test_unit.py b/tests/profiles/test_unit.py index d63ff0c..34bfd0a 100644 --- a/tests/profiles/test_unit.py +++ b/tests/profiles/test_unit.py @@ -1,7 +1,7 @@ -import unittest +import unittest2 from tuned.profiles import Unit -class UnitTestCase(unittest.TestCase): +class UnitTestCase(unittest2.TestCase): def test_default_options(self): unit = Unit("sample", {}) diff --git a/tests/storage/test_pickle_provider.py b/tests/storage/test_pickle_provider.py index e04ab5a..9a2fba2 100644 --- a/tests/storage/test_pickle_provider.py +++ b/tests/storage/test_pickle_provider.py @@ -1,7 +1,12 @@ import unittest import os.path import tempfile + import tuned.storage +import tuned.consts as consts + +temp_storage_file = tempfile.TemporaryFile(mode='r') +consts.DEFAULT_STORAGE_FILE = temp_storage_file.name class StoragePickleProviderTestCase(unittest.TestCase): def setUp(self): @@ -17,7 +22,7 @@ class StoragePickleProviderTestCase(unittest.TestCase): self.assertEqual(self._temp_filename, provider._path) provider = tuned.storage.PickleProvider() - self.assertEqual("/run/tuned/save.pickle", provider._path) + self.assertEqual(temp_storage_file.name, provider._path) def test_memory_persistence(self): provider = tuned.storage.PickleProvider(self._temp_filename) @@ -66,3 +71,7 @@ class StoragePickleProviderTestCase(unittest.TestCase): provider.load() self.assertIsNone(provider.get("ns1", "opt1")) self.assertIsNone(provider.get("ns2", "opt2")) + + @classmethod + def tearDownClass(cls): + temp_storage_file.close() diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/utils/test_commands.py b/tests/utils/test_commands.py new file mode 100644 index 0000000..324b96c --- /dev/null +++ b/tests/utils/test_commands.py @@ -0,0 +1,244 @@ +import unittest2 +import tempfile +import flexmock +import shutil +import re +import os + +from tuned.utils.commands import commands +import tuned.consts as consts +from tuned.exceptions import TunedException +import tuned.utils.commands + +tuned.utils.commands.log = flexmock.flexmock(info = lambda *args: None,\ + error = lambda *args: None,debug = lambda *args: None,\ + warn = lambda *args: None) + +class CommandsTestCase(unittest2.TestCase): + def setUp(self): + self._commands = commands() + self._test_dir = tempfile.mkdtemp() + self._test_file = tempfile.NamedTemporaryFile(mode='r',dir = self._test_dir) + + def test_get_bool(self): + positive_values = ['y','yes','t','true'] + negative_values = ['n','no','f','false'] + + for val in positive_values: + self.assertEqual(self._commands.get_bool(val),"1") + + for val in negative_values: + self.assertEqual(self._commands.get_bool(val),"0") + + self.assertEqual(self._commands.get_bool('bad_value'),'bad_value') + + def test_remove_ws(self): + self.assertEqual(self._commands.remove_ws(' a bc '),'a bc') + + def test_unquote(self): + self.assertEqual(self._commands.unquote('"whatever"'),'whatever') + + def test_escape(self): + self.assertEqual(self._commands.escape('\\'),'\\\\') + + def test_unescape(self): + self.assertEqual(self._commands.unescape('\\'),'') + + def test_align_str(self): + self.assertEqual(self._commands.align_str('abc',5,'def'),'abc def') + + def test_dict2list(self): + dictionary = {'key1':1,'key2':2,'key3':3} + self.assertEqual(self._commands.dict2list(dictionary)\ + ,['key1',1,'key2',2,'key3',3]) + + def test_re_lookup_compile(self): + pattern = re.compile(r'([1-9])') + dictionary = {'[1-9]':''} + self.assertEqual(self._commands.re_lookup_compile(dictionary).pattern\ + ,pattern.pattern) + self.assertIsNone(self._commands.re_lookup_compile(None)) + + def test_multiple_re_replace(self): + text = 'abcd1234' + dictionary = {'abc':'gfh'} + pattern = self._commands.re_lookup_compile(dictionary) + self.assertEqual(self._commands.multiple_re_replace(dictionary,text)\ + ,'gfhd1234') + self.assertEqual(self._commands.multiple_re_replace(\ + dictionary,text,pattern),'gfhd1234') + + def test_re_lookup(self): + dictionary = {'abc':'abc','mno':'mno'} + text1 = 'abc def' + text2 = 'jkl mno' + text12 = 'abc mno' + text3 = 'whatever' + self.assertEqual(self._commands.re_lookup(dictionary,text1),'abc') + self.assertEqual(self._commands.re_lookup(dictionary,text2),'mno') + self.assertEqual(self._commands.re_lookup(dictionary,text12),'abc') + self.assertIsNone(self._commands.re_lookup(dictionary,text3),None) + + def test_write_to_file(self): + self.assertTrue(self._commands.write_to_file(self._test_file.name,\ + 'hello world')) + with open(self._test_file.name,'r') as f: + self.assertEqual(f.read(),'hello world') + + self.assertTrue(self._commands.write_to_file(self._test_file.name,\ + 'world hello')) + with open(self._test_file.name,'r') as f: + self.assertEqual(f.read(),'world hello') + + local_test_file = self._test_dir + '/dir' +'/self._test_file' + self.assertTrue(self._commands.write_to_file(local_test_file,\ + 'hello world',True)) + with open(local_test_file,'r') as f: + self.assertEqual(f.read(),'hello world') + + shutil.rmtree(os.path.dirname(local_test_file)) + + self.assertFalse(self._commands.write_to_file(local_test_file,\ + 'hello world')) + + def test_read_file(self): + with open(self._test_file.name,'w') as f: + f.write('hello world') + self.assertEqual(self._commands.read_file(self._test_file.name),\ + 'hello world') + self.assertEqual(self._commands.read_file('/bad_name','error'),\ + 'error') + + def test_rmtree(self): + test_tree = self._test_dir + '/one/two' + os.makedirs(test_tree) + test_tree = self._test_dir + '/one' + self.assertTrue(self._commands.rmtree(test_tree)) + self.assertFalse(os.path.isdir(test_tree)) + self.assertTrue(self._commands.rmtree(test_tree)) + + def test_unlink(self): + local_test_file = self._test_dir + 'file_to_delete' + open(local_test_file,'w').close() + self.assertTrue(os.path.exists(local_test_file)) + self.assertTrue(self._commands.unlink(local_test_file)) + self.assertFalse(os.path.exists(local_test_file)) + self.assertTrue(self._commands.unlink(local_test_file)) + + def test_rename(self): + rename_test_file = self._test_dir + '/bad_name' + open(rename_test_file,'w').close() + self.assertTrue(self._commands.rename(rename_test_file,\ + self._test_dir + '/right_name')) + self.assertTrue(os.path.exists(self._test_dir + '/right_name')) + os.remove(self._test_dir + '/right_name') + + def test_copy(self): + copy_test_file = self._test_dir + '/origo' + with open(copy_test_file,'w') as f: + f.write('hello world') + self.assertTrue(self._commands.copy(copy_test_file,\ + self._test_dir + '/copy')) + self.assertTrue(os.path.exists(self._test_dir + '/copy')) + self.assertTrue(os.path.exists(self._test_dir + '/origo')) + with open(self._test_dir + '/copy','r') as f: + self.assertEqual(f.read(),'hello world') + os.remove(self._test_dir + '/origo') + os.remove(self._test_dir + '/copy') + + def test_replace_in_file(self): + with open(self._test_file.name,'w') as f: + f.write('hello world') + + self.assertTrue(self._commands.replace_in_file(self._test_file.name,\ + 'hello','bye')) + with open(self._test_file.name,'r') as f: + self.assertEqual(f.read(),'bye world') + + def test_multiple_replace_in_file(self): + dictionary = {'abc':'123','ghi':'456'} + + with open(self._test_file.name,'w') as f: + f.write('abc def ghi') + + self.assertTrue(self._commands.multiple_replace_in_file(\ + self._test_file.name,dictionary)) + with open(self._test_file.name,'r') as f: + self.assertEqual(f.read(),'123 def 456') + + def test_add_modify_option_in_file(self): + with open(self._test_file.name,'w') as f: + f.write('option1="123"\noption2="456"\n') + + dictionary = {'option3':789,'option1':321} + self.assertTrue(self._commands.add_modify_option_in_file(\ + self._test_file.name,dictionary)) + with open(self._test_file.name,'r') as f: + self.assertEqual(f.read(),\ + 'option1="321"\noption2="456"\noption3="789"\n') + + def test_get_active_option(self): + self.assertEqual(self._commands.get_active_option('opt1 [opt2] opt3'),\ + 'opt2') + self.assertEqual(self._commands.get_active_option('opt1 opt2 opt3'),\ + 'opt1') + self.assertEqual(self._commands.get_active_option(\ + 'opt1 opt2 opt3',False),'opt1 opt2 opt3') + + def test_hex2cpulist(self): + self.assertEqual(self._commands.hex2cpulist('0xf'),[0,1,2,3]) + self.assertEqual(self._commands.hex2cpulist('0x1,0000,0001'),[0,32]) + + def test_cpulist_unpack(self): + cpus = '4-8,^6,0xf00,,' + self.assertEqual(self._commands.cpulist_unpack(cpus),[4,5,7,8,9,10,11]) + + def test_cpulist_pack(self): + self.assertEqual(self._commands.cpulist_pack([0,1,3,4,5,6,8,9,32]),\ + ['0-1','3-6','8-9','32']) + + def test_cpulist2hex(self): + self.assertEqual(self._commands.cpulist2hex('1-3,5,32'),\ + '00000001,0000002e') + + def test_cpulist2bitmask(self): + self.assertEqual(self._commands.cpulist2bitmask([1,2,3]),0b1110) + self.assertEqual(self._commands.cpulist2bitmask([2,4,6]),0b1010100) + + def test_get_size(self): + self.assertEqual(self._commands.get_size('100KB'),102400) + self.assertEqual(self._commands.get_size('100Kb'),102400) + self.assertEqual(self._commands.get_size('100kb'),102400) + self.assertEqual(self._commands.get_size('1MB'),1024 * 1024) + self.assertEqual(self._commands.get_size('1GB'),1024 * 1024 * 1024) + + def test_get_active_profile(self): + consts.ACTIVE_PROFILE_FILE = self._test_dir + '/active_profile' + consts.PROFILE_MODE_FILE = self._test_dir + '/profile_mode' + with open(consts.ACTIVE_PROFILE_FILE,'w') as f: + f.write('test_profile') + with open(consts.PROFILE_MODE_FILE,'w') as f: + f.write('auto') + (profile,mode) = self._commands.get_active_profile() + self.assertEqual(profile,'test_profile') + self.assertEqual(mode,False) + os.remove(consts.ACTIVE_PROFILE_FILE) + os.remove(consts.PROFILE_MODE_FILE) + (profile,mode) = self._commands.get_active_profile() + self.assertEqual(profile,None) + self.assertEqual(mode,None) + + def test_save_active_profile(self): + consts.ACTIVE_PROFILE_FILE = self._test_dir + '/active_profile' + consts.PROFILE_MODE_FILE = self._test_dir + '/profile_mode' + self._commands.save_active_profile('test_profile',False) + with open(consts.ACTIVE_PROFILE_FILE) as f: + self.assertEqual(f.read(),'test_profile\n') + with open(consts.PROFILE_MODE_FILE) as f: + self.assertEqual(f.read(),'auto\n') + os.remove(consts.ACTIVE_PROFILE_FILE) + os.remove(consts.PROFILE_MODE_FILE) + + def tearDown(self): + self._test_file.close() + shutil.rmtree(self._test_dir) diff --git a/tests/utils/test_global_config.py b/tests/utils/test_global_config.py new file mode 100644 index 0000000..d6e9d5e --- /dev/null +++ b/tests/utils/test_global_config.py @@ -0,0 +1,42 @@ +import unittest2 +import flexmock +import tempfile +import shutil +import os + +import tuned.consts as consts +import tuned.utils.global_config as global_config + +class GlobalConfigTestCase(unittest2.TestCase): + @classmethod + def setUpClass(cls): + global_config.log = flexmock.flexmock(info = lambda *args: None,\ + error = lambda *args: None,debug = lambda *args: None,\ + warn = lambda *args: None) + + cls.test_dir = tempfile.mkdtemp() + with open(cls.test_dir + '/test_config','w') as f: + f.write('test_option = hello\ntest_bool = 1\ntest_size = 12MB\n'\ + + 'false_bool=0\n') + + cls._global_config = global_config.GlobalConfig(\ + cls.test_dir + '/test_config') + + def test_get(self): + self.assertEqual(self._global_config.get('test_option'), 'hello') + + def test_get_bool(self): + self.assertTrue(self._global_config.get_bool('test_bool')) + self.assertFalse(self._global_config.get_bool('false_bool')) + + def test_get_size(self): + self.assertEqual(self._global_config.get_size('test_size'),\ + 12*1024*1024) + + self._global_config.set('test_size','bad_value') + + self.assertIsNone(self._global_config.get_size('test_size')) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.test_dir) diff --git a/tuned/admin/admin.py b/tuned/admin/admin.py index 3f84413..22ffcde 100644 --- a/tuned/admin/admin.py +++ b/tuned/admin/admin.py @@ -73,7 +73,7 @@ class Admin(object): action = getattr(self, "_action_" + action_name) except AttributeError as e: if not self._dbus: - self._error(e + ", action '%s' is not implemented" % action_name) + self._error(str(e) + ", action '%s' is not implemented" % action_name) return False if self._dbus: try: diff --git a/tuned/hardware/device_matcher_udev.py b/tuned/hardware/device_matcher_udev.py index a35c8c4..e690d5b 100644 --- a/tuned/hardware/device_matcher_udev.py +++ b/tuned/hardware/device_matcher_udev.py @@ -12,7 +12,13 @@ class DeviceMatcherUdev(device_matcher.DeviceMatcher): """ properties = '' - for key, val in list(device.items()): + + try: + items = device.properties.items() + except AttributeError: + items = device.items() + + for key, val in list(items): properties += key + '=' + val + '\n' return re.search(regex, properties, re.MULTILINE) is not None diff --git a/tuned/hardware/inventory.py b/tuned/hardware/inventory.py index 2293baa..07cdedd 100644 --- a/tuned/hardware/inventory.py +++ b/tuned/hardware/inventory.py @@ -12,7 +12,7 @@ class Inventory(object): about related hardware events. """ - def __init__(self, udev_context=None, udev_monitor_cls=None, monitor_observer_factory=None, buffer_size=None): + def __init__(self, udev_context=None, udev_monitor_cls=None, monitor_observer_factory=None, buffer_size=None, set_receive_buffer_size=True): if udev_context is not None: self._udev_context = udev_context else: @@ -23,7 +23,9 @@ class Inventory(object): self._udev_monitor = udev_monitor_cls.from_netlink(self._udev_context) if buffer_size is None: buffer_size = consts.CFG_DEF_UDEV_BUFFER_SIZE - self._udev_monitor.set_receive_buffer_size(buffer_size) + + if (set_receive_buffer_size): + self._udev_monitor.set_receive_buffer_size(buffer_size) if monitor_observer_factory is None: monitor_observer_factory = _MonitorObserverFactory() diff --git a/tuned/storage/pickle_provider.py b/tuned/storage/pickle_provider.py index 832a9f8..771704d 100644 --- a/tuned/storage/pickle_provider.py +++ b/tuned/storage/pickle_provider.py @@ -31,14 +31,14 @@ class PickleProvider(interfaces.Provider): def save(self): try: log.debug("Saving %s" % str(self._data)) - with open(self._path, "w") as f: + with open(self._path, "wb") as f: pickle.dump(self._data, f) except (OSError, IOError) as e: log.error("Error saving storage file '%s': %s" % (self._path, e)) def load(self): try: - with open(self._path, "r") as f: + with open(self._path, "rb") as f: self._data = pickle.load(f) except (OSError, IOError) as e: log.debug("Error loading storage file '%s': %s" % (self._path, e)) diff --git a/tuned/utils/global_config.py b/tuned/utils/global_config.py index a72d80f..cea7b98 100644 --- a/tuned/utils/global_config.py +++ b/tuned/utils/global_config.py @@ -16,9 +16,9 @@ class GlobalConfig(): "update_interval = integer(default=%s)" % consts.CFG_DEF_UPDATE_INTERVAL, "recommend_command = boolean(default=%s)" % consts.CFG_DEF_RECOMMEND_COMMAND] - def __init__(self): + def __init__(self,config_file = consts.GLOBAL_CONFIG_FILE): self._cfg = {} - self.load_config() + self.load_config(file_name=config_file) self._cmd = commands() def load_config(self, file_name = consts.GLOBAL_CONFIG_FILE):