Browse Source

reports

master
Ulrich Carmesin 3 years ago
parent
commit
ed84a84040
  1. 3
      basic/constants.py
  2. 4
      basic/message.py
  3. 22
      basic/program.py
  4. 0
      test/test_date.py
  5. 158
      test/test_report.py
  6. 15
      utils/config_tool.py
  7. 3
      utils/date_tool.py
  8. 2
      utils/db_abstract.py
  9. 59
      utils/match_tool.py
  10. 5
      utils/path_tool.py
  11. 272
      utils/report_tool.py
  12. 45
      utils/xml2_tool.py
  13. 51
      utils/zip_tool.py

3
basic/constants.py

@ -39,6 +39,9 @@ PAR_MODUS = 'modus'
PAR_COMP = 'component' PAR_COMP = 'component'
PAR_FCT = 'function' PAR_FCT = 'function'
PAR_TOOL = 'tool' PAR_TOOL = 'tool'
PAR_STEP = 'step'
PAR_DESCRIPT = 'desription'
""" """
PAR_TESTCASE = "testcase" PAR_TESTCASE = "testcase"
PAR_TESTSUITE = "usecase" PAR_TESTSUITE = "usecase"
""" name of testcase extracted from PAR_TCDIR """ """ name of testcase extracted from PAR_TCDIR """

4
basic/message.py

@ -219,7 +219,7 @@ class Message:
def log(self, prio, text): def log(self, prio, text):
""" eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt""" """ eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt"""
if (int(prio) <= int(self.level)) and (self.componente is None): if (int(prio) <= int(self.level)) and (self.componente is None): # and self.logfile.closed == False:
self.logfile.write(text + "\n") self.logfile.write(text + "\n")
elif (int(prio) <= int(self.level)): elif (int(prio) <= int(self.level)):
self.messages.append(text) self.messages.append(text)
@ -228,7 +228,7 @@ class Message:
def debug(self, prio, text): def debug(self, prio, text):
""" eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt""" """ eigentliche Schreibroutine: hierin wird debug-Level beruecksichtgigt"""
if (int(prio) < int(self.level)+1): if (int(prio) < int(self.level)+1) : #and self.debugfile.closed == False:
self.debugfile.write(text + "\n") self.debugfile.write(text + "\n")
def merge(self, submsg): def merge(self, submsg):

22
basic/program.py

