|
@@ -3,10 +3,10 @@ |
|
|
# See Copyright for copyright notice! |
|
|
# See Copyright for copyright notice! |
|
|
########################################################################### |
|
|
########################################################################### |
|
|
|
|
|
|
|
|
import sys, types, os.path, pickle |
|
|
|
|
|
|
|
|
import sys, os.path, pickle |
|
|
import StringIO, copy, re |
|
|
import StringIO, copy, re |
|
|
import unittest |
|
|
|
|
|
import ConfigParser |
|
|
|
|
|
|
|
|
import unittest, ConfigParser |
|
|
|
|
|
from ZSI.wstools.WSDLTools import WSDLReader |
|
|
|
|
|
|
|
|
""" |
|
|
""" |
|
|
utils: |
|
|
utils: |
|
@@ -19,7 +19,7 @@ utils: |
|
|
|
|
|
|
|
|
thisFileName = sys.modules[__name__].__file__ |
|
|
thisFileName = sys.modules[__name__].__file__ |
|
|
|
|
|
|
|
|
class configHandler(ConfigParser.ConfigParser): |
|
|
|
|
|
|
|
|
class ConfigHandler(ConfigParser.ConfigParser): |
|
|
|
|
|
|
|
|
def __init__(self, name="config.py"): |
|
|
def __init__(self, name="config.py"): |
|
|
ConfigParser.ConfigParser.__init__(self) |
|
|
ConfigParser.ConfigParser.__init__(self) |
|
@@ -30,25 +30,48 @@ class configHandler(ConfigParser.ConfigParser): |
|
|
self.read(os.path.dirname(thisFileName) + os.sep + name) |
|
|
self.read(os.path.dirname(thisFileName) + os.sep + name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getConfigNames(self, section, numMethods, valueFunc=None): |
|
|
|
|
|
|
|
|
def getConfigNames(self, sections, numMethods, valueFunc=None): |
|
|
|
|
|
"""A generator which returns one value from a given config |
|
|
|
|
|
file section at a time. It also optionally calls a |
|
|
|
|
|
passed-function for that value, and yields the result as well. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
result = None |
|
|
result = None |
|
|
for name, value in self.items(section): |
|
|
|
|
|
for i in range(0, numMethods): |
|
|
|
|
|
yield value # indicate which test in all cases |
|
|
|
|
|
if i == 0: |
|
|
|
|
|
result = None |
|
|
|
|
|
|
|
|
for section in sections: |
|
|
|
|
|
for name, value in self.items(section): |
|
|
|
|
|
for i in range(0, numMethods): |
|
|
|
|
|
yield value # indicate which test in all cases |
|
|
|
|
|
if i == 0: |
|
|
|
|
|
result = None |
|
|
|
|
|
if valueFunc: |
|
|
|
|
|
try: |
|
|
|
|
|
result = valueFunc(value) |
|
|
|
|
|
except KeyboardInterrupt: |
|
|
|
|
|
sys.exit(-1) # for now |
|
|
|
|
|
except: # don't care, test will be skipped |
|
|
|
|
|
pass |
|
|
if valueFunc: |
|
|
if valueFunc: |
|
|
try: |
|
|
|
|
|
result = valueFunc(value) |
|
|
|
|
|
except KeyboardInterrupt: |
|
|
|
|
|
sys.exit(-1) # for now |
|
|
|
|
|
except: # don't care, test will be skipped |
|
|
|
|
|
pass |
|
|
|
|
|
if valueFunc: |
|
|
|
|
|
yield result |
|
|
|
|
|
|
|
|
yield result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def length(self, sections): |
|
|
|
|
|
"""Determines the total number of items in all the |
|
|
|
|
|
chosen sections from a config file. |
|
|
|
|
|
""" |
|
|
|
|
|
total = 0 |
|
|
|
|
|
for section in sections: |
|
|
|
|
|
total += len(self.options(section)) |
|
|
|
|
|
return total |
|
|
|
|
|
|
|
|
def length(self, section): |
|
|
|
|
|
return len(self.options(section)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setUpWsdl(path): |
|
|
|
|
|
"""Load a WSDL given a file path or a URL. |
|
|
|
|
|
""" |
|
|
|
|
|
if path[:7] == 'http://': |
|
|
|
|
|
wsdl = WSDLReader().loadFromURL(path) |
|
|
|
|
|
else: |
|
|
|
|
|
wsdl = WSDLReader().loadFromFile(path) |
|
|
|
|
|
return wsdl |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def loadPickledObj(fname): |
|
|
def loadPickledObj(fname): |
|
@@ -165,7 +188,7 @@ class MatchTestLoader(unittest.TestLoader): |
|
|
simpler and less verbose way to select a subset of tests to run. |
|
|
simpler and less verbose way to select a subset of tests to run. |
|
|
If all tests will always be run, use unittest.TestLoader instead. |
|
|
If all tests will always be run, use unittest.TestLoader instead. |
|
|
|
|
|
|
|
|
If a top-level test invokes test cases in other scripts, |
|
|
|
|
|
|
|
|
If a top-level test invokes test cases in other modules, |
|
|
MatchTestLoader should be created with topLevel set to True |
|
|
MatchTestLoader should be created with topLevel set to True |
|
|
to get the correct results. For example, |
|
|
to get the correct results. For example, |
|
|
|
|
|
|
|
@@ -177,57 +200,92 @@ class MatchTestLoader(unittest.TestLoader): |
|
|
if no additional arguments beyond the test script name are provided. |
|
|
if no additional arguments beyond the test script name are provided. |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
def __init__(self, topLevel, config, defaultTest): |
|
|
|
|
|
|
|
|
def __init__(self, topLevel, configName, defaultTest): |
|
|
unittest.TestLoader.__init__(self) |
|
|
unittest.TestLoader.__init__(self) |
|
|
self.testMethodPrefix = "test" |
|
|
self.testMethodPrefix = "test" |
|
|
self.defaultTest = defaultTest |
|
|
self.defaultTest = defaultTest |
|
|
self.topLevel = topLevel |
|
|
self.topLevel = topLevel |
|
|
self.config = config |
|
|
|
|
|
self.nameGenerator = None |
|
|
|
|
|
|
|
|
if configName: |
|
|
|
|
|
self.config = ConfigHandler(configName) |
|
|
|
|
|
self.sections = [] |
|
|
|
|
|
self.nameGenerator = None |
|
|
|
|
|
|
|
|
def loadTestsFromNames(self, unused, module=None): |
|
|
|
|
|
"""Instead of loading the test names passed into it from |
|
|
|
|
|
unittest.TestProgram, loadTestsFromNames uses arguments from the |
|
|
|
|
|
command-line instead. This method is necessary because the |
|
|
|
|
|
superclass method called from unittest.TestProgram would fail on |
|
|
|
|
|
sub-string arguments, and because the default test would |
|
|
|
|
|
not be called properly in some cases, if using the argument |
|
|
|
|
|
passed in. |
|
|
|
|
|
|
|
|
|
|
|
There can be multiple names, both in full or as a substring, on |
|
|
|
|
|
the command-line. After getting the arguments, this method |
|
|
|
|
|
calls the corresponding method in the superclass. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setUpArgs(self): |
|
|
|
|
|
"""Sets up the use of arguments from the command-line to select |
|
|
|
|
|
tests to run. There can be multiple names, both in full or as |
|
|
|
|
|
a substring, on the command-line. |
|
|
|
|
|
""" |
|
|
|
|
|
sectionList = self.config.sections() |
|
|
self.testArgs = [] |
|
|
self.testArgs = [] |
|
|
if not self.topLevel or (len(sys.argv) != 1): |
|
|
|
|
|
for arg in sys.argv[1:]: |
|
|
|
|
|
|
|
|
argv = [] |
|
|
|
|
|
# ignore section names in determining what to |
|
|
|
|
|
# load (sys.argv can be passed into setSection, |
|
|
|
|
|
# where any section names are extracted) |
|
|
|
|
|
for name in sys.argv: |
|
|
|
|
|
if name not in sectionList: |
|
|
|
|
|
argv.append(name) |
|
|
|
|
|
if not self.topLevel or (len(argv) != 1): |
|
|
|
|
|
for arg in argv[1:]: |
|
|
if arg.find("-") != 0: |
|
|
if arg.find("-") != 0: |
|
|
self.testArgs.append(arg) |
|
|
self.testArgs.append(arg) |
|
|
|
|
|
# has the effect of loading all tests |
|
|
if not self.testArgs: |
|
|
if not self.testArgs: |
|
|
self.testArgs = [None] |
|
|
self.testArgs = [None] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def loadTestsFromNames(self, unused, module=None): |
|
|
|
|
|
"""Hard-wires using the default test. It ignores the names |
|
|
|
|
|
passed into it from unittest.TestProgram, because the |
|
|
|
|
|
default loader would fail on substrings or section names. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
suites = unittest.TestLoader.loadTestsFromNames(self, |
|
|
suites = unittest.TestLoader.loadTestsFromNames(self, |
|
|
(self.defaultTest,), module) |
|
|
(self.defaultTest,), module) |
|
|
return suites |
|
|
return suites |
|
|
|
|
|
|
|
|
def loadTestsFromConfig(self, testCaseClass, section, fname="config.py", |
|
|
|
|
|
valueFunc=None): |
|
|
|
|
|
config = configHandler(fname) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setSection(self, args): |
|
|
|
|
|
"""Sets section(s) of config file to read. |
|
|
|
|
|
""" |
|
|
|
|
|
sectionList = self.config.sections() |
|
|
|
|
|
if ((type(args) is list) or |
|
|
|
|
|
(type(args) is tuple)): |
|
|
|
|
|
for arg in args: |
|
|
|
|
|
if arg in sectionList: |
|
|
|
|
|
self.sections.append(arg) |
|
|
|
|
|
if self.sections: |
|
|
|
|
|
return True |
|
|
|
|
|
elif type(args) is str: |
|
|
|
|
|
if args in sectionList: |
|
|
|
|
|
self.sections.append(args) |
|
|
|
|
|
return True |
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def loadTestsFromConfig(self, testCaseClass, valueFunc=None): |
|
|
|
|
|
"""Loads n number of instances of testCaseClass, where |
|
|
|
|
|
n is the number of items in the config file section(s). |
|
|
|
|
|
getConfigNames is a generator which is used to parcel |
|
|
|
|
|
out the values in the section(s) to the testCaseClass |
|
|
|
|
|
instances. |
|
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
self.setUpArgs() |
|
|
numTestCases = self.getTestCaseNumber(testCaseClass) |
|
|
numTestCases = self.getTestCaseNumber(testCaseClass) |
|
|
self.nameGenerator = config.getConfigNames(section, |
|
|
|
|
|
|
|
|
self.nameGenerator = self.config.getConfigNames(self.sections, |
|
|
numTestCases, valueFunc) |
|
|
numTestCases, valueFunc) |
|
|
configLen = config.length(section) |
|
|
|
|
|
|
|
|
configLen = self.config.length(self.sections) |
|
|
suite = unittest.TestSuite() |
|
|
suite = unittest.TestSuite() |
|
|
suite.addTest(self.loadTestsFromTestCase(testCaseClass)) |
|
|
|
|
|
for i in range(1, configLen): |
|
|
|
|
|
|
|
|
for i in range(0, configLen): |
|
|
suite.addTest(self.loadTestsFromTestCase(testCaseClass)) |
|
|
suite.addTest(self.loadTestsFromTestCase(testCaseClass)) |
|
|
return suite |
|
|
return suite |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getTestCaseNumber(self, testCaseClass): |
|
|
def getTestCaseNumber(self, testCaseClass): |
|
|
"""looks for any test methods whose name contains testStr, checking |
|
|
|
|
|
|
|
|
"""Looks for any test methods whose name contains testStr, checking |
|
|
if a test method has already been added. If there is not a match, |
|
|
if a test method has already been added. If there is not a match, |
|
|
it checks for an exact match with the test case name, and |
|
|
it checks for an exact match with the test case name, and |
|
|
returns the number of test cases. |
|
|
returns the number of test cases. |
|
@@ -236,7 +294,6 @@ class MatchTestLoader(unittest.TestLoader): |
|
|
prevAdded = [] |
|
|
prevAdded = [] |
|
|
counter = 0 |
|
|
counter = 0 |
|
|
for testStr in self.testArgs: |
|
|
for testStr in self.testArgs: |
|
|
# print "test argument ", testStr |
|
|
|
|
|
if testStr: |
|
|
if testStr: |
|
|
for m in methods: |
|
|
for m in methods: |
|
|
if m.find(testStr) >= 0 and m not in prevAdded: |
|
|
if m.find(testStr) >= 0 and m not in prevAdded: |
|
|