diff --git a/openqa_review/openqa_review.py b/openqa_review/openqa_review.py index e4ea8ce..db2fa47 100755 --- a/openqa_review/openqa_review.py +++ b/openqa_review/openqa_review.py @@ -222,10 +222,22 @@ class NotEnoughBuildsError(Exception): pass -def parse_summary(details): +def parse_summary(details, url): """Parse and return build summary as dict.""" + passed = details.get("passed", 0) + softfailed = details.get("softfailed", 0) + failed = details.get("failed", 0) + # build pages matching no tests show no job as well as builds only consisting of incomplete jobs + # see https://progress.opensuse.org/issues/60458 + assert ( + passed + softfailed + failed > 0 or details["running"] == 0 + ), "invalid test results found reading %s, make sure you specified valid builds (leading zero missing?)" % ( + url, + ) return { - i.previous.strip().rstrip(":").lower(): int(i.text) for i in details.find(id="summary").find_all(class_="badge") + "passed": passed, + "softfailed": softfailed, + "failed": failed, } @@ -494,7 +506,7 @@ def build_url(build): if "distri" in b.keys() else "distri=" + "&distri=".join(sorted(b["distris"].keys())) ) - return "/tests/overview?%s&version=%s&build=%s&groupid=%i" % ( + return "/tests/overview.json?%s&version=%s&build=%s&groupid=%i" % ( distri_str, b["version"], quote(build), @@ -1097,20 +1109,10 @@ def __init__(self, browser, job_group_url, root_url, args): browser, job_group_url, args.builds, args.against_reviewed, args.running_threshold ) # read last finished - current_details = browser.get_soup(current_url) - previous_details = browser.get_soup(previous_url) - for details in current_details, previous_details: - # build pages matching no tests show no job as well as builds only consisting of incomplete jobs - # see https://progress.opensuse.org/issues/60458 - assert ( - sum(int(badge.text) for badge in details.find_all(class_="badge")) > 0 - or len(details.find_all(class_="status")) > 0 - ), "invalid page with no test results found reading %s and %s, make sure you specified valid builds (leading zero missing?)" % ( - current_url, - previous_url, - ) - current_summary = parse_summary(current_details) - previous_summary = parse_summary(previous_details) + current_details = browser.get_json(current_url) + previous_details = browser.get_json(previous_url) + current_summary = parse_summary(current_details["aggregated"], current_url) + previous_summary = parse_summary(previous_details["aggregated"], previous_url) changes = SortedDict({k: v - previous_summary.get(k, 0) for k, v in iteritems(current_summary)}) self.changes_str = ( @@ -1124,9 +1126,10 @@ def __init__(self, browser, job_group_url, root_url, args): self.ref_build = get_build_nr(previous_url) # for each architecture iterate over all + # XXX: should 'archs' be mandatory? tests won't pass unless it's optional cur_archs, prev_archs = ( - set(arch.text for arch in details.find_all("th", id=re.compile("flavor_"))) - for details in [current_details, previous_details] + set(arch for arch in details.get("archs", {})) + for details in [current_details["aggregated"], previous_details["aggregated"]] ) archs = cur_archs if args.arch: diff --git a/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3D42.1%26build%3D1507%26groupid%3D25 b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3D42.1%26build%3D1507%26groupid%3D25 new file mode 100644 index 0000000..8bb0533 --- /dev/null +++ b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3D42.1%26build%3D1507%26groupid%3D25 @@ -0,0 +1 @@ +{"aggregated":{"aborted":0,"failed":0,"none":0,"not_complete":0,"passed":0,"running":0,"scheduled":0,"unknown":0},"archs":{},"build":"1507","distri":"opensuse","groups":[null],"results":{},"until":null,"version":"42.1"} diff --git a/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160916%26groupid%3D4 b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160916%26groupid%3D4 new file mode 120000 index 0000000..90cb4c9 --- /dev/null +++ b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160916%26groupid%3D4 @@ -0,0 +1 @@ +:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160917%26groupid%3D4 \ No newline at end of file diff --git a/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160917%26groupid%3D4 b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160917%26groupid%3D4 new file mode 100644 index 0000000..09644f8 --- /dev/null +++ b/tests/:tests:overview.json%3Fdistri%3Dopensuse%26version%3DTumbleweed%26build%3D20160917%26groupid%3D4 @@ -0,0 +1 @@ +{"aggregated":{"aborted":0,"failed":2,"none":0,"not_complete":0,"passed":0,"running":0,"scheduled":0,"softfailed":1,"unknown":0},"archs":{"opensuse":{"15.2":{"Argon-Live":["ppc64"]}}},"build":"3.101","distri":null,"groups":[null],"results":{"opensuse":{"15.2":{"Argon-Live":{"krypton-live":{"description":"Maintainer: fvogt@suse.de\n\nTest for openSUSE Krypton\/Argon Live-Media","ppc64":{"bugdetails":null,"bugs":null,"comments":1,"deps":"{\"children\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"has_parents\":0,\"parents\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"parents_ok\":1}","failed":1,"failures":["firefox_audio"],"jobid":1805475,"label":null,"overall":"failed","passed":19,"state":"done","unknown":0}},"krypton-live-installation":{"description":"Boots the openSUSE Krypton\/Argon Live DVD and uses the installer to install with default settings, then reboots into the installed system.","ppc64":{"bugdetails":null,"bugs":null,"comments":null,"deps":"{\"children\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"has_parents\":0,\"parents\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"parents_ok\":1}","failed":0,"failures":[],"jobid":1805476,"label":null,"overall":"softfailed","passed":17,"state":"done","unknown":0}},"krypton-live-wayland@64bit_virtio-3G":{"description":"Tests the openSUSE Krypton Live DVD like krypton-live, but switches to a Wayland session on login.","ppc64":{"bugdetails":null,"bugs":null,"comments":null,"deps":"{\"children\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"has_parents\":0,\"parents\":{\"Chained\":[],\"Directly chained\":[],\"Parallel\":[]},\"parents_ok\":1}","failed":1,"failures":["finish_desktop"],"jobid":1805477,"label":null,"overall":"failed","passed":2,"state":"done","unknown":18}}}}}},"until":null,"version":null}