From b64f655f54cb6d1f23712eef129341af4a25423c Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 20 Aug 2012 08:26:53 -0400 Subject: fixed EntrySet.best_matching() --- src/lib/Bcfg2/Server/Plugin.py | 25 ++++++++---------- src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py | 5 ++++ testsuite/Testlib/TestServer/TestPlugin.py | 38 +++++++++++++--------------- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugin.py b/src/lib/Bcfg2/Server/Plugin.py index 79b3d4c7e..946b38f75 100644 --- a/src/lib/Bcfg2/Server/Plugin.py +++ b/src/lib/Bcfg2/Server/Plugin.py @@ -1,15 +1,16 @@ """This module provides the baseclass for Bcfg2 Server Plugins.""" -import copy -import logging -import lxml.etree import os import re import sys +import copy +import logging +import operator import threading +import lxml.etree import Bcfg2.Server -from Bcfg2.Bcfg2Py3k import ConfigParser import Bcfg2.Options +from Bcfg2.Bcfg2Py3k import ConfigParser try: import django @@ -47,11 +48,14 @@ info_regex = re.compile('owner:(\s)*(?P\S+)|' + 'mtime:(\s)*(?P\w+)|') def bind_info(entry, metadata, infoxml=None, default=default_file_metadata): + print 'default: %s' % default for attr, val in list(default.items()): entry.set(attr, val) if infoxml: mdata = dict() + print "calling Match on %s" % infoxml infoxml.pnode.Match(metadata, mdata, entry=entry) + print "mdata=%s" % mdata if 'Info' not in mdata: msg = "Failed to set metadata for file %s" % entry.get('name') logger.error(msg) @@ -1000,15 +1004,6 @@ class Specificity(object): self.prio = prio self.delta = delta - def __lt__(self, other): - return self.__cmp__(other) < 0 - - def __gt__(self, other): - return self.__cmp__(other) > 0 - - def __eq__(self, other): - return self.__cmp__(other) == 0 - def matches(self, metadata): return self.all or \ self.hostname == metadata.hostname or \ @@ -1091,7 +1086,7 @@ class EntrySet(Debuggable): def get_matching(self, metadata): return [item for item in list(self.entries.values()) - if item.specific.matches(metadata)] + if item.__specific__ and item.specific.matches(metadata)] def best_matching(self, metadata, matching=None): """ Return the appropriate interpreted template from the set of @@ -1100,7 +1095,7 @@ class EntrySet(Debuggable): matching = self.get_matching(metadata) if matching: - matching.sort() + matching.sort(key=operator.attrgetter("specific")) return matching[0] else: raise PluginExecutionError("No matching entries available for %s " diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py index e93fb9da7..f7577d60e 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py @@ -207,6 +207,11 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): logger.error("Could not process event %s for %s; ignoring" % (action, event.filename)) + def get_matching(self, metadata): + return [item for item in list(self.entries.values()) + if (isinstance(item, CfgGenerator) and + item.specific.matches(metadata))] + def entry_init(self, event, proc): if proc.__specific__: Bcfg2.Server.Plugin.EntrySet.entry_init( diff --git a/testsuite/Testlib/TestServer/TestPlugin.py b/testsuite/Testlib/TestServer/TestPlugin.py index 678c65264..8e2a11d9e 100644 --- a/testsuite/Testlib/TestServer/TestPlugin.py +++ b/testsuite/Testlib/TestServer/TestPlugin.py @@ -1694,6 +1694,8 @@ class TestEntrySet(TestDebuggable): items[3].specific.matches.return_value = False items[4].specific.matches.return_value = True items[5].specific.matches.return_value = True + for i in items.values(): + i.__specific__ = True metadata = Mock() eset = self.get_obj() eset.entries = items @@ -1714,14 +1716,10 @@ class TestEntrySet(TestDebuggable): for m in matching: m.reset_mock() - def specific(all=False, group=False, prio=None, host=False): - spec = MagicMock() - spec.all = all - spec.group = group - spec.prio = prio - spec.host = host - if prio: - spec.__cmp__ = lambda s, o: cmp(s.prio, o.prio) + def specific(all=False, group=False, prio=None, hostname=False): + spec = Mock() + spec.specific = Specificity(all=all, group=group, prio=prio, + hostname=hostname) return spec self.assertRaises(PluginExecutionError, @@ -1735,34 +1733,34 @@ class TestEntrySet(TestDebuggable): # test with a single file for all reset() - matching.insert(0, specific(all=True)) + expected = specific(all=True) + matching.append(expected) mock_get_matching.return_value = matching - self.assertEqual(eset.best_matching(metadata), - matching[0]) + self.assertEqual(eset.best_matching(metadata), expected) mock_get_matching.assert_called_with(metadata) # test with a single group-specific file reset() - matching.insert(0, specific(group=True, prio=10)) + expected = specific(group=True, prio=10) + matching.append(expected) mock_get_matching.return_value = matching - self.assertEqual(eset.best_matching(metadata), - matching[0]) + self.assertEqual(eset.best_matching(metadata), expected) mock_get_matching.assert_called_with(metadata) # test with multiple group-specific files reset() - matching.insert(0, specific(group=True, prio=20)) + expected = specific(group=True, prio=20) + matching.append(expected) mock_get_matching.return_value = matching - self.assertEqual(eset.best_matching(metadata), - matching[0]) + self.assertEqual(eset.best_matching(metadata), expected) mock_get_matching.assert_called_with(metadata) # test with host-specific file reset() - matching.insert(0, specific(host=True)) + expected = specific(hostname=True) + matching.append(expected) mock_get_matching.return_value = matching - self.assertEqual(eset.best_matching(metadata), - matching[0]) + self.assertEqual(eset.best_matching(metadata), expected) mock_get_matching.assert_called_with(metadata) @patch("Bcfg2.Server.Plugin.%s.entry_init" % test_obj.__name__) -- cgit v1.2.3-1-g7c22