On Fri, 2015-02-13 at 22:09 -0800, Adam Williamson wrote: > On Fri, 2015-02-13 at 04:47 -0800, Adam Williamson wrote: > > OK, I completed my fedfind/wikitcms conversion patch for > > openqa_fedora_tools. I also fixed up some of the test case > > submission data bits - they broke with relval report-auto (instead > > of jskladan's version of non-interactive result submission) > > because they didn't quite grok the 'test instance' concept report- > > auto follows. > > Here's a follow-up (applies on top of the previous three) with my > latest work.
And here's the patch :/ -- Adam Williamson Fedora QA Community Monkey IRC: adamw | Twitter: AdamW_Fedora | XMPP: adamw AT happyassassin . net http://www.happyassassin.net
From d76d85b0644b8afb02c32c3c3af6df5820fb8bea Mon Sep 17 00:00:00 2001 From: Adam Williamson <[email protected]> Date: Fri, 13 Feb 2015 19:36:12 -0800 Subject: [PATCH] further revisions to use improved fedfind/wikitcms abilities We can still run against the latest validation event with 'current' (as before), but now we can also run arbitrary *composes* (not just validation events) with 'compose'. It will try and find a matching ValidationEvent and will report results if --submit-results is passed - but if not it'll still run the OpenQA tests against the compose. This mode can also run without wikitcms (with only fedfind) for pure OpenQA job initiation. If run without args, 'compose' will run against today's Rawhide nightly. This takes advantage of a bunch of clever voodoo added to wikitcms and fedfind to try and ensure version attributes are convertible freely between them, and to guess ones that aren't supplied. --- tools/openqa_trigger/conf_test_suites.py | 2 +- tools/openqa_trigger/openqa_trigger.py | 131 ++++++++++++++++++++--------- tools/openqa_trigger/report_job_results.py | 8 +- 3 files changed, 98 insertions(+), 43 deletions(-) diff --git a/tools/openqa_trigger/conf_test_suites.py b/tools/openqa_trigger/conf_test_suites.py index fd19714..9f6fcfb 100644 --- a/tools/openqa_trigger/conf_test_suites.py +++ b/tools/openqa_trigger/conf_test_suites.py @@ -195,7 +195,7 @@ TESTSUITES = { "server_delete_partial": [ "Server netinst", "QA:Testcase_install_to_VirtIO", - "QA:Testcase_partitioning_guided_delete_partial" + "QA:Testcase_partitioning_guided_delete_partial", "QA:Testcase_Anaconda_User_Interface_Graphical", "QA:Testcase_Anaconda_user_creation", "QA:Testcase_Package_Sets_Minimal_Package_Install", diff --git a/tools/openqa_trigger/openqa_trigger.py b/tools/openqa_trigger/openqa_trigger.py index a6fdbe0..883aa57 100755 --- a/tools/openqa_trigger/openqa_trigger.py +++ b/tools/openqa_trigger/openqa_trigger.py @@ -8,7 +8,11 @@ import os.path import sys import subprocess import argparse -import wikitcms.wiki +# We can at least find images and run OpenQA jobs without wikitcms +try: + import wikitcms.wiki +except: + pass import fedfind.release from report_job_results import report_results @@ -33,17 +37,13 @@ def read_last(): result[version] = json_parsed.get(version, None) return result, json_parsed -def download_image(image, event): +def download_image(image): """Download a given image with a name that should be unique for this event and arch (until we start testing different images for the same event and arch). Returns the filename of the image (not the path). """ - # We don't *really* need to pass in event and use event.version - # here, but as we're quite strongly tied to a validation event - # and we use it as an identifier elsewhere, using it here too - # keeps things consistent. - isoname = "{0}_{1}.iso".format(event.version.replace(' ', '_'), image.arch) + isoname = "{0}_{1}.iso".format(image.version.replace(' ', '_'), image.arch) filename = os.path.join(ISO_PATH, isoname) if not os.path.isfile(filename): # Icky hack around a urlgrabber bug: @@ -51,13 +51,13 @@ def download_image(image, event): urlgrabber.urlgrab(image.url.replace('https', 'http'), filename) return isoname -def run_openqa_jobs(isoname, arch, event_version): +def run_openqa_jobs(isoname, arch, image_version): """# run OpenQA 'isos' job on selected isoname, with given arch and event version as the 'build'. **NOTE**: the 'build' is parsed back into the 'relval report-auto' arguments later. Using event.version makes sure this works. Returns list of job IDs """ - command = RUN_COMMAND % (isoname, arch, event_version.replace(' ', '_')) + command = RUN_COMMAND % (isoname, arch, image_version.replace(' ', '_')) # starts OpenQA jobs output = subprocess.check_output(command.split()) @@ -76,6 +76,10 @@ def run_openqa_jobs(isoname, arch, event_version): # run OpenQA on current compose if it is newer version since last run def run_current(args, wiki): + if not wiki: + sys.exit("python-wikitcms is required for --current. Try " + "--compose to run against today's Rawhide nightly " + "without wiki result submission.") last_versions, json_parsed = read_last() currev = wiki.current_event print("Current event: {0}".format(currev.version)) @@ -87,7 +91,7 @@ def run_current(args, wiki): else: runarches.append(arch) json_parsed[arch] = currev.sortname - jobs = jobs_from_event(currev, runarches) + jobs = jobs_from_fedfind(currev.ff_release, runarches) # write info about latest versions f = open(PERSISTENT, "w") @@ -99,24 +103,54 @@ def run_current(args, wiki): report_results(jobs) sys.exit() -# run OpenQA on a specified event (don't update 'current' records -# or report results) -def run_event(args, wiki): +def run_compose(args, wiki=None): + """run OpenQA on a specified compose, optionally reporting results + if a matching wikitcms ValidationEvent can be found. + """ + # get the fedfind release object try: - event = wiki.get_validation_event( - args.release, args.build, args.version) + ff_release = fedfind.release.get_release( + release=args.release, milestone=args.milestone, + compose=args.compose) except ValueError as err: sys.exit(err[0]) + + try: + # sanity check, there's...some voodoo in here. but this isn't + # really strictly necessary, and we don't use the event object + # for anything. + event = wiki.get_validation_event( + release=ff_release.release, milestone=ff_release.milestone, + compose=ff_release.compose) + if args.submit_results: + evff = event.ff_release + if ff_release.version != evff.version: + print("Release validation event's fedfind object does not " + "match the one from fedfind's get_release(). Something's" + " wrong somewhere. Result submission disabled.") + args.submit_results = False + except ValueError: + if args.submit_results: + print("Warning: could not find validation test event for this " + "compose. Continuing with OpenQA jobs, but results will " + " not be submitted to the wiki.") + args.submit_results = False + + print("Running on compose: {0}".format(ff_release.version)) if args.arch: - print(jobs_from_event(event, [args.arch])) + jobs = jobs_from_fedfind(ff_release, [args.arch]) else: - print(jobs_from_event(event)) + jobs = jobs_from_fedfind(ff_release) + print(jobs) + if args.submit_results: + report_results(jobs) sys.exit() -def jobs_from_event(event, arches=VERSIONS): - """Given a python-wikitcms ValidationEvent, find the ISOs we want - and run jobs on them. arches is an iterable of arches to run on, - if not specified, we'll use our constant.""" +def jobs_from_fedfind(ff_release, arches=VERSIONS): + """Given a fedfind.Release object, find the ISOs we want and run + jobs on them. arches is an iterable of arches to run on, if not + specified, we'll use our constant. + """ # Find boot.iso images for our arches; third query is a bit of a # bodge till I know what 22 TCs/RCs will actually look like, # ideally we want a query that will reliably return one image per @@ -128,10 +162,10 @@ def jobs_from_event(event, arches=VERSIONS): fedfind.release.Query('arch', arches), fedfind.release.Query('payload', ('server', 'generic'))) - for image in event.ff_release.find_images(queries): + for image in ff_release.find_images(queries): print("{0} {1}".format(image.url, image.desc)) - isoname = download_image(image, event) - job_ids = run_openqa_jobs(isoname, image.arch, event.version) + isoname = download_image(image) + job_ids = run_openqa_jobs(isoname, image.arch, ff_release.version) jobs.extend(job_ids) return jobs @@ -147,31 +181,46 @@ if __name__ == "__main__": '-t', '--test', help=test_help, required=False, action='store_true') parser_current.set_defaults(func=run_current) - parser_event = subparsers.add_parser( - 'event', description="Run for a specific event.") - parser_event.add_argument( - '-r', '--release', type=int, required=True, choices=range(12, 100), + parser_compose = subparsers.add_parser( + 'compose', description="Run for a specific compose (TC/RC or nightly)." + " If a matching release validation test event can be found and " + "--submit-results is passed, results will be reported.") + parser_compose.add_argument( + '-r', '--release', type=int, required=False, choices=range(12, 100), metavar="12-99", help="Release number of a specific compose to run " - "against.") - parser_event.add_argument( - '-b', '--build', help="The build to run for; either a milestone " - "(for a TC/RC), or 'Rawhide' or 'Branched' (for a nightly build)", - required=True, + "against. Must be passed for validation event discovery to succeed.") + parser_compose.add_argument( + '-m', '--milestone', help="The milestone to operate on (Alpha, Beta, " + "Final, Branched, Rawhide). Must be specified for a TC/RC; for a " + "nightly, will be guessed if not specified", required=False, choices=['Alpha', 'Beta', 'Final', 'Branched', 'Rawhide']) - parser_event.add_argument( - '-v', '--version', help="The version to run for; either the compose " - "(for a TC/RC), or the date (for a nightly build)", required=True, + parser_compose.add_argument( + '-c', '--compose', help="The version to run for; either the compose " + "(for a TC/RC), or the date (for a nightly build)", required=False, metavar="{T,R}C1-19 or YYYYMMDD") - parser_event.add_argument( + parser_compose.add_argument( '-a', '--arch', help="The arch to run for", required=False, choices=('x86_64', 'i386')) - parser_event.add_argument( + parser_compose.add_argument( + '-s', '--submit-results', help="Submit the results to the release " + "validation event for this compose, if possible", required=False, + action='store_true') + parser_compose.add_argument( '-t', '--test', help=test_help, required=False, action='store_true') - parser_event.set_defaults(func=run_event) + parser_compose.set_defaults(func=run_compose) args = parser.parse_args() + + wiki = None if args.test: - wiki = wikitcms.wiki.Wiki(('https', 'stg.fedoraproject.org'), '/w/') + try: + wiki = wikitcms.wiki.Wiki(('https', 'stg.fedoraproject.org'), + '/w/') + except NameError: + pass else: - wiki = wikitcms.wiki.Wiki(('https', 'fedoraproject.org'), '/w/') + try: + wiki = wikitcms.wiki.Wiki(('https', 'fedoraproject.org'), '/w/') + except NameError: + pass args.func(args, wiki) diff --git a/tools/openqa_trigger/report_job_results.py b/tools/openqa_trigger/report_job_results.py index a617562..bfe6f05 100644 --- a/tools/openqa_trigger/report_job_results.py +++ b/tools/openqa_trigger/report_job_results.py @@ -46,7 +46,13 @@ def get_relval_commands(passed_testcases): for key in passed_testcases: cmd_ = relval_template version, _, build, arch = key - cmd_ += ' --release "%s" --build %s --version "%s"' % tuple(build.split('_')) + buildtup = build.split('_') + if len(buildtup) == 2 and buildtup[0].lower() == 'rawhide': + # Catch the Rawhide nightly special case + cmd_ += ' --milestone Rawhide --compose {0}'.format(buildtup[1]) + else: + # Normal case + cmd_ += ' --release "%s" --milestone %s --compose "%s"' % buildtup for tc_name in passed_testcases[key]: testcase = conf_test_suites.TESTCASES[tc_name] -- 2.3.0
_______________________________________________ qa-devel mailing list [email protected] https://admin.fedoraproject.org/mailman/listinfo/qa-devel
