diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py index 628c2d3564af43d7e02108ac0b9d006e53dc7443..742c167aadf9b4246934e74b7c884095d1ce1b58 100644 --- a/lib/spack/spack/cmd/install.py +++ b/lib/spack/spack/cmd/install.py @@ -141,6 +141,24 @@ def setup_parser(subparser): default=None, help="CDash URL where reports will be uploaded" ) + subparser.add_argument( + '--cdash-build', + default=None, + help="""The name of the build that will be reported to CDash. +Defaults to spec of the package to install.""" + ) + subparser.add_argument( + '--cdash-site', + default=None, + help="""The site name that will be reported to CDash. +Defaults to current system hostname.""" + ) + subparser.add_argument( + '--cdash-track', + default='Experimental', + help="""Results will be reported to this group on CDash. +Defaults to Experimental.""" + ) arguments.add_common_arguments(subparser, ['yes_to_all']) @@ -224,9 +242,7 @@ def install(parser, args, **kwargs): tty.warn("Deprecated option: --run-tests: use --test=all instead") # 1. Abstract specs from cli - reporter = spack.report.collect_info(args.log_format, - ' '.join(args.package), - args.cdash_upload_url) + reporter = spack.report.collect_info(args.log_format, args) if args.log_file: reporter.filename = args.log_file diff --git a/lib/spack/spack/report.py b/lib/spack/spack/report.py index 74e5caf1940067da1710e40103574cf8395faf31..d092fe1c69ce35caff542c86b66feeab3729e7e4 100644 --- a/lib/spack/spack/report.py +++ b/lib/spack/spack/report.py @@ -228,15 +228,14 @@ class collect_info(object): Args: format_name (str or None): one of the supported formats - install_command (str): the command line passed to spack - cdash_upload_url (str or None): where to upload the report + args (dict): args passed to spack install Raises: ValueError: when ``format_name`` is not in ``valid_formats`` """ - def __init__(self, format_name, install_command, cdash_upload_url): + def __init__(self, format_name, args): self.filename = None - if cdash_upload_url: + if args.cdash_upload_url: self.format_name = 'cdash' self.filename = 'cdash_report' else: @@ -245,8 +244,7 @@ def __init__(self, format_name, install_command, cdash_upload_url): if self.format_name not in valid_formats: raise ValueError('invalid report type: {0}' .format(self.format_name)) - self.report_writer = report_writers[self.format_name]( - install_command, cdash_upload_url) + self.report_writer = report_writers[self.format_name](args) def concretization_report(self, msg): self.report_writer.concretization_report(self.filename, msg) diff --git a/lib/spack/spack/reporter.py b/lib/spack/spack/reporter.py index 17efe23637367b0b47694ce7cbeac50202ad22b6..b2706db7969df8cca60f832e2b840337cf0111e6 100644 --- a/lib/spack/spack/reporter.py +++ b/lib/spack/spack/reporter.py @@ -10,9 +10,8 @@ class Reporter(object): """Base class for report writers.""" - def __init__(self, install_command, cdash_upload_url): - self.install_command = install_command - self.cdash_upload_url = cdash_upload_url + def __init__(self, args): + self.args = args def build_report(self, filename, report_data): pass diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py index 7093afa2ef2702f4a58fd47fe6231c326408002c..068f9275b7f3fc5751a383bf7ad792df0117e249 100644 --- a/lib/spack/spack/reporters/cdash.py +++ b/lib/spack/spack/reporters/cdash.py @@ -51,15 +51,17 @@ class CDash(Reporter): CDash instance hosted at https://mydomain.com/cdash. """ - def __init__(self, install_command, cdash_upload_url): - Reporter.__init__(self, install_command, cdash_upload_url) + def __init__(self, args): + Reporter.__init__(self, args) self.template_dir = os.path.join('reports', 'cdash') - self.hostname = socket.gethostname() + self.cdash_upload_url = args.cdash_upload_url + self.install_command = ' '.join(args.package) + self.buildname = args.cdash_build or self.install_command + self.site = args.cdash_site or socket.gethostname() self.osname = platform.system() self.starttime = int(time.time()) - # TODO: remove hardcoded use of Experimental here. - # Make the submission model configurable. - self.buildstamp = time.strftime("%Y%m%d-%H%M-Experimental", + buildstamp_format = "%Y%m%d-%H%M-{0}".format(args.cdash_track) + self.buildstamp = time.strftime(buildstamp_format, time.localtime(self.starttime)) def build_report(self, filename, report_data): @@ -176,10 +178,11 @@ def concretization_report(self, filename, msg): def initialize_report(self, filename, report_data): if not os.path.exists(filename): os.mkdir(filename) - report_data['install_command'] = self.install_command + report_data['buildname'] = self.buildname report_data['buildstamp'] = self.buildstamp - report_data['hostname'] = self.hostname + report_data['install_command'] = self.install_command report_data['osname'] = self.osname + report_data['site'] = self.site def upload(self, filename): if not self.cdash_upload_url: diff --git a/lib/spack/spack/reporters/junit.py b/lib/spack/spack/reporters/junit.py index 264da413f0d8ee35f26b854a25b4c02272b9da2e..37f389f651df3d7a0597c519d7aa0614fa809d5d 100644 --- a/lib/spack/spack/reporters/junit.py +++ b/lib/spack/spack/reporters/junit.py @@ -17,8 +17,8 @@ class JUnit(Reporter): """Generate reports of spec installations for JUnit.""" - def __init__(self, install_command, cdash_upload_url): - Reporter.__init__(self, install_command, cdash_upload_url) + def __init__(self, args): + Reporter.__init__(self, args) self.template_file = os.path.join('reports', 'junit.xml') def build_report(self, filename, report_data): diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py index 904472f2439dfa885ecb2d307630eefd3d097bdf..666d93020f5f3906d11e698801954a3e432904f6 100644 --- a/lib/spack/spack/test/cmd/install.py +++ b/lib/spack/spack/test/cmd/install.py @@ -432,6 +432,29 @@ def test_cdash_upload_clean_build(tmpdir, mock_fetch, install_mockery, assert '<Text>' not in content +@pytest.mark.disable_clean_stage_check +def test_cdash_upload_extra_params(tmpdir, mock_fetch, install_mockery, capfd): + # capfd interferes with Spack's capturing + with capfd.disabled(): + with tmpdir.as_cwd(): + with pytest.raises((HTTPError, URLError)): + install( + '--log-file=cdash_reports', + '--cdash-build=my_custom_build', + '--cdash-site=my_custom_site', + '--cdash-track=my_custom_track', + '--cdash-upload-url=http://localhost/fakeurl/submit.php?project=Spack', + 'a') + report_dir = tmpdir.join('cdash_reports') + assert report_dir in tmpdir.listdir() + report_file = report_dir.join('Build.xml') + assert report_file in report_dir.listdir() + content = report_file.open().read() + assert 'Site BuildName="my_custom_build"' in content + assert 'Name="my_custom_site"' in content + assert '-my_custom_track' in content + + @pytest.mark.disable_clean_stage_check def test_build_error_output(tmpdir, mock_fetch, install_mockery, capfd): with capfd.disabled(): diff --git a/share/spack/templates/reports/cdash/Site.xml b/share/spack/templates/reports/cdash/Site.xml index a47ffd34e64bf3e752ecb1fdc3c55743b561de6a..f0a150b6e533dd1ac0cb4d4fff959d0addd2ce6a 100644 --- a/share/spack/templates/reports/cdash/Site.xml +++ b/share/spack/templates/reports/cdash/Site.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<Site BuildName="{{ install_command }}" +<Site BuildName="{{ buildname }}" BuildStamp="{{ buildstamp }}" - Name="{{ hostname }}" + Name="{{ site }}" OSName="{{ osname }}" > diff --git a/share/spack/templates/reports/cdash/Update.xml b/share/spack/templates/reports/cdash/Update.xml index 39f3d6a3370bd1d52748b5b9c4fd531b22566498..2ef5de347d81be9fd6b9f174fee1ca51cbc42c2f 100644 --- a/share/spack/templates/reports/cdash/Update.xml +++ b/share/spack/templates/reports/cdash/Update.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <Update> - <Site>{{ hostname }}</Site> - <BuildName>{{ install_command }}</BuildName> + <Site>{{ site }}</Site> + <BuildName>{{ buildname }}</BuildName> <BuildStamp>{{ buildstamp }}</BuildStamp> <StartTime>{{ starttime }}</StartTime> <EndTime>{{ endtime }}</EndTime>