diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-04-24 13:47:31 -0400 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-04-24 13:47:31 -0400 |
commit | 0ff6b2788de683dd89203c7ae1393ea922a62c32 (patch) | |
tree | 54ce843377ab26c6336de7f1abf3ec906d49aa69 /testsuite | |
parent | 46a47b4120b3d892b8149a5e181e4d976ad87f99 (diff) | |
parent | 29399cbc599919fd9c88448bde692132c803e69b (diff) | |
download | bcfg2-0ff6b2788de683dd89203c7ae1393ea922a62c32.tar.gz bcfg2-0ff6b2788de683dd89203c7ae1393ea922a62c32.tar.bz2 bcfg2-0ff6b2788de683dd89203c7ae1393ea922a62c32.zip |
Merge branch 'maint'
Conflicts:
src/lib/Bcfg2/Client/Client.py
src/lib/Bcfg2/Client/Frame.py
src/lib/Bcfg2/Client/Tools/YUM.py
src/lib/Bcfg2/Options.py
src/lib/Bcfg2/Server/Admin/Perf.py
src/lib/Bcfg2/Server/Admin/Xcmd.py
src/lib/Bcfg2/Server/Admin/__init__.py
src/lib/Bcfg2/Server/Core.py
src/lib/Bcfg2/Server/FileMonitor/Fam.py
src/lib/Bcfg2/Server/Lint/RequiredAttrs.py
src/lib/Bcfg2/Server/Plugin/helpers.py
src/lib/Bcfg2/Server/Plugins/Base.py
src/lib/Bcfg2/Server/Plugins/Bundler.py
src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
src/lib/Bcfg2/Server/Plugins/Cvs.py
src/lib/Bcfg2/Server/Plugins/Darcs.py
src/lib/Bcfg2/Server/Plugins/Decisions.py
src/lib/Bcfg2/Server/Plugins/FileProbes.py
src/lib/Bcfg2/Server/Plugins/Fossil.py
src/lib/Bcfg2/Server/Plugins/Git.py
src/lib/Bcfg2/Server/Plugins/Metadata.py
src/lib/Bcfg2/Server/Plugins/NagiosGen.py
src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
src/lib/Bcfg2/Server/Plugins/Packages/Source.py
src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
src/lib/Bcfg2/Server/Plugins/Properties.py
src/lib/Bcfg2/Server/Plugins/__init__.py
src/lib/Bcfg2/Server/__init__.py
src/sbin/bcfg2-build-reports
src/sbin/bcfg2-crypt
testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py
testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py
Diffstat (limited to 'testsuite')
13 files changed, 303 insertions, 123 deletions
diff --git a/testsuite/Testsrc/Testlib/TestClient/TestTools/TestPOSIX/TestFile.py b/testsuite/Testsrc/Testlib/TestClient/TestTools/TestPOSIX/TestFile.py index 662e0e1b6..8f933e08f 100644 --- a/testsuite/Testsrc/Testlib/TestClient/TestTools/TestPOSIX/TestFile.py +++ b/testsuite/Testsrc/Testlib/TestClient/TestTools/TestPOSIX/TestFile.py @@ -64,10 +64,18 @@ class TestPOSIXFile(TestPOSIXTool): self.assertEqual(ptool._get_data(entry), ("test", True)) entry = copy.deepcopy(orig_entry) + entry.set("encoding", "base64") + entry.set("empty", "true") + self.assertEqual(ptool._get_data(entry), ("", True)) + + entry = copy.deepcopy(orig_entry) entry.set("empty", "true") self.assertEqual(ptool._get_data(entry), ("", False)) entry = copy.deepcopy(orig_entry) + self.assertEqual(ptool._get_data(entry), ("", False)) + + entry = copy.deepcopy(orig_entry) entry.text = "test" self.assertEqual(ptool._get_data(entry), ("test", False)) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testbase.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testbase.py index a1e624824..318f5ceaa 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testbase.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testbase.py @@ -72,14 +72,32 @@ class TestPlugin(TestDebuggable): if core is None: core = Mock() core.setup = MagicMock() - return self.test_obj(core, datastore) + @patchIf(not isinstance(os.makedirs, Mock), "os.makedirs", Mock()) + def inner(): + return self.test_obj(core, datastore) + return inner() - def test__init(self): + @patch("os.makedirs") + @patch("os.path.exists") + def test__init(self, mock_exists, mock_makedirs): core = Mock() core.setup = MagicMock() + + mock_exists.return_value = True + p = self.get_obj(core=core) + self.assertEqual(p.data, os.path.join(datastore, p.name)) + self.assertEqual(p.core, core) + mock_exists.assert_any_call(p.data) + self.assertFalse(mock_makedirs.called) + + mock_exists.reset_mock() + mock_makedirs.reset_mock() + mock_exists.return_value = False p = self.get_obj(core=core) self.assertEqual(p.data, os.path.join(datastore, p.name)) self.assertEqual(p.core, core) + mock_exists.assert_any_call(p.data) + mock_makedirs.assert_any_call(p.data) @patch("os.makedirs") def test_init_repo(self, mock_makedirs): diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py index 6187880b7..929f665b1 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py @@ -133,7 +133,11 @@ class TestDirectoryBacked(Bcfg2TestCase): """ ensure that the child object has the correct interface """ self.assertTrue(hasattr(self.test_obj.__child__, "HandleEvent")) - def get_obj(self): + @patch("os.makedirs", Mock()) + def get_obj(self, fam=None): + if fam is None: + fam = Mock() + @patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__, self.test_obj.__name__), Mock()) @@ -142,12 +146,26 @@ class TestDirectoryBacked(Bcfg2TestCase): self.test_obj.__name__)) return inner() - def test__init(self): + @patch("os.makedirs") + @patch("os.path.exists") + def test__init(self, mock_exists, mock_makedirs): @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_exists.return_value = True + mock_add_monitor.assert_called_with('') + mock_exists.assert_called_with(db.data) + self.assertFalse(mock_makedirs.called) + + mock_add_monitor.reset_mock() + mock_exists.reset_mock() + mock_makedirs.reset_mock() + mock_exists.return_value = False + db = self.test_obj(datastore) mock_add_monitor.assert_called_with('') + mock_exists.assert_called_with(db.data) + mock_makedirs.assert_called_with(db.data) inner() @@ -367,20 +385,24 @@ class TestXMLFileBacked(TestFileBacked): def get_obj(self, path=None, should_monitor=False): if path is None: path = self.path - return self.test_obj(path, should_monitor=should_monitor) + + @patchIf(not isinstance(os.path.exists, Mock), + "os.path.exists", Mock()) + def inner(): + return self.test_obj(path, should_monitor=should_monitor) + return inner() @patch("Bcfg2.Server.FileMonitor.get_fam") def test__init(self, mock_get_fam): xfb = self.get_obj() self.assertEqual(xfb.fam, mock_get_fam.return_value) - if self.should_monitor is not True: - xfb = self.get_obj() - self.assertFalse(xfb.fam.AddMonitor.called) - - if self.should_monitor is not False: + if self.should_monitor: xfb = self.get_obj(should_monitor=True) xfb.fam.AddMonitor.assert_called_with(self.path, xfb) + else: + xfb = self.get_obj() + self.assertFalse(xfb.fam.AddMonitor.called) @patch("glob.glob") @patch("lxml.etree.parse") @@ -571,21 +593,21 @@ class TestXMLFileBacked(TestFileBacked): def test_add_monitor(self): xfb = self.get_obj() xfb.add_monitor("/test/test2.xml") - self.assertIn("/test/test2.xml", xfb.extras) + self.assertIn("/test/test2.xml", xfb.extra_monitors) if self.should_monitor is not True: xfb = self.get_obj() xfb.fam = Mock() xfb.add_monitor("/test/test3.xml") self.assertFalse(xfb.fam.AddMonitor.called) - self.assertIn("/test/test3.xml", xfb.extras) + self.assertIn("/test/test3.xml", xfb.extra_monitors) if self.should_monitor is not False: xfb = self.get_obj(should_monitor=True) xfb.fam = Mock() xfb.add_monitor("/test/test4.xml") xfb.fam.AddMonitor.assert_called_with("/test/test4.xml", xfb) - self.assertIn("/test/test4.xml", xfb.extras) + self.assertIn("/test/test4.xml", xfb.extra_monitors) class TestStructFile(TestXMLFileBacked): @@ -1370,13 +1392,18 @@ class TestXMLDirectoryBacked(TestDirectoryBacked): class TestPrioDir(TestPlugin, TestGenerator, TestXMLDirectoryBacked): test_obj = PrioDir - @patch("Bcfg2.Server.Plugin.helpers.%s.add_directory_monitor" % - test_obj.__name__, - Mock()) def get_obj(self, core=None): if core is None: core = Mock() - return self.test_obj(core, datastore) + + @patch("%s.%s.add_directory_monitor" % + (self.test_obj.__module__, self.test_obj.__name__), + Mock()) + @patchIf(not isinstance(os.makedirs, Mock), "os.makedirs", Mock()) + def inner(): + return self.test_obj(core, datastore) + + return inner() def test_HandleEvent(self): TestXMLDirectoryBacked.test_HandleEvent(self) @@ -1622,7 +1649,8 @@ class TestEntrySet(TestDebuggable): bogus))) for ignore in self.ignore: - self.assertTrue(eset.ignore.match(ignore)) + self.assertTrue(eset.ignore.match(ignore), + "%s should be ignored but wasn't" % ignore) self.assertFalse(eset.ignore.match(basename)) self.assertFalse(eset.ignore.match(basename + ".G20_foo")) @@ -1961,6 +1989,7 @@ class TestGroupSpool(TestPlugin, TestGenerator): return inner() def test__init(self): + @patchIf(not isinstance(os.makedirs, Mock), "os.makedirs", Mock()) @patch("%s.%s.AddDirectoryMonitor" % (self.test_obj.__module__, self.test_obj.__name__)) def inner(mock_Add): diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testinterfaces.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testinterfaces.py index 6effe05de..ac0454f84 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testinterfaces.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testinterfaces.py @@ -97,11 +97,6 @@ class TestProbing(Bcfg2TestCase): class TestStatistics(TestPlugin): test_obj = Statistics - def get_obj(self, core=None): - if core is None: - core = Mock() - return self.test_obj(core, datastore) - def test_process_statistics(self): s = self.get_obj() self.assertRaises(NotImplementedError, @@ -354,12 +349,6 @@ class TestGoalValidator(Bcfg2TestCase): class TestVersion(TestPlugin): test_obj = Version - def get_obj(self, core=None): - if core is None: - core = Mock() - core.setup = MagicMock() - return self.test_obj(core, datastore) - def test_get_revision(self): d = self.get_obj() self.assertRaises(NotImplementedError, d.get_revision) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgGenshiGenerator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgGenshiGenerator.py index 154d6a8db..b73670fb7 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgGenshiGenerator.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgGenshiGenerator.py @@ -2,6 +2,7 @@ import os import sys import lxml.etree from mock import Mock, MagicMock, patch +import Bcfg2.Server.Plugins.Cfg.CfgGenshiGenerator from Bcfg2.Server.Plugins.Cfg.CfgGenshiGenerator import * from Bcfg2.Server.Plugin import PluginExecutionError diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestGroupPatterns.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestGroupPatterns.py index a9346156c..c6e6f5ef7 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestGroupPatterns.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestGroupPatterns.py @@ -92,7 +92,12 @@ class TestPatternFile(TestXMLFileBacked): core.fam = fam elif not core: core = Mock() - return self.test_obj(path, core=core) + + @patchIf(not isinstance(lxml.etree.Element, Mock), + "lxml.etree.Element", Mock()) + def inner(): + return self.test_obj(path, core=core) + return inner() @patch("Bcfg2.Server.Plugins.GroupPatterns.PatternMap") def test_Index(self, mock_PatternMap): @@ -135,6 +140,14 @@ class TestPatternFile(TestXMLFileBacked): class TestGroupPatterns(TestPlugin, TestConnector): test_obj = GroupPatterns + def get_obj(self, core=None): + @patchIf(not isinstance(lxml.etree.Element, Mock), + "lxml.etree.Element", Mock()) + def inner(): + return TestPlugin.get_obj(self, core=core) + return inner() + + def test_get_additional_groups(self): gp = self.get_obj() gp.config = Mock() diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py index 221eb8a3c..a9e9d9701 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py @@ -94,7 +94,13 @@ def get_metadata_object(core=None, watch_clients=False, use_db=False): core.setup = MagicMock() core.metadata_cache = MagicMock() core.setup.cfp.getboolean = Mock(return_value=use_db) - return Metadata(core, datastore, watch_clients=watch_clients) + + @patchIf(not isinstance(os.makedirs, Mock), "os.makedirs", Mock()) + @patchIf(not isinstance(lxml.etree.Element, Mock), + "lxml.etree.Element", Mock()) + def inner(): + return Metadata(core, datastore, watch_clients=watch_clients) + return inner() class TestMetadataDB(DBModelTestCase): @@ -203,7 +209,11 @@ class TestXMLMetadataConfig(TestXMLFileBacked): def get_obj(self, basefile="clients.xml", core=None, watch_clients=False): self.metadata = get_metadata_object(core=core, watch_clients=watch_clients) - return XMLMetadataConfig(self.metadata, watch_clients, basefile) + @patchIf(not isinstance(lxml.etree.Element, Mock), + "lxml.etree.Element", Mock()) + def inner(): + return XMLMetadataConfig(self.metadata, watch_clients, basefile) + return inner() @patch("Bcfg2.Server.FileMonitor.get_fam", Mock()) def test__init(self): @@ -1531,7 +1541,11 @@ class TestMetadata_ClientsXML(TestMetadataBase): metadata = self.get_obj() fam = Bcfg2.Server.FileMonitor._FAM Bcfg2.Server.FileMonitor._FAM = MagicMock() - metadata.clients_xml = metadata._handle_file("clients.xml") + @patchIf(not isinstance(lxml.etree.Element, Mock), + "lxml.etree.Element", Mock()) + def inner(): + metadata.clients_xml = metadata._handle_file("clients.xml") + inner() metadata = TestMetadata.load_clients_data(self, metadata=metadata, xdata=xdata) rv = TestMetadataBase.load_clients_data(self, metadata=metadata, diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py index 958dba4ff..30b08ef2f 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py @@ -1,7 +1,9 @@ import os import sys +import copy import time import lxml.etree +import Bcfg2.version import Bcfg2.Server import Bcfg2.Server.Plugin from mock import Mock, MagicMock, patch @@ -25,6 +27,47 @@ test_data = dict(a=1, b=[1, 2, 3], c="test", d=dict(a=1, b=dict(a=1), c=(1, "2", 3))) +class FakeElement(lxml.etree._Element): + getroottree = Mock() + + def __init__(self, el): + self._element = el + + def __getattribute__(self, attr): + el = lxml.etree._Element.__getattribute__(self, + '__dict__')['_element'] + if attr == "getroottree": + return FakeElement.getroottree + elif attr == "_element": + return el + else: + return getattr(el, attr) + + +class StoringElement(object): + OriginalElement = copy.copy(lxml.etree.Element) + + def __init__(self): + self.element = None + self.return_value = None + + def __call__(self, *args, **kwargs): + self.element = self.OriginalElement(*args, **kwargs) + self.return_value = FakeElement(self.element) + return self.return_value + + +class StoringSubElement(object): + OriginalSubElement = copy.copy(lxml.etree.SubElement) + + def __call__(self, parent, tag, **kwargs): + try: + return self.OriginalSubElement(parent._element, tag, + **kwargs) + except AttributeError: + return self.OriginalSubElement(parent, tag, **kwargs) + + class FakeList(list): pass @@ -173,6 +216,8 @@ group-specific""" ps.get_matching.return_value = matching metadata = Mock() + metadata.version_info = \ + Bcfg2.version.Bcfg2VersionInfo(Bcfg2.version.__version__) pdata = ps.get_probe_data(metadata) ps.get_matching.assert_called_with(metadata) # we can't create a matching operator.attrgetter object, and I @@ -199,9 +244,7 @@ class TestProbes(TestProbing, TestConnector, TestDatabaseBacked): test_obj = Probes def get_obj(self, core=None): - if core is None: - core = MagicMock() - return self.test_obj(core, datastore) + return TestDatabaseBacked.get_obj(self, core=core) def get_test_probedata(self): test_xdata = lxml.etree.Element("test") @@ -245,9 +288,10 @@ text # test__init(), which relies on being able to check the calls # of load_data(), and thus on load_data() being consistently # mocked) - @patch("Bcfg2.Server.Plugins.Probes.Probes.load_data", new=load_data) + @patch("%s.%s.load_data" % (self.test_obj.__module__, + self.test_obj.__name__), new=load_data) def inner(): - return Probes(core, datastore) + return self.get_obj(core) return inner() @@ -284,61 +328,71 @@ text probes._write_data_db.assert_called_with("test") self.assertFalse(probes._write_data_xml.called) - @patch("%s.open" % builtins) - def test__write_data_xml(self, mock_open): + def test__write_data_xml(self): probes = self.get_probes_object(use_db=False) probes.probedata = self.get_test_probedata() probes.cgroups = self.get_test_cgroups() - probes._write_data_xml(None) - - mock_open.assert_called_with(os.path.join(datastore, probes.name, - "probed.xml"), "w") - data = lxml.etree.XML(mock_open.return_value.write.call_args[0][0]) - self.assertEqual(len(data.xpath("//Client")), 2) - - foodata = data.find("Client[@name='foo.example.com']") - self.assertIsNotNone(foodata) - self.assertIsNotNone(foodata.get("timestamp")) - self.assertEqual(len(foodata.findall("Probe")), - len(probes.probedata['foo.example.com'])) - self.assertEqual(len(foodata.findall("Group")), - len(probes.cgroups['foo.example.com'])) - xml = foodata.find("Probe[@name='xml']") - self.assertIsNotNone(xml) - self.assertIsNotNone(xml.get("value")) - xdata = lxml.etree.XML(xml.get("value")) - self.assertIsNotNone(xdata) - self.assertIsNotNone(xdata.find("test")) - self.assertEqual(xdata.find("test").get("foo"), "foo") - text = foodata.find("Probe[@name='text']") - self.assertIsNotNone(text) - self.assertIsNotNone(text.get("value")) - multiline = foodata.find("Probe[@name='multiline']") - self.assertIsNotNone(multiline) - self.assertIsNotNone(multiline.get("value")) - self.assertGreater(len(multiline.get("value").splitlines()), 1) - - bardata = data.find("Client[@name='bar.example.com']") - self.assertIsNotNone(bardata) - self.assertIsNotNone(bardata.get("timestamp")) - self.assertEqual(len(bardata.findall("Probe")), - len(probes.probedata['bar.example.com'])) - self.assertEqual(len(bardata.findall("Group")), - len(probes.cgroups['bar.example.com'])) - empty = bardata.find("Probe[@name='empty']") - self.assertIsNotNone(empty) - self.assertIsNotNone(empty.get("value")) - self.assertEqual(empty.get("value"), "") - if HAS_JSON: - jdata = bardata.find("Probe[@name='json']") - self.assertIsNotNone(jdata) - self.assertIsNotNone(jdata.get("value")) - self.assertItemsEqual(test_data, json.loads(jdata.get("value"))) - if HAS_YAML: - ydata = bardata.find("Probe[@name='yaml']") - self.assertIsNotNone(ydata) - self.assertIsNotNone(ydata.get("value")) - self.assertItemsEqual(test_data, yaml.load(ydata.get("value"))) + + @patch("lxml.etree.Element") + @patch("lxml.etree.SubElement", StoringSubElement()) + def inner(mock_Element): + mock_Element.side_effect = StoringElement() + probes._write_data_xml(None) + + top = mock_Element.side_effect.return_value + write = top.getroottree.return_value.write + self.assertEqual(write.call_args[0][0], + os.path.join(datastore, probes.name, + "probed.xml")) + + data = top._element + foodata = data.find("Client[@name='foo.example.com']") + self.assertIsNotNone(foodata) + self.assertIsNotNone(foodata.get("timestamp")) + self.assertEqual(len(foodata.findall("Probe")), + len(probes.probedata['foo.example.com'])) + self.assertEqual(len(foodata.findall("Group")), + len(probes.cgroups['foo.example.com'])) + xml = foodata.find("Probe[@name='xml']") + self.assertIsNotNone(xml) + self.assertIsNotNone(xml.get("value")) + xdata = lxml.etree.XML(xml.get("value")) + self.assertIsNotNone(xdata) + self.assertIsNotNone(xdata.find("test")) + self.assertEqual(xdata.find("test").get("foo"), "foo") + text = foodata.find("Probe[@name='text']") + self.assertIsNotNone(text) + self.assertIsNotNone(text.get("value")) + multiline = foodata.find("Probe[@name='multiline']") + self.assertIsNotNone(multiline) + self.assertIsNotNone(multiline.get("value")) + self.assertGreater(len(multiline.get("value").splitlines()), 1) + + bardata = data.find("Client[@name='bar.example.com']") + self.assertIsNotNone(bardata) + self.assertIsNotNone(bardata.get("timestamp")) + self.assertEqual(len(bardata.findall("Probe")), + len(probes.probedata['bar.example.com'])) + self.assertEqual(len(bardata.findall("Group")), + len(probes.cgroups['bar.example.com'])) + empty = bardata.find("Probe[@name='empty']") + self.assertIsNotNone(empty) + self.assertIsNotNone(empty.get("value")) + self.assertEqual(empty.get("value"), "") + if HAS_JSON: + jdata = bardata.find("Probe[@name='json']") + self.assertIsNotNone(jdata) + self.assertIsNotNone(jdata.get("value")) + self.assertItemsEqual(test_data, + json.loads(jdata.get("value"))) + if HAS_YAML: + ydata = bardata.find("Probe[@name='yaml']") + self.assertIsNotNone(ydata) + self.assertIsNotNone(ydata.get("value")) + self.assertItemsEqual(test_data, + yaml.load(ydata.get("value"))) + + inner() @skipUnless(HAS_DJANGO, "Django not found, skipping") def test__write_data_db(self): @@ -410,18 +464,24 @@ text probes._load_data_db.assert_any_call() self.assertFalse(probes._load_data_xml.called) - @patch("%s.open" % builtins) @patch("lxml.etree.parse") - def test__load_data_xml(self, mock_parse, mock_open): + def test__load_data_xml(self, mock_parse): probes = self.get_probes_object(use_db=False) - # to get the value for lxml.etree.parse to parse, we call - # _write_data_xml, mock the open() call, and grab the data - # that gets "written" to probed.xml probes.probedata = self.get_test_probedata() probes.cgroups = self.get_test_cgroups() - probes._write_data_xml(None) - xdata = \ - lxml.etree.XML(str(mock_open.return_value.write.call_args[0][0])) + + # to get the value for lxml.etree.parse to parse, we call + # _write_data_xml, mock the lxml.etree._ElementTree.write() + # call, and grab the data that gets "written" to probed.xml + @patch("lxml.etree.Element") + @patch("lxml.etree.SubElement", StoringSubElement()) + def inner(mock_Element): + mock_Element.side_effect = StoringElement() + probes._write_data_xml(None) + top = mock_Element.side_effect.return_value + return top._element + + xdata = inner() mock_parse.return_value = xdata.getroottree() probes.probedata = dict() probes.cgroups = dict() @@ -559,5 +619,3 @@ text metadata.hostname = "nonexistent" self.assertEqual(probes.get_additional_data(metadata), ClientProbeDataSet()) - - diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py index b63d08524..92dc85fb1 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py @@ -295,8 +295,8 @@ class TestXMLPropertyFile(TestPropertyFile, TestStructFile): self.assertFalse(mock_copy.called) -class TestPropDirectoryBacked(TestDirectoryBacked): - test_obj = PropDirectoryBacked +class TestProperties(TestPlugin, TestConnector, TestDirectoryBacked): + test_obj = Properties testfiles = ['foo.xml', 'bar.baz.xml'] if HAS_JSON: testfiles.extend(["foo.json", "foo.xml.json"]) @@ -305,16 +305,13 @@ class TestPropDirectoryBacked(TestDirectoryBacked): ignore = ['foo.xsd', 'bar.baz.xsd', 'quux.xml.xsd'] badevents = ['bogus.txt'] - -class TestProperties(TestPlugin, TestConnector): - test_obj = Properties - - def test__init(self): - TestPlugin.test__init(self) - - core = Mock() - p = self.get_obj(core=core) - self.assertIsInstance(p.store, PropDirectoryBacked) + def get_obj(self, core=None): + @patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__, + self.test_obj.__name__), + Mock()) + def inner(): + return TestPlugin.get_obj(self, core=core) + return inner() @patch("copy.copy") def test_get_additional_data(self, mock_copy): @@ -322,11 +319,11 @@ class TestProperties(TestPlugin, TestConnector): p = self.get_obj() metadata = Mock() - p.store.entries = {"foo.xml": Mock(), - "foo.yml": Mock()} + p.entries = {"foo.xml": Mock(), + "foo.yml": Mock()} rv = p.get_additional_data(metadata) expected = dict() - for name, entry in p.store.entries.items(): + for name, entry in p.entries.items(): entry.get_additional_data.assert_called_with(metadata) expected[name] = entry.get_additional_data.return_value self.assertItemsEqual(rv, expected) diff --git a/testsuite/Testsrc/Testlib/TestStatistics.py b/testsuite/Testsrc/Testlib/TestStatistics.py new file mode 100644 index 000000000..496cbac28 --- /dev/null +++ b/testsuite/Testsrc/Testlib/TestStatistics.py @@ -0,0 +1,44 @@ +import os +import sys +from mock import Mock, MagicMock, patch + +# add all parent testsuite directories to sys.path to allow (most) +# relative imports in python 2.4 +path = os.path.dirname(__file__) +while path != "/": + if os.path.basename(path).lower().startswith("test"): + sys.path.append(path) + if os.path.basename(path) == "testsuite": + break + path = os.path.dirname(path) +from common import * + +from Bcfg2.Statistics import * + + +class TestStatistic(Bcfg2TestCase): + def test_stat(self): + stat = Statistic("test", 1) + self.assertEqual(stat.get_value(), ("test", (1.0, 1.0, 1.0, 1))) + stat.add_value(10) + self.assertEqual(stat.get_value(), ("test", (1.0, 10.0, 5.5, 2))) + stat.add_value(100) + self.assertEqual(stat.get_value(), ("test", (1.0, 100.0, 37.0, 3))) + stat.add_value(12.345) + self.assertEqual(stat.get_value(), ("test", (1.0, 100.0, 30.83625, 4))) + stat.add_value(0.655) + self.assertEqual(stat.get_value(), ("test", (0.655, 100.0, 24.8, 5))) + + +class TestStatistics(Bcfg2TestCase): + def test_stats(self): + stats = Statistics() + self.assertEqual(stats.display(), dict()) + stats.add_value("test1", 1) + self.assertEqual(stats.display(), dict(test1=(1.0, 1.0, 1.0, 1))) + stats.add_value("test2", 1.23) + self.assertEqual(stats.display(), dict(test1=(1.0, 1.0, 1.0, 1), + test2=(1.23, 1.23, 1.23, 1))) + stats.add_value("test1", 10) + self.assertEqual(stats.display(), dict(test1=(1.0, 10.0, 5.5, 2), + test2=(1.23, 1.23, 1.23, 1))) diff --git a/testsuite/before_install.sh b/testsuite/before_install.sh index 884971e45..5f1a59aaf 100755 --- a/testsuite/before_install.sh +++ b/testsuite/before_install.sh @@ -2,9 +2,12 @@ # before_install script for Travis-CI +PYVER=$(python -c 'import sys;print(".".join(str(v) for v in sys.version_info[0:2]))') + sudo apt-get update -qq -sudo apt-get install -qq swig pylint libxml2-utils +sudo apt-get install -qq swig libxml2-utils if [[ "$WITH_OPTIONAL_DEPS" == "yes" ]]; then - sudo apt-get install -qq python-selinux python-pylibacl python-pyinotify \ - python-yaml yum + if [[ ${PYVER:0:1} == "2" ]]; then + sudo apt-get install -qq python-selinux python-pylibacl yum + fi fi diff --git a/testsuite/install.sh b/testsuite/install.sh index c1685f831..817ed5911 100755 --- a/testsuite/install.sh +++ b/testsuite/install.sh @@ -7,12 +7,16 @@ pip install -r testsuite/requirements.txt --use-mirrors PYVER=$(python -c 'import sys;print(".".join(str(v) for v in sys.version_info[0:2]))') if [[ "$WITH_OPTIONAL_DEPS" == "yes" ]]; then + pip install --use-mirrors genshi PyYAML pyinotify if [[ $PYVER == "2.5" ]]; then - # markdown 2.2.0 is broken on py2.5, so until 2.2.1 is released use 2.1 - pip install --use-mirrors 'markdown<2.2' - pip install --use-mirrors simplejson + # markdown 2.2+ doesn't work on py2.5 + pip install --use-mirrors simplejson 'markdown<2.2' + fi + if [[ ${PYVER:0:1} == "2" ]]; then + # django supports py3k, but South doesn't, and the django bits + # in bcfg2 require South + pip install cheetah 'django<1.5' South M2Crypto fi - pip install --use-mirrors genshi cheetah 'django<1.4' South M2Crypto else # python < 2.6 requires M2Crypto for SSL communication, not just # for encryption support diff --git a/testsuite/requirements.txt b/testsuite/requirements.txt index 8529b247f..2d6dbc557 100644 --- a/testsuite/requirements.txt +++ b/testsuite/requirements.txt @@ -2,4 +2,6 @@ lxml nose mock sphinx -daemon +pylint +pep8 +python-daemon |