blob: 0deeb5e802c7c224d519b810071e8469f2c22818 [file] [log] [blame]
#!/usr/bin/python3
# importxml.py -- import a .sum file into Postgresql
#
# Copyright (C) 2020 Free Software Foundation, Inc.
#
# This file is part of DejaGnu.
#
# DejaGnu is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This script imports the XML output files from DejaGnu into a
# Postgresql database for easier analysis. As it parses
# the manifest file produced by a toolchain build when
# when using ABE, building thw toolchain requires ABE.
#
import os
import sys
import getopt
import pdb
import re
from lxml import etree
from lxml.etree import tostring
import psycopg2
from datetime import datetime
from sys import argv
# from tqdm import tqdm
# from progress.bar import Bar, PixelBar
from progress.spinner import PixelSpinner
# DejaGnu files
from djstats import DjStats
from manifest import AbeManifest
def usage(argv):
print(argv[0] + ": options: xmlfile xmlfile xmlfile, etc...")
print("""
\t--help(-h) Help
\t--database(-d) database (default "dejagnu")
\t--manifest(-m) Manifest file name
\t--testrun(-m) Testrun number (optional)
""")
quit()
# Default values
dbname = "dejagnu"
infiles = ""
manifest = None
testrun = 0
try:
(opts, vals) = getopt.getopt(argv[1:], "h,m:,d:,t:", ["help", "manifest", "database", "testrun"])
for (opt, val) in opts:
if opt == '--help' or opt == '-h':
usage(argv)
elif opt == "--testrun" or opt == '-t':
testrun = int(val)
elif opt == "--database" or opt == '-d':
dbname = val
elif opt == "--manifest" or opt == '-m':
manifest = val
else:
infiles += val
except getopt.GetoptError as e:
logging.error('%r' % e)
usage(argv)
quit()
infiles = vals
if not infiles:
usage(argv)
try:
connect = " dbname=" + dbname
dbshell = psycopg2.connect(connect)
if dbshell.closed == 0:
dbshell.autocommit = True
print("Opened connection to %r %r" % (dbname, dbshell))
dbcursor = dbshell.cursor()
if dbcursor.closed == 0:
print("Opened cursor in %r %r" % (dbname, dbcursor))
except Exception as e:
print("Couldn't connect to database: %r" % e)
# Get the last testrun number
if testrun <= 0:
query = "SELECT testrun FROM testruns ORDER BY testruns DESC LIMIT 1;"
try:
dbcursor.execute(query)
except Exception as e:
if e.pgcode != None:
print("ERROR: Query failed to fetch! %r" % e.pgerror)
print("ERROR: Query that failed: %r" % query)
quit()
tmp = dbcursor.fetchone()
if tmp is None:
testrun = "1"
else:
testrun = str(int(tmp[0]) + 1)
#
# Read the ABE manifest data for this build, which contains their
# details for each component of this toolchain build.
#
abem = AbeManifest(dbcursor)
if manifest:
# Read data from a text file
abem.readManifest(manifest)
abem.insert(testrun)
else:
# Read data from the database
abem.populate(testrun)
# abem.dump()
#
# Parse the XML file from the test run
#
allstats = dict()
fails = dict()
for xml in infiles:
gstats = DjStats(dbcursor)
spin = PixelSpinner("Processing " + os.path.basename(xml) + "...")
# Ignore invalid charcters.
fd = open(xml)
parser = etree.XMLParser(recover=True)
doc = etree.parse(fd, parser)
tests = list()
testenv = dict()
for docit in doc.getiterator():
test = dict()
# print("TAG: %r" % docit.tag)
if docit.tag == 'testrun':
for elit in docit.getiterator():
# print("FIXME testenv: %r, %r" % (elit.tag, elit.text))
testenv[elit.tag] = elit.text
continue
if docit.tag == 'test':
# test = {'result': "", 'name': "", 'output': ""}
test = dict()
for elit in docit.getiterator():
# print("FIXME test: %r, %r" % (elit.tag, elit.text))
if elit.tag == 'test':
continue
elif elit.text:
# Cleanup the text
text = elit.text.rstrip('/')
colon = text.find(': ')
if colon > 0:
text = text[colon+1:]
else:
text = ""
test[elit.tag] = text
tests.append(test)
if test['result'] == 'FAIL':
fails[testenv['tool']] = test['output']
query = "INSERT INTO tests(testrun, result, name, tool, output) VALUES(%r, %r, %r, %r, %r)" % (testrun, test['result'], test['name'], testenv['tool'], test['output'])
spin.next()
dbcursor.execute(query)
gstats.populate(testenv['tool'], testrun)
allstats[testenv['tool']] = gstats
#
# Update the testruns table
#
# FIXME: should use a date from the XML file
query = """INSERT INTO testruns(testrun, date, target, build) VALUES(%r, %r, %r, %r)""" % (testrun, testenv['timestamp'], testenv['target'], testenv['build'])
try:
dbcursor.execute(query)
except Exception as e:
if e.pgcode != None:
print("ERROR: Query failed to fetch! %r" % e.pgerror)
print("ERROR: Query that failed: %r" % query)
for tool,gstats in allstats.items():
gstats.dump()
for ff in fails:
print(ff)