@ -12,7 +12,7 @@ import copy
import yaml, os import yaml, os
from datetime import datetime from datetime import datetime
import basic.constants as B
import basic.message import basic.message
import basic.message import basic.message
import basic.componentHandling import basic.componentHandling
@ -36,7 +36,7 @@ jobdef = {
"logdir": "{job.par.envdir}/{log}/log_{time}.txt" }, "logdir": "{job.par.envdir}/{log}/log_{time}.txt" },
"test_executer": { "test_executer": {
"pardef": "", "pardef": "",
"pfilesource" : "", "pfilesource" : "tsparfile",
"pfiletarget" : "tsparfile", "pfiletarget" : "tsparfile",
"basedir": "tsbase", "basedir": "tsbase",
"dirname": "tsdir", "dirname": "tsdir",
@ -55,6 +55,20 @@ jobdef = {
"basedir": "tcbase", "basedir": "tcbase",
"dirname": "tcdir", "dirname": "tcdir",
"logdir": "{job.par.tcdir}/{log}/log_{tctime}.txt" }, "logdir": "{job.par.tcdir}/{log}/log_{tctime}.txt" },
"collect_testcase": {
"pardef": "tcdir", # ",tdtyp,tdsrc,tdname",
"pfilesource" : "envparfile",
"pfiletarget" : "tcparfile",
"basedir": "tcbase",
"dirname": "tcdir",
"logdir": "{job.par.tcdir}/{log}/log_{tctime}.txt" },
"compare_testcase": {
"pardef": "tcdir", # ",tdtyp,tdsrc,tdname",
"pfilesource" : "envparfile",
"pfiletarget" : "tcparfile",
"basedir": "tcbase",
"dirname": "tcdir",
"logdir": "{job.par.tcdir}/{log}/log_{tctime}.txt" },
"test_system": { "test_system": {
"pardef": "tcdir,tdtyp,tdsrc,tdname", "pardef": "tcdir,tdtyp,tdsrc,tdname",
"pfilesource": "tsparfile", "pfilesource": "tsparfile",
@ -292,6 +306,7 @@ class Parameter:
parser.add_argument('-c', '--component', action='store') # PAR_COMP parser.add_argument('-c', '--component', action='store') # PAR_COMP
parser.add_argument('-f', '--function', action='store') # PAR_FCT parser.add_argument('-f', '--function', action='store') # PAR_FCT
parser.add_argument('-t', '--tool', action='store') # PAR_TOOL parser.add_argument('-t', '--tool', action='store') # PAR_TOOL
parser.add_argument('-s', '--'+B.PAR_STEP, action='store') # PAR_STEP
# parser.add_argument('-t', '--typ', default='einzel', action='store') # parser.add_argument('-t', '--typ', default='einzel', action='store')
# parser.add_argument('-d', '--dir', action='store') # parser.add_argument('-d', '--dir', action='store')
args = parser.parse_args() args = parser.parse_args()
@ -321,6 +336,7 @@ class Parameter:
job = Job.getInstance() job = Job.getInstance()
print("setParLoaded " ) print("setParLoaded " )
readedPar = job.loadParameter() readedPar = job.loadParameter()
if readedPar is not None: if readedPar is not None:
for k in readedPar["par"].keys(): for k in readedPar["par"].keys():
if not hasattr(self, k): if not hasattr(self, k):
@ -328,7 +344,7 @@ class Parameter:
def setJobAttr(self, key, val): def setJobAttr(self, key, val):
setattr(self, key, val) setattr(self, key, val)
self.parstring = self.parstring + " --" + key + " " + val self.parstring = self.parstring + " --" + key + " " + str(val)
def getJobPar(self, key): def getJobPar(self, key):
a = key.split(":") a = key.split(":")

0
test/test_date.py

158
test/test_report.py

@ -0,0 +1,158 @@
import unittest
import os
import basic.program
import basic.program
import components.component
from basic.componentHandling import ComponentManager
import init_testcase
import test_executer
import test.constants
import utils.report_tool
import utils.match_tool as M
import basic.constants as B
HOME_PATH = test.constants.HOME_PATH
class MyTestCase(unittest.TestCase):
def getReport(self):
job = basic.program.Job.getInstance()
report = utils.report_tool.Report()
archiv = job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_ARCHIV]+"/"
i = 0
for m in M.MATCH_TYPES:
report.setPaths("TC0001", "comp01", "arte01", m, archiv+"path0111"+str(i), archiv+"path0111"+str(i)+"02")
report.setPaths("TC0001", "comp01", "arte02", m, archiv+"path0112"+str(i)+"", archiv+"path0112"+str(i)+"02")
report.setPaths("TC0001", "comp02", "arte01", m, archiv+"path0121"+str(i)+"", archiv+"path0121"+str(i)+"02")
report.setPaths("TC0002", "comp01", "arte01", m, archiv+"path0211"+str(i)+"", archiv+"path0211"+str(i)+"02")
report.setPaths("TC0002", "comp02", "arte01", m, archiv+"path0221"+str(i)+"", archiv+"path0221"+str(i)+"02")
report.setMatchResult("TC0001", "comp01", "arte01", m, "result" + str(i), "<table>" + str(i) + "</table>")
report.setMatchResult("TC0001", "comp01", "arte02", m, "result" + str(i), "<table>" + str(i) + "</table>")
report.setMatchResult("TC0001", "comp02", "arte01", m, "result" + str(1), "<table>" + str(i) + "</table>")
report.setMatchResult("TC0002", "comp01", "arte01", m, "result" + str(1), "<table>" + str(i) + "</table>")
report.setMatchResult("TC0002", "comp02", "arte01", m, "result" + str(i), "<table>" + str(i) + "</table>")
i += 1
if i > 4:
i = 0
return report
def test_cssClass(self):
job = basic.program.Job("unit")
args = { "application": "TEST", "environment": "ENV01", "modus": "unit", "tstime": "2022-03-19_12-09-09",
"tsdir": '/home/ulrich/6_Projekte/Programme/datest/test/conf/lauf/testlauf/TST001_2022-03-19_12-09-09',
"step": 2 }
# "usecase": "TST001", "tstime": "2022-03-17_17-28"}
job.par.setParameterArgs(args)
job.setProgram("test_executer")
report = self.getReport()
i = 0
for m in M.MATCH_TYPES:
cssClass = report.getCssClass("TC0001", "comp01", "arte01", m)
print(m + " test0111 " + cssClass)
self.assertEqual(cssClass, "result"+str(i))
i += 1
if i > 4:
i = 0
cssClass = report.getCssClass("TC0002", "comp01", "arte01", m)
print(m + " test0121 " + cssClass)
cssClass = report.getCssClass("TC0001", "comp01", "arte02")
self.assertEqual(cssClass, "result4")
print("test0112 "+cssClass)
cssClass = report.getCssClass("TC0001", "comp02", "arte01")
print("test0121 "+cssClass)
self.assertEqual(cssClass, "result1")
cssClass = report.getCssClass("TC0002", "comp01")
self.assertEqual(cssClass, "result1")
cssClass = report.getCssClass("TC0002")
self.assertEqual(cssClass, "result4")
def test_title(self):
job = basic.program.Job.getInstance()
print(" ---------- test_title")
setattr(job.par, "testsuite", "TST001")
report = self.getReport()
html = report.getTitle("TC0001", "comp01", "arte01", M.MATCH_POSTCOND)
print(html)
html = report.getTitle("TC0001")
self.assertEqual((utils.report_tool.REP_TITLE in html), True)
self.assertEqual((utils.report_tool.REP_TC in html), True)
self.assertEqual(("TC0001" in html), True)
html = report.getTitle()
self.assertEqual((utils.report_tool.REP_TITLE in html), True)
self.assertEqual((utils.report_tool.REP_TS in html), True)
self.assertEqual(("TST001" in html), True)
def test_overview(self):
job = basic.program.Job.getInstance()
print(" ---------- test_overview")
report = self.getReport()
html = report.getOverview("TC0001")
print(html)
def test_filename(self):
job = basic.program.Job.getInstance()
setattr(job.par, "testcase", "TC0001")
setattr(job.par, "tctime", "2022-03-23_21-23-32")
print(" ---------- test_filename")
cm = basic.componentHandling.ComponentManager()
for c in ["comp02"]:
comp = components.component.Component()
comp.name = c
basic.componentHandling.comps[c] = comp
report = self.getReport()
html = report.getFilepath("TC0001", "comp02", "arte01", M.MATCH_POSTCOND)
print(html)
def test_headlines(self):
job = basic.program.Job.getInstance()
setattr(job.par, "testcase", "TC0001")
setattr(job.par, "tctime", "2022-03-23_21-23-32")
cm = basic.componentHandling.ComponentManager()
for c in ["comp02"]:
comp = components.component.Component()
comp.name = c
basic.componentHandling.comps[c] = comp
print(" ---------- test_headlines")
report = self.getReport()
html = report.getTestcaseHead("TC0001")
print(html)
html = report.getComponentHead("TC0001", "comp02")
print(html)
html = report.getArtefactBlock("TC0001", "comp02", "arte01")
print(html)
def test_reportS(self):
job = basic.program.Job.getInstance()
setattr(job.par, "testcase", "TC0001")
setattr(job.par, "testcases", ["TC0001", "TC0002"])
setattr(job.par, "tctime", "2022-03-23_21-23-32")
print(" ---------- reportTestcase")
report = self.getReport()
cm = basic.componentHandling.ComponentManager()
for compname in ["comp01", "comp02"]:
conf = {}
comp = components.component.Component()
comp.files = { "A": "/home/match/pre.csv", "B": "/home/match/post.csv"}
comp.name = compname
comp.conf = conf
basic.componentHandling.comps[compname] = comp
html_1 = report.reportTestcase("TC0001")
print(html_1)
print("<<---------------------------------- TC0001")
report.extractTestcase("TC0001", html_1)
setattr(job.par, "testcase", "TC0002")
html_2 = report.reportTestcase("TC0002")
print(html_2)
print("<<---------------------------------- TC0002")
report.extractTestcase("TC0002", html_2)
setattr(job.par, "testsuite", "TST001")
html = report.reportTestsuite()
print(html)
print("<<---------------------------------- TST001")
if __name__ == '__main__':
unittest.main()
# report.setPaths("TC0001", "comp01", "arte01", m, archiv+"path0111"+str(i), archiv+"path0111"+str(i)+"02")

15
utils/config_tool.py

@ -114,6 +114,21 @@ def getConfValue(attribute, comp):
return "" return ""
def getAttr(o, name):
#print("hasAttr " + str(type(o))+" "+name)
if (isinstance(o, dict)):
if (name in o.keys()):
#print("hasAttr dict ok " + str(type(o)))
return o[name]
#print("hasAttr dict "+str(type(o)))
elif (isinstance(o, list)):
pass
#print("hasAttr list "+str(type(o)))
elif hasattr(o, name):
#print("hasAttr class ok "+str(type(o)))
return getattr(o, name)
return False
def hasAttr(o, name): def hasAttr(o, name):
#print("hasAttr " + str(type(o))+" "+name) #print("hasAttr " + str(type(o))+" "+name)

3
utils/date_tool.py

@ -8,5 +8,8 @@ import datetime
F_DIR = "%Y-%m-%d_%H-%M-%S" F_DIR = "%Y-%m-%d_%H-%M-%S"
def getActdate(format): def getActdate(format):
return getFormatdate(datetime.datetime.now(), format) return getFormatdate(datetime.datetime.now(), format)
def getFormatdate(date, format): def getFormatdate(date, format):
""" it return the date as string in the format """
return date.strftime(format) return date.strftime(format)

2
utils/db_abstract.py

@ -201,6 +201,8 @@ class DbFcts():
raise Exception("method is not implemented") raise Exception("method is not implemented")
def loadDdl(self): def loadDdl(self):
"""" load the DDL for each database-table
the ddl are mostly stored as csv in the component-folder """
job = basic.program.Job.getInstance() job = basic.program.Job.getInstance()
if (B.DATA_NODE_DDL in self.comp.conf): if (B.DATA_NODE_DDL in self.comp.conf):
return return

59
utils/match_tool.py

@ -6,6 +6,7 @@
# --------------------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------------------
import json import json
import utils.css_tool import utils.css_tool
import utils.report_tool
import basic.program import basic.program
import basic.constants as B import basic.constants as B
# ------------------------------------------------------------ # ------------------------------------------------------------
@ -82,6 +83,7 @@ MATCH = {
"longA": "Soll-Vorher", "longA": "Soll-Vorher",
"longB": "Ist-Vorher", "longB": "Ist-Vorher",
"mode": "info", "mode": "info",
"filename": "01_Vorbedingungen",
"title": "Pruefung Vorbedingung (Soll-Vorher - Ist-Vorher)" "title": "Pruefung Vorbedingung (Soll-Vorher - Ist-Vorher)"
}, },
MATCH_POSTCOND: { MATCH_POSTCOND: {
@ -92,6 +94,7 @@ MATCH = {
"longA": "Soll-Nachher", "longA": "Soll-Nachher",
"longB": "Ist-Nachher", "longB": "Ist-Nachher",
"mode": "hard", "mode": "hard",
"filename": "00_Fachabgleich",
"title": "Fachliche Auswertung (Soll-Nachher - Ist-Nachher)" "title": "Fachliche Auswertung (Soll-Nachher - Ist-Nachher)"
}, },
MATCH_SUCCESS: { MATCH_SUCCESS: {
@ -102,6 +105,7 @@ MATCH = {
"longA": "Ist-Vorher", "longA": "Ist-Vorher",
"longB": "Ist-Nachher", "longB": "Ist-Nachher",
"mode": "action", "mode": "action",
"filename": "04_Ablauf",
"title": "Ablauf-Differenz (Ist-Vorher - Ist-Nachher)" "title": "Ablauf-Differenz (Ist-Vorher - Ist-Nachher)"
}, },
MATCH_PRESTEP: { MATCH_PRESTEP: {
@ -112,6 +116,7 @@ MATCH = {
"longA": "Vor-Schritt", "longA": "Vor-Schritt",
"longB": "Ist-Nachher", "longB": "Ist-Nachher",
"mode": "action", "mode": "action",
"filename": "02_Vorschritt",
"title": "Schritt-Differenz (Vorschritt-Nachher - Ist-Nachher)" "title": "Schritt-Differenz (Vorschritt-Nachher - Ist-Nachher)"
}, },
MATCH_TESTEXAMPLE: { MATCH_TESTEXAMPLE: {
@ -122,11 +127,11 @@ MATCH = {
"longA": "Vor-Schritt", "longA": "Vor-Schritt",
"longB": "Ist-Nachher", "longB": "Ist-Nachher",
"mode": "action", "mode": "action",
"filename": "03_Vergleichstestfall",
"title": "Schritt-Differenz (Vorschritt-Nachher - Ist-Nachher)" "title": "Schritt-Differenz (Vorschritt-Nachher - Ist-Nachher)"
}, },
} }
class Matching(): class Matching():
def __init__(self, comp): def __init__(self, comp):
self.comp = comp self.comp = comp
@ -150,11 +155,14 @@ class Matching():
:param match: kind of actual match :param match: kind of actual match
:return: :return:
""" """
self.sideA = tdata[MATCH[match]["A"]] self.sideA = tdata[MATCH[match]["A"]]["data"]
self.sideB = tdata[MATCH[match]["B"]] self.sideB = tdata[MATCH[match]["B"]]["data"]
self.matchfiles["A"] = tdata[MATCH[match]["A"]]["path"]
self.matchfiles["B"] = tdata[MATCH[match]["B"]]["path"]
self.matchtype = match self.matchtype = match
self.mode = MATCH[match]["mode"] self.mode = MATCH[match]["mode"]
self.setDiffHeader() self.setDiffHeader()
self.report = utils.report_tool.Report.getInstance()
def resetHits(self): def resetHits(self):
self.linksA = {} self.linksA = {}
@ -163,8 +171,6 @@ class Matching():
self.matchkeys = {} self.matchkeys = {}
def isHitA(self, key): def isHitA(self, key):
print("isHitA "+str(key))
for k in self.linksA: print(k)
return ((key in self.linksA) and (self.linksA[key] != "null")) return ((key in self.linksA) and (self.linksA[key] != "null"))
def isHitB(self, key): def isHitB(self, key):
return ((key in self.linksB) and (self.linksB[key] != "null")) return ((key in self.linksB) and (self.linksB[key] != "null"))
@ -333,9 +339,10 @@ def matchTree(matching):
""" """
job = basic.program.Job.getInstance() job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("match_tool"))-4 verify = int(job.getDebugLevel("match_tool"))-4
job.debug(verify, "matching "+matching.mode) job.debug(verify, "..>> start matching "+matching.mode)
matchElement(matching, matching.sideA, matching.sideB, "") matchElement(matching, matching.sideA, matching.sideB, "")
matching.setDiffFooter() matching.setDiffFooter()
job.debug(verify, "..>> ende matching "+matching.htmltext)
return matching.htmltext return matching.htmltext
def matchElement(matching, A, B, path): def matchElement(matching, A, B, path):
@ -388,37 +395,53 @@ def matchDict(matching, A, B, path):
job.debug(verify, "matchDict "+path) job.debug(verify, "matchDict "+path)
if (A is not None): if (A is not None):
for k in A: for k in A:
print(k) job.debug(verify, "matchDict 400 " + k + ".")
if k == "_match": if k in ["_match"]:
continue continue
if (B is not None) and (B[k]): if (B is not None) and (B[k]):
if (isinstance(A[k], dict)): A[k]["_match"] = "Y" if (isinstance(A[k], dict)): A[k]["_match"] = "Y"
if (isinstance(B[k], dict)): B[k]["_match"] = "Y" if (isinstance(B[k], dict)): B[k]["_match"] = "Y"
job.debug(verify, "matchDict 404 " + k + "." + path)
matchElement(matching, A[k], B[k], path+":"+k) matchElement(matching, A[k], B[k], path+":"+k)
else: else:
if (isinstance(A[k], dict)): A[k]["_match"] = "N" if (isinstance(A[k], dict)): A[k]["_match"] = "N"
job.debug(verify, "matchDict 408 " + path)
matchElement(matching, A[k], None, path+":"+k) matchElement(matching, A[k], None, path+":"+k)
if (B is not None): if (B is not None):
for k in B: for k in B:
if k == "_match": job.debug(verify, "matchDict 412 " + k + ".")
if k in ["_match"]:
continue continue
if (A is not None) and (A[k]): if (A is not None) and (A[k]):
continue continue
else: elif (A is None) or (k not in A):
if (A is not None) and (isinstance(A[k], dict)): B[k]["_match"] = "N" if (A is not None) and (isinstance(A[k], dict)): B[k]["_match"] = "N"
job.debug(verify, "matchDict 418 " + k + "." + path)
matchElement(matching, None, B[k], path+":"+k) matchElement(matching, None, B[k], path+":"+k)
job.debug(verify, "matchDict 420 ...<<---")
return matching return matching
def matchArray(matching, A, B, path): def matchArray(matching, A, B, path):
""" matches the datarows of the datatree """ """ matches the datarows of the datatree """
job = basic.program.Job.getInstance() job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("match_tool"))-1 verify = int(job.getDebugLevel("match_tool"))-4
job.debug(verify, "matchArray "+path) job.debug(verify, "matchArray "+path+"\n.."+matching.htmltext)
matching.sideA = A matching.sideA = A
matching.sideB = B matching.sideB = B
matchBestfit(matching, path) matchBestfit(matching, path)
matchRestfit(matching) matchRestfit(matching)
htmltext = compareRows(matching, path) a = path.split(":")
for x in a:
if (x == "_data"): break
table = x
report = utils.report_tool.Report.getInstance()
report.setPaths(getattr(job.par, "testcase"), matching.comp.name, table, matching.matchtype,
matching.matchfiles["A"], matching.matchfiles["B"])
# report.setMatchResult("TC0001", "comp01", "arte01", m, "result" + str(i), "<table>" + str(i) + "</table>")
htmltext = report.getTitle(getattr(job.par, "testcase"), matching.comp.name, table, matching.matchtype)
htmltext += report.getComponentHead(getattr(job.par, "testcase"), matching.comp.name, table, matching.matchtype)
htmltext += report.getArtefactBlock(getattr(job.par, "testcase"), matching.comp.name, table, matching.matchtype)
htmltext += compareRows(matching, path)
matching.htmltext += htmltext matching.htmltext += htmltext
def compareRows(matching, path): def compareRows(matching, path):
@ -426,15 +449,11 @@ def compareRows(matching, path):
job = basic.program.Job.getInstance() job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("match_tool"))-1 verify = int(job.getDebugLevel("match_tool"))-1
ddl = matching.getTableDdl(path) ddl = matching.getTableDdl(path)
report = utils.report_tool.Report.getInstance()
table = "" table = ""
a = path.split(":")
for x in a:
if (x == "_data"): break
table = x
header = [] header = []
htmltext = "<p>Tabelle : "+table+"</p>" # "<p>Tabelle : "+table+"</p>"
htmltext += "<table>" htmltext = "<table><tr><th></th>"
htmltext += "<tr><th></th>"
for f in ddl[B.DATA_NODE_HEADER]: for f in ddl[B.DATA_NODE_HEADER]:
job.debug(verify, "ddl " + f + " ") job.debug(verify, "ddl " + f + " ")
header.append({ "field": f, "type": ddl[f]["type"], "acceptance": ddl[f]["acceptance"]}) header.append({ "field": f, "type": ddl[f]["type"], "acceptance": ddl[f]["acceptance"]})

