#!/usr/bin/env python3 # # Copyright (c) 2015, Edward Hervey # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301, USA. import os import sys import xml.etree.cElementTree def extract_info(xmlfile): e = xml.etree.cElementTree.parse(xmlfile).getroot() r = {} for i in e: r[(i.get("classname"), i.get("name"))] = i return r if "__main__" == __name__: if len(sys.argv) < 2: print("Usage : %s [] " % sys.argv[0]) if len(sys.argv) == 3: oldfile = extract_info(sys.argv[1]) newfile = extract_info(sys.argv[2]) else: oldfile = [] newfile = extract_info(sys.argv[1]) # new failures (pass in old run, fail in new run) newfail = [] # new fixes (fail in old run, pass in new run) newfix = [] # tests that are still failing stillfail = [] # tests that are still failling but for a different reason failchange = [] # failed tests sorted by reason reasons = {} # all files allfiles = [] # failed tests sorted by file failedfiles = {} if oldfile: # tests that weren't present in old run newtests = [x for x in newfile.keys() if x not in oldfile] # tests that are no longer present in new run gonetests = [x for x in oldfile.keys() if x not in newfile] # go over new tests for k, v in newfile.iteritems(): tn, fn = k if not fn in allfiles: allfiles.append(fn) newf = v.findall("error") if newf: # extract the failure reason r = newf[0].get("message") if "Application returned 18" in r or "Application returned -5" in r: rs = r.split('[')[1].split(']')[0].split(',') for la in rs: la = la.strip() if la not in reasons: reasons[la] = [] reasons[la].append(k) if fn not in failedfiles: failedfiles[fn] = [] failedfiles[fn].append((tn, r)) if k in oldfile: oldone = oldfile.get(k) # compare failures oldf = oldone.findall("error") if newf and not oldf: newfail.append(k) if oldf and not newf: newfix.append(k) if oldf and newf: stillfail.append(k) a = oldf[0] b = newf[0] print a, b # check if the failure reasons are the same if a.get("type") != b.get("type"): failchange.append(k) elif a.get("message") != b.get("message"): failchange.append(k) if newfail: print("New failures", len(newfail)) newfail.sort() for i in newfail: print " %s : %s" % (i[0], i[1]) f = newfile[i].find("error") print " ", f.get("type"), f.get("message") print if newfix: print "New fixes", len(newfix) newfix.sort() for i in newfix: print " %s : %s" % (i[0], i[1]) print if failchange: print "Failure changes", len(failchange) failchange.sort() for i in failchange: print " %s : %s" % (i[0], i[1]) oldt = oldfile[i].find("error").get("type") newt = newfile[i].find("error").get("type") if oldt != newt: print " Went from '%s' to '%s'" % (oldt, newt) print " Previous message :", oldfile[i].find("error").get("message") print " New message :", newfile[i].find("error").get("message") print for k, v in reasons.iteritems(): print "Failure type : ", k, len(v) v.sort() for i in v: print " %s : %s" % (i[0], i[1]) print nofailfiles = sorted([fn for fn in allfiles if fn not in failedfiles]) if nofailfiles: print "Files without failures", len(nofailfiles) for f in nofailfiles: print " ", f print for k, v in failedfiles.iteritems(): print "Failed File :", k for i in v: print " %s : %s" % (i[0], i[1])