summaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2012-08-22 08:22:46 -0400
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2012-08-22 08:31:06 -0400
commita69b11d94553bb0b6baf8e6b675d25fa40e0f001 (patch)
tree45dfadb4f70b1280da88cd06ba74785acc94e699 /testsuite
parentce9b7aedbe9cfe8de4e576dbe125c5a7161f5f5d (diff)
downloadbcfg2-a69b11d94553bb0b6baf8e6b675d25fa40e0f001.tar.gz
bcfg2-a69b11d94553bb0b6baf8e6b675d25fa40e0f001.tar.bz2
bcfg2-a69b11d94553bb0b6baf8e6b675d25fa40e0f001.zip
fixed conditional patching of pylibacl/selinux methods for py2.6
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/Testlib/TestClient/TestTools/TestPOSIX/Testbase.py513
-rw-r--r--testsuite/common.py15
2 files changed, 270 insertions, 258 deletions
diff --git a/testsuite/Testlib/TestClient/TestTools/TestPOSIX/Testbase.py b/testsuite/Testlib/TestClient/TestTools/TestPOSIX/Testbase.py
index e7772d508..65b92f75f 100644
--- a/testsuite/Testlib/TestClient/TestTools/TestPOSIX/Testbase.py
+++ b/testsuite/Testlib/TestClient/TestTools/TestPOSIX/Testbase.py
@@ -286,13 +286,15 @@ class TestPOSIXTool(Bcfg2TestCase):
mock_set_acls.assert_called_with(entry, path=entry.get("name"))
@skipUnless(has_acls, "ACLS not found, skipping")
+ @patchIf(has_acls, "posix1e.ACL")
+ @patchIf(has_acls, "posix1e.Entry")
@patch("os.path.isdir")
@patch("Bcfg2.Client.Tools.POSIX.base.%s._norm_uid" % test_obj.__name__)
@patch("Bcfg2.Client.Tools.POSIX.base.%s._norm_gid" % test_obj.__name__)
@patch("Bcfg2.Client.Tools.POSIX.base.%s._list_entry_acls" %
test_obj.__name__)
def test_set_acls(self, mock_list_entry_acls, mock_norm_gid, mock_norm_uid,
- mock_isdir):
+ mock_isdir, mock_Entry, mock_ACL):
entry = lxml.etree.Element("Path", name="/etc/foo", type="file")
# disable acls for the initial test
@@ -324,116 +326,113 @@ class TestPOSIXTool(Bcfg2TestCase):
mock_norm_uid.return_value = 10
mock_norm_gid.return_value = 100
- @patch("posix1e.ACL")
- @patch("posix1e.Entry")
- def inner(mock_Entry, mock_ACL):
- # set up the unreasonably complex return value for
- # posix1e.ACL(), which has three separate uses
- fileacl_rv = MagicMock()
- fileacl_rv.valid.return_value = True
- fileacl_rv.__iter__.return_value = iter(file_acls)
- filedef_rv = MagicMock()
- filedef_rv.valid.return_value = True
- filedef_rv.__iter__.return_value = iter(file_acls)
- acl_rv = MagicMock()
- def mock_acl_rv(file=None, filedef=None, acl=None):
- if file:
- return fileacl_rv
- elif filedef:
- return filedef_rv
- elif acl:
- return acl_rv
-
- # set up the equally unreasonably complex return value for
- # posix1e.Entry, which returns a new entry and adds it to
- # an ACL, so we have to track the Mock objects it returns.
- # why can't they just have an acl.add_entry() method?!?
- acl_entries = []
- def mock_entry_rv(acl):
- rv = MagicMock()
- rv.acl = acl
- rv.permset = set()
- acl_entries.append(rv)
- return rv
- mock_Entry.side_effect = mock_entry_rv
-
- def reset():
- mock_isdir.reset_mock()
- mock_ACL.reset_mock()
- mock_Entry.reset_mock()
- fileacl_rv.reset_mock()
-
- # test fs mounted noacl
- mock_ACL.side_effect = IOError(95, "Operation not permitted")
- self.assertFalse(self.ptool._set_acls(entry))
-
- # test other error
- reset()
- mock_ACL.side_effect = IOError
- self.assertFalse(self.ptool._set_acls(entry))
-
- reset()
- mock_ACL.side_effect = mock_acl_rv
- mock_isdir.return_value = True
- self.assertTrue(self.ptool._set_acls(entry))
- self.assertItemsEqual(mock_ACL.call_args_list,
- [call(file=entry.get("name")),
- call(filedef=entry.get("name"))])
- self.assertItemsEqual(fileacl_rv.delete_entry.call_args_list,
- [call(a) for a in remove_acls])
- self.assertItemsEqual(filedef_rv.delete_entry.call_args_list,
- [call(a) for a in remove_acls])
- mock_list_entry_acls.assert_called_with(entry)
- mock_norm_uid.assert_called_with("user")
- mock_norm_gid.assert_called_with("group")
- fileacl_rv.calc_mask.assert_any_call()
- fileacl_rv.applyto.assert_called_with(entry.get("name"),
- posix1e.ACL_TYPE_ACCESS)
- filedef_rv.calc_mask.assert_any_call()
- filedef_rv.applyto.assert_called_with(entry.get("name"),
- posix1e.ACL_TYPE_DEFAULT)
-
- # build tuples of the Entry objects that were added to acl
- # and defaacl so they're easier to compare for equality
- added_acls = []
- for acl in acl_entries:
- added_acls.append((acl.acl, acl.tag_type, acl.qualifier,
- sum(acl.permset)))
- self.assertItemsEqual(added_acls,
- [(filedef_rv, posix1e.ACL_USER, 10, 7),
- (fileacl_rv, posix1e.ACL_GROUP, 100, 5)])
-
- reset()
- # have to reassign these because they're iterators, and
- # they've already been iterated over once
- fileacl_rv.__iter__.return_value = iter(file_acls)
- filedef_rv.__iter__.return_value = iter(file_acls)
- mock_list_entry_acls.reset_mock()
- mock_norm_uid.reset_mock()
- mock_norm_gid.reset_mock()
- mock_isdir.return_value = False
- acl_entries = []
- self.assertTrue(self.ptool._set_acls(entry, path="/bin/bar"))
- mock_ACL.assert_called_with(file="/bin/bar")
- self.assertItemsEqual(fileacl_rv.delete_entry.call_args_list,
- [call(a) for a in remove_acls])
- mock_list_entry_acls.assert_called_with(entry)
- mock_norm_gid.assert_called_with("group")
- fileacl_rv.calc_mask.assert_any_call()
- fileacl_rv.applyto.assert_called_with("/bin/bar",
- posix1e.ACL_TYPE_ACCESS)
-
- added_acls = []
- for acl in acl_entries:
- added_acls.append((acl.acl, acl.tag_type, acl.qualifier,
- sum(acl.permset)))
- self.assertItemsEqual(added_acls,
- [(fileacl_rv, posix1e.ACL_GROUP, 100, 5)])
+ # set up the unreasonably complex return value for
+ # posix1e.ACL(), which has three separate uses
+ fileacl_rv = MagicMock()
+ fileacl_rv.valid.return_value = True
+ fileacl_rv.__iter__.return_value = iter(file_acls)
+ filedef_rv = MagicMock()
+ filedef_rv.valid.return_value = True
+ filedef_rv.__iter__.return_value = iter(file_acls)
+ acl_rv = MagicMock()
+ def mock_acl_rv(file=None, filedef=None, acl=None):
+ if file:
+ return fileacl_rv
+ elif filedef:
+ return filedef_rv
+ elif acl:
+ return acl_rv
+
+ # set up the equally unreasonably complex return value for
+ # posix1e.Entry, which returns a new entry and adds it to
+ # an ACL, so we have to track the Mock objects it returns.
+ # why can't they just have an acl.add_entry() method?!?
+ acl_entries = []
+ def mock_entry_rv(acl):
+ rv = MagicMock()
+ rv.acl = acl
+ rv.permset = set()
+ acl_entries.append(rv)
+ return rv
+ mock_Entry.side_effect = mock_entry_rv
- inner()
+ def reset():
+ mock_isdir.reset_mock()
+ mock_ACL.reset_mock()
+ mock_Entry.reset_mock()
+ fileacl_rv.reset_mock()
+
+ # test fs mounted noacl
+ mock_ACL.side_effect = IOError(95, "Operation not permitted")
+ self.assertFalse(self.ptool._set_acls(entry))
+
+ # test other error
+ reset()
+ mock_ACL.side_effect = IOError
+ self.assertFalse(self.ptool._set_acls(entry))
+
+ reset()
+ mock_ACL.side_effect = mock_acl_rv
+ mock_isdir.return_value = True
+ self.assertTrue(self.ptool._set_acls(entry))
+ self.assertItemsEqual(mock_ACL.call_args_list,
+ [call(file=entry.get("name")),
+ call(filedef=entry.get("name"))])
+ self.assertItemsEqual(fileacl_rv.delete_entry.call_args_list,
+ [call(a) for a in remove_acls])
+ self.assertItemsEqual(filedef_rv.delete_entry.call_args_list,
+ [call(a) for a in remove_acls])
+ mock_list_entry_acls.assert_called_with(entry)
+ mock_norm_uid.assert_called_with("user")
+ mock_norm_gid.assert_called_with("group")
+ fileacl_rv.calc_mask.assert_any_call()
+ fileacl_rv.applyto.assert_called_with(entry.get("name"),
+ posix1e.ACL_TYPE_ACCESS)
+ filedef_rv.calc_mask.assert_any_call()
+ filedef_rv.applyto.assert_called_with(entry.get("name"),
+ posix1e.ACL_TYPE_DEFAULT)
+
+ # build tuples of the Entry objects that were added to acl
+ # and defaacl so they're easier to compare for equality
+ added_acls = []
+ for acl in acl_entries:
+ added_acls.append((acl.acl, acl.tag_type, acl.qualifier,
+ sum(acl.permset)))
+ self.assertItemsEqual(added_acls,
+ [(filedef_rv, posix1e.ACL_USER, 10, 7),
+ (fileacl_rv, posix1e.ACL_GROUP, 100, 5)])
+
+ reset()
+ # have to reassign these because they're iterators, and
+ # they've already been iterated over once
+ fileacl_rv.__iter__.return_value = iter(file_acls)
+ filedef_rv.__iter__.return_value = iter(file_acls)
+ mock_list_entry_acls.reset_mock()
+ mock_norm_uid.reset_mock()
+ mock_norm_gid.reset_mock()
+ mock_isdir.return_value = False
+ acl_entries = []
+ self.assertTrue(self.ptool._set_acls(entry, path="/bin/bar"))
+ mock_ACL.assert_called_with(file="/bin/bar")
+ self.assertItemsEqual(fileacl_rv.delete_entry.call_args_list,
+ [call(a) for a in remove_acls])
+ mock_list_entry_acls.assert_called_with(entry)
+ mock_norm_gid.assert_called_with("group")
+ fileacl_rv.calc_mask.assert_any_call()
+ fileacl_rv.applyto.assert_called_with("/bin/bar",
+ posix1e.ACL_TYPE_ACCESS)
+
+ added_acls = []
+ for acl in acl_entries:
+ added_acls.append((acl.acl, acl.tag_type, acl.qualifier,
+ sum(acl.permset)))
+ self.assertItemsEqual(added_acls,
+ [(fileacl_rv, posix1e.ACL_GROUP, 100, 5)])
@skipUnless(has_selinux, "SELinux not found, skipping")
- def test_set_secontext(self):
+ @patchIf(has_selinux, "selinux.restorecon")
+ @patchIf(has_selinux, "selinux.lsetfilecon")
+ def test_set_secontext(self, mock_lsetfilecon, mock_restorecon):
entry = lxml.etree.Element("Path", name="/etc/foo", type="file")
# disable selinux for the initial test
@@ -441,37 +440,32 @@ class TestPOSIXTool(Bcfg2TestCase):
self.assertTrue(self.ptool._set_secontext(entry))
Bcfg2.Client.Tools.POSIX.base.has_selinux = True
- @patch("selinux.restorecon")
- @patch("selinux.lsetfilecon")
- def inner(mock_lsetfilecon, mock_restorecon):
- # no context given
- self.assertTrue(self.ptool._set_secontext(entry))
- self.assertFalse(mock_restorecon.called)
- self.assertFalse(mock_lsetfilecon.called)
-
- mock_restorecon.reset_mock()
- mock_lsetfilecon.reset_mock()
- entry.set("secontext", "__default__")
- self.assertTrue(self.ptool._set_secontext(entry))
- mock_restorecon.assert_called_with(entry.get("name"))
- self.assertFalse(mock_lsetfilecon.called)
-
- mock_restorecon.reset_mock()
- mock_lsetfilecon.reset_mock()
- mock_lsetfilecon.return_value = 0
- entry.set("secontext", "foo_t")
- self.assertTrue(self.ptool._set_secontext(entry))
- self.assertFalse(mock_restorecon.called)
- mock_lsetfilecon.assert_called_with(entry.get("name"), "foo_t")
-
- mock_restorecon.reset_mock()
- mock_lsetfilecon.reset_mock()
- mock_lsetfilecon.return_value = 1
- self.assertFalse(self.ptool._set_secontext(entry))
- self.assertFalse(mock_restorecon.called)
- mock_lsetfilecon.assert_called_with(entry.get("name"), "foo_t")
-
- inner()
+ # no context given
+ self.assertTrue(self.ptool._set_secontext(entry))
+ self.assertFalse(mock_restorecon.called)
+ self.assertFalse(mock_lsetfilecon.called)
+
+ mock_restorecon.reset_mock()
+ mock_lsetfilecon.reset_mock()
+ entry.set("secontext", "__default__")
+ self.assertTrue(self.ptool._set_secontext(entry))
+ mock_restorecon.assert_called_with(entry.get("name"))
+ self.assertFalse(mock_lsetfilecon.called)
+
+ mock_restorecon.reset_mock()
+ mock_lsetfilecon.reset_mock()
+ mock_lsetfilecon.return_value = 0
+ entry.set("secontext", "foo_t")
+ self.assertTrue(self.ptool._set_secontext(entry))
+ self.assertFalse(mock_restorecon.called)
+ mock_lsetfilecon.assert_called_with(entry.get("name"), "foo_t")
+
+ mock_restorecon.reset_mock()
+ mock_lsetfilecon.reset_mock()
+ mock_lsetfilecon.return_value = 1
+ self.assertFalse(self.ptool._set_secontext(entry))
+ self.assertFalse(mock_restorecon.called)
+ mock_lsetfilecon.assert_called_with(entry.get("name"), "foo_t")
@patch("grp.getgrnam")
def test_norm_gid(self, mock_getgrnam):
@@ -576,9 +570,9 @@ class TestPOSIXTool(Bcfg2TestCase):
context = 'system_u:object_r:root_t:s0'
path = '/test'
- @patch("selinux.getfilecon")
@patch('os.stat')
- def inner(mock_stat, mock_getfilecon):
+ @patchIf(has_selinux, "selinux.getfilecon")
+ def inner(mock_getfilecon, mock_stat):
mock_getfilecon.return_value = [len(context) + 1, context]
mock_stat.return_value = MagicMock()
# disable acls for this call and test them separately
@@ -587,7 +581,7 @@ class TestPOSIXTool(Bcfg2TestCase):
self.assertEqual(self.ptool._gather_data(path)[4], 'root_t')
Bcfg2.Client.Tools.POSIX.base.has_acls = state
mock_getfilecon.assert_called_with(path)
-
+
inner()
@skipUnless(has_acls, "ACLS not found, skipping")
@@ -607,6 +601,7 @@ class TestPOSIXTool(Bcfg2TestCase):
Bcfg2.Client.Tools.POSIX.base.has_selinux = state
mock_list_file_acls.assert_called_with(path)
+ @patchIf(has_selinux, "selinux.matchpathcon")
@patch("Bcfg2.Client.Tools.POSIX.base.%s._verify_acls" % test_obj.__name__)
@patch("Bcfg2.Client.Tools.POSIX.base.%s._gather_data" % test_obj.__name__)
@patch("Bcfg2.Client.Tools.POSIX.base.%s._norm_entry_uid" %
@@ -614,7 +609,8 @@ class TestPOSIXTool(Bcfg2TestCase):
@patch("Bcfg2.Client.Tools.POSIX.base.%s._norm_entry_gid" %
test_obj.__name__)
def test_verify_metadata(self, mock_norm_gid, mock_norm_uid,
- mock_gather_data, mock_verify_acls):
+ mock_gather_data, mock_verify_acls,
+ mock_matchpathcon):
entry = lxml.etree.Element("Path", name="/test", type="file",
group="group", owner="user", perms="664",
secontext='etc_t')
@@ -740,42 +736,38 @@ class TestPOSIXTool(Bcfg2TestCase):
entry.set("mtime", str(mtime))
entry.set("secontext", "__default__")
- @patch("selinux.matchpathcon")
- def inner(entry, mock_matchpathcon):
- context1 = "system_u:object_r:etc_t:s0"
- context2 = "system_u:object_r:root_t:s0"
- mock_matchpathcon.return_value = [1 + len(context1),
- context1]
- gather_data_rv = [stat_rv, None, None, None, None, []]
- for attr, idx, val in expected:
- gather_data_rv[idx] = val
- mock_gather_data.return_value = tuple(gather_data_rv)
- self.assertTrue(self.ptool._verify_metadata(entry))
- mock_gather_data.assert_called_with(entry.get("name"))
- mock_verify_acls.assert_called_with(entry,
- path=entry.get("name"))
- mock_matchpathcon.assert_called_with(entry.get("name"), 0)
- self.assertEqual(entry.get("current_exists", 'true'), 'true')
- for attr, idx, val in expected:
- self.assertEqual(entry.get(attr), val)
- self.assertEqual(entry.get("current_mtime"), str(mtime))
-
- entry = reset()
- entry.set("mtime", str(mtime))
- entry.set("secontext", "__default__")
- mock_matchpathcon.return_value = [1 + len(context2),
- context2]
- self.assertFalse(self.ptool._verify_metadata(entry))
- mock_gather_data.assert_called_with(entry.get("name"))
- mock_verify_acls.assert_called_with(entry,
- path=entry.get("name"))
- mock_matchpathcon.assert_called_with(entry.get("name"), 0)
- self.assertEqual(entry.get("current_exists", 'true'), 'true')
- for attr, idx, val in expected:
- self.assertEqual(entry.get(attr), val)
- self.assertEqual(entry.get("current_mtime"), str(mtime))
+ context1 = "system_u:object_r:etc_t:s0"
+ context2 = "system_u:object_r:root_t:s0"
+ mock_matchpathcon.return_value = [1 + len(context1),
+ context1]
+ gather_data_rv = [stat_rv, None, None, None, None, []]
+ for attr, idx, val in expected:
+ gather_data_rv[idx] = val
+ mock_gather_data.return_value = tuple(gather_data_rv)
+ self.assertTrue(self.ptool._verify_metadata(entry))
+ mock_gather_data.assert_called_with(entry.get("name"))
+ mock_verify_acls.assert_called_with(entry,
+ path=entry.get("name"))
+ mock_matchpathcon.assert_called_with(entry.get("name"), 0)
+ self.assertEqual(entry.get("current_exists", 'true'), 'true')
+ for attr, idx, val in expected:
+ self.assertEqual(entry.get(attr), val)
+ self.assertEqual(entry.get("current_mtime"), str(mtime))
- inner(entry)
+ entry = reset()
+ entry.set("mtime", str(mtime))
+ entry.set("secontext", "__default__")
+ mock_matchpathcon.return_value = [1 + len(context2),
+ context2]
+ self.assertFalse(self.ptool._verify_metadata(entry))
+ mock_gather_data.assert_called_with(entry.get("name"))
+ mock_verify_acls.assert_called_with(entry,
+ path=entry.get("name"))
+ mock_matchpathcon.assert_called_with(entry.get("name"), 0)
+ self.assertEqual(entry.get("current_exists", 'true'), 'true')
+ for attr, idx, val in expected:
+ self.assertEqual(entry.get(attr), val)
+ self.assertEqual(entry.get("current_mtime"), str(mtime))
@skipUnless(has_acls, "ACLS not found, skipping")
def test_list_entry_acls(self):
@@ -792,89 +784,94 @@ class TestPOSIXTool(Bcfg2TestCase):
@patch("pwd.getpwuid")
@patch("grp.getgrgid")
@patch("os.path.isdir")
- def test_list_file_acls(self, mock_isdir, mock_getgrgid, mock_getpwuid):
+ def test_list_file_acls(self, mock_isdir, mock_getgrgid, mock_getpwuid,
+ mock_ACL):
path = '/test'
- @patch("posix1e.ACL")
- def inner(mock_ACL):
- # build a set of file ACLs to return from posix1e.ACL(file=...)
- file_acls = []
- acl = Mock()
- acl.tag_type = posix1e.ACL_USER
- acl.qualifier = 10
- # yes, this is a bogus permset. thanks to _norm_acl_perms
- # it works and is easier than many of the alternatives.
- acl.permset = 'rwx'
- file_acls.append(acl)
- acl = Mock()
- acl.tag_type = posix1e.ACL_GROUP
- acl.qualifier = 100
- acl.permset = 'rx'
- file_acls.append(acl)
- acl = Mock()
- acl.tag_type = posix1e.ACL_MASK
- file_acls.append(acl)
- acls = {("access", posix1e.ACL_USER, "user"): 7,
- ("access", posix1e.ACL_GROUP, "group"): 5}
-
- # set up the unreasonably complex return value for
- # posix1e.ACL(), which has two separate uses
- fileacl_rv = MagicMock()
- fileacl_rv.valid.return_value = True
- fileacl_rv.__iter__.return_value = iter(file_acls)
- filedef_rv = MagicMock()
- filedef_rv.valid.return_value = True
- filedef_rv.__iter__.return_value = iter(file_acls)
- def mock_acl_rv(file=None, filedef=None):
- if file:
- return fileacl_rv
- elif filedef:
- return filedef_rv
- # other return values
- mock_isdir.return_value = False
- mock_getgrgid.return_value = ("group", "x", 5, [])
- mock_getpwuid.return_value = ("user", "x", 5, 5, "User",
- "/home/user", "/bin/zsh")
-
- def reset():
- mock_isdir.reset_mock()
- mock_getgrgid.reset_mock()
- mock_getpwuid.reset_mock()
- mock_ACL.reset_mock()
-
- mock_ACL.side_effect = IOError(95, "Operation not supported")
- self.assertItemsEqual(self.ptool._list_file_acls(path), dict())
-
- reset()
- mock_ACL.side_effect = IOError
- self.assertItemsEqual(self.ptool._list_file_acls(path), dict())
-
- reset()
- mock_ACL.side_effect = mock_acl_rv
- self.assertItemsEqual(self.ptool._list_file_acls(path), acls)
- mock_isdir.assert_called_with(path)
- mock_getgrgid.assert_called_with(100)
- mock_getpwuid.assert_called_with(10)
- mock_ACL.assert_called_with(file=path)
-
- reset()
- mock_isdir.return_value = True
- fileacl_rv.__iter__.return_value = iter(file_acls)
- filedef_rv.__iter__.return_value = iter(file_acls)
-
- defacls = acls
- for akey, perms in acls.items():
- defacls[('default', akey[1], akey[2])] = perms
- self.assertItemsEqual(self.ptool._list_file_acls(path), defacls)
- mock_isdir.assert_called_with(path)
- self.assertItemsEqual(mock_getgrgid.call_args_list,
- [call(100), call(100)])
- self.assertItemsEqual(mock_getpwuid.call_args_list,
- [call(10), call(10)])
- self.assertItemsEqual(mock_ACL.call_args_list,
- [call(file=path), call(filedef=path)])
+ # build a set of file ACLs to return from posix1e.ACL(file=...)
+ file_acls = []
+ acl = Mock()
+ acl.tag_type = posix1e.ACL_USER
+ acl.qualifier = 10
+ # yes, this is a bogus permset. thanks to _norm_acl_perms
+ # it works and is easier than many of the alternatives.
+ acl.permset = 'rwx'
+ file_acls.append(acl)
+ acl = Mock()
+ acl.tag_type = posix1e.ACL_GROUP
+ acl.qualifier = 100
+ acl.permset = 'rx'
+ file_acls.append(acl)
+ acl = Mock()
+ acl.tag_type = posix1e.ACL_MASK
+ file_acls.append(acl)
+ acls = {("access", posix1e.ACL_USER, "user"): 7,
+ ("access", posix1e.ACL_GROUP, "group"): 5}
+
+ # set up the unreasonably complex return value for
+ # posix1e.ACL(), which has two separate uses
+ fileacl_rv = MagicMock()
+ fileacl_rv.valid.return_value = True
+ fileacl_rv.__iter__.return_value = iter(file_acls)
+ filedef_rv = MagicMock()
+ filedef_rv.valid.return_value = True
+ filedef_rv.__iter__.return_value = iter(file_acls)
+ def mock_acl_rv(file=None, filedef=None):
+ if file:
+ return fileacl_rv
+ elif filedef:
+ return filedef_rv
+ # other return values
+ mock_isdir.return_value = False
+ mock_getgrgid.return_value = ("group", "x", 5, [])
+ mock_getpwuid.return_value = ("user", "x", 5, 5, "User",
+ "/home/user", "/bin/zsh")
+
+ def reset():
+ mock_isdir.reset_mock()
+ mock_getgrgid.reset_mock()
+ mock_getpwuid.reset_mock()
+ mock_ACL.reset_mock()
- inner()
+ mock_ACL.side_effect = IOError(95, "Operation not supported")
+ self.assertItemsEqual(self.ptool._list_file_acls(path), dict())
+
+ reset()
+ mock_ACL.side_effect = IOError
+ self.assertItemsEqual(self.ptool._list_file_acls(path), dict())
+
+ reset()
+ mock_ACL.side_effect = mock_acl_rv
+ self.assertItemsEqual(self.ptool._list_file_acls(path), acls)
+ mock_isdir.assert_called_with(path)
+ mock_getgrgid.assert_called_with(100)
+ mock_getpwuid.assert_called_with(10)
+ mock_ACL.assert_called_with(file=path)
+
+ reset()
+ mock_isdir.return_value = True
+ fileacl_rv.__iter__.return_value = iter(file_acls)
+ filedef_rv.__iter__.return_value = iter(file_acls)
+
+ defacls = acls
+ for akey, perms in acls.items():
+ defacls[('default', akey[1], akey[2])] = perms
+ self.assertItemsEqual(self.ptool._list_file_acls(path), defacls)
+ mock_isdir.assert_called_with(path)
+ self.assertItemsEqual(mock_getgrgid.call_args_list,
+ [call(100), call(100)])
+ self.assertItemsEqual(mock_getpwuid.call_args_list,
+ [call(10), call(10)])
+ self.assertItemsEqual(mock_ACL.call_args_list,
+ [call(file=path), call(filedef=path)])
+
+ if has_acls:
+ # python 2.6 applies decorators at compile-time, not at
+ # run-time, so we can't do these as decorators because
+ # pylibacl might not be installed. (If it's not, this test
+ # will be skipped, so as long as this is done at run-time
+ # we're safe.)
+ test_list_file_acls = patch("posix1e.ACL")(test_list_file_acls)
@skipUnless(has_acls, "ACLS not found, skipping")
@patch("Bcfg2.Client.Tools.POSIX.base.%s._list_file_acls" %
diff --git a/testsuite/common.py b/testsuite/common.py
index b49b75477..5788ad05d 100644
--- a/testsuite/common.py
+++ b/testsuite/common.py
@@ -1,6 +1,7 @@
import os
import sys
import unittest
+from mock import patch
from functools import wraps
datastore = "/"
@@ -253,3 +254,17 @@ def syncdb(modeltest):
inst = modeltest(methodName='test_syncdb')
inst.test_syncdb()
inst.test_cleandb()
+
+
+def patchIf(condition, entity, **kwargs):
+ """ perform conditional patching. this is necessary because some
+ libraries might not be installed (e.g., selinux, pylibacl), and
+ patching will barf on that. Other workarounds are not available
+ to us; e.g., context managers aren't in python 2.4, and using
+ inner functions doesn't work because python 2.6 applies all
+ decorators at compile-time, not at run-time, so decorating inner
+ functions does not prevent the decorators from being run. """
+ if condition:
+ return patch(entity, **kwargs)
+ else:
+ return lambda f: f