summaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-08-29 11:12:38 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-08-29 11:12:38 -0400
commit6d2304bb814a31f7e489ef6c6caca2d3a748ed0e (patch)
treeff7abb2f9f3407a7c221ae281916cfc6d8aab735 /testsuite
parent12d351a0213cdc39631acb143d9c2c8bf90e1d72 (diff)
downloadbcfg2-6d2304bb814a31f7e489ef6c6caca2d3a748ed0e.tar.gz
bcfg2-6d2304bb814a31f7e489ef6c6caca2d3a748ed0e.tar.bz2
bcfg2-6d2304bb814a31f7e489ef6c6caca2d3a748ed0e.zip
testsuite: rewrote Rules/Defaults tests to be actually useful
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDefaults.py29
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestRules.py203
-rw-r--r--testsuite/common.py42
3 files changed, 202 insertions, 72 deletions
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDefaults.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDefaults.py
index 7be3d8e84..9b4a6af88 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDefaults.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestDefaults.py
@@ -1,5 +1,6 @@
import os
import sys
+import copy
import lxml.etree
from mock import Mock, MagicMock, patch
from Bcfg2.Server.Plugins.Defaults import *
@@ -62,3 +63,31 @@ class TestDefaults(TestRules, TestGoalValidator):
def test__regex_enabled(self):
r = self.get_obj()
self.assertTrue(r._regex_enabled)
+
+ def _do_test(self, name, groups=None):
+ if groups is None:
+ groups = []
+ d = self.get_obj()
+ metadata = Mock(groups=groups)
+ config = lxml.etree.Element("Configuration")
+ struct = lxml.etree.SubElement(config, "Bundle", name=name)
+ entry = copy.deepcopy(self.abstract[name])
+ struct.append(entry)
+ d.validate_goals(metadata, config)
+ self.assertXMLEqual(entry, self.concrete[name])
+
+ def _do_test_failure(self, name, groups=None, handles=None):
+ if groups is None:
+ groups = []
+ d = self.get_obj()
+ metadata = Mock(groups=groups)
+ config = lxml.etree.Element("Configuration")
+ struct = lxml.etree.SubElement(config, "Bundle", name=name)
+ orig = copy.deepcopy(self.abstract[name])
+ entry = copy.deepcopy(self.abstract[name])
+ struct.append(entry)
+ d.validate_goals(metadata, config)
+ self.assertXMLEqual(entry, orig)
+
+ def test_regex(self):
+ self._do_test('regex')
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestRules.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestRules.py
index 0bd69b371..45f3671e8 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestRules.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestRules.py
@@ -1,9 +1,11 @@
import os
import sys
+import copy
import lxml.etree
-import Bcfg2.Server.Plugin
+import Bcfg2.Options
from mock import Mock, MagicMock, patch
from Bcfg2.Server.Plugins.Rules import *
+from Bcfg2.Server.Plugin import PluginExecutionError
# add all parent testsuite directories to sys.path to allow (most)
# relative imports in python 2.4
@@ -15,68 +17,159 @@ while path != "/":
break
path = os.path.dirname(path)
from common import *
-from TestPlugin import TestPrioDir
+from TestPlugin.Testhelpers import TestPrioDir
class TestRules(TestPrioDir):
test_obj = Rules
+ abstract = dict(
+ basic=lxml.etree.Element("Path", name="/etc/basic"),
+ unhandled=lxml.etree.Element("Path", name="/etc/unhandled"),
+ priority=lxml.etree.Element("Path", name="/etc/priority"),
+ content=lxml.etree.Element("Path", name="/etc/text-content"),
+ duplicate=lxml.etree.Element("SEBoolean", name="duplicate"),
+ group=lxml.etree.Element("SEPort", name="6789/tcp"),
+ children=lxml.etree.Element("Path", name="/etc/child-entries"),
+ regex=lxml.etree.Element("Package", name="regex"),
+ slash=lxml.etree.Element("Path", name="/etc/trailing/slash"),
+ no_slash=lxml.etree.Element("Path", name="/etc/no/trailing/slash/"))
+
+ concrete = dict(
+ basic=lxml.etree.Element("Path", name="/etc/basic", type="directory",
+ owner="root", group="root", mode="0600"),
+ priority=lxml.etree.Element("Path", name="/etc/priority",
+ type="directory", owner="root",
+ group="root", mode="0600"),
+ content=lxml.etree.Element("Path", name="/etc/text-content",
+ type="file", owner="bar", group="bar",
+ mode="0644"),
+ duplicate=lxml.etree.Element("SEBoolean", name="duplicate",
+ value="on"),
+ group=lxml.etree.Element("SEPort", name="6789/tcp",
+ selinuxtype="bcfg2_server_t"),
+ children=lxml.etree.Element("Path", name="/etc/child-entries",
+ type="directory", owner="root",
+ group="root", mode="0775"),
+ regex=lxml.etree.Element("Package", name="regex", type="yum",
+ version="any"),
+ slash=lxml.etree.Element("Path", name="/etc/trailing/slash",
+ type="directory", owner="root", group="root",
+ mode="0600"),
+ no_slash=lxml.etree.Element("Path", name="/etc/no/trailing/slash/",
+ type="directory", owner="root",
+ group="root", mode="0600"))
+
+ concrete['content'].text = "Text content"
+ lxml.etree.SubElement(concrete['children'],
+ "ACL", type="default", scope="user", user="foouser",
+ perms="rw")
+ lxml.etree.SubElement(concrete['children'],
+ "ACL", type="default", scope="group", group="users",
+ perms="rx")
+
+ in_file = copy.deepcopy(concrete)
+ in_file['regex'].set("name", ".*")
+ in_file['slash'].set("name", "/etc/trailing/slash/")
+ in_file['no_slash'].set("name", "/etc/no/trailing/slash")
+
+ rules1 = lxml.etree.Element("Rules", priority="10")
+ rules1.append(in_file['basic'])
+ lxml.etree.SubElement(rules1, "Path", name="/etc/priority",
+ type="directory", owner="foo", group="foo",
+ mode="0644")
+ foogroup = lxml.etree.SubElement(rules1, "Group", name="foogroup")
+ foogroup.append(in_file['group'])
+ rules1.append(in_file['content'])
+ rules1.append(copy.copy(in_file['duplicate']))
+
+ rules2 = lxml.etree.Element("Rules", priority="20")
+ rules2.append(in_file['priority'])
+ rules2.append(in_file['children'])
+ rules2.append(in_file['no_slash'])
+
+ rules3 = lxml.etree.Element("Rules", priority="10")
+ rules3.append(in_file['duplicate'])
+ rules3.append(in_file['regex'])
+ rules3.append(in_file['slash'])
+
+ rules = {"rules1.xml": rules1, "rules2.xml": rules2, "rules3.xml": rules3}
+
def setUp(self):
TestPrioDir.setUp(self)
+ set_setup_default("lax_decryption", True)
set_setup_default("rules_regex", False)
- def test_HandlesEntry(self):
+ def get_child(self, name):
+ """ Turn one of the XML documents in `rules` into a child
+ object """
+ filename = os.path.join(datastore, self.test_obj.name, name)
+ rv = self.test_obj.__child__(filename)
+ rv.data = lxml.etree.tostring(self.rules[name])
+ rv.Index()
+ return rv
+
+ def get_obj(self, core=None):
+ r = TestPrioDir.get_obj(self, core=core)
+ r.entries = dict([(n, self.get_child(n)) for n in self.rules.keys()])
+ return r
+
+ def _do_test(self, name, groups=None):
+ if groups is None:
+ groups = []
r = self.get_obj()
- r.Entries = dict(Path={"/etc/foo.conf": Mock(),
- "/etc/bar.conf": Mock()})
- r._matches = Mock()
- metadata = Mock()
-
- entry = lxml.etree.Element("Path", name="/etc/foo.conf")
- self.assertEqual(r.HandlesEntry(entry, metadata),
- r._matches.return_value)
- r._matches.assert_called_with(entry, metadata,
- r.Entries['Path'].keys())
-
- r._matches.reset_mock()
- entry = lxml.etree.Element("Path", name="/etc/baz.conf")
- self.assertEqual(r.HandlesEntry(entry, metadata),
- r._matches.return_value)
- r._matches.assert_called_with(entry, metadata,
- r.Entries['Path'].keys())
-
- r._matches.reset_mock()
- entry = lxml.etree.Element("Package", name="foo")
- self.assertFalse(r.HandlesEntry(entry, metadata))
-
- @patch("Bcfg2.Server.Plugin.PrioDir._matches")
- def test__matches(self, mock_matches):
+ metadata = Mock(groups=groups)
+ entry = copy.deepcopy(self.abstract[name])
+ self.assertTrue(r.HandlesEntry(entry, metadata))
+ r.HandleEntry(entry, metadata)
+ self.assertXMLEqual(entry, self.concrete[name])
+
+ def _do_test_failure(self, name, groups=None, handles=None):
+ if groups is None:
+ groups = []
r = self.get_obj()
- metadata = Mock()
-
- # test parent _matches() returning True
- entry = lxml.etree.Element("Path", name="/etc/foo.conf")
- candidate = lxml.etree.Element("Path", name="/etc/bar.conf")
- mock_matches.return_value = True
- self.assertTrue(r._matches(entry, metadata, candidate))
- mock_matches.assert_called_with(r, entry, metadata, candidate)
-
- # test all conditions returning False
- mock_matches.reset_mock()
- mock_matches.return_value = False
- self.assertFalse(r._matches(entry, metadata, candidate))
- mock_matches.assert_called_with(r, entry, metadata, candidate)
-
- # test special Path cases -- adding and removing trailing slash
- mock_matches.reset_mock()
- withslash = lxml.etree.Element("Path", name="/etc/foo")
- withoutslash = lxml.etree.Element("Path", name="/etc/foo/")
- self.assertTrue(r._matches(withslash, metadata, withoutslash))
- self.assertTrue(r._matches(withoutslash, metadata, withslash))
-
- if r._regex_enabled:
- mock_matches.reset_mock()
- candidate = lxml.etree.Element("Path", name="/etc/.*\.conf")
- self.assertTrue(r._matches(entry, metadata, candidate))
- mock_matches.assert_called_with(r, entry, metadata, candidate)
- self.assertIn("/etc/.*\.conf", r._regex_cache.keys())
+ metadata = Mock(groups=groups)
+ entry = self.abstract[name]
+ if handles is not None:
+ self.assertEqual(handles, r.HandlesEntry(entry, metadata))
+ self.assertRaises(PluginExecutionError,
+ r.HandleEntry, entry, metadata)
+
+ def test_basic(self):
+ """ Test basic Rules usage """
+ self._do_test('basic')
+ self._do_test_failure('unhandled', handles=False)
+
+ def test_priority(self):
+ """ Test that Rules respects priority """
+ self._do_test('priority')
+
+ def test_duplicate(self):
+ """ Test that Rules raises exceptions for duplicate entries """
+ self._do_test_failure('duplicate')
+
+ def test_content(self):
+ """ Test that Rules copies text content from concrete entries """
+ self._do_test('content')
+
+ def test_group(self):
+ """ Test that Rules respects <Group/> tags """
+ self._do_test('group', groups=['foogroup'])
+ self._do_test_failure('group', groups=['bargroup'], handles=False)
+
+ def test_children(self):
+ """ Test that Rules copies child elements from concrete entries """
+ self._do_test('children')
+
+ def test_regex(self):
+ """ Test that Rules handles regular expressions properly """
+ Bcfg2.Options.setup.rules_regex = False
+ self._do_test_failure('regex', handles=False)
+ Bcfg2.Options.setup.rules_regex = True
+ self._do_test('regex')
+ Bcfg2.Options.setup.rules_regex = False
+
+ def test_slash(self):
+ """ Test that Rules handles trailing slashes on Path entries """
+ self._do_test('slash')
+ self._do_test('no_slash')
diff --git a/testsuite/common.py b/testsuite/common.py
index b375d3703..9f46e01cc 100644
--- a/testsuite/common.py
+++ b/testsuite/common.py
@@ -282,31 +282,39 @@ class Bcfg2TestCase(unittest.TestCase):
"%s is not less than or equal to %s")
def assertXMLEqual(self, el1, el2, msg=None):
- """ Test that the two XML trees given are equal. Both
- elements and all children are expected to have ``name``
- attributes. """
+ """ Test that the two XML trees given are equal. """
if msg is None:
- msg = "XML trees were not equal"
+ msg = "XML trees are not equal: %s"
+ else:
+ msg += ": %s"
fullmsg = msg + "\nFirst: %s" % lxml.etree.tostring(el1) + \
"\nSecond: %s" % lxml.etree.tostring(el2)
- self.assertEqual(el1.tag, el2.tag, msg=fullmsg)
- self.assertEqual(el1.text, el2.text, msg=fullmsg)
+ self.assertEqual(el1.tag, el2.tag, msg=fullmsg % "Tags differ")
+ self.assertEqual(el1.text, el2.text,
+ msg=fullmsg % "Text content differs")
self.assertItemsEqual(el1.attrib.items(), el2.attrib.items(),
- msg=fullmsg)
+ msg=fullmsg % "Attributes differ")
self.assertEqual(len(el1.getchildren()),
len(el2.getchildren()),
- msg=fullmsg)
+ msg=fullmsg % "Different numbers of children")
+ matched = []
for child1 in el1.getchildren():
- cname = child1.get("name")
- self.assertIsNotNone(cname,
- msg="Element %s has no 'name' attribute" %
- child1.tag)
- children2 = el2.xpath("%s[@name='%s']" % (child1.tag, cname))
- self.assertEqual(len(children2), 1,
- msg="More than one %s element named %s" % \
- (child1.tag, cname))
- self.assertXMLEqual(child1, children2[0], msg=msg)
+ for child2 in el2.xpath(child1.tag):
+ if child2 in matched:
+ continue
+ try:
+ self.assertXMLEqual(child1, child2)
+ matched.append(child2)
+ break
+ except AssertionError:
+ continue
+ else:
+ assert False, \
+ fullmsg % ("Element %s is missing from second" %
+ lxml.etree.tostring(child1))
+ self.assertItemsEqual(el2.getchildren(), matched,
+ msg=fullmsg % "Second has extra element(s)")
class DBModelTestCase(Bcfg2TestCase):