summaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-04-24 13:47:31 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-04-24 13:47:31 -0400
commit0ff6b2788de683dd89203c7ae1393ea922a62c32 (patch)
tree54ce843377ab26c6336de7f1abf3ec906d49aa69 /testsuite
parent46a47b4120b3d892b8149a5e181e4d976ad87f99 (diff)
parent29399cbc599919fd9c88448bde692132c803e69b (diff)
downloadbcfg2-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')
-rw-r--r--testsuite/Testsrc/Testlib/TestClient/TestTools/TestPOSIX/TestFile.py8
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testbase.py22
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py61
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testinterfaces.py11
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgGenshiGenerator.py1
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestGroupPatterns.py15
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py20
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py192
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProperties.py27
-rw-r--r--testsuite/Testsrc/Testlib/TestStatistics.py44
-rwxr-xr-xtestsuite/before_install.sh9
-rwxr-xr-xtestsuite/install.sh12
-rw-r--r--testsuite/requirements.txt4
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