153 lines
4.8 KiB
Python
153 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
############################################################################
|
|
# apps/testing/cmocka/tools/cmocka_report.py
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership. The
|
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance with the
|
|
# License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
############################################################################
|
|
|
|
import json
|
|
import os
|
|
import xml.etree.ElementTree as ET
|
|
from enum import Enum
|
|
|
|
import typer
|
|
import xmltodict
|
|
from bs4 import BeautifulSoup
|
|
from junit2htmlreport.parser import Junit
|
|
|
|
|
|
class ConvertType(str, Enum):
|
|
XML2JSON = "xml2json"
|
|
XML2HTML = "xml2html"
|
|
MERGEXML = "merge"
|
|
|
|
|
|
class CmockaReport:
|
|
def __init__(self, xml, out):
|
|
self.xml = xml
|
|
self.out = out
|
|
|
|
def xml2dict(self):
|
|
"""Parse the XML file and convert it into a dictionary"""
|
|
try:
|
|
with open(self.xml, "r") as f:
|
|
content = f.read()
|
|
soup = BeautifulSoup(content, "xml")
|
|
xml_dict = xmltodict.parse(str(soup))
|
|
return xml_dict
|
|
except FileNotFoundError:
|
|
print("No such file or directory: {0}".format(self.xml))
|
|
except Exception:
|
|
print("Failed to parse XML file")
|
|
|
|
def xml2json(self):
|
|
"""Convert XML dictionary into a JSON string"""
|
|
xml_dict = self.xml2dict()
|
|
if xml_dict is None:
|
|
return
|
|
|
|
json_data = json.dumps(xml_dict, indent=4)
|
|
if self.out:
|
|
try:
|
|
f = open(self.out, "w")
|
|
f.write(json_data)
|
|
f.close()
|
|
print("Job Done")
|
|
except FileNotFoundError:
|
|
print("No such file or directory: {0}".format(self.out))
|
|
except Exception:
|
|
print("Failed to write json file")
|
|
else:
|
|
print(json_data)
|
|
|
|
def xml2html(self):
|
|
"""Convert XML file into a html file"""
|
|
if not self.out:
|
|
self.out = "{0}.html".format(self.xml.split(".")[0])
|
|
try:
|
|
report = Junit(self.xml)
|
|
html = report.html()
|
|
f = open(self.out, "wb")
|
|
f.write(html.encode("UTF-8"))
|
|
f.close()
|
|
print("Job Done")
|
|
except FileNotFoundError:
|
|
print("No such file: {0}".format(self.out))
|
|
except Exception:
|
|
print("Failed to write html file")
|
|
|
|
def mergexml(self):
|
|
"""Merge multiple XML files into one"""
|
|
merged = ET.Element("testsuites")
|
|
for _ in os.listdir(self.xml):
|
|
if _.endswith(".xml"):
|
|
try:
|
|
tree = ET.parse(os.path.join(self.xml, _))
|
|
root = tree.getroot()
|
|
merged.extend(list(root))
|
|
except ET.ParseError as e:
|
|
print("Error parsing XML:", _, e)
|
|
return
|
|
if not merged:
|
|
print("Can not find any xml file")
|
|
return
|
|
if self.out:
|
|
try:
|
|
ET.ElementTree(merged).write(
|
|
self.out, encoding="UTF-8", xml_declaration=True
|
|
)
|
|
print("Job Done")
|
|
except FileNotFoundError:
|
|
print("No such file or directory: {0}".format(self.out))
|
|
except Exception:
|
|
print("Failed to write merge xml file")
|
|
else:
|
|
ET.dump(merged)
|
|
|
|
|
|
app = typer.Typer()
|
|
|
|
|
|
@app.command()
|
|
def main(
|
|
operate: ConvertType = typer.Option(
|
|
default=ConvertType.XML2JSON, help="operation type"
|
|
),
|
|
xml: str = typer.Option(default=None, help="where is the xml file or xml dir"),
|
|
out: str = typer.Option(default=None, help="write to output instead of stdout"),
|
|
):
|
|
"""
|
|
:param operate: operation type\n
|
|
:param xml: where where xml file\n
|
|
:param out: write to output instead of stdout\n
|
|
"""
|
|
if xml is None:
|
|
raise typer.BadParameter("Please provide xml file or xml dir")
|
|
rpt = CmockaReport(xml, out)
|
|
if operate == ConvertType.XML2JSON:
|
|
rpt.xml2json()
|
|
elif operate == ConvertType.XML2HTML:
|
|
rpt.xml2html()
|
|
elif operate == ConvertType.MERGEXML:
|
|
rpt.mergexml()
|
|
else:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|