5
utils/path_tool.py

@ -14,7 +14,7 @@ import basic.constants as B
def getKeyValue(key, comp=None): def getKeyValue(key, comp=None):
job = basic.program.Job.getInstance() job = basic.program.Job.getInstance()
verify = job.getDebugLevel("path_tool") verify = job.getDebugLevel("path_tool")-4
pt = PathConf.getInstance() pt = PathConf.getInstance()
job.debug(verify, "getKeyValue " + key) job.debug(verify, "getKeyValue " + key)
if 'job.par' in key: if 'job.par' in key:
@ -30,7 +30,7 @@ def getKeyValue(key, comp=None):
raise Exception("Component is missing for "+key) raise Exception("Component is missing for "+key)
if not utils.config_tool.hasAttr(comp, key[5:]): if not utils.config_tool.hasAttr(comp, key[5:]):
pass pass
pass return utils.config_tool.getAttr(comp, key[5:])
elif 'env.' in key: elif 'env.' in key:
#if key[4:] #if key[4:]
pass pass
@ -61,6 +61,7 @@ def composePatttern(pattern, comp):
l = re.findall('\{.*?\}', pattern) l = re.findall('\{.*?\}', pattern)
job.debug(verify, l) job.debug(verify, l)
for pat in l: for pat in l:
print(str(max) + ": " + pattern + ": " + pat)
pit = getKeyValue(pat[1:-1], comp) pit = getKeyValue(pat[1:-1], comp)
job.debug(verify, str(max) + ": " + pattern + ": " + pat + ": " + pit) job.debug(verify, str(max) + ": " + pattern + ": " + pat + ": " + pit)
pattern = pattern.replace(pat, pit) pattern = pattern.replace(pat, pit)

