summaryrefslogtreecommitdiffstats
path: root/testsuite/Testsrc/Testlib/TestServer/TestPlugins
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/Testsrc/Testlib/TestServer/TestPlugins')
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestAWSTags.py140
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py8
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py19
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py105
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py65
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py79
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py38
7 files changed, 349 insertions, 105 deletions
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestAWSTags.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestAWSTags.py
new file mode 100644
index 000000000..05e0bb9a1
--- /dev/null
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestAWSTags.py
@@ -0,0 +1,140 @@
+import os
+import sys
+import lxml.etree
+import Bcfg2.Server.Plugin
+from mock import Mock, MagicMock, patch
+try:
+ from Bcfg2.Server.Plugins.AWSTags import *
+ HAS_BOTO = True
+except ImportError:
+ HAS_BOTO = False
+
+# 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 TestPlugin import TestPlugin, TestConnector, TestClientRunHooks
+
+config = '''
+<AWSTags>
+ <Tag name="name-only">
+ <Group>group1</Group>
+ <Group>group2</Group>
+ </Tag>
+ <Tag name="name-and-value" value="value">
+ <Group>group3</Group>
+ </Tag>
+ <Tag name="regex-(.*)">
+ <Group>group-$1</Group>
+ </Tag>
+ <Tag name="regex-value" value="(.*)">
+ <Group>group-$1</Group>
+ </Tag>
+</AWSTags>
+'''
+
+tags = {
+ "empty.example.com": {},
+ "no-matches.example.com": {"nameonly": "foo",
+ "Name": "no-matches",
+ "foo": "bar"},
+ "foo.example.com": {"name-only": "name-only",
+ "name-and-value": "wrong",
+ "regex-name": "foo"},
+ "bar.example.com": {"name-and-value": "value",
+ "regex-value": "bar"}}
+
+groups = {
+ "empty.example.com": [],
+ "no-matches.example.com": [],
+ "foo.example.com": ["group1", "group2", "group-name"],
+ "bar.example.com": ["group3", "group-value", "group-bar"]}
+
+
+def make_instance(name):
+ rv = Mock()
+ rv.private_dns_name = name
+ rv.tags = tags[name]
+ return rv
+
+
+instances = [make_instance(n) for n in tags.keys()]
+
+
+def get_all_instances(filters=None):
+ insts = [i for i in instances
+ if i.private_dns_name == filters['private-dns-name']]
+ res = Mock()
+ res.instances = insts
+ return [res]
+
+
+if HAS_BOTO:
+ class TestAWSTags(TestPlugin, TestClientRunHooks, TestConnector):
+ test_obj = AWSTags
+
+ def get_obj(self, core=None):
+ @patchIf(not isinstance(Bcfg2.Server.Plugins.AWSTags.connect_ec2,
+ Mock),
+ "Bcfg2.Server.Plugins.AWSTags.connect_ec2", Mock())
+ @patch("lxml.etree.Element", Mock())
+ def inner():
+ obj = TestPlugin.get_obj(self, core=core)
+ obj.config.data = config
+ obj.config.Index()
+ return obj
+ return inner()
+
+ @patch("Bcfg2.Server.Plugins.AWSTags.connect_ec2")
+ def test_connect(self, mock_connect_ec2):
+ """ Test connection to EC2 """
+ key_id = "a09sdbipasdf"
+ access_key = "oiilb234ipwe9"
+
+ def cfp_get(section, option):
+ if option == "access_key_id":
+ return key_id
+ elif option == "secret_access_key":
+ return access_key
+ else:
+ return Mock()
+
+ core = Mock()
+ core.setup.cfp.get = Mock(side_effect=cfp_get)
+ awstags = self.get_obj(core=core)
+ mock_connect_ec2.assert_called_with(
+ aws_access_key_id=key_id,
+ aws_secret_access_key=access_key)
+
+ def test_get_additional_data(self):
+ """ Test AWSTags.get_additional_data() """
+ awstags = self.get_obj()
+ awstags._ec2.get_all_instances = \
+ Mock(side_effect=get_all_instances)
+
+ for hostname, expected in tags.items():
+ metadata = Mock()
+ metadata.hostname = hostname
+ self.assertItemsEqual(awstags.get_additional_data(metadata),
+ expected)
+
+ def test_get_additional_groups_caching(self):
+ """ Test AWSTags.get_additional_groups() with caching enabled """
+ awstags = self.get_obj()
+ awstags._ec2.get_all_instances = \
+ Mock(side_effect=get_all_instances)
+
+ for hostname, expected in groups.items():
+ metadata = Mock()
+ metadata.hostname = hostname
+ actual = awstags.get_additional_groups(metadata)
+ msg = """%s has incorrect groups:
+actual: %s
+expected: %s""" % (hostname, actual, expected)
+ self.assertItemsEqual(actual, expected, msg)
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py
index 71a7410da..2bfec0e2d 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgEncryptedGenerator.py
@@ -1,6 +1,7 @@
import os
import sys
import lxml.etree
+import Bcfg2.Server.Plugins.Cfg
from mock import Mock, MagicMock, patch
from Bcfg2.Server.Plugins.Cfg.CfgEncryptedGenerator import *
from Bcfg2.Server.Plugin import PluginExecutionError
@@ -47,9 +48,10 @@ if can_skip or HAS_CRYPTO:
ceg = self.get_obj()
ceg.handle_event(event)
mock_handle_event.assert_called_with(ceg, event)
- mock_decrypt.assert_called_with("encrypted",
- setup=SETUP,
- algorithm=mock_get_algorithm.return_value)
+ mock_decrypt.assert_called_with(
+ "encrypted",
+ setup=Bcfg2.Server.Plugins.Cfg.SETUP,
+ algorithm=mock_get_algorithm.return_value)
self.assertEqual(ceg.data, "plaintext")
reset()
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py
index dc4b11241..e139a592b 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPrivateKeyCreator.py
@@ -31,6 +31,7 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile):
should_monitor = False
def get_obj(self, name=None, fam=None):
+ Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator.CFG = Mock()
return TestCfgCreator.get_obj(self, name=name)
@patch("Bcfg2.Server.Plugins.Cfg.CfgCreator.handle_event")
@@ -259,24 +260,6 @@ class TestCfgPrivateKeyCreator(TestCfgCreator, TestStructFile):
pkc.write_data.assert_called_with("privatekey", group="foo")
mock_rmtree.assert_called_with(datastore)
- reset()
- self.assertEqual(pkc.create_data(entry, metadata, return_pair=True),
- ("ssh-rsa publickey pubkey.filename\n",
- "privatekey"))
- pkc.XMLMatch.assert_called_with(metadata)
- pkc.get_specificity.assert_called_with(metadata,
- pkc.XMLMatch.return_value)
- pkc._gen_keypair.assert_called_with(metadata,
- pkc.XMLMatch.return_value)
- self.assertItemsEqual(mock_open.call_args_list,
- [call(privkey + ".pub"), call(privkey)])
- pkc.pubkey_creator.get_filename.assert_called_with(group="foo")
- pkc.pubkey_creator.write_data.assert_called_with(
- "ssh-rsa publickey pubkey.filename\n",
- group="foo")
- pkc.write_data.assert_called_with("privatekey", group="foo")
- mock_rmtree.assert_called_with(datastore)
-
inner()
if HAS_CRYPTO:
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py
index 04772cf9a..ef4610fae 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/TestCfgPublicKeyCreator.py
@@ -26,6 +26,7 @@ class TestCfgPublicKeyCreator(TestCfgCreator, TestStructFile):
should_monitor = False
def get_obj(self, name=None, fam=None):
+ Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator.CFG = Mock()
return TestCfgCreator.get_obj(self, name=name)
@patch("Bcfg2.Server.Plugins.Cfg.CfgCreator.handle_event")
@@ -37,41 +38,117 @@ class TestCfgPublicKeyCreator(TestCfgCreator, TestStructFile):
mock_HandleEvent.assert_called_with(pkc, evt)
mock_handle_event.assert_called_with(pkc, evt)
- def test_create_data(self):
+ @patch("os.unlink")
+ @patch("os.path.exists")
+ @patch("tempfile.mkstemp")
+ @patch("os.fdopen", Mock())
+ @patch("%s.open" % builtins)
+ def test_create_data(self, mock_open, mock_mkstemp, mock_exists,
+ mock_unlink):
metadata = Mock()
pkc = self.get_obj()
pkc.cfg = Mock()
+ pkc.core = Mock()
+ pkc.cmd = Mock()
+ pkc.write_data = Mock()
+ pubkey = "public key data"
privkey_entryset = Mock()
privkey_creator = Mock()
- pubkey = Mock()
- privkey = Mock()
- privkey_creator.create_data.return_value = (pubkey, privkey)
- privkey_entryset.best_matching.return_value = privkey_creator
+ privkey_creator.get_specificity = Mock()
+ privkey_creator.get_specificity.return_value = dict()
+ fileloc = pkc.get_filename()
pkc.cfg.entries = {"/home/foo/.ssh/id_rsa": privkey_entryset}
+ def reset():
+ privkey_creator.reset_mock()
+ pkc.cmd.reset_mock()
+ pkc.core.reset_mock()
+ pkc.write_data.reset_mock()
+ mock_exists.reset_mock()
+ mock_unlink.reset_mock()
+ mock_mkstemp.reset_mock()
+ mock_open.reset_mock()
+
# public key doesn't end in .pub
entry = lxml.etree.Element("Path", name="/home/bar/.ssh/bogus")
self.assertRaises(CfgCreationError,
pkc.create_data, entry, metadata)
+ self.assertFalse(pkc.write_data.called)
+
+ # cannot bind private key
+ reset()
+ pkc.core.Bind.side_effect = PluginExecutionError
+ entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub")
+ self.assertRaises(CfgCreationError,
+ pkc.create_data, entry, metadata)
+ self.assertFalse(pkc.write_data.called)
# private key not in cfg.entries
+ reset()
+ pkc.core.Bind.side_effect = None
+ pkc.core.Bind.return_value = "private key data"
entry = lxml.etree.Element("Path", name="/home/bar/.ssh/id_rsa.pub")
self.assertRaises(CfgCreationError,
pkc.create_data, entry, metadata)
+ self.assertFalse(pkc.write_data.called)
- # successful operation
+ # no privkey.xml defined
+ reset()
+ privkey_entryset.best_matching.side_effect = PluginExecutionError
+ entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub")
+ self.assertRaises(CfgCreationError,
+ pkc.create_data, entry, metadata)
+ self.assertFalse(pkc.write_data.called)
+
+ # successful operation, create new key
+ reset()
+ pkc.cmd.run.return_value = Mock()
+ pkc.cmd.run.return_value.success = True
+ pkc.cmd.run.return_value.stdout = pubkey
+ mock_mkstemp.return_value = (Mock(), str(Mock()))
+ mock_exists.return_value = False
+ privkey_entryset.best_matching.side_effect = None
+ privkey_entryset.best_matching.return_value = privkey_creator
entry = lxml.etree.Element("Path", name="/home/foo/.ssh/id_rsa.pub")
self.assertEqual(pkc.create_data(entry, metadata), pubkey)
+ self.assertTrue(pkc.core.Bind.called)
+ (privkey_entry, md) = pkc.core.Bind.call_args[0]
+ self.assertXMLEqual(privkey_entry,
+ lxml.etree.Element("Path",
+ name="/home/foo/.ssh/id_rsa"))
+ self.assertEqual(md, metadata)
+
privkey_entryset.get_handlers.assert_called_with(metadata, CfgCreator)
- privkey_entryset.best_matching.assert_called_with(metadata,
- privkey_entryset.get_handlers.return_value)
- self.assertXMLEqual(privkey_creator.create_data.call_args[0][0],
+ privkey_entryset.best_matching.assert_called_with(
+ metadata,
+ privkey_entryset.get_handlers.return_value)
+ mock_exists.assert_called_with(fileloc)
+ pkc.cmd.run.assert_called_with(["ssh-keygen", "-y", "-f",
+ mock_mkstemp.return_value[1]])
+ self.assertEqual(pkc.write_data.call_args[0][0], pubkey)
+ mock_unlink.assert_called_with(mock_mkstemp.return_value[1])
+ self.assertFalse(mock_open.called)
+
+ # successful operation, no need to create new key
+ reset()
+ mock_exists.return_value = True
+ mock_open.return_value = Mock()
+ mock_open.return_value.read.return_value = pubkey
+ pkc.cmd.run.return_value.stdout = None
+ self.assertEqual(pkc.create_data(entry, metadata), pubkey)
+ self.assertTrue(pkc.core.Bind.called)
+ (privkey_entry, md) = pkc.core.Bind.call_args[0]
+ self.assertXMLEqual(privkey_entry,
lxml.etree.Element("Path",
name="/home/foo/.ssh/id_rsa"))
- self.assertEqual(privkey_creator.create_data.call_args[0][1], metadata)
+ self.assertEqual(md, metadata)
- # no privkey.xml
- privkey_entryset.best_matching.side_effect = PluginExecutionError
- self.assertRaises(CfgCreationError,
- pkc.create_data, entry, metadata)
+ privkey_entryset.get_handlers.assert_called_with(metadata, CfgCreator)
+ privkey_entryset.best_matching.assert_called_with(
+ metadata,
+ privkey_entryset.get_handlers.return_value)
+ mock_exists.assert_called_with(fileloc)
+ mock_open.assert_called_with(fileloc)
+ self.assertFalse(mock_mkstemp.called)
+ self.assertFalse(pkc.write_data.called)
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py
index 2e758774e..fdfb3a9f7 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py
@@ -6,7 +6,7 @@ import Bcfg2.Options
from Bcfg2.Compat import walk_packages
from mock import Mock, MagicMock, patch
from Bcfg2.Server.Plugins.Cfg import *
-from Bcfg2.Server.Plugin import PluginExecutionError
+from Bcfg2.Server.Plugin import PluginExecutionError, Specificity
# add all parent testsuite directories to sys.path to allow (most)
# relative imports in python 2.4
@@ -298,21 +298,20 @@ class TestCfgEntrySet(TestEntrySet):
for submodule in walk_packages(path=Bcfg2.Server.Plugins.Cfg.__path__,
prefix="Bcfg2.Server.Plugins.Cfg."):
expected.append(submodule[1].rsplit('.', 1)[-1])
- eset = self.get_obj()
- self.assertItemsEqual(expected,
- [h.__name__ for h in eset.handlers])
+ self.assertItemsEqual(expected, [h.__name__ for h in handlers()])
- def test_handle_event(self):
+ @patch("Bcfg2.Server.Plugins.Cfg.handlers")
+ def test_handle_event(self, mock_handlers):
eset = self.get_obj()
eset.entry_init = Mock()
- eset._handlers = [Mock(), Mock(), Mock()]
- for hdlr in eset.handlers:
+ mock_handlers.return_value = [Mock(), Mock(), Mock()]
+ for hdlr in mock_handlers.return_value:
hdlr.__name__ = "handler"
eset.entries = dict()
def reset():
eset.entry_init.reset_mock()
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
hdlr.reset_mock()
# test that a bogus deleted event is discarded
@@ -322,7 +321,7 @@ class TestCfgEntrySet(TestEntrySet):
eset.handle_event(evt)
self.assertFalse(eset.entry_init.called)
self.assertItemsEqual(eset.entries, dict())
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
self.assertFalse(hdlr.handles.called)
self.assertFalse(hdlr.ignore.called)
@@ -333,7 +332,7 @@ class TestCfgEntrySet(TestEntrySet):
evt.filename = os.path.join(datastore, "test.txt")
# test with no handler that handles
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
hdlr.handles.return_value = False
hdlr.ignore.return_value = False
@@ -341,16 +340,16 @@ class TestCfgEntrySet(TestEntrySet):
eset.handle_event(evt)
self.assertFalse(eset.entry_init.called)
self.assertItemsEqual(eset.entries, dict())
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
hdlr.handles.assert_called_with(evt, basename=eset.path)
hdlr.ignore.assert_called_with(evt, basename=eset.path)
# test with a handler that handles the entry
reset()
- eset.handlers[-1].handles.return_value = True
+ mock_handlers.return_value[-1].handles.return_value = True
eset.handle_event(evt)
- eset.entry_init.assert_called_with(evt, eset.handlers[-1])
- for hdlr in eset.handlers:
+ eset.entry_init.assert_called_with(evt, mock_handlers.return_value[-1])
+ for hdlr in mock_handlers.return_value:
hdlr.handles.assert_called_with(evt, basename=eset.path)
if not hdlr.return_value:
hdlr.ignore.assert_called_with(evt, basename=eset.path)
@@ -358,14 +357,14 @@ class TestCfgEntrySet(TestEntrySet):
# test with a handler that ignores the entry before one
# that handles it
reset()
- eset.handlers[0].ignore.return_value = True
+ mock_handlers.return_value[0].ignore.return_value = True
eset.handle_event(evt)
self.assertFalse(eset.entry_init.called)
- eset.handlers[0].handles.assert_called_with(evt,
+ mock_handlers.return_value[0].handles.assert_called_with(evt,
basename=eset.path)
- eset.handlers[0].ignore.assert_called_with(evt,
+ mock_handlers.return_value[0].ignore.assert_called_with(evt,
basename=eset.path)
- for hdlr in eset.handlers[1:]:
+ for hdlr in mock_handlers.return_value[1:]:
self.assertFalse(hdlr.handles.called)
self.assertFalse(hdlr.ignore.called)
@@ -377,7 +376,7 @@ class TestCfgEntrySet(TestEntrySet):
eset.entries[evt.filename] = Mock()
eset.handle_event(evt)
self.assertFalse(eset.entry_init.called)
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
self.assertFalse(hdlr.handles.called)
self.assertFalse(hdlr.ignore.called)
eset.entries[evt.filename].handle_event.assert_called_with(evt)
@@ -387,7 +386,7 @@ class TestCfgEntrySet(TestEntrySet):
evt.code2str.return_value = "deleted"
eset.handle_event(evt)
self.assertFalse(eset.entry_init.called)
- for hdlr in eset.handlers:
+ for hdlr in mock_handlers.return_value:
self.assertFalse(hdlr.handles.called)
self.assertFalse(hdlr.ignore.called)
self.assertItemsEqual(eset.entries, dict())
@@ -462,7 +461,7 @@ class TestCfgEntrySet(TestEntrySet):
metadata = Mock()
# test basic entry, no validation, no filters, etc.
- eset._generate_data.return_value = "data"
+ eset._generate_data.return_value = ("data", None)
eset.get_handlers.return_value = []
bound = eset.bind_entry(entry, metadata)
eset.bind_info_to_entry.assert_called_with(entry, metadata)
@@ -475,7 +474,7 @@ class TestCfgEntrySet(TestEntrySet):
# test empty entry
entry = reset()
- eset._generate_data.return_value = ""
+ eset._generate_data.return_value = ("", None)
bound = eset.bind_entry(entry, metadata)
eset.bind_info_to_entry.assert_called_with(entry, metadata)
eset._generate_data.assert_called_with(entry, metadata)
@@ -486,7 +485,9 @@ class TestCfgEntrySet(TestEntrySet):
# test filters
entry = reset()
- eset._generate_data.return_value = "initial data"
+ generator = Mock()
+ generator.specific = Specificity(all=True)
+ eset._generate_data.return_value = ("initial data", generator)
filters = [Mock(), Mock()]
filters[0].modify_data.return_value = "modified data"
filters[1].modify_data.return_value = "final data"
@@ -508,7 +509,7 @@ class TestCfgEntrySet(TestEntrySet):
entry.set("encoding", "base64")
mock_b64encode.return_value = "base64 data"
eset.get_handlers.return_value = []
- eset._generate_data.return_value = "data"
+ eset._generate_data.return_value = ("data", None)
bound = eset.bind_entry(entry, metadata)
eset.bind_info_to_entry.assert_called_with(entry, metadata)
eset._generate_data.assert_called_with(entry, metadata)
@@ -559,7 +560,7 @@ class TestCfgEntrySet(TestEntrySet):
def reset():
for e in eset.entries.values():
- if e.specific is not None:
+ if hasattr(e.specific, "reset_mock"):
e.specific.reset_mock()
metadata = Mock()
@@ -576,7 +577,7 @@ class TestCfgEntrySet(TestEntrySet):
[eset.entries['test1.txt'],
eset.entries['test3.txt']])
for entry in eset.entries.values():
- if entry.specific is not None:
+ if hasattr(entry.specific.matches, "called"):
self.assertFalse(entry.specific.matches.called)
reset()
@@ -584,20 +585,22 @@ class TestCfgEntrySet(TestEntrySet):
[eset.entries['test6.txt']])
eset.entries['test6.txt'].specific.matches.assert_called_with(metadata)
for ename, entry in eset.entries.items():
- if ename != 'test6.txt' and entry.specific is not None:
+ if (ename != 'test6.txt' and
+ hasattr(entry.specific.matches, "called")):
self.assertFalse(entry.specific.matches.called)
reset()
self.assertItemsEqual(eset.get_handlers(metadata, CfgFilter), [])
eset.entries['test7.txt'].specific.matches.assert_called_with(metadata)
for ename, entry in eset.entries.items():
- if ename != 'test7.txt' and entry.specific is not None:
+ if (ename != 'test7.txt' and
+ hasattr(entry.specific.matches, "called")):
self.assertFalse(entry.specific.matches.called)
reset()
self.assertItemsEqual(eset.get_handlers(metadata, Mock), [])
for ename, entry in eset.entries.items():
- if entry.specific is not None:
+ if hasattr(entry.specific.matches, "called"):
self.assertFalse(entry.specific.matches.called)
def test_bind_info_to_entry(self):
@@ -692,7 +695,7 @@ class TestCfgEntrySet(TestEntrySet):
eset._create_data.reset_mock()
# test success
- self.assertEqual(eset._generate_data(entry, metadata),
+ self.assertEqual(eset._generate_data(entry, metadata)[0],
"data")
eset.get_handlers.assert_called_with(metadata, CfgGenerator)
eset.best_matching.assert_called_with(metadata,
@@ -709,7 +712,7 @@ class TestCfgEntrySet(TestEntrySet):
reset()
eset.best_matching.side_effect = PluginExecutionError
self.assertEqual(eset._generate_data(entry, metadata),
- eset._create_data.return_value)
+ (eset._create_data.return_value, None))
eset.get_handlers.assert_called_with(metadata, CfgGenerator)
eset.best_matching.assert_called_with(metadata,
eset.get_handlers.return_value)
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
index 742946c42..a07fffba1 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
@@ -339,6 +339,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
@patch('Bcfg2.Utils.locked', Mock(return_value=False))
@patch('fcntl.lockf', Mock())
+ @patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.load_xml")
@patch('os.open')
@patch('os.fdopen')
@patch('os.unlink')
@@ -346,7 +347,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
@patch('os.path.islink')
@patch('os.readlink')
def test_write_xml(self, mock_readlink, mock_islink, mock_rename,
- mock_unlink, mock_fdopen, mock_open):
+ mock_unlink, mock_fdopen, mock_open, mock_load_xml):
fname = "clients.xml"
config = self.get_obj(fname)
fpath = os.path.join(self.metadata.data, fname)
@@ -360,6 +361,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
mock_unlink.reset_mock()
mock_fdopen.reset_mock()
mock_open.reset_mock()
+ mock_load_xml.reset_mock()
mock_islink.return_value = False
@@ -371,6 +373,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
self.assertTrue(mock_fdopen.return_value.write.called)
mock_islink.assert_called_with(fpath)
mock_rename.assert_called_with(tmpfile, fpath)
+ mock_load_xml.assert_called_with()
# test: clients.xml.new is locked the first time we write it
def rv(fname, mode):
@@ -389,6 +392,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
self.assertTrue(mock_fdopen.return_value.write.called)
mock_islink.assert_called_with(fpath)
mock_rename.assert_called_with(tmpfile, fpath)
+ mock_load_xml.assert_called_with()
# test writing a symlinked clients.xml
reset()
@@ -397,6 +401,7 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
mock_readlink.return_value = linkdest
config.write_xml(fpath, get_clients_test_tree())
mock_rename.assert_called_with(tmpfile, linkdest)
+ mock_load_xml.assert_called_with()
# test failure of os.rename()
reset()
@@ -830,21 +835,18 @@ class TestMetadata(_TestMetadata, TestClientRunHooks, TestDatabaseBacked):
self.assertEqual(metadata.groups['group4'].category, 'category1')
self.assertEqual(metadata.default, "group1")
- all_groups = []
- negated_groups = []
+ all_groups = set()
+ negated_groups = set()
for group in get_groups_test_tree().xpath("//Groups/Client//*") + \
get_groups_test_tree().xpath("//Groups/Group//*"):
if group.tag == 'Group' and not group.getchildren():
if group.get("negate", "false").lower() == 'true':
- negated_groups.append(group.get("name"))
+ negated_groups.add(group.get("name"))
else:
- all_groups.append(group.get("name"))
- self.assertItemsEqual([g.name
- for g in metadata.group_membership.values()],
- all_groups)
- self.assertItemsEqual([g.name
- for g in metadata.negated_groups.values()],
- negated_groups)
+ all_groups.add(group.get("name"))
+ self.assertItemsEqual(metadata.ordered_groups, all_groups)
+ self.assertItemsEqual(metadata.group_membership.keys(), all_groups)
+ self.assertItemsEqual(metadata.negated_groups.keys(), negated_groups)
@patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.load_xml", Mock())
def test_set_profile(self):
@@ -885,10 +887,13 @@ class TestMetadata(_TestMetadata, TestClientRunHooks, TestDatabaseBacked):
metadata = self.load_clients_data(metadata=self.load_groups_data())
if not metadata._use_db:
metadata.clients_xml.write = Mock()
+ metadata.core.build_metadata = Mock()
+ metadata.core.build_metadata.side_effect = \
+ lambda c: metadata.get_initial_metadata(c)
+
metadata.set_profile("client1", "group2", None)
mock_update_client.assert_called_with("client1",
dict(profile="group2"))
- metadata.clients_xml.write.assert_any_call()
self.assertEqual(metadata.clientgroups["client1"], ["group2"])
metadata.clients_xml.write.reset_mock()
@@ -910,8 +915,8 @@ class TestMetadata(_TestMetadata, TestClientRunHooks, TestDatabaseBacked):
self.assertEqual(metadata.clientgroups["uuid_new"], ["group1"])
@patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.load_xml", Mock())
- @patch("socket.gethostbyaddr")
- def test_resolve_client(self, mock_gethostbyaddr):
+ @patch("socket.getnameinfo")
+ def test_resolve_client(self, mock_getnameinfo):
metadata = self.load_clients_data(metadata=self.load_groups_data())
metadata.session_cache[('1.2.3.3', None)] = (time.time(), 'client3')
self.assertEqual(metadata.resolve_client(('1.2.3.3', None)), 'client3')
@@ -928,22 +933,22 @@ class TestMetadata(_TestMetadata, TestClientRunHooks, TestDatabaseBacked):
cleanup_cache=True), 'client3')
self.assertEqual(metadata.session_cache, dict())
- mock_gethostbyaddr.return_value = ('client6', [], ['1.2.3.6'])
- self.assertEqual(metadata.resolve_client(('1.2.3.6', None)), 'client6')
- mock_gethostbyaddr.assert_called_with('1.2.3.6')
+ mock_getnameinfo.return_value = ('client6', [], ['1.2.3.6'])
+ self.assertEqual(metadata.resolve_client(('1.2.3.6', 6789)), 'client6')
+ mock_getnameinfo.assert_called_with(('1.2.3.6', 6789), socket.NI_NAMEREQD)
- mock_gethostbyaddr.reset_mock()
- mock_gethostbyaddr.return_value = ('alias3', [], ['1.2.3.7'])
- self.assertEqual(metadata.resolve_client(('1.2.3.7', None)), 'client4')
- mock_gethostbyaddr.assert_called_with('1.2.3.7')
+ mock_getnameinfo.reset_mock()
+ mock_getnameinfo.return_value = ('alias3', [], ['1.2.3.7'])
+ self.assertEqual(metadata.resolve_client(('1.2.3.7', 6789)), 'client4')
+ mock_getnameinfo.assert_called_with(('1.2.3.7', 6789), socket.NI_NAMEREQD)
- mock_gethostbyaddr.reset_mock()
- mock_gethostbyaddr.return_value = None
- mock_gethostbyaddr.side_effect = socket.herror
+ mock_getnameinfo.reset_mock()
+ mock_getnameinfo.return_value = None
+ mock_getnameinfo.side_effect = socket.herror
self.assertRaises(Bcfg2.Server.Plugin.MetadataConsistencyError,
metadata.resolve_client,
- ('1.2.3.8', None))
- mock_gethostbyaddr.assert_called_with('1.2.3.8')
+ ('1.2.3.8', 6789))
+ mock_getnameinfo.assert_called_with(('1.2.3.8', 6789), socket.NI_NAMEREQD)
@patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.load_xml", Mock())
@patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.write_xml", Mock())
@@ -1485,30 +1490,30 @@ class TestMetadata_NoClientsXML(TestMetadataBase):
"1.2.3.8"))
@patch("Bcfg2.Server.Plugins.Metadata.XMLMetadataConfig.load_xml", Mock())
- @patch("socket.gethostbyaddr")
- def test_resolve_client(self, mock_gethostbyaddr):
+ @patch("socket.getnameinfo")
+ def test_resolve_client(self, mock_getnameinfo):
metadata = self.load_clients_data(metadata=self.load_groups_data())
metadata.session_cache[('1.2.3.3', None)] = (time.time(), 'client3')
self.assertEqual(metadata.resolve_client(('1.2.3.3', None)), 'client3')
metadata.session_cache[('1.2.3.3', None)] = (time.time() - 100,
'client3')
- mock_gethostbyaddr.return_value = ("client3", [], ['1.2.3.3'])
+ mock_getnameinfo.return_value = ("client3", [], ['1.2.3.3'])
self.assertEqual(metadata.resolve_client(('1.2.3.3', None),
cleanup_cache=True), 'client3')
self.assertEqual(metadata.session_cache, dict())
- mock_gethostbyaddr.return_value = ('client6', [], ['1.2.3.6'])
- self.assertEqual(metadata.resolve_client(('1.2.3.6', None)), 'client6')
- mock_gethostbyaddr.assert_called_with('1.2.3.6')
+ mock_getnameinfo.return_value = ('client6', [], ['1.2.3.6'])
+ self.assertEqual(metadata.resolve_client(('1.2.3.6', 6789), socket.NI_NAMEREQD), 'client6')
+ mock_getnameinfo.assert_called_with(('1.2.3.6', 6789), socket.NI_NAMEREQD)
- mock_gethostbyaddr.reset_mock()
- mock_gethostbyaddr.return_value = None
- mock_gethostbyaddr.side_effect = socket.herror
+ mock_getnameinfo.reset_mock()
+ mock_getnameinfo.return_value = None
+ mock_getnameinfo.side_effect = socket.herror
self.assertRaises(Bcfg2.Server.Plugin.MetadataConsistencyError,
metadata.resolve_client,
- ('1.2.3.8', None))
- mock_gethostbyaddr.assert_called_with('1.2.3.8')
+ ('1.2.3.8', 6789), socket.NI_NAMEREQD)
+ mock_getnameinfo.assert_called_with(('1.2.3.8', 6789), socket.NI_NAMEREQD)
def test_handle_clients_xml_event(self):
pass
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
index 0794db62e..2face023f 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
@@ -1,4 +1,5 @@
import os
+import re
import sys
import copy
import time
@@ -295,7 +296,9 @@ text
def inner():
return self.get_obj(core)
- return inner()
+ rv = inner()
+ rv.allowed_cgroups = [re.compile("^.*$")]
+ return rv
def test__init(self):
mock_load_data = Mock()
@@ -466,7 +469,7 @@ text
def test_load_data_db(self):
probes = self.get_probes_object(use_db=True)
probes.load_data()
- probes._load_data_db.assert_any_call()
+ probes._load_data_db.assert_any_call(client=None)
self.assertFalse(probes._load_data_xml.called)
@patch("lxml.etree.parse")
@@ -591,6 +594,37 @@ text
self.assertEqual(probes.cgroups[cname],
self.get_test_cgroups()[cname])
+ # test again, with an explicit list of allowed groups
+ probes.allowed_cgroups = [re.compile(r'^.*s$')]
+ for cname, cdata in self.get_test_probedata().items():
+ client = Mock()
+ client.hostname = cname
+ cgroups = []
+ cprobedata = ClientProbeDataSet()
+ for pname, pdata in cdata.items():
+ dataitem = lxml.etree.Element("Probe", name=pname)
+ if pname == "text":
+ # add some groups to the plaintext test to test
+ # group parsing
+ data = [pdata]
+ for group in self.get_test_cgroups()[cname]:
+ data.append("group:%s" % group)
+ dataitem.text = "\n".join(data)
+ else:
+ dataitem.text = str(pdata)
+
+ probes.ReceiveDataItem(client, dataitem, cgroups, cprobedata)
+
+ probes.cgroups[client.hostname] = cgroups
+ probes.probedata[client.hostname] = cprobedata
+ self.assertIn(client.hostname, probes.probedata)
+ self.assertIn(pname, probes.probedata[cname])
+ self.assertEqual(pdata, probes.probedata[cname][pname])
+ self.assertIn(client.hostname, probes.cgroups)
+ self.assertEqual(probes.cgroups[cname],
+ [g for g in self.get_test_cgroups()[cname]
+ if g.endswith("s")])
+
def test_get_additional_groups(self):
TestConnector.test_get_additional_groups(self)