6"""Webscraper for make_a_fuzz nightly cluster run results.
8Given the uri of a make_a_fuzz run, this script will first
9extract the links pointing to each of the individual shards
10and then parse the output generated by each shard to
11find divergences reported by the dartfuzz_test.dart program,
12concatenate all output, or summarize all test results.
15 collect_data.py --type sum
16 https://ci.chromium.org/p/dart/builders/ci.sandbox/fuzz-linux/303
19# This script may require a one time install of BeautifulSoup:
20# sudo apt-get install python3-bs4
26from bs4 import BeautifulSoup
31# Matches shard raw stdout to extract divergence reports.
32P_DIV = re.compile("(Isolate.+? !DIVERGENCE! (\n|.)+?)Isolate ", re.MULTILINE)
34# Matches shard raw stdout to extract report summaries.
36 r"^Tests: (\d+) Success: (\d+) "
37 r"\(Rerun: (\d+)\) Skipped: (\d+) "
38 r"Timeout: (\d+) Divergences: (\d+)", re.MULTILINE)
41P_SHARD = re.compile(
r".*make_a_fuzz_shard_(\d+)")
46 resp = requests.get(uri)
47 soup = BeautifulSoup(resp.text,
"html.parser")
48 for a
in soup.findAll(
"a"):
49 if "stdout" in a.text:
51 if (
"make_a_fuzz_shard" in href
and "__trigger__" not in href):
52 links.append(href +
"?format=raw")
58 print(text.encode(
"ascii", errors=
"ignore").
decode(
"unicode-escape"))
66 sys.stderr.write(
"Shard: " + shard +
" \r")
67 m = P_DIV.findall(text)
80 m = P_SUM.findall(text)
82 sys.stderr.write(
"Failed to parse shard %s stdout for summary" % shard)
85 if int(test[-1]) == 1:
87 for i
in range(
len(s)):
91 "Tests: %d Success: %d (Rerun: %d) Skipped: %d Timeout: %d "
92 "Divergences: %d (failing shards: %s) \r" %
93 tuple(s + [
", ".
join(divs)
if divs
else "none"]),
98def get_stats(uri, output_type, keywords, output_csv):
99 resp = requests.get(uri)
101 if output_type ==
"all":
103 elif output_type ==
"div":
104 shard = P_SHARD.findall(uri)[0]
106 elif output_type ==
"sum":
107 shard = P_SHARD.findall(uri)[0]
108 should_print =
not output_csv
114 parser = argparse.ArgumentParser(description=__doc__)
117 choices=(
"div",
"sum",
"all"),
120 "Select output type (div: divergence report, sum: summary, all: complete stdout)"
126 help=
"Do not include divergences containing these keywords.")
133 "Print output in CSV format to stdout. Only supported for --type=sum")
138 "Uri of one make_a_fuzz run from https://ci.chromium.org/p/dart/builders/ci.sandbox/fuzz-linux."
140 args = parser.parse_args()
141 if args.type !=
'sum' and args.output_csv:
142 print(
'Error: --output-csv can only be provided for --type=sum')
147 if len(shard_links) == 0:
152 for link
in shard_links:
153 stats =
get_stats(link, args.type, args.filter, args.output_csv)
155 print(
"%d,%d,%d,%d,%d,%d" % tuple(stats))
161if __name__ ==
"__main__":
def get_stats(uri, output_type, keywords, output_csv)
def get_output_sum(shard, text, should_print, s=[0, 0, 0, 0, 0, 0], divs=[])
def print_output_all(text)
def print_output_div(shard, text, keywords)
def print_reencoded(text)
def print(*args, **kwargs)
static DecodeResult decode(std::string path)
static SkString join(const CommandLineFlags::StringArray &)