272
utils/report_tool.py

@ -13,40 +13,254 @@ the reporting-system in bottom-up
(2.2) transfer of the summary result-code of each testcase to an extern reporting-system - protocol - (2.2) transfer of the summary result-code of each testcase to an extern reporting-system - protocol -
(2.3) visualization of final result-code of each component and each testcase in test-set - result-report - (2.3) visualization of final result-code of each component and each testcase in test-set - result-report -
(2.4) visualization of statistical result-codes of each component and each test-set in test-context - result-report - (2.4) visualization of statistical result-codes of each component and each test-set in test-context - result-report -
| testcase-artefact | testcase-report | testsuite-report
title | comparison | testcase | testsuite
table0 | | each component | each testcase x each component
h1 | | | testcase
h2 | | component | component
h3 | -- | main-comparison | main-comparison
h4 | | other comparison | other comparison
""" """
import os
import re
import basic.program import basic.program
import utils.match_tool as M
import basic.constants as B
import utils.css_tool
import utils.path_tool
def getTcExtraction(tcpath, comp): REP_TITLE = "Ergebnisbericht"
""" REP_TC = "Testfall"
extracts the pure differences of diff-files REP_TS = "Testsuite"
:param comp: REP_COMP = "Komponente"
:return: html-code with links to diff-files REP_ART = "Artefakt"
"""
job = basic.program.Job.getInstance() class Report():
verify = -0 + job.getDebugLevel("report_tool") __instance = None
job.debug(verify, "writeDataTable " + str(comp))
body = '<div class="diff"><p>' @staticmethod
# for f in diff-files: def getInstance():
# body = body + extractDiffLines if (Report.__instance is not None):
body = body + '</p></div>' return Report.__instance
return body else:
return Report()
def getTcBody(tcpath):
""" def __init__(self):
"""
:param report: matchtype
:param comp: optional on matching
structure:
report 1:k
testcase 1:l # only in testsuite-report
components 1:m
artefacts 1:n
matches
the html-side
title : subject of result for artefact/testcase/testsuite
overview : table with links, only for testcase/testsuite
testcase : h1 with anker, only testcase/testsuite
component: h2 with anker
artefact : h3
matches : with links
paths : p with links to row-results
matching : table complete match for artefact-result resp. only diff for other matches
"""
job = basic.program.Job.getInstance()
self.report = {}
self.report["testcases"] = []
self.testcase = ""
self.component = ""
self.artefact = ""
self.matchtype = ""
#return self
def setPaths(self, testcase, component, artefact, matchtype, pathA, pathB):
if not testcase in self.report:
self.report[testcase] = {}
self.report["testcases"].append(testcase)
if not component in self.report[testcase]:
self.report[testcase][component] = {}
if not artefact in self.report[testcase][component]:
self.report[testcase][component][artefact] = {}
self.report[testcase][component][artefact][matchtype] = {}
self.report[testcase][component][artefact][matchtype]["pathA"] = pathA
self.report[testcase][component][artefact][matchtype]["pathB"] = pathB
self.testcase = testcase
self.component = component
self.artefact = artefact
self.matchtype = matchtype
def setMatchResult(self, testcase, component, artefact, matchtype, cssClass, diffTable):
self.report[testcase][component][artefact][matchtype]["css"] = cssClass
if matchtype == M.MATCH_POSTCOND:
self.report[testcase][component][artefact][matchtype]["diff"] = diffTable
def getTitle(self, testcase="", component="", artefact="", matchtype=""):
job = basic.program.Job.getInstance()
if len(matchtype) > 1:
html = "<title>"+M.MATCH[matchtype]["title"]+"</title></head><body><h1>"+M.MATCH[matchtype]["title"]+"</h1>"
elif len(testcase) > 1:
html = "<title>"+REP_TITLE+" "+REP_TC+" "+testcase+"</title></head><body><h1>"+REP_TITLE+" "+REP_TC+" "+testcase+"</h1>"
else:
html = "<title>"+REP_TITLE+" "+REP_TS+" "+getattr(job.par, "testsuite")+"</title></head><body><h1>"+REP_TITLE+" "+REP_TS+" "+getattr(job.par, "testsuite")+"</h1>"
if hasattr(job.par, B.PAR_DESCRIPT):
html += "<p>"+getattr(job.par, B.PAR_DESCRIPT)+"</p>"
return html
def getCssClass(self, testcase="", component="", artefact="", match=""):
"""
the function calculates the maximum cssClass of the granularity
the cssClass means the fault-class of the matching
:param testcase:
:param component:
:param artefact:
:return:
"""
cssClass = "result0"
if len(match) > 0:
if match in self.report[testcase][component][artefact]:
if "css" in self.report[testcase][component][artefact][match]:
if cssClass < self.report[testcase][component][artefact][match]["css"]:
cssClass = self.report[testcase][component][artefact][match]["css"]
return cssClass
elif len(artefact) > 0:
for match in self.report[testcase][component][artefact]:
if "css" in self.report[testcase][component][artefact][match]:
if cssClass < self.report[testcase][component][artefact][match]["css"]:
cssClass = self.report[testcase][component][artefact][match]["css"]
return cssClass
elif len(component) > 0:
for a in self.report[testcase][component]:
val = self.getCssClass(testcase, component, a)
if cssClass < val:
cssClass = val
return cssClass
elif len(testcase) > 0:
for c in self.report[testcase]:
val = self.getCssClass(testcase, c, "")
if cssClass < val:
cssClass = val
return cssClass
return cssClass
def getHeader(self):
job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("report_tool"))-1
htmltxt = "<!DOCTYPE html>"
htmltxt += "<html><head>"
htmltxt += utils.css_tool.getInternalStyle("diffFiles")
return htmltxt
def getOverviewHead(self, testcase=""):
if len(testcase) < 1:
return ""
htmlHead = "<table><tr><th>"+REP_TC+"</th>"
for c in self.report[testcase]:
if c in ["overview", "block"]:
continue
htmlHead += "<th>" + c + "</th>"
return htmlHead
def getOverview(self, testcase=""):
if len(testcase) < 1:
return ""
htmlHead = self.getOverviewHead(testcase)
htmlBody = "<tr class=\"tc-overview\"><td><a href=\"#"+testcase+"_testcase\">"+testcase+"</td>"
for c in self.report[testcase]:
cssClass = self.getCssClass(testcase, c, "")
htmlBody += "<td "+utils.css_tool.getInlineStyle("resultFile", cssClass)+"><a href=\"#" + testcase + "_"+c+"\">" + testcase + "</td>"
return htmlHead+"</tr>"+htmlBody+"</tr></table>"
def getTestcaseHead(self, testcase="", component="", artefact="", matchtype=""):
if len(testcase) < 1:
return ""
cssClass = self.getCssClass(testcase, "", "")
html = "<h1><a id=\""+testcase+"_testcase\">"+REP_TC+" "+testcase+"</h1>"
return html
def getComponentHead(self, testcase="", component="", artefact="", matchtype=""):
job = basic.program.Job.getInstance()
return "<h2 id=\""+testcase+"_"+component+"\">"+REP_COMP+" "+component+"</h2>"
def getArtefactBlock(self, testcase, component, artefact, matchtype=""):
job = basic.program.Job.getInstance()
html = "<h3>"+REP_ART+" "+artefact+"</h3><p>"
for match in self.report[testcase][component][artefact]:
cssClass = self.getCssClass(testcase, component, artefact, match)
path = self.getFilepath(testcase, component, artefact, match)
path = path.replace(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_ARCHIV], os.path.join("..", ".."))
html += " <a href=\""+path+"\" "+utils.css_tool.getInlineStyle("resultFile", cssClass)+">"+M.MATCH[match]["filename"]+"<a> "
html += "</p>"
if len(matchtype) < 1:
matchtype = M.MATCH_POSTCOND
html += "<p>\n"
for side in ["A", "B"]:
path = self.report[testcase][component][artefact][matchtype]["path"+side]
href = path.replace(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_ARCHIV], os.path.join("..", ".."))
html += M.MATCH[M.MATCH[M.MATCH_POSTCOND][side]]["long"]+" "
html += "<a href=\""+href+"\">"+path+"<a>\n"
if side == "A": html += "<br>"
html += "</p>"
return html
def getFilepath(self, testcase, component, artefact, matchtype):
cm = basic.componentHandling.ComponentManager()
comp = cm.getComponent(component)
path = os.path.join(utils.path_tool.composePatttern("{tcresult}", comp), artefact+"_"+M.MATCH[matchtype]["filename"]+".html")
return path
def getComparisonBlock(self, testcase, component, artefact, matchtype):
html = self.report[testcase][component][artefact][matchtype]["diff"]
return html
def reportTestcase(self, testcase):
job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("report_tool")) - 1
html = self.getHeader()
html += self.getTitle(testcase)
html += self.getOverview(testcase)
html += "<div class=\"tc-block\">"
html += self.getTestcaseHead(testcase)
for component in self.report[testcase]:
html += self.getComponentHead(testcase, component)
for artefact in self.report[testcase][component]:
html += self.getArtefactBlock(testcase, component, artefact, M.MATCH_POSTCOND)
html += self.getComparisonBlock(testcase, component, artefact, M.MATCH_POSTCOND)
html += "</div><-- class=\"tc-block\" -->"
html += "</body></html>"
return html
def extractTestcase(self, testcase, html):
job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("report_tool")) - 1
overview = re.findall("<tr class.+tc-overview.*</tr>", html)
if len(overview) == 1:
self.report[testcase]["overview"] = overview[0]
startP = html.index("<div class=\"tc-block\"")
endP = html.index("</div>")
block = html[startP:endP]
if len(block) > 1:
self.report[testcase]["block"] = block
def reportTestsuite(self):
job = basic.program.Job.getInstance()
verify = int(job.getDebugLevel("report_tool")) - 1
testcases = getattr(job.par, "testcases")
html = self.getHeader()
html += self.getTitle()
i = 0
for testcase in testcases:
if i == 0: html += self.getOverviewHead(testcase)
html += self.report[testcase]["overview"]
i += 1
html += "</table>"
for testcase in testcases:
html += self.report[testcase]["block"]
html += "</body></html>"
return html
:param tcpath:
:return:
"""
job = basic.program.Job.getInstance()
verify = -0+job.getDebugLevel("report_tool")
job.debug(verify, "writeDataTable " + str(tcpath))
body = '<div class="diff"><p>'
# for c in comps:
#
body = body + '</p></div>'
return body
def getTcHeader(tcpath): def report_testsuite(tcpath):
""" """
creates header creates header
:param tcpath: :param tcpath:

