# Copyright (C) 2013-2016 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # # GNU Mailman is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along with # GNU Mailman. If not, see . """nose2 test infrastructure.""" import os import re import doctest import importlib from mailman import public from mailman.testing.documentation import setup, teardown from mailman.testing.layers import ConfigLayer, MockAndMonkeyLayer, SMTPLayer from nose2.events import Plugin from pkg_resources import resource_filename DOT = '.' FLAGS = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF TOPDIR = os.path.dirname(resource_filename('mailman', '__init__.py')) @public class NosePlugin(Plugin): configSection = 'mailman' def __init__(self): super().__init__() self.patterns = [] self.stderr = False def set_stderr(ignore): # noqa self.stderr = True self.addArgument(self.patterns, 'P', 'pattern', 'Add a test matching pattern') self.addFlag(set_stderr, 'E', 'stderr', 'Enable stderr logging to sub-runners') def startTestRun(self, event): MockAndMonkeyLayer.testing_mode = True if (self.stderr or len(os.environ.get('MM_VERBOSE_TESTLOG', '').strip()) > 0): ConfigLayer.stderr = True def getTestCaseNames(self, event): if len(self.patterns) == 0: # No filter patterns, so everything should be tested. return # Does the pattern match the fully qualified class name? for pattern in self.patterns: full_class_name = '{}.{}'.format( event.testCase.__module__, event.testCase.__name__) if re.search(pattern, full_class_name): # Don't suppress this test class. return names = filter(event.isTestMethod, dir(event.testCase)) for name in names: full_test_name = '{}.{}.{}'.format( event.testCase.__module__, event.testCase.__name__, name) for pattern in self.patterns: if re.search(pattern, full_test_name): break else: event.excludedNames.append(name) def handleFile(self, event): path = event.path[len(TOPDIR)+1:] if len(self.patterns) > 0: for pattern in self.patterns: if re.search(pattern, path): break else: # Skip this doctest. return base, ext = os.path.splitext(path) if ext != '.rst': return # Look to see if the package defines a test layer, otherwise use the # default layer. First turn the file system path into a dotted Python # module path. parent = os.path.dirname(path) dotted = 'mailman.' + DOT.join(parent.split(os.path.sep)) try: module = importlib.import_module(dotted) except ImportError: layer = SMTPLayer else: layer = getattr(module, 'layer', SMTPLayer) test = doctest.DocFileTest( path, package='mailman', optionflags=FLAGS, setUp=setup, tearDown=teardown) test.layer = layer # Suppress the extra "Doctest: ..." line. test.shortDescription = lambda: None event.extraTests.append(test) # def startTest(self, event): # import sys; print('vvvvv', event.test, file=sys.stderr) # def stopTest(self, event): # import sys; print('^^^^^', event.test, file=sys.stderr)