Source code for pysys.launcher

#!/usr/bin/env python
# PySys System Test Framework, Copyright (C) 2006-2018  M.B.Grieve

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

# This library 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
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

# Contact: moraygrieve@users.sourceforge.net
"""
Contains utilities used by test launchers when running, printing, cleaning or making new tests. 

The module includes the L{pysys.launcher.createDescriptors} method which locates test 
descriptors based upon a given starting location on the file system, the chosen range 
of test ids, the test type, the specified requirements, and the include and exclude lists.

Utilities defined in the module can be used by any launchers, either distributed
with the framework, or created as an extension to it. Currently the framework 
distributes the console launcher module only - see L{pysys.launcher.console}. This 
module uses the current working directory in a command shell as the starting location 
on the file system, and provides utilities for parsing command line arguments in order
to launch operations against a set of tests etc.  

"""
from __future__ import print_function
__all__ = [ "createDescriptors","console" ]

import os.path, logging

# if set is not available (>python 2.6) fall back to the sets module
try:  
	set  
except NameError:  
	import sets
	from sets import Set as set

from pysys.constants import *
from pysys.xml.descriptor import XMLDescriptorParser


[docs]def createDescriptors(testIdSpecs, type, includes, excludes, trace, dir=None): """Create a list of descriptor objects representing a set of tests to run, returning the list. @param testIdSpecs: A list of strings specifying the set of testcase identifiers @param type: The type of the tests to run (manual | auto) @param includes: A list of test groups to include in the returned set @param excludes: A list of test groups to exclude in the returned set @param trace: A list of requirements to indicate tests to include in the returned set @param dir: The parent directory to search for runnable tests @return: List of L{pysys.xml.descriptor.XMLDescriptorContainer} objects @rtype: list @raises Exception: Raised if not testcases can be found or are returned by the requested input parameters """ descriptors = [] descriptorfiles = [] ignoreSet = set(OSWALK_IGNORES) descriptorSet =set(DEFAULT_DESCRIPTOR) if dir is None: dir = os.getcwd() projectfound = PROJECT.projectFile != None for root, dirs, files in os.walk(dir): intersection = descriptorSet & set(files) if intersection : descriptorfiles.append(os.path.join(root, intersection.pop())) for ignore in (ignoreSet & set(dirs)): dirs.remove(ignore) if not projectfound: for p in DEFAULT_PROJECTFILE: if p in files: projectfound = True sys.stderr.write('WARNING: PySys project file was not found in directory the script was run from but does exist at "%s" (consider running pysys from that directory instead)\n'%os.path.join(root, p)) for descriptorfile in descriptorfiles: try: descriptors.append(XMLDescriptorParser(descriptorfile).getContainer()) except Exception as value: print('%s - %s'%(sys.exc_info()[0], sys.exc_info()[1])) logging.getLogger('pysys').info("Error reading descriptorfile %s" % descriptorfile) descriptors = sorted(descriptors, key=lambda x: x.file) # trim down the list for those tests in the test specifiers tests = [] if testIdSpecs == []: tests = descriptors else: def idMatch(descriptorId, specId): return specId==descriptorId or (specId.isdigit() and re.match('.+_0*%s$'%specId, descriptorId)) for t in testIdSpecs: try: index = index1 = index2 = -1 t = t.rstrip('/\\') if re.search('^[\w_]*$', t): for i in range(0,len(descriptors)): if idMatch(descriptors[i].id, t): index = i matches = descriptors[index:index+1] elif re.search('^:[\w_]*', t): for i in range(0,len(descriptors)): if idMatch(descriptors[i].id, t.split(':')[1]): index = i matches = descriptors[:index+1] elif re.search('^[\w_]*:$', t): for i in range(0,len(descriptors)): if idMatch(descriptors[i].id, t.split(':')[0]): index = i matches = descriptors[index:] elif re.search('^[\w_]*:[\w_]*$', t): for i in range(0,len(descriptors)): if idMatch(descriptors[i].id, t.split(':')[0]): index1 = i if idMatch(descriptors[i].id, t.split(':')[1]): index2 = i matches = descriptors[index1:index2+1] else: matches = [descriptors[i] for i in range(0,len(descriptors)) if re.search(t, descriptors[i].id)] # each specified test patten must match something, else probably user made a typo if not matches: raise Exception("No matches for: '%s'", t) tests.extend(matches) except Exception: raise Exception("Unable to locate requested testcase(s): '%s'"%t) # trim down the list based on the type if type: index = 0 while index != len(tests): if type != tests[index].type: tests.pop(index) else: index = index + 1 # trim down the list based on the include and exclude groups if len(excludes) != 0: index = 0 while index != len(tests): remove = False for exclude in excludes: if exclude in tests[index].groups: remove = True break if remove: tests.pop(index) else: index = index +1 if includes != []: index = 0 while index != len(tests): keep = False for include in includes: if include in tests[index].groups: keep = True break if not keep: tests.pop(index) else: index = index +1 # trim down the list based on the traceability if trace: index = 0 while index != len(tests): if trace not in tests[index].traceability : tests.pop(index) else: index = index + 1 if len(tests) == 0: raise Exception("The supplied options did not result in the selection of any tests") else: return tests