Generate test results (designated as skipped) for parents of failed dependencies

This commit is contained in:
Peter Scheibel 2015-10-22 16:00:03 -07:00
parent 39f0f000f8
commit 246423b4b4
2 changed files with 45 additions and 24 deletions

View file

@ -57,22 +57,32 @@ def __init__(self):
self.root = ET.Element('testsuite') self.root = ET.Element('testsuite')
self.tests = [] self.tests = []
def add_test(self, buildId, passed=True, buildInfo=None): def add_test(self, buildId, testResult, buildInfo=None):
self.tests.append((buildId, passed, buildInfo)) self.tests.append((buildId, testResult, buildInfo))
def write_to(self, stream): def write_to(self, stream):
self.root.set('tests', '{0}'.format(len(self.tests))) self.root.set('tests', '{0}'.format(len(self.tests)))
for buildId, passed, buildInfo in self.tests: for buildId, testResult, buildInfo in self.tests:
testcase = ET.SubElement(self.root, 'testcase') testcase = ET.SubElement(self.root, 'testcase')
testcase.set('classname', buildId.name) testcase.set('classname', buildId.name)
testcase.set('name', buildId.stringId()) testcase.set('name', buildId.stringId())
if not passed: if testResult == TestResult.FAILED:
failure = ET.SubElement(testcase, 'failure') failure = ET.SubElement(testcase, 'failure')
failure.set('type', "Build Error") failure.set('type', "Build Error")
failure.text = buildInfo failure.text = buildInfo
elif testResult == TestResult.SKIPPED:
skipped = ET.SubElement(testcase, 'skipped')
skipped.set('type', "Skipped Build")
skipped.text = buildInfo
ET.ElementTree(self.root).write(stream) ET.ElementTree(self.root).write(stream)
class TestResult(object):
PASSED = 0
FAILED = 1
SKIPPED = 2
class BuildId(object): class BuildId(object):
def __init__(self, spec): def __init__(self, spec):
self.name = spec.name self.name = spec.name
@ -94,6 +104,8 @@ def __eq__(self, other):
def fetch_log(path): def fetch_log(path):
if not os.path.exists(path):
return list()
with open(path, 'rb') as F: with open(path, 'rb') as F:
return list(F.readlines()) return list(F.readlines())
@ -105,14 +117,18 @@ def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log):
if spec not in newInstalls: if spec not in newInstalls:
continue continue
if not all(spack.db.get(childSpec).installed for childSpec in failedDeps = set(childSpec for childSpec in
spec.dependencies.itervalues()): spec.dependencies.itervalues() if not
#TODO: create a failed test if a dependency didn't install? spack.db.get(childSpec).installed)
continue
bId = BuildId(spec)
package = spack.db.get(spec) package = spack.db.get(spec)
if failedDeps:
result = TestResult.SKIPPED
dep = iter(failedDeps).next()
depBID = BuildId(dep)
errOutput = "Skipped due to failed dependency: {0}".format(
depBID.stringId())
elif not package.installed:
result = TestResult.FAILED
lines = getLogFunc(package.build_log_path) lines = getLogFunc(package.build_log_path)
errMessages = list(line for line in lines if errMessages = list(line for line in lines if
re.search('error:', line, re.IGNORECASE)) re.search('error:', line, re.IGNORECASE))
@ -120,8 +136,12 @@ def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log):
errOutput = '\n'.join(itertools.chain( errOutput = '\n'.join(itertools.chain(
[spec.to_yaml(), "Errors:"], errOutput, [spec.to_yaml(), "Errors:"], errOutput,
["Build Log:", package.build_log_path])) ["Build Log:", package.build_log_path]))
else:
result = TestResult.PASSED
errOutput = None
output.add_test(bId, package.installed, errOutput) bId = BuildId(spec)
output.add_test(bId, result, errOutput)
def test_install(parser, args): def test_install(parser, args):

View file

@ -27,7 +27,7 @@
import spack import spack
test_install = __import__("spack.cmd.test-install", test_install = __import__("spack.cmd.test-install",
fromlist=["BuildId", "create_test_output"]) fromlist=["BuildId", "create_test_output", "TestResult"])
class MockOutput(object): class MockOutput(object):
def __init__(self): def __init__(self):
@ -76,7 +76,6 @@ class UnitInstallTest(unittest.TestCase):
def setUp(self): def setUp(self):
super(UnitInstallTest, self).setUp() super(UnitInstallTest, self).setUp()
#import pdb; pdb.set_trace()
pkgX.installed = False pkgX.installed = False
pkgY.installed = False pkgY.installed = False
@ -93,7 +92,9 @@ def test_installing_both(self):
pkgY.installed = True pkgY.installed = True
test_install.create_test_output(specX, [specX, specY], mo, getLogFunc=test_fetch_log) test_install.create_test_output(specX, [specX, specY], mo, getLogFunc=test_fetch_log)
self.assertEqual(mo.results, {bIdX:True, bIdY:True}) self.assertEqual(mo.results,
{bIdX:test_install.TestResult.PASSED,
bIdY:test_install.TestResult.PASSED})
def test_dependency_already_installed(self): def test_dependency_already_installed(self):
mo = MockOutput() mo = MockOutput()
@ -102,7 +103,7 @@ def test_dependency_already_installed(self):
pkgY.installed = True pkgY.installed = True
test_install.create_test_output(specX, [specX], mo, getLogFunc=test_fetch_log) test_install.create_test_output(specX, [specX], mo, getLogFunc=test_fetch_log)
self.assertEqual(mo.results, {bIdX:True}) self.assertEqual(mo.results, {bIdX:test_install.TestResult.PASSED})
class MockPackageDb(object): class MockPackageDb(object):
def __init__(self, init=None): def __init__(self, init=None):