This adds an automatic downloader for the latest test results from the mailing list archive and supports diffing test_summary to it. Useful if you don't want to run your own baseline.
contrib/ChangeLog: * diffsummary.py: New file. --- contrib/diffsummary.py | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 contrib/diffsummary.py diff --git a/contrib/diffsummary.py b/contrib/diffsummary.py new file mode 100755 index 000000000000..0a666707272e --- /dev/null +++ b/contrib/diffsummary.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# Show or diff test_summary output to latest posted test result for a platform +# test_summary -t | diffsummary.py (compare test result from current build to last posted) +# diffsummary.py --show (only show last posted) +from urllib.request import urlopen +from urllib.error import URLError +from html.parser import HTMLParser +import time +import re +import argparse +import platform +import tempfile +import os +import sys + +baseurl = "https://gcc.gnu.org/pipermail/gcc-testresults/" + +ap = argparse.ArgumentParser(description="Diff stdin to latest posted test result and set exit code to result") +ap.add_argument("--branch", default="experimental", + help="Branch to match (regex substring match)") +ap.add_argument("--arch", default=platform.machine() + ".*" + platform.system().lower(), + help="architecture to match (regex substring match)") +ap.add_argument("--retrytime", default=1, type=int, + help="time to wait before fetching next page (fractional seconds)") +ap.add_argument("--show", help="Show last test result, but do not diff", action="store_true", default=False) +ap.add_argument("--url", help="Show URLs downloaded", action="store_true") +ap.add_argument("--diff", help="Diff program to use (default diff)", default="diff") +ap.add_argument("--diff-args", help="Diff arguments to use (default -u)", default="-u") +ap.add_argument("--skip", type=int, default=0, help="Skip first N posted test results") +args = ap.parse_args() + +class ParseMonths(HTMLParser): + def __init__(self): + super().__init__() + self.months = [] + def handle_starttag(self, tag, attrs): + if tag == "a" and "thread.html" in attrs[0][1]: + self.months.append(attrs[0][1]) + +class ParseThread(HTMLParser): + def __init__(self): + super().__init__() + self.link = None + self.target = [] + def handle_starttag(self, tag, attrs): + if (tag == "a" + and attrs[0][1][0].isdigit() + and attrs[0][1].endswith(".html")): + self.link = attrs[0][1] + else: + self.link = None + def handle_data(self, data): + if (self.link + and re.search(args.branch, data) + and re.search(args.arch, data)): + self.target.append(thread.link) + +class ParseArticle(HTMLParser): + def __init__(self): + super().__init__() + self.contents = None + self.pre = False + self.data = None + def handle_starttag(self, tag, attrs): + self.pre = tag == "pre" + def handle_data(self, data): + if self.pre and not self.data: + self.data = data + +def my_urlopen(url): + if args.url: + print(url) + return urlopen(url) + +with my_urlopen(baseurl) as index: + months = ParseMonths() + months.feed(index.read().decode('utf-8')) +if len(months.months) == 0: + sys.exit("no months found") +for month in months.months: + with my_urlopen(baseurl + month) as m: + thread = ParseThread() + thread.feed(m.read().decode('utf-8')) + if thread.target: + if args.skip > len(thread.target): + args.skip -= len(thread.target) + continue + url = (baseurl + month).replace("thread.html", thread.target[-1 - args.skip]) + with my_urlopen(url) as t: + article = ParseArticle() + article.feed(t.read().decode('utf-8')) + if args.show: + print(article.data) + break + with tempfile.NamedTemporaryFile(delete=False) as tf: + tf.write(article.data.encode('utf-8')) + tf.close() + cmd = f"{args.diff} {args.diff_args} - {tf.name}" + print(cmd) + ret = os.system(cmd) + os.unlink(tf.name) + sys.exit(ret) + break + time.sleep(args.retrytime) -- 2.49.0