diff --git a/lib/spack/spack/cmd/test-install.py b/lib/spack/spack/cmd/test-install.py index 7b37f66967..406a6d7d33 100644 --- a/lib/spack/spack/cmd/test-install.py +++ b/lib/spack/spack/cmd/test-install.py @@ -57,22 +57,32 @@ def __init__(self): self.root = ET.Element('testsuite') self.tests = [] - def add_test(self, buildId, passed=True, buildInfo=None): - self.tests.append((buildId, passed, buildInfo)) + def add_test(self, buildId, testResult, buildInfo=None): + self.tests.append((buildId, testResult, buildInfo)) def write_to(self, stream): 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.set('classname', buildId.name) testcase.set('name', buildId.stringId()) - if not passed: + if testResult == TestResult.FAILED: failure = ET.SubElement(testcase, 'failure') failure.set('type', "Build Error") 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) +class TestResult(object): + PASSED = 0 + FAILED = 1 + SKIPPED = 2 + + class BuildId(object): def __init__(self, spec): self.name = spec.name @@ -94,6 +104,8 @@ def __eq__(self, other): def fetch_log(path): + if not os.path.exists(path): + return list() with open(path, 'rb') as F: return list(F.readlines()) @@ -105,23 +117,31 @@ def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log): if spec not in newInstalls: continue - if not all(spack.db.get(childSpec).installed for childSpec in - spec.dependencies.itervalues()): - #TODO: create a failed test if a dependency didn't install? - continue - - bId = BuildId(spec) - + failedDeps = set(childSpec for childSpec in + spec.dependencies.itervalues() if not + spack.db.get(childSpec).installed) package = spack.db.get(spec) - lines = getLogFunc(package.build_log_path) - errMessages = list(line for line in lines if - re.search('error:', line, re.IGNORECASE)) - errOutput = errMessages if errMessages else lines[-10:] - errOutput = '\n'.join(itertools.chain( - [spec.to_yaml(), "Errors:"], errOutput, - ["Build Log:", package.build_log_path])) + 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) + errMessages = list(line for line in lines if + re.search('error:', line, re.IGNORECASE)) + errOutput = errMessages if errMessages else lines[-10:] + errOutput = '\n'.join(itertools.chain( + [spec.to_yaml(), "Errors:"], errOutput, + ["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): diff --git a/lib/spack/spack/test/unit_install.py b/lib/spack/spack/test/unit_install.py index ab7d4902d0..2a94f8fec0 100644 --- a/lib/spack/spack/test/unit_install.py +++ b/lib/spack/spack/test/unit_install.py @@ -27,7 +27,7 @@ import spack test_install = __import__("spack.cmd.test-install", - fromlist=["BuildId", "create_test_output"]) + fromlist=["BuildId", "create_test_output", "TestResult"]) class MockOutput(object): def __init__(self): @@ -75,8 +75,7 @@ class UnitInstallTest(unittest.TestCase): def setUp(self): super(UnitInstallTest, self).setUp() - - #import pdb; pdb.set_trace() + pkgX.installed = False pkgY.installed = False @@ -93,7 +92,9 @@ def test_installing_both(self): pkgY.installed = True 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): mo = MockOutput() @@ -102,7 +103,7 @@ def test_dependency_already_installed(self): pkgY.installed = True 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): def __init__(self, init=None):