45
utils/xml2_tool.py

@ -0,0 +1,45 @@
import os, sys, json
import xmltodict
import pprint
class fcts:
def dict2xml(tree):
out = xmltodict.unparse(tree, pretty=True)
return out
def xml2dict(xmlstring):
tree = {}
pp = pprint.PrettyPrinter(indent=4)
tree = xmlstring.parse(xmlstring)
return tree
def readXml(filename):
pass
def addNode(xpath, value):
pass
def writeDataTable(teststatus, tdata, comp):
"""
writes the testdata into a csv-file for documentation of the test-run
:param teststatus:
:param tdata:
:param comp: if specific else None
:return:
"""
#output = xmljson.badgerfish.etree(tdata, root=xmljson.badgerfish.Element('root'))
result = bf.etree(tdata, root=Element('xml'))
# xmljson.badgerfish.tostring(output)
txt = tostring(result, pretty_print=True)
print (txt.decode('utf-8'))
# out = tostring(result, pretty_print=True)
#print (prettify(result))
pass
def prettify(elem):
"""Return a pretty-printed XML string for the Element.
"""
rough_string = tostring(elem, 'utf-8')
reparsed = xml.dom.minidom.parseString(rough_string )
return reparsed.toprettyxml(indent=" ")

51
utils/zip_tool.py

