From 3a16a7cb5a7c4142890af4b32841e15dbaa40556 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 3 Oct 2012 15:28:54 -0400 Subject: Cfg: fixed regexes for handling and ignoring files with different Cfg handlers --- src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py | 56 ++++++----------- .../TestServer/TestPlugins/TestCfg/Test_init.py | 70 +++++----------------- 2 files changed, 32 insertions(+), 94 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py index 0ab7fd98e..82b792fe0 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py @@ -44,11 +44,11 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): #: indicators). __extensions__ = [] - #: This handler ignores files with the listed extensions. A file - #: that is ignored by a handler will not be handled by any other - #: handlers; that is, a file is ignored if any handler ignores it. - #: Ignoring a file is not simply a means to defer handling of that - #: file to another handler. + #: This handler ignores all files with the listed extensions. A + #: file that is ignored by a handler will not be handled by any + #: other handlers; that is, a file is ignored if any handler + #: ignores it. Ignoring a file is not simply a means to defer + #: handling of that file to another handler. __ignore__ = [] #: Whether or not the files handled by this handler are permitted @@ -63,7 +63,7 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): Bcfg2.Server.Plugin.SpecificData.__init__(self, name, specific, encoding) self.encoding = encoding - self.regex = self.__class__.get_regex(basename=name) + self.regex = self.__class__.get_regex([name]) __init__.__doc__ = Bcfg2.Server.Plugin.SpecificData.__init__.__doc__ + \ """ .. ----- @@ -73,7 +73,7 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): .. autoattribute:: Bcfg2.Server.Plugins.Cfg.CfgBaseFileMatcher.__specific__""" @classmethod - def get_regex(cls, basename=None, extensions=None): + def get_regex(cls, basenames): """ Get a compiled regular expression to match filenames (not full paths) that this handler handles. @@ -83,23 +83,15 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): directory that contains the files the regex will be applied to) :type basename: string - :param extensions: Override the default list of - :attr:`Bcfg2.Server.Plugins.Cfg.CfgBaseFileMatcher.__extensions__` - to include in the regex. - :type extensions: list of strings :returns: compiled regex """ - if extensions is None: - extensions = cls.__extensions__ - if cls.__basenames__: - basename = '|'.join(cls.__basenames__) - - components = ['^(?P%s)' % basename] + components = ['^(?P%s)' % '|'.join(basenames)] if cls.__specific__: components.append('(|\\.H_(?P\S+?)|' + - '.G(?P\d+)_(?P\S+?))') - if extensions: - components.append('\\.(?P%s)' % '|'.join(extensions)) + '\.G(?P\d+)_(?P\S+?))') + if cls.__extensions__: + components.append('\\.(?P%s)' % + '|'.join(cls.__extensions__)) components.append('$') return re.compile("".join(components)) @@ -124,15 +116,12 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): if cls.__basenames__: basenames = cls.__basenames__ else: - basenames = [basename] + basenames = [os.path.basename(basename)] - return any( - cls.get_regex( - basename=os.path.basename(bname)).match(event.filename) - for bname in basenames) + return bool(cls.get_regex(basenames).match(event.filename)) @classmethod - def ignore(cls, event, basename=None): + def ignore(cls, event, basename=None): # pylint: disable=W0613 """ Return True if this handler ignores the file described by ``event``. See :attr:`Bcfg2.Server.Plugins.Cfg.CfgBaseFileMatcher.__ignore__` @@ -149,18 +138,7 @@ class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData): :returns: bool - True if this handler handles the file listed in the event, False otherwise. """ - if not cls.__ignore__: - return False - - if cls.__basenames__: - basenames = cls.__basenames__ - else: - basenames = [basename] - - return any( - cls.get_regex(basename=os.path.basename(bname), - extensions=cls.__ignore__).match(event.filename) - for bname in basenames) + return any(event.filename.endswith("." + e) for e in cls.__ignore__) def __str__(self): return "%s(%s)" % (self.__class__.__name__, self.name) @@ -423,7 +401,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet): if hdlr.__specific__: Bcfg2.Server.Plugin.EntrySet.entry_init( self, event, entry_type=hdlr, - specific=hdlr.get_regex(os.path.basename(self.path))) + specific=hdlr.get_regex([os.path.basename(self.path)])) else: if event.filename in self.entries: LOGGER.warn("Got duplicate add for %s" % event.filename) diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py index fb1a28bca..11f06873d 100644 --- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py +++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestCfg/Test_init.py @@ -40,8 +40,9 @@ class TestCfgBaseFileMatcher(TestSpecificData): extensions = self.test_obj.__extensions__ else: extensions = [''] - for basename in basenames: - for extension in extensions: + for extension in extensions: + regex = self.test_obj.get_regex(basenames) + for basename in basenames: def test_match(spec): mstr = basename if spec: @@ -50,7 +51,6 @@ class TestCfgBaseFileMatcher(TestSpecificData): mstr += "." + extension return regex.match(mstr) - regex = self.test_obj.get_regex(basename=basename) self.assertTrue(test_match('')) self.assertFalse(regex.match("bogus")) if self.test_obj.__specific__: @@ -86,9 +86,8 @@ class TestCfgBaseFileMatcher(TestSpecificData): if self.test_obj.__basenames__: match.return_value = False self.assertFalse(self.test_obj.handles(evt)) - self.assertItemsEqual(mock_get_regex.call_args_list, - [call(basename=b) - for b in self.test_obj.__basenames__]) + mock_get_regex.assert_called_with( + [b for b in self.test_obj.__basenames__]) self.assertItemsEqual(match.call_args_list, [call(evt.filename) for b in self.test_obj.__basenames__]) @@ -102,8 +101,7 @@ class TestCfgBaseFileMatcher(TestSpecificData): match.return_value = False self.assertFalse(self.test_obj.handles(evt, basename=os.path.basename(self.path))) - mock_get_regex.assert_called_with( - basename=os.path.basename(self.path)) + mock_get_regex.assert_called_with([os.path.basename(self.path)]) match.assert_called_with(evt.filename) mock_get_regex.reset_mock() @@ -111,60 +109,22 @@ class TestCfgBaseFileMatcher(TestSpecificData): match.return_value = True self.assertTrue(self.test_obj.handles(evt, basename=os.path.basename(self.path))) - mock_get_regex.assert_called_with( - basename=os.path.basename(self.path)) + mock_get_regex.assert_called_with([os.path.basename(self.path)]) match.assert_called_with(evt.filename) - @patch("%s.%s.get_regex" % (test_obj.__module__, test_obj.__name__)) - def test_ignore(self, mock_get_regex): - match = Mock() - mock_get_regex.return_value = Mock() - mock_get_regex.return_value.match = match - + def test_ignore(self): evt = Mock() evt.filename = "event.txt" if not self.test_obj.__ignore__: self.assertFalse(self.test_obj.ignore(evt)) - self.assertFalse(mock_get_regex.called) - self.assertFalse(self.test_obj.ignore(evt, basename=os.path.basename(self.path))) - self.assertFalse(mock_get_regex.called) - elif self.test_obj.__basenames__: - match.return_value = False - self.assertFalse(self.test_obj.ignore(evt)) - self.assertItemsEqual(mock_get_regex.call_args_list, - [call(basename=b, - extensions=self.test_obj.__ignore__) - for b in self.test_obj.__basenames__]) - self.assertItemsEqual(match.call_args_list, - [call(evt.filename) - for b in self.test_obj.__basenames__]) - - mock_get_regex.reset_mock() - match.reset_mock() - match.return_value = True - self.assertTrue(self.test_obj.ignore(evt)) - match.assert_called_with(evt.filename) else: - match.return_value = False - self.assertFalse(self.test_obj.ignore( - evt, - basename=os.path.basename(self.path))) - mock_get_regex.assert_called_with( - basename=os.path.basename(self.path), - extensions=self.test_obj.__ignore__) - match.assert_called_with(evt.filename) - - mock_get_regex.reset_mock() - match.reset_mock() - match.return_value = True - self.assertTrue(self.test_obj.ignore( - evt, - basename=os.path.basename(self.path))) - mock_get_regex.assert_called_with( - basename=os.path.basename(self.path), - extensions=self.test_obj.__ignore__) - match.assert_called_with(evt.filename) + self.assertFalse(self.test_obj.ignore(evt)) + for extension in self.test_obj.__ignore__: + for name in ["event.txt", "....", extension, "." + extension]: + for filler in ['', '.blah', '......', '.' + extension]: + evt.filename = name + filler + '.' + extension + self.assertTrue(self.test_obj.ignore(evt)) class TestCfgGenerator(TestCfgBaseFileMatcher): @@ -297,7 +257,7 @@ class TestCfgEntrySet(TestEntrySet): for hdlr in eset.handlers: self.assertFalse(hdlr.handles.called) self.assertFalse(hdlr.ignore.called) - + # test creation of a new file for action in ["exists", "created", "changed"]: evt = Mock() -- cgit v1.2.3-1-g7c22