test-install : wip to add other information
This commit is contained in:
		| @@ -23,36 +23,39 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import argparse | import argparse | ||||||
| import xml.etree.ElementTree as ET |  | ||||||
| import itertools |  | ||||||
| import re |  | ||||||
| import os |  | ||||||
| import codecs | import codecs | ||||||
|  | import itertools | ||||||
|  | import os | ||||||
|  | import re | ||||||
|  | import time | ||||||
|  | import xml.etree.ElementTree as ET | ||||||
|  |  | ||||||
| import llnl.util.tty as tty | import llnl.util.tty as tty | ||||||
| from llnl.util.filesystem import * |  | ||||||
|  |  | ||||||
| import spack | import spack | ||||||
|  | import spack.cmd | ||||||
|  | from llnl.util.filesystem import * | ||||||
| from spack.build_environment import InstallError | from spack.build_environment import InstallError | ||||||
| from spack.fetch_strategy import FetchError | from spack.fetch_strategy import FetchError | ||||||
| import spack.cmd |  | ||||||
|  |  | ||||||
| description = "Run package installation as a unit test, output formatted results." | description = "Run package installation as a unit test, output formatted results." | ||||||
|  |  | ||||||
|  |  | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|     subparser.add_argument( |     subparser.add_argument('-j', | ||||||
|         '-j', '--jobs', action='store', type=int, |                            '--jobs', | ||||||
|  |                            action='store', | ||||||
|  |                            type=int, | ||||||
|                            help="Explicitly set number of make jobs.  Default is #cpus.") |                            help="Explicitly set number of make jobs.  Default is #cpus.") | ||||||
|  |  | ||||||
|     subparser.add_argument( |     subparser.add_argument('-n', | ||||||
|         '-n', '--no-checksum', action='store_true', dest='no_checksum', |                            '--no-checksum', | ||||||
|  |                            action='store_true', | ||||||
|  |                            dest='no_checksum', | ||||||
|                            help="Do not check packages against checksum") |                            help="Do not check packages against checksum") | ||||||
|  |  | ||||||
|     subparser.add_argument( |     subparser.add_argument('-o', '--output', action='store', help="test output goes in this file") | ||||||
|         '-o', '--output', action='store', help="test output goes in this file") |  | ||||||
|  |  | ||||||
|     subparser.add_argument( |     subparser.add_argument('package', nargs=argparse.REMAINDER, help="spec of package to install") | ||||||
|         'package', nargs=argparse.REMAINDER, help="spec of package to install") |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class JunitResultFormat(object): | class JunitResultFormat(object): | ||||||
| @@ -102,8 +105,7 @@ def __eq__(self, other): | |||||||
|         if not isinstance(other, BuildId): |         if not isinstance(other, BuildId): | ||||||
|             return False |             return False | ||||||
|  |  | ||||||
|         return ((self.name, self.version, self.hashId) == |         return ((self.name, self.version, self.hashId) == (other.name, other.version, other.hashId)) | ||||||
|             (other.name, other.version, other.hashId)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def fetch_log(path): | def fetch_log(path): | ||||||
| @@ -114,14 +116,13 @@ def fetch_log(path): | |||||||
|  |  | ||||||
|  |  | ||||||
| def failed_dependencies(spec): | def failed_dependencies(spec): | ||||||
|     return set(childSpec for childSpec in spec.dependencies.itervalues() if not |     return set(childSpec for childSpec in spec.dependencies.itervalues() if not spack.repo.get(childSpec).installed) | ||||||
|         spack.repo.get(childSpec).installed) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log): | def create_test_output(top_spec, newInstalls, output, getLogFunc=fetch_log): | ||||||
|     # Post-order traversal is not strictly required but it makes sense to output |     # Post-order traversal is not strictly required but it makes sense to output | ||||||
|     # tests for dependencies first. |     # tests for dependencies first. | ||||||
|     for spec in topSpec.traverse(order='post'): |     for spec in top_spec.traverse(order='post'): | ||||||
|         if spec not in newInstalls: |         if spec not in newInstalls: | ||||||
|             continue |             continue | ||||||
|  |  | ||||||
| @@ -131,20 +132,17 @@ def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log): | |||||||
|             result = TestResult.SKIPPED |             result = TestResult.SKIPPED | ||||||
|             dep = iter(failedDeps).next() |             dep = iter(failedDeps).next() | ||||||
|             depBID = BuildId(dep) |             depBID = BuildId(dep) | ||||||
|             errOutput = "Skipped due to failed dependency: {0}".format( |             errOutput = "Skipped due to failed dependency: {0}".format(depBID.stringId()) | ||||||
|                 depBID.stringId()) |  | ||||||
|         elif (not package.installed) and (not package.stage.source_path): |         elif (not package.installed) and (not package.stage.source_path): | ||||||
|             result = TestResult.FAILED |             result = TestResult.FAILED | ||||||
|             errOutput = "Failure to fetch package resources." |             errOutput = "Failure to fetch package resources." | ||||||
|         elif not package.installed: |         elif not package.installed: | ||||||
|             result = TestResult.FAILED |             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)) |  | ||||||
|             errOutput = errMessages if errMessages else lines[-10:] |             errOutput = errMessages if errMessages else lines[-10:] | ||||||
|             errOutput = '\n'.join(itertools.chain( |             errOutput = '\n'.join(itertools.chain([spec.to_yaml(), "Errors:"], errOutput, ["Build Log:", | ||||||
|                     [spec.to_yaml(), "Errors:"], errOutput, |                                                                                            package.build_log_path])) | ||||||
|                     ["Build Log:", package.build_log_path])) |  | ||||||
|         else: |         else: | ||||||
|             result = TestResult.PASSED |             result = TestResult.PASSED | ||||||
|             errOutput = None |             errOutput = None | ||||||
| @@ -153,7 +151,16 @@ def create_test_output(topSpec, newInstalls, output, getLogFunc=fetch_log): | |||||||
|         output.add_test(bId, result, errOutput) |         output.add_test(bId, result, errOutput) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def get_top_spec_or_die(args): | ||||||
|  |     specs = spack.cmd.parse_specs(args.package, concretize=True) | ||||||
|  |     if len(specs) > 1: | ||||||
|  |         tty.die("Only 1 top-level package can be specified") | ||||||
|  |     top_spec = iter(specs).next() | ||||||
|  |     return top_spec | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_install(parser, args): | def test_install(parser, args): | ||||||
|  |     # Check the input | ||||||
|     if not args.package: |     if not args.package: | ||||||
|         tty.die("install requires a package argument") |         tty.die("install requires a package argument") | ||||||
|  |  | ||||||
| @@ -164,19 +171,11 @@ def test_install(parser, args): | |||||||
|     if args.no_checksum: |     if args.no_checksum: | ||||||
|         spack.do_checksum = False  # TODO: remove this global. |         spack.do_checksum = False  # TODO: remove this global. | ||||||
|  |  | ||||||
|     specs = spack.cmd.parse_specs(args.package, concretize=True) |     # Get the one and only top spec | ||||||
|     if len(specs) > 1: |     top_spec = get_top_spec_or_die(args) | ||||||
|         tty.die("Only 1 top-level package can be specified") |  | ||||||
|     topSpec = iter(specs).next() |  | ||||||
|  |  | ||||||
|     newInstalls = set() |  | ||||||
|     for spec in topSpec.traverse(): |  | ||||||
|         package = spack.repo.get(spec) |  | ||||||
|         if not package.installed: |  | ||||||
|             newInstalls.add(spec) |  | ||||||
|  |  | ||||||
|     if not args.output: |     if not args.output: | ||||||
|         bId = BuildId(topSpec) |         bId = BuildId(top_spec) | ||||||
|         outputDir = join_path(os.getcwd(), "test-output") |         outputDir = join_path(os.getcwd(), "test-output") | ||||||
|         if not os.path.exists(outputDir): |         if not os.path.exists(outputDir): | ||||||
|             os.mkdir(outputDir) |             os.mkdir(outputDir) | ||||||
| @@ -184,20 +183,27 @@ def test_install(parser, args): | |||||||
|     else: |     else: | ||||||
|         outputFpath = args.output |         outputFpath = args.output | ||||||
|  |  | ||||||
|     for spec in topSpec.traverse(order='post'): |     new_installs = set() | ||||||
|  |     for spec in top_spec.traverse(order='post'): | ||||||
|         # Calling do_install for the top-level package would be sufficient but |         # Calling do_install for the top-level package would be sufficient but | ||||||
|         # this attempts to keep going if any package fails (other packages which |         # this attempts to keep going if any package fails (other packages which | ||||||
|         # are not dependents may succeed) |         # are not dependents may succeed) | ||||||
|         package = spack.repo.get(spec) |         package = spack.repo.get(spec) | ||||||
|  |  | ||||||
|  |         if not package.installed: | ||||||
|  |             new_installs.add(spec) | ||||||
|  |  | ||||||
|  |         duration = 0.0 | ||||||
|         if (not failed_dependencies(spec)) and (not package.installed): |         if (not failed_dependencies(spec)) and (not package.installed): | ||||||
|             try: |             try: | ||||||
|                 package.do_install( |                 start_time = time.time() | ||||||
|                     keep_prefix=False, |                 package.do_install(keep_prefix=False, | ||||||
|                                    keep_stage=True, |                                    keep_stage=True, | ||||||
|                                    ignore_deps=False, |                                    ignore_deps=False, | ||||||
|                                    make_jobs=args.jobs, |                                    make_jobs=args.jobs, | ||||||
|                                    verbose=True, |                                    verbose=True, | ||||||
|                                    fake=False) |                                    fake=False) | ||||||
|  |                 duration = time.time() - start_time | ||||||
|             except InstallError: |             except InstallError: | ||||||
|                 pass |                 pass | ||||||
|             except FetchError: |             except FetchError: | ||||||
| @@ -205,7 +211,13 @@ def test_install(parser, args): | |||||||
|  |  | ||||||
|     jrf = JunitResultFormat() |     jrf = JunitResultFormat() | ||||||
|     handled = {} |     handled = {} | ||||||
|     create_test_output(topSpec, newInstalls, jrf) |     create_test_output(top_spec, new_installs, jrf) | ||||||
|  |  | ||||||
|     with open(outputFpath, 'wb') as F: |     with open(outputFpath, 'wb') as F: | ||||||
|         jrf.write_to(F) |         jrf.write_to(F) | ||||||
|  |  | ||||||
|  |     # with JunitTestSuite(filename) as test_suite: | ||||||
|  |     #     for spec in top_spec.traverse(order='post'): | ||||||
|  |     #          test_case = install_test(spec) | ||||||
|  |     #          test_suite.append( test_case ) | ||||||
|  |     # | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 alalazo
					alalazo