@ -0,0 +1,51 @@
import zipfile
import tarfile
import os
ZIEL = '/home/ulrich/tmp'
QUELLE = '/home/ulrich/1_privat'
FOLDER = '64-UMKER'
def untarFolder():
tar_file = tarfile.open(os.path.join(ZIEL, 'tartemp.tar.gz'), 'r:gz')
tar_file.extractall(path=os.path.join(ZIEL, 'tarliste'))
tar_file.close()
pass
def tarFolder():
with tarfile.open(os.path.join(ZIEL, 'tartemp.tar.gz'), 'w:gz') as tar_file:
for folderName, subfolders, filenames in os.walk(os.path.join(QUELLE, FOLDER)):
for filename in filenames:
folderShort = folderName.replace(QUELLE + '/', '')
# create complete filepath of file in directory
filePath = os.path.join(folderName, filename)
# Add file to zip
tar_file.add(filePath, os.path.join(folderShort, filename))
tar_file.close()
def unzipFolder():
zip_file = zipfile.ZipFile(os.path.join(ZIEL, 'temp.zip'), 'r')
zip_file.extractall(path=os.path.join(ZIEL, 'liste'))
zip_file.close()
pass
def zipFolder():
with zipfile.ZipFile(os.path.join(ZIEL, 'temp.zip'), 'w') as zip_file:
# Iterate over all the files in directory
for folderName, subfolders, filenames in os.walk(os.path.join(QUELLE, FOLDER)):
for filename in filenames:
folderShort = folderName.replace(QUELLE+'/', '')
# create complete filepath of file in directory
filePath = os.path.join(folderName, filename)
# Add file to zip
zip_file.write(filePath, os.path.join(folderShort, filename))
zip_file.close()
return ""
if __name__ == '__main__':
zipFolder()
unzipFolder()
tarFolder()
untarFolder()
Loading…
Cancel
Save