nuttx-apps/testing/cmocka/tools/cmocka_report.py

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()