From cebd0d7ad54995c37f68586a14540ad64d99d762 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 31 Oct 2012 11:46:51 -0400 Subject: fixed unit tests --- src/lib/Bcfg2/Server/Plugin/helpers.py | 12 ++-- src/lib/Bcfg2/Server/Plugins/Bundler.py | 34 +++++------ src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 2 +- src/lib/Bcfg2/Server/Plugins/__init__.py | 1 + src/lib/Bcfg2/Server/models.py | 14 ++++- .../Testlib/TestServer/TestPlugin/Testhelpers.py | 54 +++++++--------- .../Testlib/TestServer/TestPlugins/TestMetadata.py | 71 ++++++++++++---------- .../Testlib/TestServer/TestPlugins/TestProbes.py | 13 +--- 8 files changed, 102 insertions(+), 99 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py index 674aa5ffd..6ad18fa43 100644 --- a/src/lib/Bcfg2/Server/Plugin/helpers.py +++ b/src/lib/Bcfg2/Server/Plugin/helpers.py @@ -11,8 +11,8 @@ import lxml.etree import Bcfg2.Server import Bcfg2.Options import Bcfg2.Statistics +import Bcfg2.Server.FileMonitor from Bcfg2.Compat import CmpMixin, wraps -from Bcfg2.Server.FileMonitor import get_fam from Bcfg2.Server.Plugin.base import Debuggable, Plugin from Bcfg2.Server.Plugin.interfaces import Generator from Bcfg2.Server.Plugin.exceptions import SpecificityError, \ @@ -208,7 +208,7 @@ class FileBacked(object): self.name = name #: The FAM object used to receive notifications of changes - self.fam = get_fam() + self.fam = Bcfg2.Server.FileMonitor.get_fam() def HandleEvent(self, event=None): """ HandleEvent is called whenever the FAM registers an event. @@ -273,7 +273,7 @@ class DirectoryBacked(object): object.__init__(self) self.data = os.path.normpath(data) - self.fam = get_fam() + self.fam = Bcfg2.Server.FileMonitor.get_fam() #: self.entries contains information about the files monitored #: by this object. The keys of the dict are the relative @@ -809,8 +809,8 @@ class XMLSrc(XMLFileBacked): __cacheobj__ = dict __priority_required__ = True - def __init__(self, filename, fam=None, should_monitor=False): - XMLFileBacked.__init__(self, filename, fam, should_monitor) + def __init__(self, filename, should_monitor=False): + XMLFileBacked.__init__(self, filename, should_monitor) self.items = {} self.cache = None self.pnode = None @@ -1469,7 +1469,7 @@ class GroupSpool(Plugin, Generator): if self.data[-1] == '/': self.data = self.data[:-1] - self.fam = get_fam() + self.fam = Bcfg2.Server.FileMonitor.get_fam() #: See :class:`Bcfg2.Server.Plugins.interfaces.Generator` for #: details on the Entries attribute. diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py index 9c6c7946d..fa993cd85 100644 --- a/src/lib/Bcfg2/Server/Plugins/Bundler.py +++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py @@ -14,8 +14,7 @@ from Bcfg2.Options import get_option_parser try: import genshi.core import genshi.input - from genshi.template import TemplateLoader, \ - TextTemplate, MarkupTemplate, TemplateError + from genshi.template import TemplateLoader, MarkupTemplate, TemplateError HAS_GENSHI = True except ImportError: HAS_GENSHI = False @@ -55,6 +54,7 @@ if HAS_GENSHI: Bcfg2.Server.Plugin.StructFile.__init__(self, name) self.encoding = encoding self.logger = logging.getLogger(name) + self.template = None def HandleEvent(self, event=None): """Handle all fs events for this template.""" @@ -62,22 +62,20 @@ if HAS_GENSHI: return try: loader = TemplateLoader() - try: - self.template = loader.load(self.name, - cls=MarkupTemplate, - encoding=self.encoding) - except LookupError: - err = sys.exc_info()[1] - self.logger.error('Genshi lookup error in %s: %s' % - (self.name, err)) - except TemplateError: - err = sys.exc_info()[1] - self.logger.error('Genshi template error in %s: %s' % - (self.name, err)) - except genshi.input.ParseError: - err = sys.exc_info()[1] - self.logger.error('Genshi parse error in %s: %s' % - (self.name, err)) + self.template = loader.load(self.name, cls=MarkupTemplate, + encoding=self.encoding) + except LookupError: + err = sys.exc_info()[1] + self.logger.error('Genshi lookup error in %s: %s' % + (self.name, err)) + except TemplateError: + err = sys.exc_info()[1] + self.logger.error('Genshi template error in %s: %s' % + (self.name, err)) + except genshi.input.ParseError: + err = sys.exc_info()[1] + self.logger.error('Genshi parse error in %s: %s' % + (self.name, err)) def get_xml_value(self, metadata): """ get the rendered XML data that applies to the given diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 17aff900b..859a0657f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -193,7 +193,7 @@ class PulpCertificateSet(Bcfg2.Server.Plugin.EntrySet): important='true', sensitive='true', paranoid=self.metadata['paranoid']) - self.fam = Bcfg2.Server.FileMonitor.get_fam(). + self.fam = Bcfg2.Server.FileMonitor.get_fam() self.fam.AddMonitor(path, self) def HandleEvent(self, event): diff --git a/src/lib/Bcfg2/Server/Plugins/__init__.py b/src/lib/Bcfg2/Server/Plugins/__init__.py index e69de29bb..1f85702f0 100644 --- a/src/lib/Bcfg2/Server/Plugins/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/__init__.py @@ -0,0 +1 @@ +""" Bcfg2 Plugins """ diff --git a/src/lib/Bcfg2/Server/models.py b/src/lib/Bcfg2/Server/models.py index 4ac2be43b..11d85c248 100644 --- a/src/lib/Bcfg2/Server/models.py +++ b/src/lib/Bcfg2/Server/models.py @@ -5,6 +5,7 @@ import copy import logging import Bcfg2.Options import Bcfg2.Server.Plugins +from Bcfg2.Compat import walk_packages from django.db import models LOGGER = logging.getLogger('Bcfg2.Server.models') @@ -21,7 +22,18 @@ def load_models(plugins=None, cfile='/etc/bcfg2.conf', quiet=True): # namely, _all_ plugins, so that the database is guaranteed to # work, even if /etc/bcfg2.conf isn't set up properly plugin_opt = copy.deepcopy(Bcfg2.Options.SERVER_PLUGINS) - plugin_opt.default = Bcfg2.Server.Plugins.__all__ + all_plugins = [] + for submodule in walk_packages(path=Bcfg2.Server.Plugins.__path__, + prefix="Bcfg2.Server.Plugins."): + module = submodule[1].rsplit('.', 1)[-1] + if submodule[1] == "Bcfg2.Server.Plugins.%s" % module: + # we only include direct children of + # Bcfg2.Server.Plugins -- e.g., all_plugins should + # include Bcfg2.Server.Plugins.Cfg, but not + # Bcfg2.Server.Plugins.Cfg.CfgInfoXML + all_plugins.append(module) + plugin_opt.default = all_plugins + setup = Bcfg2.Options.get_option_parser() setup.add_option("plugins", plugin_opt) setup.add_option("configfile", Bcfg2.Options.CFILE) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py index 290bd7d5c..7845d5926 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py @@ -114,10 +114,10 @@ class TestFileBacked(Bcfg2TestCase): test_obj = FileBacked path = os.path.join(datastore, "test") - def get_obj(self, path=None, fam=None): + def get_obj(self, path=None): if path is None: path = self.path - return self.test_obj(path, fam=fam) + return self.test_obj(path) @patch("%s.open" % builtins) def test_HandleEvent(self, mock_open): @@ -163,24 +163,20 @@ class TestDirectoryBacked(Bcfg2TestCase): """ ensure that the child object has the correct interface """ self.assertTrue(hasattr(self.test_obj.__child__, "HandleEvent")) - def get_obj(self, fam=None): - if fam is None: - fam = Mock() - + def get_obj(self): @patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__, self.test_obj.__name__), Mock()) def inner(): return self.test_obj(os.path.join(datastore, - self.test_obj.__name__), - fam) + self.test_obj.__name__)) return inner() def test__init(self): @patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__, self.test_obj.__name__)) def inner(mock_add_monitor): - db = self.test_obj(datastore, Mock()) + db = self.test_obj(datastore) mock_add_monitor.assert_called_with('') inner() @@ -249,10 +245,9 @@ class TestDirectoryBacked(Bcfg2TestCase): db.fam = Mock() class MockChild(Mock): - def __init__(self, path, fam, **kwargs): + def __init__(self, path, **kwargs): Mock.__init__(self, **kwargs) self.path = path - self.fam = fam self.HandleEvent = Mock() db.__child__ = MockChild @@ -262,7 +257,6 @@ class TestDirectoryBacked(Bcfg2TestCase): self.assertIn(path, db.entries) self.assertEqual(db.entries[path].path, os.path.join(db.data, path)) - self.assertEqual(db.entries[path].fam, db.fam) db.entries[path].HandleEvent.assert_called_with(event) @patch("os.path.isdir") @@ -400,27 +394,27 @@ class TestXMLFileBacked(TestFileBacked): should_monitor = None path = os.path.join(datastore, "test", "test1.xml") - def get_obj(self, path=None, fam=None, should_monitor=False): + def get_obj(self, path=None, should_monitor=False): if path is None: path = self.path - return self.test_obj(path, fam=fam, should_monitor=should_monitor) + return self.test_obj(path, should_monitor=should_monitor) - def test__init(self): - fam = Mock() + @patch("Bcfg2.Server.FileMonitor.get_fam") + def test__init(self, mock_get_fam): xfb = self.get_obj() if self.should_monitor is True: - self.assertIsNotNone(xfb.fam) + self.assertEqual(xfb.fam, mock_get_fam.return_value) else: self.assertIsNone(xfb.fam) if self.should_monitor is not True: - xfb = self.get_obj(fam=fam) - self.assertFalse(fam.AddMonitor.called) + xfb = self.get_obj() + self.assertFalse(xfb.fam.AddMonitor.called) if self.should_monitor is not False: fam.reset_mock() - xfb = self.get_obj(fam=fam, should_monitor=True) - fam.AddMonitor.assert_called_with(self.path, xfb) + xfb = self.get_obj(should_monitor=True) + xfb.fam.AddMonitor.assert_called_with(self.path, xfb) @patch("os.path.exists") @patch("lxml.etree.parse") @@ -568,6 +562,7 @@ class TestXMLFileBacked(TestFileBacked): test3 = lxml.etree.Element("Test", name="test3") replacements = {"/test/test2.xml": test2, "/test/test_dir/test3.xml": test3} + def xinclude(): for el in xfb.xdata.findall('//%sinclude' % Bcfg2.Server.XI_NAMESPACE): @@ -585,25 +580,25 @@ class TestXMLFileBacked(TestFileBacked): self.assertItemsEqual([tostring(e) for e in xfb.entries], [tostring(e) for e in children]) + @patch("Bcfg2.Server.FileMonitor.get_fam", Mock()) def test_add_monitor(self): xfb = self.get_obj() xfb.add_monitor("/test/test2.xml") self.assertIn("/test/test2.xml", xfb.extras) - fam = Mock() if self.should_monitor is not True: fam.reset_mock() - xfb = self.get_obj(fam=fam) - fam.reset_mock() + xfb = self.get_obj() + xfb.fam = Mock() xfb.add_monitor("/test/test3.xml") - self.assertFalse(fam.AddMonitor.called) + self.assertFalse(xfb.fam.AddMonitor.called) self.assertIn("/test/test3.xml", xfb.extras) if self.should_monitor is not False: - fam.reset_mock() - xfb = self.get_obj(fam=fam, should_monitor=True) + xfb = self.get_obj(should_monitor=True) + xfb.fam = Mock() xfb.add_monitor("/test/test4.xml") - fam.AddMonitor.assert_called_with("/test/test4.xml", xfb) + xfb.fam.AddMonitor.assert_called_with("/test/test4.xml", xfb) self.assertIn("/test/test4.xml", xfb.extras) @@ -2071,6 +2066,3 @@ class TestGroupSpool(TestPlugin, TestGenerator): gs.event_id.assert_called_with(event) self.assertNotIn("/baz/quux", gs.entries) self.assertNotIn("/baz/quux", gs.Entries[gs.entry_type]) - - - diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py index b1db34462..0afa5220d 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py @@ -6,7 +6,6 @@ import socket import lxml.etree import Bcfg2.Server import Bcfg2.Server.Plugin -from Bcfg2.Server.FileMonitor import _FAM from Bcfg2.Server.Plugins.Metadata import * from mock import Mock, MagicMock, patch @@ -205,9 +204,10 @@ class TestXMLMetadataConfig(TestXMLFileBacked): watch_clients=watch_clients) return XMLMetadataConfig(self.metadata, watch_clients, basefile) + @patch("Bcfg2.Server.FileMonitor.get_fam", Mock()) def test__init(self): xmc = self.get_obj() - self.assertFalse(_FAM.AddMonitor.called) + self.assertFalse(xmc.fam.AddMonitor.called) def test_xdata(self): config = self.get_obj() @@ -251,20 +251,21 @@ class TestXMLMetadataConfig(TestXMLFileBacked): self.assertEqual(config.base_xdata, "") def test_add_monitor(self): - core = MagicMock() - config = self.get_obj(core=core) + config = self.get_obj() + config.fam = Mock() fname = "test.xml" fpath = os.path.join(self.metadata.data, fname) config.extras = [] config.add_monitor(fpath) - self.assertFalse(_FAM.AddMonitor.called) + self.assertFalse(config.fam.AddMonitor.called) self.assertEqual(config.extras, [fpath]) - config = self.get_obj(core=core, watch_clients=True) + config = self.get_obj(watch_clients=True) + config.fam = Mock() config.add_monitor(fpath) - _FAM.AddMonitor.assert_called_with(fpath, config.metadata) + config.fam.AddMonitor.assert_called_with(fpath, config.metadata) self.assertItemsEqual(config.extras, [fpath]) def test_Index(self): @@ -488,7 +489,8 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): client_name = "%s%s" % (prefix, i) return client_name - def test__init(self): + @patch("Bcfg2.Server.FileMonitor.get_fam") + def test__init(self, mock_get_fam): # test with watch_clients=False core = MagicMock() metadata = self.get_obj(core=core) @@ -501,22 +503,21 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): self.assertEqual(metadata.states, dict()) # test with watch_clients=True - fam = Bcfg2.Server.FileMonitor._FAM - Bcfg2.Server.FileMonitor._FAM = MagicMock() metadata = self.get_obj(core=core, watch_clients=True) self.assertEqual(len(metadata.states), 2) - Bcfg2.Server.FileMonitor._FAM.AddMonitor.assert_any_call(os.path.join(metadata.data, - "groups.xml"), - metadata) - Bcfg2.Server.FileMonitor._FAM.AddMonitor.assert_any_call(os.path.join(metadata.data, - "clients.xml"), - metadata) - - Bcfg2.Server.FileMonitor._FAM.reset_mock() - Bcfg2.Server.FileMonitor._FAM.AddMonitor = Mock(side_effect=IOError) + mock_get_fam.return_value.AddMonitor.assert_any_call( + os.path.join(metadata.data, "groups.xml"), + metadata) + mock_get_fam.return_value.AddMonitor.assert_any_call( + os.path.join(metadata.data, "clients.xml"), + metadata) + + mock_get_fam.reset_mock() + fam = Mock() + fam.AddMonitor = Mock(side_effect=IOError) + mock_get_fam.return_value = fam self.assertRaises(Bcfg2.Server.Plugin.PluginInitError, self.get_obj, core=core, watch_clients=True) - Bcfg2.Server.FileMonitor._FAM = fam @patch('os.makedirs', Mock()) @patch('%s.open' % builtins) @@ -577,6 +578,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_add_group(self): metadata = self.get_obj() metadata.groups_xml.write = Mock() + metadata.groups_xml.load_xml = Mock() metadata.groups_xml.data = lxml.etree.XML('').getroottree() metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data) @@ -609,6 +611,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_update_group(self): metadata = self.get_obj() metadata.groups_xml.write_xml = Mock() + metadata.groups_xml.load_xml = Mock() metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree()) metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data) @@ -626,6 +629,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_remove_group(self): metadata = self.get_obj() metadata.groups_xml.write_xml = Mock() + metadata.groups_xml.load_xml = Mock() metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree()) metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data) @@ -641,6 +645,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_add_bundle(self): metadata = self.get_obj() metadata.groups_xml.write = Mock() + metadata.groups_xml.load_xml = Mock() metadata.groups_xml.data = lxml.etree.XML('').getroottree() metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data) @@ -664,6 +669,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_remove_bundle(self): metadata = self.get_obj() metadata.groups_xml.write_xml = Mock() + metadata.groups_xml.load_xml = Mock() metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree()) metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data) @@ -679,6 +685,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_add_client(self): metadata = self.get_obj() metadata.clients_xml.write = Mock() + metadata.clients_xml.load_xml = Mock() metadata.clients_xml.data = lxml.etree.XML('').getroottree() metadata.clients_xml.basedata = copy.copy(metadata.clients_xml.data) @@ -713,6 +720,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked): def test_update_client(self): metadata = self.get_obj() metadata.clients_xml.write_xml = Mock() + metadata.clients_xml.load_xml = Mock() metadata.clients_xml.data = copy.deepcopy(get_clients_test_tree()) metadata.clients_xml.basedata = copy.copy(metadata.clients_xml.data) @@ -1261,25 +1269,24 @@ class TestMetadataBase(TestMetadata): return client_name @patch('os.path.exists') - def test__init(self, mock_exists): - fam = Bcfg2.Server.FileMonitor._FAM - Bcfg2.Server.FileMonitor._FAM = MagicMock() + @patch('Bcfg2.Server.FileMonitor.get_fam') + def test__init(self, mock_get_fam, mock_exists): mock_exists.return_value = False metadata = self.get_obj(watch_clients=True) self.assertIsInstance(metadata, Bcfg2.Server.Plugin.DatabaseBacked) - Bcfg2.Server.FileMonitor._FAM.AddMonitor.assert_called_once_with( + mock_get_fam.return_value.AddMonitor.assert_called_with( os.path.join(metadata.data, "groups.xml"), metadata) mock_exists.return_value = True - Bcfg2.Server.FileMonitor._FAM.reset_mock() - metadata = self.get_obj(core=core, watch_clients=True) - core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data, - "groups.xml"), - metadata) - core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data, - "clients.xml"), - metadata) + mock_get_fam.reset_mock() + metadata = self.get_obj(watch_clients=True) + mock_get_fam.return_value.AddMonitor.assert_any_call( + os.path.join(metadata.data, "groups.xml"), + metadata) + mock_get_fam.return_value.AddMonitor.assert_any_call( + os.path.join(metadata.data, "clients.xml"), + metadata) def test_add_group(self): pass diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py index 2e1d6df51..958dba4ff 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py @@ -16,7 +16,6 @@ while path != "/": break path = os.path.dirname(path) from common import * -from Bcfg2.Server.FileMonitor import _FAM from Bcfg2.Server.Plugins.Probes import * from TestPlugin import TestEntrySet, TestProbing, TestConnector, \ TestDatabaseBacked @@ -101,14 +100,11 @@ class TestProbeSet(TestEntrySet): rv.entry_type = MagicMock() return rv - def test__init(self): - fam = Bcfg2.Server.FileMonitor._FAM - Bcfg2.Server.FileMonitor._FAM = Mock() + @patch("Bcfg2.Server.FileMonitor.get_fam") + def test__init(self, mock_get_fam): ps = self.get_obj() self.assertEqual(ps.plugin_name, "Probes") - Bcfg2.Server.FileMonitor._FAM.AddMonitor.assert_called_with(datastore, - ps) - Bcfg2.Server.FileMonitor._FAM = fam + mock_get_fam.return_value.AddMonitor.assert_called_with(datastore, ps) TestEntrySet.test__init(self) def test_HandleEvent(self): @@ -258,9 +254,6 @@ text def test__init(self): mock_load_data = Mock() probes = self.get_probes_object(load_data=mock_load_data) - _FAM.AddMonitor.assert_called_with(os.path.join(datastore, - probes.name), - probes.probes) mock_load_data.assert_any_call() self.assertEqual(probes.probedata, ClientProbeDataSet()) self.assertEqual(probes.cgroups, dict()) -- cgit v1.2.3-1-g7c22