add per job percentages for responsibility of fails
this provides per build_name failure percentages. This shows what percentage of the failures of a build_name a bug is responsible for. Change-Id: I77f7997331342f244a53a4f98198da8f8145814f
This commit is contained in:
parent
9501108af4
commit
51839edfae
@ -15,6 +15,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import collections
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -63,7 +64,15 @@ def all_fails(classifier):
|
|||||||
return all_fails
|
return all_fails
|
||||||
|
|
||||||
|
|
||||||
def classifying_rate(classifier, data):
|
def num_fails_per_build_name(all_jobs):
|
||||||
|
counts = collections.defaultdict(int)
|
||||||
|
for f in all_jobs:
|
||||||
|
build, job = f.split('.', 1)
|
||||||
|
counts[job] += 1
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def classifying_rate(fails, data):
|
||||||
"""Builds and prints the classification rate.
|
"""Builds and prints the classification rate.
|
||||||
|
|
||||||
It's important to know how good a job we are doing, so this
|
It's important to know how good a job we are doing, so this
|
||||||
@ -71,24 +80,20 @@ def classifying_rate(classifier, data):
|
|||||||
classification rate. For every failure in the gate queue did
|
classification rate. For every failure in the gate queue did
|
||||||
we find a match for it.
|
we find a match for it.
|
||||||
"""
|
"""
|
||||||
fails = all_fails(classifier)
|
|
||||||
for bugnum in data:
|
for bugnum in data:
|
||||||
bug = data[bugnum]
|
bug = data[bugnum]
|
||||||
for job in bug['failed_jobs']:
|
for job in bug['failed_jobs']:
|
||||||
fails[job] = True
|
fails[job] = True
|
||||||
|
|
||||||
total = len(fails.keys())
|
total = len(fails.keys())
|
||||||
bad_jobs = {}
|
bad_jobs = collections.defaultdict(int)
|
||||||
count = 0
|
count = 0
|
||||||
for f in fails:
|
for f in fails:
|
||||||
if fails[f] is True:
|
if fails[f] is True:
|
||||||
count += 1
|
count += 1
|
||||||
else:
|
else:
|
||||||
build, job = f.split('.', 1)
|
build, job = f.split('.', 1)
|
||||||
if job in bad_jobs:
|
bad_jobs[job] += 1
|
||||||
bad_jobs[job] += 1
|
|
||||||
else:
|
|
||||||
bad_jobs[job] = 1
|
|
||||||
|
|
||||||
print("Classification percentage: %2.2f%%" %
|
print("Classification percentage: %2.2f%%" %
|
||||||
((float(count) / float(total)) * 100.0))
|
((float(count) / float(total)) * 100.0))
|
||||||
@ -101,28 +106,73 @@ def classifying_rate(classifier, data):
|
|||||||
print " %3s : %s" % (s[1], s[0])
|
print " %3s : %s" % (s[1], s[0])
|
||||||
|
|
||||||
|
|
||||||
def collect_metrics(classifier):
|
def _status_count(results):
|
||||||
|
counts = {}
|
||||||
|
facets = er_results.FacetSet()
|
||||||
|
facets.detect_facets(
|
||||||
|
results,
|
||||||
|
["build_status", "build_uuid"])
|
||||||
|
|
||||||
|
for key in facets:
|
||||||
|
counts[key] = len(facets[key])
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def _failure_count(hits):
|
||||||
|
if "FAILURE" in hits:
|
||||||
|
return hits["FAILURE"]
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _failed_jobs(results):
|
||||||
|
failed_jobs = []
|
||||||
|
facets = er_results.FacetSet()
|
||||||
|
facets.detect_facets(
|
||||||
|
results,
|
||||||
|
["build_status", "build_uuid"])
|
||||||
|
if "FAILURE" in facets:
|
||||||
|
for build in facets["FAILURE"]:
|
||||||
|
for result in facets["FAILURE"][build]:
|
||||||
|
failed_jobs.append("%s.%s" % (build, result.build_name))
|
||||||
|
return failed_jobs
|
||||||
|
|
||||||
|
|
||||||
|
def _count_fails_per_build_name(hits):
|
||||||
|
facets = er_results.FacetSet()
|
||||||
|
counts = collections.defaultdict(int)
|
||||||
|
facets.detect_facets(
|
||||||
|
hits,
|
||||||
|
["build_status", "build_name", "build_uuid"])
|
||||||
|
if "FAILURE" in facets:
|
||||||
|
for build_name in facets["FAILURE"]:
|
||||||
|
counts[build_name] += 1
|
||||||
|
return counts
|
||||||
|
|
||||||
|
|
||||||
|
def _failure_percentage(hits, fails):
|
||||||
|
total_fails_per_build_name = num_fails_per_build_name(fails)
|
||||||
|
fails_per_build_name = _count_fails_per_build_name(hits)
|
||||||
|
per = {}
|
||||||
|
for build in fails_per_build_name:
|
||||||
|
this_job = fails_per_build_name[build]
|
||||||
|
if build in total_fails_per_build_name:
|
||||||
|
total = total_fails_per_build_name[build]
|
||||||
|
per[build] = (float(this_job) / float(total)) * 100.0
|
||||||
|
return per
|
||||||
|
|
||||||
|
|
||||||
|
def collect_metrics(classifier, fails):
|
||||||
data = {}
|
data = {}
|
||||||
for q in classifier.queries:
|
for q in classifier.queries:
|
||||||
results = classifier.hits_by_query(q['query'], size=30000)
|
results = classifier.hits_by_query(q['query'], size=30000)
|
||||||
facets = er_results.FacetSet()
|
hits = _status_count(results)
|
||||||
facets.detect_facets(
|
|
||||||
results,
|
|
||||||
["build_status", "build_uuid"])
|
|
||||||
|
|
||||||
num_fails = 0
|
|
||||||
failed_jobs = []
|
|
||||||
if "FAILURE" in facets:
|
|
||||||
num_fails = len(facets["FAILURE"])
|
|
||||||
for build in facets["FAILURE"]:
|
|
||||||
for result in facets["FAILURE"][build]:
|
|
||||||
failed_jobs.append("%s.%s" % (build, result.build_name))
|
|
||||||
|
|
||||||
data[q['bug']] = {
|
data[q['bug']] = {
|
||||||
'fails': num_fails,
|
'fails': _failure_count(hits),
|
||||||
'hits': facets,
|
'hits': hits,
|
||||||
|
'percentages': _failure_percentage(results, fails),
|
||||||
'query': q['query'],
|
'query': q['query'],
|
||||||
'failed_jobs': failed_jobs
|
'failed_jobs': _failed_jobs(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@ -135,13 +185,18 @@ def print_metrics(data, with_lp=False):
|
|||||||
sorted_data = sorted(data.iteritems(),
|
sorted_data = sorted(data.iteritems(),
|
||||||
key=lambda x: -x[1]['fails'])
|
key=lambda x: -x[1]['fails'])
|
||||||
for d in sorted_data:
|
for d in sorted_data:
|
||||||
|
bug = d[0]
|
||||||
|
data = d[1]
|
||||||
print("Bug: https://bugs.launchpad.net/bugs/%s => %s"
|
print("Bug: https://bugs.launchpad.net/bugs/%s => %s"
|
||||||
% (d[0], d[1]['query'].rstrip()))
|
% (bug, data['query'].rstrip()))
|
||||||
if with_lp:
|
if with_lp:
|
||||||
get_launchpad_bug(d[0])
|
get_launchpad_bug(d[0])
|
||||||
print "Hits"
|
print "Hits"
|
||||||
for s in d[1]['hits'].keys():
|
for s in data['hits']:
|
||||||
print " %s: %s" % (s, len(d[1]['hits'][s]))
|
print " %s: %s" % (s, data['hits'][s])
|
||||||
|
print "Percentage of Gate Queue Job failures triggered by this bug"
|
||||||
|
for s in data['percentages']:
|
||||||
|
print " %s: %2.2f%%" % (s, data['percentages'][s])
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
@ -160,10 +215,11 @@ def get_launchpad_bug(bug):
|
|||||||
def main():
|
def main():
|
||||||
opts = get_options()
|
opts = get_options()
|
||||||
classifier = er.Classifier(opts.dir)
|
classifier = er.Classifier(opts.dir)
|
||||||
data = collect_metrics(classifier)
|
fails = all_fails(classifier)
|
||||||
|
data = collect_metrics(classifier, fails)
|
||||||
print_metrics(data, with_lp=opts.lp)
|
print_metrics(data, with_lp=opts.lp)
|
||||||
if opts.rate:
|
if opts.rate:
|
||||||
classifying_rate(classifier, data)
|
classifying_rate(fails, data)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
Reference in New Issue
Block a user