diff --git a/OfflineMBT.setup b/OfflineMBT.setup
index 7eee055a..77fadeb0 100644
--- a/OfflineMBT.setup
+++ b/OfflineMBT.setup
@@ -398,7 +398,7 @@
+ url="https://TNO.github.io/XPlus/nightly/"/>
OfflineMBT - Maven Dependencies
diff --git a/bundles/nl.asml.matala.generator.fast/src/nl/asml/matala/generator/bpmn/FromConcreteToBpmn.xtend b/bundles/nl.asml.matala.generator.fast/src/nl/asml/matala/generator/bpmn/FromConcreteToBpmn.xtend
index 4b021b2e..c56106d5 100644
--- a/bundles/nl.asml.matala.generator.fast/src/nl/asml/matala/generator/bpmn/FromConcreteToBpmn.xtend
+++ b/bundles/nl.asml.matala.generator.fast/src/nl/asml/matala/generator/bpmn/FromConcreteToBpmn.xtend
@@ -26,6 +26,7 @@ class FromConcreteToBpmn extends AbstractGenerator implements IStandardProjectGe
val absTspecFsa = fsa.createFolderAccess(FOLDER_ABSTRACT_TSPEC)
val absTspecURI = conTspecRes.URI.trimFileExtension.appendFileExtension('atspec')
val absTspecRes = absTspecFsa.loadResource(absTspecURI.lastSegment, conTspecRes.resourceSet)
+ absTspecRes.checkResource()
// Generate bpmn for atspec
val fromAbstractToBpmn = new FromAbstractToBpmn()
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest.py b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest.py
index a33f3838..ac39b99a 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest.py
@@ -10,10 +10,12 @@
if __package__ is None or __package__ == '':
from gettest_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from gettest_data import Data
+ from gettest_reporting import get_reporting, initialize_reporting, Location
from gettest_Simulation import Simulation, simulate
else:
from .gettest_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from .gettest_data import Data
+ from .gettest_reporting import get_reporting, initialize_reporting, Location
from .gettest_Simulation import Simulation, simulate
import subprocess
import copy
@@ -233,7 +235,8 @@ def initializeTestGeneration(self):
if k + "_" +elm.__repr__() in self.map_transition_modes_to_name:
print("WARN: duplicate modes detected for same transition.")
print(k + "_" +elm.__repr__())
- print("WARN: references to the above transitions are ambigous!")
+ print("WARN: references to the above transitions are ambiguous!")
+ get_reporting().warning("Duplicate modes detected for same transition, Check References in Details", details=f"{k}_{str.join('\n',[str(s) for s in elm.items()])}")
self.map_transition_modes_to_name[k + "_" +elm.__repr__()] = k + "_" + str(cnt)
# self.map_transition_modes_to_name[k + "_" + pprint.pformat(elm.items(), width=60, compact=True,depth=5)] = k + "_" + str(cnt)
cnt = cnt + 1
@@ -252,7 +255,7 @@ def generateTestCases(self):
for entry in pn.visitedTList:
# txt = ''
if entry:
- _test_scn = TestSCN(self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
+ _test_scn = TestSCN(pspec_path, self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
idx = idx + 1
j = 0
for step in entry:
@@ -340,103 +343,127 @@ def copy(self, name=None):
type=bool,
default=False,
help="Disable simulation")
-
+
+ parser.add_argument("-srfile","--status_report_file",
+ type=Path,
+ default=None,
+ help="The path to where the status report will be saved")
+
+ parser.add_argument("-pspath","--pspec_path",
+ type=str,
+ default="",
+ help="The relatve path to the pspec file to be used for test generation")
+
p = parser.parse_args()
p.tspec_dir.mkdir(exist_ok=True)
p.plantuml_dir.mkdir(exist_ok=True)
-
- a = datetime.datetime.now()
- pn = gettestModel()
- print("[INFO] Loaded CPN model.")
- # pn.n.draw('net-gv-graph.png')
- s = StateGraph(pn.n)
- # s.build()
- # s.draw('test-gv-graph.png')
- # print(" Finished Generation, writing to file.. ")
- print("[INFO] Starting Reachability Graph Generation")
- # pn.generateScenarios(s,0,[],[],[],0,300)
- sys.setrecursionlimit(400)
- pn.generateSCN()
- print('Num Tests: ', pn.numTestCases)
- print("[INFO] Finished.")
- b = datetime.datetime.now()
+ status_report_file = p.status_report_file if p.status_report_file != None else p.tspec_dir / "status_report.json"
+ status_report_file.parent.mkdir(parents=True, exist_ok=True)
+ pspec_path = p.pspec_path
+ reporting = initialize_reporting(status_report_file)
- # s.goto(0)
+ try:
+ a = datetime.datetime.now()
+ pn = gettestModel()
+ print("[INFO] Loaded CPN model.")
+ # pn.n.draw('net-gv-graph.png')
+ s = StateGraph(pn.n)
+ # s.build()
+ # s.draw('test-gv-graph.png')
+ # print(" Finished Generation, writing to file.. ")
+ print("[INFO] Starting Reachability Graph Generation")
+ # pn.generateScenarios(s,0,[],[],[],0,300)
+ sys.setrecursionlimit(400)
+ pn.generateSCN()
+ print('Num Tests: ', pn.numTestCases)
+ print("[INFO] Finished.")
+ b = datetime.datetime.now()
- fname = p.plantuml_dir / "rg.plantuml"
- with open(fname, 'w') as f:
- pn.generateReachabilityGraph(f)
- print("[INFO] Created %s" % (fname,))
- c = datetime.datetime.now()
-
- print("[INFO] Starting Test Generation.")
- pn.initializeTestGeneration()
- pn.generateTestCases()
-
- # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
- print("[INFO] Test Generation Finished.")
- d = datetime.datetime.now()
+ # s.goto(0)
+
+ fname = p.plantuml_dir / "rg.plantuml"
+ with open(fname, 'w') as f:
+ pn.generateReachabilityGraph(f)
+ print("[INFO] Created %s" % (fname,))
+ c = datetime.datetime.now()
- print("[INFO] Creating Structure and Behavior Views in PlantUML.")
- map_block_uml_txt = {}
- for t in pn.n.transition():
- map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+ print("[INFO] Starting Test Generation.")
+ pn.initializeTestGeneration()
+ pn.generateTestCases()
- for t in pn.n.transition():
- gtxt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'json.loads' in t.guard._str:
- # print(t.guard._str.replace('json.loads',''))
- # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- gtxt += 'component %s\n' % (t.name)
- if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
- gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'component %s\n' % (t.name)
- gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
- map_block_uml_txt[t.name.split('_')[0]] = gtxt
+ # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
+ print("[INFO] Test Generation Finished.")
+ d = datetime.datetime.now()
- for t in pn.n.transition():
- for inp in pn.n.pre(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in inp:
- txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ print("[INFO] Creating Structure and Behavior Views in PlantUML.")
+ map_block_uml_txt = {}
+ for t in pn.n.transition():
+ map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+
+ for t in pn.n.transition():
+ gtxt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'json.loads' in t.guard._str:
+ # print(t.guard._str.replace('json.loads',''))
+ # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ gtxt += 'component %s\n' % (t.name)
+ if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
+ gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ else:
+ gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
else:
- txt += '%s --> [%s]\n' % (inp, t.name)
- map_block_uml_txt[t.name.split('_')[0]] = txt
- for out in pn.n.post(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in out:
- txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
- else:
- txt += '[%s] --> %s\n' % (t.name, out)
- map_block_uml_txt[t.name.split('_')[0]] = txt
-
- for key in map_block_uml_txt:
- txt = map_block_uml_txt.get(key)
- txt += '@enduml\n'
- map_block_uml_txt[key] = txt
- fname = p.plantuml_dir / (key + ".plantuml")
- with open(fname, 'w') as f:
- f.write(txt)
-
- print("[INFO] View Generation Finished.")
- e = datetime.datetime.now()
- print("[INFO] Time Statistics")
- print("[INFO] * Reachability Computation: %s" % (b - a))
- print("[INFO] * Reachability PUML Creation: %s" % (c - b))
- print("[INFO] * Test Generation: %s" % (d - c))
- print("[INFO] * PlantUML View Generation: %s" % (e - d))
-
- # print("[INFO] Starting Command-Line Simulation.")
- # simulate(pn.n)
-
- #if not p.no_sim:
- # print('[SIM] Start Simulation? (Y/N) :')
- # value = input(" Enter Choice: ")
- # if value == "Y" or value == "y":
- # os.system('cls')
- # simulate(pn.n)
-
- print("[INFO] Exiting..")
+ gtxt += 'component %s\n' % (t.name)
+ gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
+ map_block_uml_txt[t.name.split('_')[0]] = gtxt
+
+ for t in pn.n.transition():
+ for inp in pn.n.pre(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in inp:
+ txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ else:
+ txt += '%s --> [%s]\n' % (inp, t.name)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+ for out in pn.n.post(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in out:
+ txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ else:
+ txt += '[%s] --> %s\n' % (t.name, out)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+
+ for key in map_block_uml_txt:
+ txt = map_block_uml_txt.get(key)
+ txt += '@enduml\n'
+ map_block_uml_txt[key] = txt
+ fname = p.plantuml_dir / (key + ".plantuml")
+ with open(fname, 'w') as f:
+ f.write(txt)
+
+ print("[INFO] View Generation Finished.")
+ e = datetime.datetime.now()
+ print("[INFO] Time Statistics")
+ print("[INFO] * Reachability Computation: %s" % (b - a))
+ print("[INFO] * Reachability PUML Creation: %s" % (c - b))
+ print("[INFO] * Test Generation: %s" % (d - c))
+ print("[INFO] * PlantUML View Generation: %s" % (e - d))
+
+ # print("[INFO] Starting Command-Line Simulation.")
+ # simulate(pn.n)
+
+ #if not p.no_sim:
+ # print('[SIM] Start Simulation? (Y/N) :')
+ # value = input(" Enter Choice: ")
+ # if value == "Y" or value == "y":
+ # os.system('cls')
+ # simulate(pn.n)
+
+ except Exception as e:
+ print("[ERROR] " + str(e))
+ if not isinstance(e, StatusException):
+ get_reporting().exception(message = e.__class__.__name__, exception = e)
+ finally:
+ print("[INFO] Saving status_report.json")
+ severity = reporting.save()
+ print("[INFO] Saved status_report.json")
+ print(f"[INFO] Exiting with status: {severity.name}")
+ exit(severity.value)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_TestSCN.py b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_TestSCN.py
index a13222e9..61e9937a 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_TestSCN.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_TestSCN.py
@@ -22,12 +22,13 @@ class TestSCN:
constraint_dict = {}
tr_assert_ref_dict = {}
- def __init__(self, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
+ def __init__(self, _pspec_path, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
self.step_list = []
self.step_dependencies = []
self.map_transition_assert = _mapTrAssert
self.constraint_dict = _constraint_dict
self.tr_assert_ref_dict = _tr_assert_ref_dict
+ self.pspec_path = _pspec_path
def generate_viz(self, idx, output_dir):
txt = "@startuml\n"
@@ -73,7 +74,7 @@ def recurseJson(self, items, prefix):
raise TypeError('Unsupported type')
txt += f" {prefix} := {items}\n"
return txt
-
+
def printData(self, idata):
txt = ""
for k, v in idata.items():
@@ -83,10 +84,10 @@ def printData(self, idata):
# for jk in j.keys():
# txt += self.recurseJson(j[jk], "%s.%s" % (k,jk))
return txt
-
+
def generateTSpec(self, idx, sutTypesList, sutVarTransitionMap, transitionQnameMap, output_dir):
txt = ""
- txt += "import \"gettest.ps\"\n\n"
+ txt += f"""import "{self.pspec_path}gettest.ps"\n\n"""
txt += "using gettest.Root.test\n"
txt += "using gettest.Root.single\n"
txt += "\nabstract-test-definition\n\n"
@@ -297,8 +298,8 @@ class CEntry:
name = ""
constr = ""
+
def __init__(self, n, c):
self.name = n
self.constr = c
-
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_data.py b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_data.py
index 44170b8b..675bf1a4 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_data.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_data.py
@@ -1,6 +1,9 @@
import copy
import json
-
+if __package__ is None or __package__ == '':
+ from gettest_reporting import get_reporting, Location
+else:
+ from .gettest_reporting import get_reporting, Location
class Data:
@@ -29,6 +32,11 @@ def get_Single():
@staticmethod
def execute_Root_T1_default_single(test):
- single = {"aString": list(test["aMap"].items())[2][1], "aInt": test["aList"][2]}
+ try:
+ single = {"aString": list(test["aMap"].items())[2][1], "aInt": test["aList"][2]}
+ except Exception as e:
+ __location = Location(28,31,523,107,"single := Single { aString = get(test.aMap, 2), aInt = get(test.aList, 2) }")
+ __source_file = "gettest.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(single)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_reporting.py b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_reporting.py
new file mode 100644
index 00000000..5d65d98e
--- /dev/null
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/gettest/CPNServer/gettest/gettest_reporting.py
@@ -0,0 +1,153 @@
+import json
+import traceback
+from enum import Enum
+from typing import List, Optional, Dict, Any
+from dataclasses import dataclass, field
+from pathlib import Path
+
+class StatusException(Exception):
+ def __init__(self, message: str):
+ super().__init__(message)
+
+class Severity(Enum):
+ OK = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CANCEL = 4
+
+@dataclass
+class Location:
+ startLine: int
+ endLine: int
+ offset: int
+ length: int
+ text: str
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'startLine': self.startLine,
+ 'endLine': self.endLine,
+ 'offset': self.offset,
+ 'length': self.length,
+ 'text': self.text,
+ }
+
+@dataclass
+class StatusReport:
+ plugin: str
+ severity: Severity
+ message: str
+ source: str = ""
+ code: int = 0
+ details: Optional[str] = None
+ location: Optional[Location] = None
+ children: List['StatusReport'] = field(default_factory=list)
+ exception: Optional[Exception] = field(default=None, repr=False)
+
+ def __post_init__(self):
+ if self.exception is not None:
+ if self.details is None:
+ self.details = self._get_stack_trace_as_string(self.exception)
+ self.exception = None # Don't retain non-serializable object
+
+ if self.children:
+ child_severities = [child.severity for child in self.children if child is not None]
+ if child_severities:
+ max_child_severity = max(child_severities, key=lambda s: s.value)
+ if max_child_severity.value > self.severity.value:
+ self.severity = max_child_severity
+
+ @staticmethod
+ def _get_stack_trace_as_string(exception: Exception) -> str:
+ if exception is None:
+ return None
+ tb_lines = traceback.format_exception(type(exception), exception, exception.__traceback__)
+ if len(tb_lines) > 15:
+ tb_lines = tb_lines[:15] + [f"\t... {len(tb_lines) - 15} more\n"]
+ return "".join(tb_lines)
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'plugin': self.plugin,
+ 'severity': self.severity.name,
+ 'message': self.message,
+ 'source': self.source,
+ 'code': self.code,
+ 'details': self.details,
+ 'location': self.location.to_dict() if self.location else None,
+ 'children': [child.to_dict() for child in self.children if child is not None],
+ }
+
+class StatusReporting:
+ def __init__(self, save_path: str):
+ self.save_path = Path(save_path)
+ self.reports: List[StatusReport] = []
+
+ def _log(self, severity: Severity, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, exception: Optional[Exception] = None, location: Optional[Location] = None) -> StatusReport:
+ report = StatusReport(
+ plugin="",
+ severity=severity,
+ message=message,
+ source=source,
+ code=code,
+ details=details,
+ location=location,
+ exception=exception
+ )
+ self.reports.append(report)
+ return report
+
+ def info(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.INFO, message, source, code, details, None, location)
+
+ def warning(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.WARNING, message, source, code, details, None, location)
+
+ def error(self, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.ERROR, message, source, code, details, None, location)
+
+ def exception(self, message: str, exception: Exception, source: str = "", details: str = None, code: int = 0, location: Location = None) -> StatusReport:
+ self._log(Severity.ERROR, message, source, code, details, exception, location)
+ #on exception the process is stopped
+ raise StatusException(message)
+
+ def save(self) -> Severity:
+
+ root_severity = Severity.OK
+ if self.reports:
+ root_severity = max((report.severity for report in self.reports), key=lambda s: s.value)
+
+ root_report = StatusReport(
+ plugin="",
+ severity=root_severity,
+ message=f"Python generation of gettest",
+ source="",
+ code=0,
+ details=None,
+ location=None,
+ children=self.reports,
+ exception=None
+ )
+
+ data = root_report.to_dict()
+ with open(self.save_path, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return root_severity
+
+
+_status_reporting_instance: Optional[StatusReporting] = None
+
+def initialize_reporting(save_path: str) -> StatusReporting:
+ global _status_reporting_instance
+ _status_reporting_instance = StatusReporting(save_path)
+ return _status_reporting_instance
+
+def get_reporting() -> StatusReporting:
+ global _status_reporting_instance
+ if _status_reporting_instance is None:
+ raise RuntimeError("StatusReporting not initialized. Call initialize_reporting() first.")
+ return _status_reporting_instance
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging.py b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging.py
index 0a6fb785..0a32f5f2 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging.py
@@ -10,10 +10,12 @@
if __package__ is None or __package__ == '':
from imaging_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from imaging_data import Data
+ from imaging_reporting import get_reporting, initialize_reporting, Location
from imaging_Simulation import Simulation, simulate
else:
from .imaging_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from .imaging_data import Data
+ from .imaging_reporting import get_reporting, initialize_reporting, Location
from .imaging_Simulation import Simulation, simulate
import subprocess
import copy
@@ -520,7 +522,8 @@ def initializeTestGeneration(self):
if k + "_" +elm.__repr__() in self.map_transition_modes_to_name:
print("WARN: duplicate modes detected for same transition.")
print(k + "_" +elm.__repr__())
- print("WARN: references to the above transitions are ambigous!")
+ print("WARN: references to the above transitions are ambiguous!")
+ get_reporting().warning("Duplicate modes detected for same transition, Check References in Details", details=f"{k}_{str.join('\n',[str(s) for s in elm.items()])}")
self.map_transition_modes_to_name[k + "_" +elm.__repr__()] = k + "_" + str(cnt)
# self.map_transition_modes_to_name[k + "_" + pprint.pformat(elm.items(), width=60, compact=True,depth=5)] = k + "_" + str(cnt)
cnt = cnt + 1
@@ -542,7 +545,7 @@ def generateTestCases(self):
for entry in pn.visitedTList:
# txt = ''
if entry:
- _test_scn = TestSCN(self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
+ _test_scn = TestSCN(pspec_path, self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
idx = idx + 1
j = 0
for step in entry:
@@ -630,103 +633,127 @@ def copy(self, name=None):
type=bool,
default=False,
help="Disable simulation")
-
+
+ parser.add_argument("-srfile","--status_report_file",
+ type=Path,
+ default=None,
+ help="The path to where the status report will be saved")
+
+ parser.add_argument("-pspath","--pspec_path",
+ type=str,
+ default="",
+ help="The relatve path to the pspec file to be used for test generation")
+
p = parser.parse_args()
p.tspec_dir.mkdir(exist_ok=True)
p.plantuml_dir.mkdir(exist_ok=True)
-
- a = datetime.datetime.now()
- pn = imagingModel()
- print("[INFO] Loaded CPN model.")
- # pn.n.draw('net-gv-graph.png')
- s = StateGraph(pn.n)
- # s.build()
- # s.draw('test-gv-graph.png')
- # print(" Finished Generation, writing to file.. ")
- print("[INFO] Starting Reachability Graph Generation")
- # pn.generateScenarios(s,0,[],[],[],0,300)
- sys.setrecursionlimit(400)
- pn.generateSCN()
- print('Num Tests: ', pn.numTestCases)
- print("[INFO] Finished.")
- b = datetime.datetime.now()
+ status_report_file = p.status_report_file if p.status_report_file != None else p.tspec_dir / "status_report.json"
+ status_report_file.parent.mkdir(parents=True, exist_ok=True)
+ pspec_path = p.pspec_path
+ reporting = initialize_reporting(status_report_file)
- # s.goto(0)
+ try:
+ a = datetime.datetime.now()
+ pn = imagingModel()
+ print("[INFO] Loaded CPN model.")
+ # pn.n.draw('net-gv-graph.png')
+ s = StateGraph(pn.n)
+ # s.build()
+ # s.draw('test-gv-graph.png')
+ # print(" Finished Generation, writing to file.. ")
+ print("[INFO] Starting Reachability Graph Generation")
+ # pn.generateScenarios(s,0,[],[],[],0,300)
+ sys.setrecursionlimit(400)
+ pn.generateSCN()
+ print('Num Tests: ', pn.numTestCases)
+ print("[INFO] Finished.")
+ b = datetime.datetime.now()
- fname = p.plantuml_dir / "rg.plantuml"
- with open(fname, 'w') as f:
- pn.generateReachabilityGraph(f)
- print("[INFO] Created %s" % (fname,))
- c = datetime.datetime.now()
-
- print("[INFO] Starting Test Generation.")
- pn.initializeTestGeneration()
- pn.generateTestCases()
-
- # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
- print("[INFO] Test Generation Finished.")
- d = datetime.datetime.now()
+ # s.goto(0)
+
+ fname = p.plantuml_dir / "rg.plantuml"
+ with open(fname, 'w') as f:
+ pn.generateReachabilityGraph(f)
+ print("[INFO] Created %s" % (fname,))
+ c = datetime.datetime.now()
- print("[INFO] Creating Structure and Behavior Views in PlantUML.")
- map_block_uml_txt = {}
- for t in pn.n.transition():
- map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+ print("[INFO] Starting Test Generation.")
+ pn.initializeTestGeneration()
+ pn.generateTestCases()
- for t in pn.n.transition():
- gtxt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'json.loads' in t.guard._str:
- # print(t.guard._str.replace('json.loads',''))
- # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- gtxt += 'component %s\n' % (t.name)
- if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
- gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'component %s\n' % (t.name)
- gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
- map_block_uml_txt[t.name.split('_')[0]] = gtxt
+ # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
+ print("[INFO] Test Generation Finished.")
+ d = datetime.datetime.now()
- for t in pn.n.transition():
- for inp in pn.n.pre(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in inp:
- txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ print("[INFO] Creating Structure and Behavior Views in PlantUML.")
+ map_block_uml_txt = {}
+ for t in pn.n.transition():
+ map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+
+ for t in pn.n.transition():
+ gtxt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'json.loads' in t.guard._str:
+ # print(t.guard._str.replace('json.loads',''))
+ # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ gtxt += 'component %s\n' % (t.name)
+ if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
+ gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ else:
+ gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
else:
- txt += '%s --> [%s]\n' % (inp, t.name)
- map_block_uml_txt[t.name.split('_')[0]] = txt
- for out in pn.n.post(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in out:
- txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
- else:
- txt += '[%s] --> %s\n' % (t.name, out)
- map_block_uml_txt[t.name.split('_')[0]] = txt
-
- for key in map_block_uml_txt:
- txt = map_block_uml_txt.get(key)
- txt += '@enduml\n'
- map_block_uml_txt[key] = txt
- fname = p.plantuml_dir / (key + ".plantuml")
- with open(fname, 'w') as f:
- f.write(txt)
-
- print("[INFO] View Generation Finished.")
- e = datetime.datetime.now()
- print("[INFO] Time Statistics")
- print("[INFO] * Reachability Computation: %s" % (b - a))
- print("[INFO] * Reachability PUML Creation: %s" % (c - b))
- print("[INFO] * Test Generation: %s" % (d - c))
- print("[INFO] * PlantUML View Generation: %s" % (e - d))
-
- # print("[INFO] Starting Command-Line Simulation.")
- # simulate(pn.n)
-
- #if not p.no_sim:
- # print('[SIM] Start Simulation? (Y/N) :')
- # value = input(" Enter Choice: ")
- # if value == "Y" or value == "y":
- # os.system('cls')
- # simulate(pn.n)
-
- print("[INFO] Exiting..")
+ gtxt += 'component %s\n' % (t.name)
+ gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
+ map_block_uml_txt[t.name.split('_')[0]] = gtxt
+
+ for t in pn.n.transition():
+ for inp in pn.n.pre(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in inp:
+ txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ else:
+ txt += '%s --> [%s]\n' % (inp, t.name)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+ for out in pn.n.post(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in out:
+ txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ else:
+ txt += '[%s] --> %s\n' % (t.name, out)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+
+ for key in map_block_uml_txt:
+ txt = map_block_uml_txt.get(key)
+ txt += '@enduml\n'
+ map_block_uml_txt[key] = txt
+ fname = p.plantuml_dir / (key + ".plantuml")
+ with open(fname, 'w') as f:
+ f.write(txt)
+
+ print("[INFO] View Generation Finished.")
+ e = datetime.datetime.now()
+ print("[INFO] Time Statistics")
+ print("[INFO] * Reachability Computation: %s" % (b - a))
+ print("[INFO] * Reachability PUML Creation: %s" % (c - b))
+ print("[INFO] * Test Generation: %s" % (d - c))
+ print("[INFO] * PlantUML View Generation: %s" % (e - d))
+
+ # print("[INFO] Starting Command-Line Simulation.")
+ # simulate(pn.n)
+
+ #if not p.no_sim:
+ # print('[SIM] Start Simulation? (Y/N) :')
+ # value = input(" Enter Choice: ")
+ # if value == "Y" or value == "y":
+ # os.system('cls')
+ # simulate(pn.n)
+
+ except Exception as e:
+ print("[ERROR] " + str(e))
+ if not isinstance(e, StatusException):
+ get_reporting().exception(message = e.__class__.__name__, exception = e)
+ finally:
+ print("[INFO] Saving status_report.json")
+ severity = reporting.save()
+ print("[INFO] Saved status_report.json")
+ print(f"[INFO] Exiting with status: {severity.name}")
+ exit(severity.value)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_TestSCN.py b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_TestSCN.py
index 03f33dae..a580c1ea 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_TestSCN.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_TestSCN.py
@@ -22,12 +22,13 @@ class TestSCN:
constraint_dict = {}
tr_assert_ref_dict = {}
- def __init__(self, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
+ def __init__(self, _pspec_path, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
self.step_list = []
self.step_dependencies = []
self.map_transition_assert = _mapTrAssert
self.constraint_dict = _constraint_dict
self.tr_assert_ref_dict = _tr_assert_ref_dict
+ self.pspec_path = _pspec_path
def generate_viz(self, idx, output_dir):
txt = "@startuml\n"
@@ -73,7 +74,7 @@ def recurseJson(self, items, prefix):
raise TypeError('Unsupported type')
txt += f" {prefix} := {items}\n"
return txt
-
+
def printData(self, idata):
txt = ""
for k, v in idata.items():
@@ -83,10 +84,10 @@ def printData(self, idata):
# for jk in j.keys():
# txt += self.recurseJson(j[jk], "%s.%s" % (k,jk))
return txt
-
+
def generateTSpec(self, idx, sutTypesList, sutVarTransitionMap, transitionQnameMap, output_dir):
txt = ""
- txt += "import \"imaging.ps\"\n\n"
+ txt += f"""import "{self.pspec_path}imaging.ps"\n\n"""
txt += "using imaging.SupervisonModelSupervisionImagePreparation.ImagingRequest\n"
txt += "using imaging.SupervisonModelSupervisionImagePreparation.AcqUpdate\n"
txt += "using imaging.SupervisonModelSupervisionImagePreparation.EqStatus\n"
@@ -351,8 +352,8 @@ class CEntry:
name = ""
constr = ""
+
def __init__(self, n, c):
self.name = n
self.constr = c
-
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_data.py b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_data.py
index e882739d..2c6c1410 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_data.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_data.py
@@ -1,6 +1,9 @@
import copy
import json
-
+if __package__ is None or __package__ == '':
+ from imaging_reporting import get_reporting, Location
+else:
+ from .imaging_reporting import get_reporting, Location
class Data:
@@ -97,416 +100,871 @@ def get_VacuumEnum():
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_Unprepare_default_AcquisitionReq(ImagingRequest):
- AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ try:
+ AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ except Exception as e:
+ __location = Location(41,44,1101,128,"AcquisitionReq := AcqReq { cmd_type = ImagingRequest.cmd_type, id = ImagingRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcquisitionReq)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_Prepare_default_AcquisitionReq(ImagingRequest,EqStatus):
- AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ try:
+ AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ except Exception as e:
+ __location = Location(54,57,1647,128,"AcquisitionReq := AcqReq { cmd_type = ImagingRequest.cmd_type, id = ImagingRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcquisitionReq)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_Prepare_default_EqStatus(ImagingRequest,EqStatus):
- EqStatus = EqStatus
+ try:
+ EqStatus = EqStatus
+ except Exception as e:
+ __location = Location(60,60,1865,20,"EqStatus := EqStatus")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_Waitforprepare_default_Gateway_102q82v(Flow_0kkvgdv,AcqUpdate,EqStatus):
- Gateway_102q82v = Flow_0kkvgdv
+ try:
+ Gateway_102q82v = Flow_0kkvgdv
+ except Exception as e:
+ __location = Location(68,68,2133,31,"Gateway_102q82v := Flow_0kkvgdv")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_102q82v)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_Waitforprepare_default_EqStatus(Flow_0kkvgdv,AcqUpdate,EqStatus):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::PREPARING"}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::PREPARING"}
+ except Exception as e:
+ __location = Location(72,76,2271,187,"EqStatus:=EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = EqStatus.pump_status, acq_status = Status::PREPARING }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_WaitforUnprepare_default_Gateway_102q82v(AcqUpdate,EqStatus,Flow_1kpcqqf):
- Gateway_102q82v = Flow_1kpcqqf
+ try:
+ Gateway_102q82v = Flow_1kpcqqf
+ except Exception as e:
+ __location = Location(84,84,2710,31,"Gateway_102q82v := Flow_1kpcqqf")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_102q82v)
@staticmethod
def execute_SupervisonModelSupervisionImagePreparation_WaitforUnprepare_default_EqStatus(AcqUpdate,EqStatus,Flow_1kpcqqf):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::UNPREPARING"}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::UNPREPARING"}
+ except Exception as e:
+ __location = Location(88,92,2848,189,"EqStatus:=EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = EqStatus.pump_status, acq_status = Status::UNPREPARING }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelPumpController_done_default_Gateway_0td58pc(Flow_0x0gs9b):
- Gateway_0td58pc = Flow_0x0gs9b
+ try:
+ Gateway_0td58pc = Flow_0x0gs9b
+ except Exception as e:
+ __location = Location(123,123,3693,31,"Gateway_0td58pc := Flow_0x0gs9b")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0td58pc)
@staticmethod
def execute_SupervisonModelPumpController_done_default_PumpUpdate(Flow_0x0gs9b):
- PumpUpdate = {"result": "ResponseEnum::OK"}
+ try:
+ PumpUpdate = {"result": "ResponseEnum::OK"}
+ except Exception as e:
+ __location = Location(126,126,3793,52,"PumpUpdate := PumpResp { result = ResponseEnum::OK }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(PumpUpdate)
@staticmethod
def execute_SupervisonModelPumpController_startpump_default_Flow_0x0gs9b(PumpRequest):
- Flow_0x0gs9b = {"id": PumpRequest["id"]}
+ try:
+ Flow_0x0gs9b = {"id": PumpRequest["id"]}
+ except Exception as e:
+ __location = Location(135,135,4152,43,"Flow_0x0gs9b := CTX { id = PumpRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0x0gs9b)
@staticmethod
def execute_SupervisonModelPumpController_stoppump_default_Flow_104f6k4(PumpRequest):
- Flow_104f6k4 = {"id": PumpRequest["id"]}
+ try:
+ Flow_104f6k4 = {"id": PumpRequest["id"]}
+ except Exception as e:
+ __location = Location(144,144,4501,43,"Flow_104f6k4 := CTX { id = PumpRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_104f6k4)
@staticmethod
def execute_SupervisonModelPumpController_pumpstopped_default_Gateway_0td58pc(Flow_104f6k4):
- Gateway_0td58pc = Flow_104f6k4
+ try:
+ Gateway_0td58pc = Flow_104f6k4
+ except Exception as e:
+ __location = Location(152,152,4755,31,"Gateway_0td58pc := Flow_104f6k4")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0td58pc)
@staticmethod
def execute_SupervisonModelPumpController_pumpstopped_default_PumpUpdate(Flow_104f6k4):
- PumpUpdate = {"result": "ResponseEnum::OK"}
+ try:
+ PumpUpdate = {"result": "ResponseEnum::OK"}
+ except Exception as e:
+ __location = Location(155,155,4855,52,"PumpUpdate := PumpResp { result = ResponseEnum::OK }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(PumpUpdate)
@staticmethod
def execute_SupervisonModelImagingController_WaitforUnprepareImaging_default_Gateway_0gu94f4(Flow_05szwsj,ImagingUpdate):
- Gateway_0gu94f4 = Flow_05szwsj
+ try:
+ Gateway_0gu94f4 = Flow_05szwsj
+ except Exception as e:
+ __location = Location(193,193,5820,31,"Gateway_0gu94f4 := Flow_05szwsj")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0gu94f4)
@staticmethod
def execute_SupervisonModelImagingController_returntoprep_default_Gateway_0xpxevh(Gateway_0gu94f4):
- Gateway_0xpxevh = Gateway_0gu94f4
+ try:
+ Gateway_0xpxevh = Gateway_0gu94f4
+ except Exception as e:
+ __location = Location(201,201,6068,34,"Gateway_0xpxevh := Gateway_0gu94f4")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0xpxevh)
@staticmethod
def execute_SupervisonModelImagingController_UnprepareImaging_default_Flow_05szwsj(Gateway_0i3nw09):
- Flow_05szwsj = Gateway_0i3nw09
- Flow_05szwsj["id"] = Flow_05szwsj["id"] + 1
+ try:
+ Flow_05szwsj = Gateway_0i3nw09
+ except Exception as e:
+ __location = Location(209,209,6323,31,"Flow_05szwsj := Gateway_0i3nw09")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_05szwsj["id"] = Flow_05szwsj["id"] + 1
+ except Exception as e:
+ __location = Location(210,210,6368,36,"Flow_05szwsj.id := Flow_05szwsj.id+1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_05szwsj)
@staticmethod
def execute_SupervisonModelImagingController_UnprepareImaging_default_ImagingRequest(Gateway_0i3nw09):
- ImagingRequest = {"cmd_type": "ImageEnum::UNPREPARE", "id": Gateway_0i3nw09["id"], "image_quality": "ImageQuality::NA"}
+ try:
+ ImagingRequest = {"cmd_type": "ImageEnum::UNPREPARE", "id": Gateway_0i3nw09["id"], "image_quality": "ImageQuality::NA"}
+ except Exception as e:
+ __location = Location(213,213,6477,118,"ImagingRequest:= ImgReq { cmd_type = ImageEnum::UNPREPARE, id = Gateway_0i3nw09.id, image_quality = ImageQuality::NA }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImagingRequest)
@staticmethod
def execute_SupervisonModelImagingController_WaitforImagingStopped_default_Gateway_0i3nw09(Flow_0ncxpgd,ImagingUpdate):
- Gateway_0i3nw09 = Flow_0ncxpgd
+ try:
+ Gateway_0i3nw09 = Flow_0ncxpgd
+ except Exception as e:
+ __location = Location(221,221,6843,31,"Gateway_0i3nw09 := Flow_0ncxpgd")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0i3nw09)
@staticmethod
def execute_SupervisonModelImagingController_StartLowResImaging_default_Gateway_08l0os0(Gateway_0kvhy0o):
- Gateway_08l0os0 = Gateway_0kvhy0o
- Gateway_08l0os0["id"] = Gateway_08l0os0["id"] + 1
+ try:
+ Gateway_08l0os0 = Gateway_0kvhy0o
+ except Exception as e:
+ __location = Location(229,229,7104,34,"Gateway_08l0os0 := Gateway_0kvhy0o")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Gateway_08l0os0["id"] = Gateway_08l0os0["id"] + 1
+ except Exception as e:
+ __location = Location(230,230,7152,42,"Gateway_08l0os0.id := Gateway_08l0os0.id+1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_08l0os0)
@staticmethod
def execute_SupervisonModelImagingController_StartLowResImaging_default_ImagingRequest(Gateway_0kvhy0o):
- ImagingRequest = {"cmd_type": "ImageEnum::START", "id": Gateway_0kvhy0o["id"], "image_quality": "ImageQuality::LOW"}
+ try:
+ ImagingRequest = {"cmd_type": "ImageEnum::START", "id": Gateway_0kvhy0o["id"], "image_quality": "ImageQuality::LOW"}
+ except Exception as e:
+ __location = Location(233,233,7267,116,"ImagingRequest := ImgReq { cmd_type = ImageEnum::START, id = Gateway_0kvhy0o.id, image_quality = ImageQuality::LOW }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImagingRequest)
@staticmethod
def execute_SupervisonModelImagingController_nextimage_default_Gateway_0kvhy0o(Gateway_0i3nw09):
- Gateway_0kvhy0o = Gateway_0i3nw09
+ try:
+ Gateway_0kvhy0o = Gateway_0i3nw09
+ except Exception as e:
+ __location = Location(241,241,7593,34,"Gateway_0kvhy0o := Gateway_0i3nw09")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0kvhy0o)
@staticmethod
def execute_SupervisonModelImagingController_StartHighResImaging_default_Gateway_08l0os0(Gateway_0kvhy0o):
- Gateway_08l0os0 = Gateway_0kvhy0o
- Gateway_08l0os0["id"] = Gateway_08l0os0["id"] + 1
+ try:
+ Gateway_08l0os0 = Gateway_0kvhy0o
+ except Exception as e:
+ __location = Location(249,249,7859,34,"Gateway_08l0os0 := Gateway_0kvhy0o")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Gateway_08l0os0["id"] = Gateway_08l0os0["id"] + 1
+ except Exception as e:
+ __location = Location(250,250,7907,42,"Gateway_08l0os0.id := Gateway_08l0os0.id+1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_08l0os0)
@staticmethod
def execute_SupervisonModelImagingController_StartHighResImaging_default_ImagingRequest(Gateway_0kvhy0o):
- ImagingRequest = {"cmd_type": "ImageEnum::START", "id": Gateway_0kvhy0o["id"], "image_quality": "ImageQuality::HIGH"}
+ try:
+ ImagingRequest = {"cmd_type": "ImageEnum::START", "id": Gateway_0kvhy0o["id"], "image_quality": "ImageQuality::HIGH"}
+ except Exception as e:
+ __location = Location(253,253,8022,117,"ImagingRequest := ImgReq { cmd_type = ImageEnum::START, id = Gateway_0kvhy0o.id, image_quality = ImageQuality::HIGH }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImagingRequest)
@staticmethod
def execute_SupervisonModelImagingController_Stopimaging_default_Flow_0ncxpgd(Flow_1k04xzh):
- Flow_0ncxpgd = Flow_1k04xzh
- Flow_0ncxpgd["id"] = Flow_0ncxpgd["id"] + 1
+ try:
+ Flow_0ncxpgd = Flow_1k04xzh
+ except Exception as e:
+ __location = Location(261,261,8347,28,"Flow_0ncxpgd := Flow_1k04xzh")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_0ncxpgd["id"] = Flow_0ncxpgd["id"] + 1
+ except Exception as e:
+ __location = Location(262,262,8389,36,"Flow_0ncxpgd.id := Flow_0ncxpgd.id+1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0ncxpgd)
@staticmethod
def execute_SupervisonModelImagingController_Stopimaging_default_ImagingRequest(Flow_1k04xzh):
- ImagingRequest = {"cmd_type": "ImageEnum::STOP", "id": Flow_1k04xzh["id"], "image_quality": "ImageQuality::NA"}
+ try:
+ ImagingRequest = {"cmd_type": "ImageEnum::STOP", "id": Flow_1k04xzh["id"], "image_quality": "ImageQuality::NA"}
+ except Exception as e:
+ __location = Location(265,265,8498,111,"ImagingRequest := ImgReq { cmd_type = ImageEnum::STOP, id = Flow_1k04xzh.id, image_quality = ImageQuality::NA }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImagingRequest)
@staticmethod
def execute_SupervisonModelImagingController_WaitforPrepared_default_Gateway_0kvhy0o(Flow_029nrs5,ImagingUpdate):
- Gateway_0kvhy0o = Flow_029nrs5
+ try:
+ Gateway_0kvhy0o = Flow_029nrs5
+ except Exception as e:
+ __location = Location(273,273,8844,31,"Gateway_0kvhy0o := Flow_029nrs5")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0kvhy0o)
@staticmethod
def execute_SupervisonModelImagingController_PrepareImaging_default_Flow_029nrs5(Gateway_0xpxevh):
- Flow_029nrs5 = Gateway_0xpxevh
- Flow_029nrs5["id"] = Flow_029nrs5["id"] + 1
+ try:
+ Flow_029nrs5 = Gateway_0xpxevh
+ except Exception as e:
+ __location = Location(281,281,9092,31,"Flow_029nrs5 := Gateway_0xpxevh")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_029nrs5["id"] = Flow_029nrs5["id"] + 1
+ except Exception as e:
+ __location = Location(282,282,9137,36,"Flow_029nrs5.id := Flow_029nrs5.id+1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_029nrs5)
@staticmethod
def execute_SupervisonModelImagingController_PrepareImaging_default_ImagingRequest(Gateway_0xpxevh):
- ImagingRequest = {"cmd_type": "ImageEnum::PREPARE", "id": Gateway_0xpxevh["id"], "image_quality": "ImageQuality::NA"}
+ try:
+ ImagingRequest = {"cmd_type": "ImageEnum::PREPARE", "id": Gateway_0xpxevh["id"], "image_quality": "ImageQuality::NA"}
+ except Exception as e:
+ __location = Location(285,285,9246,117,"ImagingRequest := ImgReq { cmd_type = ImageEnum::PREPARE, id = Gateway_0xpxevh.id, image_quality = ImageQuality::NA }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImagingRequest)
@staticmethod
def execute_SupervisonModelImagingController_ImagingFinished_default_Flow_1k04xzh(Gateway_08l0os0,ImagingUpdate):
- Flow_1k04xzh = Gateway_08l0os0
+ try:
+ Flow_1k04xzh = Gateway_08l0os0
+ except Exception as e:
+ __location = Location(293,293,9597,31,"Flow_1k04xzh := Gateway_08l0os0")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1k04xzh)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_StartPump_default_Flow_0balrow(EqStatus,VacuumRequest,Gateway_1j81da5):
- Flow_0balrow = Gateway_1j81da5
+ try:
+ Flow_0balrow = Gateway_1j81da5
+ except Exception as e:
+ __location = Location(332,332,10654,31,"Flow_0balrow := Gateway_1j81da5")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0balrow)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_StartPump_default_PumpRequest(EqStatus,VacuumRequest,Gateway_1j81da5):
- PumpRequest = {"cmd_type": "VacuumEnum::ON", "id": VacuumRequest["id"]}
+ try:
+ PumpRequest = {"cmd_type": "VacuumEnum::ON", "id": VacuumRequest["id"]}
+ except Exception as e:
+ __location = Location(335,338,10769,116,"PumpRequest := PumpReq { cmd_type = VacuumEnum::ON, id = VacuumRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(PumpRequest)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_StartPump_default_EqStatus(EqStatus,VacuumRequest,Gateway_1j81da5):
- EqStatus = EqStatus
+ try:
+ EqStatus = EqStatus
+ except Exception as e:
+ __location = Location(341,341,10975,20,"EqStatus := EqStatus")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_WaitforPumpOff_default_Gateway_1i0qy9g(PumpUpdate,EqStatus,Flow_0cjhiik):
- Gateway_1i0qy9g = Flow_0cjhiik
+ try:
+ Gateway_1i0qy9g = Flow_0cjhiik
+ except Exception as e:
+ __location = Location(349,349,11236,31,"Gateway_1i0qy9g := Flow_0cjhiik")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_1i0qy9g)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_WaitforPumpOff_default_EqStatus(PumpUpdate,EqStatus,Flow_0cjhiik):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": "Status::OFF", "acq_status": EqStatus["acq_status"]}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": "Status::OFF", "acq_status": EqStatus["acq_status"]}
+ except Exception as e:
+ __location = Location(353,357,11373,182,"EqStatus := EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = Status::OFF, acq_status = EqStatus.acq_status }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_Restart_default_Gateway_1j81da5(Gateway_1i0qy9g):
- Gateway_1j81da5 = Gateway_1i0qy9g
+ try:
+ Gateway_1j81da5 = Gateway_1i0qy9g
+ except Exception as e:
+ __location = Location(365,365,11760,34,"Gateway_1j81da5 := Gateway_1i0qy9g")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_1j81da5)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_TurnOffPump_default_Flow_0cjhiik(Flow_1wguswc,EqStatus,VacuumRequest):
- Flow_0cjhiik = Flow_1wguswc
+ try:
+ Flow_0cjhiik = Flow_1wguswc
+ except Exception as e:
+ __location = Location(374,374,12129,28,"Flow_0cjhiik := Flow_1wguswc")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0cjhiik)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_TurnOffPump_default_PumpRequest(Flow_1wguswc,EqStatus,VacuumRequest):
- PumpRequest = {"cmd_type": "VacuumEnum::OFF", "id": VacuumRequest["id"]}
+ try:
+ PumpRequest = {"cmd_type": "VacuumEnum::OFF", "id": VacuumRequest["id"]}
+ except Exception as e:
+ __location = Location(377,380,12241,117,"PumpRequest := PumpReq { cmd_type = VacuumEnum::OFF, id = VacuumRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(PumpRequest)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_TurnOffPump_default_EqStatus(Flow_1wguswc,EqStatus,VacuumRequest):
- EqStatus = EqStatus
+ try:
+ EqStatus = EqStatus
+ except Exception as e:
+ __location = Location(383,383,12448,20,"EqStatus := EqStatus")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_WaitforPumpStated_default_Flow_1wguswc(PumpUpdate,Flow_0balrow,EqStatus):
- Flow_1wguswc = Flow_0balrow
+ try:
+ Flow_1wguswc = Flow_0balrow
+ except Exception as e:
+ __location = Location(391,391,12712,28,"Flow_1wguswc := Flow_0balrow")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1wguswc)
@staticmethod
def execute_SupervisonModelSupervisionPressureHandler_WaitforPumpStated_default_EqStatus(PumpUpdate,Flow_0balrow,EqStatus):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": "Status::ON", "acq_status": EqStatus["acq_status"]}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": "Status::ON", "acq_status": EqStatus["acq_status"]}
+ except Exception as e:
+ __location = Location(395,399,12846,181,"EqStatus := EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = Status::ON, acq_status = EqStatus.acq_status }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelTemperatureController_return_default_Gateway_1sv33t8(Gateway_12yhscn):
- Gateway_1sv33t8 = Gateway_12yhscn
- Gateway_1sv33t8["id"] = Gateway_1sv33t8["id"]
+ try:
+ Gateway_1sv33t8 = Gateway_12yhscn
+ except Exception as e:
+ __location = Location(434,434,13845,34,"Gateway_1sv33t8 := Gateway_12yhscn")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Gateway_1sv33t8["id"] = Gateway_1sv33t8["id"]
+ except Exception as e:
+ __location = Location(435,435,13893,40,"Gateway_1sv33t8.id := Gateway_1sv33t8.id")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_1sv33t8)
@staticmethod
def execute_SupervisonModelTemperatureController_CheckTemp_default_Flow_01g3o4k(Gateway_1sv33t8,temp_achieved):
- Flow_01g3o4k = Gateway_1sv33t8
+ try:
+ Flow_01g3o4k = Gateway_1sv33t8
+ except Exception as e:
+ __location = Location(446,446,14300,31,"Flow_01g3o4k := Gateway_1sv33t8")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_01g3o4k)
@staticmethod
def execute_SupervisonModelTemperatureController_SetTemperature_default_Flow_0estwso(Event_1r2zvr6):
- Flow_0estwso = Event_1r2zvr6
- Flow_0estwso["id"] = Flow_0estwso["id"] + 1
+ try:
+ Flow_0estwso = Event_1r2zvr6
+ except Exception as e:
+ __location = Location(454,454,14546,29,"Flow_0estwso := Event_1r2zvr6")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_0estwso["id"] = Flow_0estwso["id"] + 1
+ except Exception as e:
+ __location = Location(455,455,14589,38,"Flow_0estwso.id := Flow_0estwso.id + 1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0estwso)
@staticmethod
def execute_SupervisonModelTemperatureController_SetTemperature_default_TempRequest(Event_1r2zvr6):
- TempRequest = {"cmd_type": "TempEnum::SET", "id": Event_1r2zvr6["id"]}
+ try:
+ TempRequest = {"cmd_type": "TempEnum::SET", "id": Event_1r2zvr6["id"]}
+ except Exception as e:
+ __location = Location(458,461,14697,115,"TempRequest := TempReq { cmd_type = TempEnum::SET, id = Event_1r2zvr6.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(TempRequest)
@staticmethod
def execute_SupervisonModelTemperatureController_ResetTemperature_default_Flow_0ay6jpo(Flow_01g3o4k):
- Flow_0ay6jpo = Flow_01g3o4k
- Flow_0ay6jpo["id"] = Flow_0ay6jpo["id"] + 1
+ try:
+ Flow_0ay6jpo = Flow_01g3o4k
+ except Exception as e:
+ __location = Location(469,469,15030,28,"Flow_0ay6jpo := Flow_01g3o4k")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_0ay6jpo["id"] = Flow_0ay6jpo["id"] + 1
+ except Exception as e:
+ __location = Location(470,470,15072,38,"Flow_0ay6jpo.id := Flow_0ay6jpo.id + 1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0ay6jpo)
@staticmethod
def execute_SupervisonModelTemperatureController_ResetTemperature_default_TempRequest(Flow_01g3o4k):
- TempRequest = {"cmd_type": "TempEnum::RESET", "id": Flow_01g3o4k["id"]}
+ try:
+ TempRequest = {"cmd_type": "TempEnum::RESET", "id": Flow_01g3o4k["id"]}
+ except Exception as e:
+ __location = Location(473,476,15180,116,"TempRequest := TempReq { cmd_type = TempEnum::RESET, id = Flow_01g3o4k.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(TempRequest)
@staticmethod
def execute_SupervisonModelTemperatureController_WaitforReset_default_Gateway_12yhscn(Flow_0ay6jpo,TempUpdate):
- Gateway_12yhscn = Flow_0ay6jpo
+ try:
+ Gateway_12yhscn = Flow_0ay6jpo
+ except Exception as e:
+ __location = Location(484,484,15522,31,"Gateway_12yhscn := Flow_0ay6jpo")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_12yhscn)
@staticmethod
def execute_SupervisonModelTemperatureController_WaitforTempSet_default_Gateway_1sv33t8(TempUpdate,Flow_0estwso):
- Gateway_1sv33t8 = Flow_0estwso
+ try:
+ Gateway_1sv33t8 = Flow_0estwso
+ except Exception as e:
+ __location = Location(492,492,15784,31,"Gateway_1sv33t8 := Flow_0estwso")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_1sv33t8)
@staticmethod
def execute_SupervisonModelVacuumController_TurnOff_default_Flow_1dvvja5(Flow_1erv6vq):
- Flow_1dvvja5 = Flow_1erv6vq
- Flow_1dvvja5["id"] = Flow_1dvvja5["id"] + 1
+ try:
+ Flow_1dvvja5 = Flow_1erv6vq
+ except Exception as e:
+ __location = Location(526,526,16566,28,"Flow_1dvvja5 := Flow_1erv6vq")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_1dvvja5["id"] = Flow_1dvvja5["id"] + 1
+ except Exception as e:
+ __location = Location(527,527,16608,38,"Flow_1dvvja5.id := Flow_1dvvja5.id + 1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1dvvja5)
@staticmethod
def execute_SupervisonModelVacuumController_TurnOff_default_VacuumRequest(Flow_1erv6vq):
- VacuumRequest = {"cmd_type": "VacuumEnum::OFF", "id": Flow_1erv6vq["id"]}
+ try:
+ VacuumRequest = {"cmd_type": "VacuumEnum::OFF", "id": Flow_1erv6vq["id"]}
+ except Exception as e:
+ __location = Location(530,530,16718,76,"VacuumRequest := VacReq { cmd_type = VacuumEnum::OFF, id = Flow_1erv6vq.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(VacuumRequest)
@staticmethod
def execute_SupervisonModelVacuumController_SetVacuum_default_Flow_1phqrfh(Gateway_0mqr7c2):
- Flow_1phqrfh = Gateway_0mqr7c2
- Flow_1phqrfh["id"] = Flow_1phqrfh["id"] + 1
+ try:
+ Flow_1phqrfh = Gateway_0mqr7c2
+ except Exception as e:
+ __location = Location(538,538,17001,31,"Flow_1phqrfh := Gateway_0mqr7c2")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_1phqrfh["id"] = Flow_1phqrfh["id"] + 1
+ except Exception as e:
+ __location = Location(539,539,17046,38,"Flow_1phqrfh.id := Flow_1phqrfh.id + 1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1phqrfh)
@staticmethod
def execute_SupervisonModelVacuumController_SetVacuum_default_VacuumRequest(Gateway_0mqr7c2):
- VacuumRequest = {"cmd_type": "VacuumEnum::ON", "id": Gateway_0mqr7c2["id"]}
+ try:
+ VacuumRequest = {"cmd_type": "VacuumEnum::ON", "id": Gateway_0mqr7c2["id"]}
+ except Exception as e:
+ __location = Location(542,542,17156,78,"VacuumRequest := VacReq { cmd_type = VacuumEnum::ON, id = Gateway_0mqr7c2.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(VacuumRequest)
@staticmethod
def execute_SupervisonModelVacuumController_return_default_Gateway_0mqr7c2(Gateway_07w0e8f):
- Gateway_0mqr7c2 = Gateway_07w0e8f
+ try:
+ Gateway_0mqr7c2 = Gateway_07w0e8f
+ except Exception as e:
+ __location = Location(550,550,17437,34,"Gateway_0mqr7c2 := Gateway_07w0e8f")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0mqr7c2)
@staticmethod
def execute_SupervisonModelVacuumController_WaitforOff_default_Gateway_07w0e8f(VacuumUpdate,Flow_1dvvja5):
- Gateway_07w0e8f = Flow_1dvvja5
+ try:
+ Gateway_07w0e8f = Flow_1dvvja5
+ except Exception as e:
+ __location = Location(558,558,17695,31,"Gateway_07w0e8f := Flow_1dvvja5")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_07w0e8f)
@staticmethod
def execute_SupervisonModelVacuumController_WaitforVacuumSet_default_Flow_1erv6vq(VacuumUpdate,Flow_1phqrfh):
- Flow_1erv6vq = Flow_1phqrfh
+ try:
+ Flow_1erv6vq = Flow_1phqrfh
+ except Exception as e:
+ __location = Location(566,566,17960,28,"Flow_1erv6vq := Flow_1phqrfh")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1erv6vq)
@staticmethod
def execute_SupervisonModelAcquisitionController_AcquisitionStopped_default_Gateway_0h81kts(Flow_1w9tlf4):
- Gateway_0h81kts = Flow_1w9tlf4
+ try:
+ Gateway_0h81kts = Flow_1w9tlf4
+ except Exception as e:
+ __location = Location(599,599,18726,31,"Gateway_0h81kts := Flow_1w9tlf4")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0h81kts)
@staticmethod
def execute_SupervisonModelAcquisitionController_AcquisitionStopped_default_AcqUpdate(Flow_1w9tlf4):
- AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_1w9tlf4["id"]}
+ try:
+ AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_1w9tlf4["id"]}
+ except Exception as e:
+ __location = Location(602,602,18825,72,"AcqUpdate := AcqResp { result = ResponseEnum::OK, id = Flow_1w9tlf4.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcqUpdate)
@staticmethod
def execute_SupervisonModelAcquisitionController_Execacquisitioninitandteardown_default_Flow_084nmm6(AcquisitionReq):
- Flow_084nmm6 = {"id": AcquisitionReq["id"]}
+ try:
+ Flow_084nmm6 = {"id": AcquisitionReq["id"]}
+ except Exception as e:
+ __location = Location(611,611,19318,46,"Flow_084nmm6 := CTX { id = AcquisitionReq.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_084nmm6)
@staticmethod
def execute_SupervisonModelAcquisitionController_StartAcquisition_default_Flow_1rusz82(AcquisitionReq):
- Flow_1rusz82 = {"id": AcquisitionReq["id"]}
+ try:
+ Flow_1rusz82 = {"id": AcquisitionReq["id"]}
+ except Exception as e:
+ __location = Location(620,620,19700,46,"Flow_1rusz82 := CTX { id = AcquisitionReq.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1rusz82)
@staticmethod
def execute_SupervisonModelAcquisitionController_Acquisitionexecdone_default_Gateway_0h81kts(Flow_084nmm6):
- Gateway_0h81kts = Flow_084nmm6
+ try:
+ Gateway_0h81kts = Flow_084nmm6
+ except Exception as e:
+ __location = Location(628,628,19974,31,"Gateway_0h81kts := Flow_084nmm6")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0h81kts)
@staticmethod
def execute_SupervisonModelAcquisitionController_Acquisitionexecdone_default_AcqUpdate(Flow_084nmm6):
- AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_084nmm6["id"]}
+ try:
+ AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_084nmm6["id"]}
+ except Exception as e:
+ __location = Location(631,631,20073,72,"AcqUpdate := AcqResp { result = ResponseEnum::OK, id = Flow_084nmm6.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcqUpdate)
@staticmethod
def execute_SupervisonModelAcquisitionController_StopAcquisition_default_Flow_1w9tlf4(AcquisitionReq):
- Flow_1w9tlf4 = {"id": AcquisitionReq["id"]}
+ try:
+ Flow_1w9tlf4 = {"id": AcquisitionReq["id"]}
+ except Exception as e:
+ __location = Location(640,640,20478,46,"Flow_1w9tlf4 := CTX { id = AcquisitionReq.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1w9tlf4)
@staticmethod
def execute_SupervisonModelAcquisitionController_StopAcquisition_default_ImageData(AcquisitionReq):
- ImageData = {"id": AcquisitionReq["id"]}
+ try:
+ ImageData = {"id": AcquisitionReq["id"]}
+ except Exception as e:
+ __location = Location(643,643,20606,47,"ImageData := AcqData { id = AcquisitionReq.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(ImageData)
@staticmethod
def execute_SupervisonModelAcquisitionController_AcquisitionStarted_default_Gateway_0h81kts(Flow_1rusz82):
- Gateway_0h81kts = Flow_1rusz82
+ try:
+ Gateway_0h81kts = Flow_1rusz82
+ except Exception as e:
+ __location = Location(651,651,20878,31,"Gateway_0h81kts := Flow_1rusz82")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0h81kts)
@staticmethod
def execute_SupervisonModelAcquisitionController_AcquisitionStarted_default_AcqUpdate(Flow_1rusz82):
- AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_1rusz82["id"]}
+ try:
+ AcqUpdate = {"result": "ResponseEnum::OK", "id": Flow_1rusz82["id"]}
+ except Exception as e:
+ __location = Location(654,654,20977,72,"AcqUpdate := AcqResp { result = ResponseEnum::OK, id = Flow_1rusz82.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcqUpdate)
@staticmethod
def execute_SupervisonModelSupervisionImaging_WaitforStopAcquisition_default_Gateway_16m9e4j(AcqUpdate,Flow_0678bm1,EqStatus):
- Gateway_16m9e4j = Flow_0678bm1
+ try:
+ Gateway_16m9e4j = Flow_0678bm1
+ except Exception as e:
+ __location = Location(693,693,22048,31,"Gateway_16m9e4j := Flow_0678bm1")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_16m9e4j)
@staticmethod
def execute_SupervisonModelSupervisionImaging_WaitforStopAcquisition_default_EqStatus(AcqUpdate,Flow_0678bm1,EqStatus):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::OFF"}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::OFF"}
+ except Exception as e:
+ __location = Location(697,701,22186,183,"EqStatus := EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = EqStatus.pump_status, acq_status = Status::OFF }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionImaging_CheckLowResImageQuality_default_Gateway_0qg69ul(ImageData,Gateway_16m9e4j,LastAcqReq):
- Gateway_0qg69ul = Gateway_16m9e4j
+ try:
+ Gateway_0qg69ul = Gateway_16m9e4j
+ except Exception as e:
+ __location = Location(721,721,23105,34,"Gateway_0qg69ul := Gateway_16m9e4j")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0qg69ul)
@staticmethod
def execute_SupervisonModelSupervisionImaging_WaitforStartAcquisition_default_Gateway_0qg69ul(AcqUpdate,EqStatus,Flow_1bajtwc):
- Gateway_0qg69ul = Flow_1bajtwc
+ try:
+ Gateway_0qg69ul = Flow_1bajtwc
+ except Exception as e:
+ __location = Location(730,730,23464,31,"Gateway_0qg69ul := Flow_1bajtwc")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0qg69ul)
@staticmethod
def execute_SupervisonModelSupervisionImaging_WaitforStartAcquisition_default_EqStatus(AcqUpdate,EqStatus,Flow_1bajtwc):
- EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::ON"}
+ try:
+ EqStatus = {"temp_status": EqStatus["temp_status"], "pump_status": EqStatus["pump_status"], "acq_status": "Status::ON"}
+ except Exception as e:
+ __location = Location(734,738,23602,182,"EqStatus := EquipmentStatus { temp_status = EqStatus.temp_status, pump_status = EqStatus.pump_status, acq_status = Status::ON }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionImaging_StopAcquisition_default_AcquisitionReq(ImagingRequest):
- AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ try:
+ AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ except Exception as e:
+ __location = Location(748,751,24165,128,"AcquisitionReq := AcqReq { cmd_type = ImagingRequest.cmd_type, id = ImagingRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcquisitionReq)
@staticmethod
def execute_SupervisonModelSupervisionImaging_StartAcquisition_default_AcquisitionReq(ImagingRequest,EqStatus):
- AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ try:
+ AcquisitionReq = {"cmd_type": ImagingRequest["cmd_type"], "id": ImagingRequest["id"]}
+ except Exception as e:
+ __location = Location(761,764,24767,128,"AcquisitionReq := AcqReq { cmd_type = ImagingRequest.cmd_type, id = ImagingRequest.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(AcquisitionReq)
@staticmethod
def execute_SupervisonModelSupervisionImaging_StartAcquisition_default_LastAcqReq(ImagingRequest,EqStatus):
- LastAcqReq = ImagingRequest
+ try:
+ LastAcqReq = ImagingRequest
+ except Exception as e:
+ __location = Location(767,767,24978,26,"LastAcqReq:=ImagingRequest")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(LastAcqReq)
@staticmethod
def execute_SupervisonModelSupervisionImaging_StartAcquisition_default_EqStatus(ImagingRequest,EqStatus):
- EqStatus = EqStatus
+ try:
+ EqStatus = EqStatus
+ except Exception as e:
+ __location = Location(770,770,25094,20,"EqStatus := EqStatus")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionImaging_CheckHighResImageQuality_default_Gateway_0qg69ul(ImageData,Gateway_16m9e4j,LastAcqReq):
- Gateway_0qg69ul = Gateway_16m9e4j
+ try:
+ Gateway_0qg69ul = Gateway_16m9e4j
+ except Exception as e:
+ __location = Location(790,790,25854,34,"Gateway_0qg69ul := Gateway_16m9e4j")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0qg69ul)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_CreateResetTempMessage_default_TempCMD(TempRequest,EqStatus):
- TempCMD = TempRequest
+ try:
+ TempCMD = TempRequest
+ except Exception as e:
+ __location = Location(825,825,26908,22,"TempCMD := TempRequest")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(TempCMD)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_CreateResetTempMessage_default_EqStatus(TempRequest,EqStatus):
- EqStatus = EqStatus
+ try:
+ EqStatus = EqStatus
+ except Exception as e:
+ __location = Location(828,828,27020,20,"EqStatus := EqStatus")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_ExecuteSetTemp_default_Event_13ys7sy(Gateway_1qk9wqe,EqStatus,TempCMD):
- Event_13ys7sy = Gateway_1qk9wqe
+ try:
+ Event_13ys7sy = Gateway_1qk9wqe
+ except Exception as e:
+ __location = Location(836,836,27330,32,"Event_13ys7sy := Gateway_1qk9wqe")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Event_13ys7sy)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_ExecuteSetTemp_default_temp_achieved(Gateway_1qk9wqe,EqStatus,TempCMD):
- temp_achieved = {"result": "ResponseEnum::OK", "reqid": TempCMD["id"]}
+ try:
+ temp_achieved = {"result": "ResponseEnum::OK", "reqid": TempCMD["id"]}
+ except Exception as e:
+ __location = Location(840,843,27485,116,"temp_achieved := TempResp { result = ResponseEnum::OK, reqid = TempCMD.id }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(temp_achieved)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_ExecuteSetTemp_default_EqStatus(Gateway_1qk9wqe,EqStatus,TempCMD):
- EqStatus = {"temp_status": "Status::ON", "pump_status": EqStatus["pump_status"], "acq_status": EqStatus["acq_status"]}
+ try:
+ EqStatus = {"temp_status": "Status::ON", "pump_status": EqStatus["pump_status"], "acq_status": EqStatus["acq_status"]}
+ except Exception as e:
+ __location = Location(846,850,27682,181,"EqStatus := EquipmentStatus { temp_status = Status::ON, pump_status = EqStatus.pump_status, acq_status = EqStatus.acq_status }")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(EqStatus)
@staticmethod
def execute_SupervisonModelSupervisionTemperatureHandler_CreateSetTempMessage_default_TempCMD(TempRequest):
- TempCMD = TempRequest
+ try:
+ TempCMD = TempRequest
+ except Exception as e:
+ __location = Location(860,860,28246,22,"TempCMD := TempRequest")
+ __source_file = "imaging.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(TempCMD)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_reporting.py b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_reporting.py
new file mode 100644
index 00000000..767fa104
--- /dev/null
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/imaging/CPNServer/imaging/imaging_reporting.py
@@ -0,0 +1,153 @@
+import json
+import traceback
+from enum import Enum
+from typing import List, Optional, Dict, Any
+from dataclasses import dataclass, field
+from pathlib import Path
+
+class StatusException(Exception):
+ def __init__(self, message: str):
+ super().__init__(message)
+
+class Severity(Enum):
+ OK = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CANCEL = 4
+
+@dataclass
+class Location:
+ startLine: int
+ endLine: int
+ offset: int
+ length: int
+ text: str
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'startLine': self.startLine,
+ 'endLine': self.endLine,
+ 'offset': self.offset,
+ 'length': self.length,
+ 'text': self.text,
+ }
+
+@dataclass
+class StatusReport:
+ plugin: str
+ severity: Severity
+ message: str
+ source: str = ""
+ code: int = 0
+ details: Optional[str] = None
+ location: Optional[Location] = None
+ children: List['StatusReport'] = field(default_factory=list)
+ exception: Optional[Exception] = field(default=None, repr=False)
+
+ def __post_init__(self):
+ if self.exception is not None:
+ if self.details is None:
+ self.details = self._get_stack_trace_as_string(self.exception)
+ self.exception = None # Don't retain non-serializable object
+
+ if self.children:
+ child_severities = [child.severity for child in self.children if child is not None]
+ if child_severities:
+ max_child_severity = max(child_severities, key=lambda s: s.value)
+ if max_child_severity.value > self.severity.value:
+ self.severity = max_child_severity
+
+ @staticmethod
+ def _get_stack_trace_as_string(exception: Exception) -> str:
+ if exception is None:
+ return None
+ tb_lines = traceback.format_exception(type(exception), exception, exception.__traceback__)
+ if len(tb_lines) > 15:
+ tb_lines = tb_lines[:15] + [f"\t... {len(tb_lines) - 15} more\n"]
+ return "".join(tb_lines)
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'plugin': self.plugin,
+ 'severity': self.severity.name,
+ 'message': self.message,
+ 'source': self.source,
+ 'code': self.code,
+ 'details': self.details,
+ 'location': self.location.to_dict() if self.location else None,
+ 'children': [child.to_dict() for child in self.children if child is not None],
+ }
+
+class StatusReporting:
+ def __init__(self, save_path: str):
+ self.save_path = Path(save_path)
+ self.reports: List[StatusReport] = []
+
+ def _log(self, severity: Severity, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, exception: Optional[Exception] = None, location: Optional[Location] = None) -> StatusReport:
+ report = StatusReport(
+ plugin="",
+ severity=severity,
+ message=message,
+ source=source,
+ code=code,
+ details=details,
+ location=location,
+ exception=exception
+ )
+ self.reports.append(report)
+ return report
+
+ def info(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.INFO, message, source, code, details, None, location)
+
+ def warning(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.WARNING, message, source, code, details, None, location)
+
+ def error(self, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.ERROR, message, source, code, details, None, location)
+
+ def exception(self, message: str, exception: Exception, source: str = "", details: str = None, code: int = 0, location: Location = None) -> StatusReport:
+ self._log(Severity.ERROR, message, source, code, details, exception, location)
+ #on exception the process is stopped
+ raise StatusException(message)
+
+ def save(self) -> Severity:
+
+ root_severity = Severity.OK
+ if self.reports:
+ root_severity = max((report.severity for report in self.reports), key=lambda s: s.value)
+
+ root_report = StatusReport(
+ plugin="",
+ severity=root_severity,
+ message=f"Python generation of imaging",
+ source="",
+ code=0,
+ details=None,
+ location=None,
+ children=self.reports,
+ exception=None
+ )
+
+ data = root_report.to_dict()
+ with open(self.save_path, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return root_severity
+
+
+_status_reporting_instance: Optional[StatusReporting] = None
+
+def initialize_reporting(save_path: str) -> StatusReporting:
+ global _status_reporting_instance
+ _status_reporting_instance = StatusReporting(save_path)
+ return _status_reporting_instance
+
+def get_reporting() -> StatusReporting:
+ global _status_reporting_instance
+ if _status_reporting_instance is None:
+ raise RuntimeError("StatusReporting not initialized. Call initialize_reporting() first.")
+ return _status_reporting_instance
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371.py b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371.py
index 029a734a..070891ac 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371.py
@@ -10,10 +10,12 @@
if __package__ is None or __package__ == '':
from issue371_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from issue371_data import Data
+ from issue371_reporting import get_reporting, initialize_reporting, Location
from issue371_Simulation import Simulation, simulate
else:
from .issue371_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from .issue371_data import Data
+ from .issue371_reporting import get_reporting, initialize_reporting, Location
from .issue371_Simulation import Simulation, simulate
import subprocess
import copy
@@ -233,7 +235,8 @@ def initializeTestGeneration(self):
if k + "_" +elm.__repr__() in self.map_transition_modes_to_name:
print("WARN: duplicate modes detected for same transition.")
print(k + "_" +elm.__repr__())
- print("WARN: references to the above transitions are ambigous!")
+ print("WARN: references to the above transitions are ambiguous!")
+ get_reporting().warning("Duplicate modes detected for same transition, Check References in Details", details=f"{k}_{str.join('\n',[str(s) for s in elm.items()])}")
self.map_transition_modes_to_name[k + "_" +elm.__repr__()] = k + "_" + str(cnt)
# self.map_transition_modes_to_name[k + "_" + pprint.pformat(elm.items(), width=60, compact=True,depth=5)] = k + "_" + str(cnt)
cnt = cnt + 1
@@ -252,7 +255,7 @@ def generateTestCases(self):
for entry in pn.visitedTList:
# txt = ''
if entry:
- _test_scn = TestSCN(self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
+ _test_scn = TestSCN(pspec_path, self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
idx = idx + 1
j = 0
for step in entry:
@@ -340,103 +343,127 @@ def copy(self, name=None):
type=bool,
default=False,
help="Disable simulation")
-
+
+ parser.add_argument("-srfile","--status_report_file",
+ type=Path,
+ default=None,
+ help="The path to where the status report will be saved")
+
+ parser.add_argument("-pspath","--pspec_path",
+ type=str,
+ default="",
+ help="The relatve path to the pspec file to be used for test generation")
+
p = parser.parse_args()
p.tspec_dir.mkdir(exist_ok=True)
p.plantuml_dir.mkdir(exist_ok=True)
-
- a = datetime.datetime.now()
- pn = issue371Model()
- print("[INFO] Loaded CPN model.")
- # pn.n.draw('net-gv-graph.png')
- s = StateGraph(pn.n)
- # s.build()
- # s.draw('test-gv-graph.png')
- # print(" Finished Generation, writing to file.. ")
- print("[INFO] Starting Reachability Graph Generation")
- # pn.generateScenarios(s,0,[],[],[],0,300)
- sys.setrecursionlimit(400)
- pn.generateSCN()
- print('Num Tests: ', pn.numTestCases)
- print("[INFO] Finished.")
- b = datetime.datetime.now()
+ status_report_file = p.status_report_file if p.status_report_file != None else p.tspec_dir / "status_report.json"
+ status_report_file.parent.mkdir(parents=True, exist_ok=True)
+ pspec_path = p.pspec_path
+ reporting = initialize_reporting(status_report_file)
- # s.goto(0)
+ try:
+ a = datetime.datetime.now()
+ pn = issue371Model()
+ print("[INFO] Loaded CPN model.")
+ # pn.n.draw('net-gv-graph.png')
+ s = StateGraph(pn.n)
+ # s.build()
+ # s.draw('test-gv-graph.png')
+ # print(" Finished Generation, writing to file.. ")
+ print("[INFO] Starting Reachability Graph Generation")
+ # pn.generateScenarios(s,0,[],[],[],0,300)
+ sys.setrecursionlimit(400)
+ pn.generateSCN()
+ print('Num Tests: ', pn.numTestCases)
+ print("[INFO] Finished.")
+ b = datetime.datetime.now()
- fname = p.plantuml_dir / "rg.plantuml"
- with open(fname, 'w') as f:
- pn.generateReachabilityGraph(f)
- print("[INFO] Created %s" % (fname,))
- c = datetime.datetime.now()
-
- print("[INFO] Starting Test Generation.")
- pn.initializeTestGeneration()
- pn.generateTestCases()
-
- # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
- print("[INFO] Test Generation Finished.")
- d = datetime.datetime.now()
+ # s.goto(0)
+
+ fname = p.plantuml_dir / "rg.plantuml"
+ with open(fname, 'w') as f:
+ pn.generateReachabilityGraph(f)
+ print("[INFO] Created %s" % (fname,))
+ c = datetime.datetime.now()
- print("[INFO] Creating Structure and Behavior Views in PlantUML.")
- map_block_uml_txt = {}
- for t in pn.n.transition():
- map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+ print("[INFO] Starting Test Generation.")
+ pn.initializeTestGeneration()
+ pn.generateTestCases()
- for t in pn.n.transition():
- gtxt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'json.loads' in t.guard._str:
- # print(t.guard._str.replace('json.loads',''))
- # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- gtxt += 'component %s\n' % (t.name)
- if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
- gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'component %s\n' % (t.name)
- gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
- map_block_uml_txt[t.name.split('_')[0]] = gtxt
+ # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
+ print("[INFO] Test Generation Finished.")
+ d = datetime.datetime.now()
- for t in pn.n.transition():
- for inp in pn.n.pre(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in inp:
- txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ print("[INFO] Creating Structure and Behavior Views in PlantUML.")
+ map_block_uml_txt = {}
+ for t in pn.n.transition():
+ map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+
+ for t in pn.n.transition():
+ gtxt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'json.loads' in t.guard._str:
+ # print(t.guard._str.replace('json.loads',''))
+ # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ gtxt += 'component %s\n' % (t.name)
+ if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
+ gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ else:
+ gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
else:
- txt += '%s --> [%s]\n' % (inp, t.name)
- map_block_uml_txt[t.name.split('_')[0]] = txt
- for out in pn.n.post(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in out:
- txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
- else:
- txt += '[%s] --> %s\n' % (t.name, out)
- map_block_uml_txt[t.name.split('_')[0]] = txt
-
- for key in map_block_uml_txt:
- txt = map_block_uml_txt.get(key)
- txt += '@enduml\n'
- map_block_uml_txt[key] = txt
- fname = p.plantuml_dir / (key + ".plantuml")
- with open(fname, 'w') as f:
- f.write(txt)
-
- print("[INFO] View Generation Finished.")
- e = datetime.datetime.now()
- print("[INFO] Time Statistics")
- print("[INFO] * Reachability Computation: %s" % (b - a))
- print("[INFO] * Reachability PUML Creation: %s" % (c - b))
- print("[INFO] * Test Generation: %s" % (d - c))
- print("[INFO] * PlantUML View Generation: %s" % (e - d))
-
- # print("[INFO] Starting Command-Line Simulation.")
- # simulate(pn.n)
-
- #if not p.no_sim:
- # print('[SIM] Start Simulation? (Y/N) :')
- # value = input(" Enter Choice: ")
- # if value == "Y" or value == "y":
- # os.system('cls')
- # simulate(pn.n)
-
- print("[INFO] Exiting..")
+ gtxt += 'component %s\n' % (t.name)
+ gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
+ map_block_uml_txt[t.name.split('_')[0]] = gtxt
+
+ for t in pn.n.transition():
+ for inp in pn.n.pre(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in inp:
+ txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ else:
+ txt += '%s --> [%s]\n' % (inp, t.name)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+ for out in pn.n.post(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in out:
+ txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ else:
+ txt += '[%s] --> %s\n' % (t.name, out)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+
+ for key in map_block_uml_txt:
+ txt = map_block_uml_txt.get(key)
+ txt += '@enduml\n'
+ map_block_uml_txt[key] = txt
+ fname = p.plantuml_dir / (key + ".plantuml")
+ with open(fname, 'w') as f:
+ f.write(txt)
+
+ print("[INFO] View Generation Finished.")
+ e = datetime.datetime.now()
+ print("[INFO] Time Statistics")
+ print("[INFO] * Reachability Computation: %s" % (b - a))
+ print("[INFO] * Reachability PUML Creation: %s" % (c - b))
+ print("[INFO] * Test Generation: %s" % (d - c))
+ print("[INFO] * PlantUML View Generation: %s" % (e - d))
+
+ # print("[INFO] Starting Command-Line Simulation.")
+ # simulate(pn.n)
+
+ #if not p.no_sim:
+ # print('[SIM] Start Simulation? (Y/N) :')
+ # value = input(" Enter Choice: ")
+ # if value == "Y" or value == "y":
+ # os.system('cls')
+ # simulate(pn.n)
+
+ except Exception as e:
+ print("[ERROR] " + str(e))
+ if not isinstance(e, StatusException):
+ get_reporting().exception(message = e.__class__.__name__, exception = e)
+ finally:
+ print("[INFO] Saving status_report.json")
+ severity = reporting.save()
+ print("[INFO] Saved status_report.json")
+ print(f"[INFO] Exiting with status: {severity.name}")
+ exit(severity.value)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_TestSCN.py b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_TestSCN.py
index 26b4b647..f2427ed0 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_TestSCN.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_TestSCN.py
@@ -22,12 +22,13 @@ class TestSCN:
constraint_dict = {}
tr_assert_ref_dict = {}
- def __init__(self, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
+ def __init__(self, _pspec_path, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
self.step_list = []
self.step_dependencies = []
self.map_transition_assert = _mapTrAssert
self.constraint_dict = _constraint_dict
self.tr_assert_ref_dict = _tr_assert_ref_dict
+ self.pspec_path = _pspec_path
def generate_viz(self, idx, output_dir):
txt = "@startuml\n"
@@ -73,7 +74,7 @@ def recurseJson(self, items, prefix):
raise TypeError('Unsupported type')
txt += f" {prefix} := {items}\n"
return txt
-
+
def printData(self, idata):
txt = ""
for k, v in idata.items():
@@ -83,10 +84,10 @@ def printData(self, idata):
# for jk in j.keys():
# txt += self.recurseJson(j[jk], "%s.%s" % (k,jk))
return txt
-
+
def generateTSpec(self, idx, sutTypesList, sutVarTransitionMap, transitionQnameMap, output_dir):
txt = ""
- txt += "import \"issue371.ps\"\n\n"
+ txt += f"""import "{self.pspec_path}issue371.ps"\n\n"""
txt += "using issue371.Root.Event_0o4qsh5\n"
txt += "using issue371.Root.Event_1bks5sc\n"
txt += "\nabstract-test-definition\n\n"
@@ -297,8 +298,8 @@ class CEntry:
name = ""
constr = ""
+
def __init__(self, n, c):
self.name = n
self.constr = c
-
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_data.py b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_data.py
index 1084dfb2..d2756afa 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_data.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_data.py
@@ -1,6 +1,9 @@
import copy
import json
-
+if __package__ is None or __package__ == '':
+ from issue371_reporting import get_reporting, Location
+else:
+ from .issue371_reporting import get_reporting, Location
class Data:
@@ -25,14 +28,34 @@ def get_MyContext():
@staticmethod
def execute_Root_T1_default_Event_1bks5sc(Event_0o4qsh5):
- Event_1bks5sc = Event_0o4qsh5
- if True:
- pass
- else:
- pass
- for i in list(range(2)):
- pass
- if not (False):
- Event_1bks5sc["myField"] = 1
+ try:
+ Event_1bks5sc = Event_0o4qsh5
+ except Exception as e:
+ __location = Location(26,26,510,30,"Event_1bks5sc := Event_0o4qsh5")
+ __source_file = "issue371.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ if True:
+ pass
+ else:
+ pass
+ except Exception as e:
+ __location = Location(27,31,554,94,"if true then // Empty else // Empty fi")
+ __source_file = "issue371.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ for i in list(range(2)):
+ pass
+ except Exception as e:
+ __location = Location(32,34,662,69,"for int i in range(2) do // Empty end-for")
+ __source_file = "issue371.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ if not (False):
+ Event_1bks5sc["myField"] = 1
+ except Exception as e:
+ __location = Location(35,37,745,75,"if not false then Event_1bks5sc.myField := 1 fi")
+ __source_file = "issue371.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Event_1bks5sc)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_reporting.py b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_reporting.py
new file mode 100644
index 00000000..44e1d050
--- /dev/null
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/issue371/CPNServer/issue371/issue371_reporting.py
@@ -0,0 +1,153 @@
+import json
+import traceback
+from enum import Enum
+from typing import List, Optional, Dict, Any
+from dataclasses import dataclass, field
+from pathlib import Path
+
+class StatusException(Exception):
+ def __init__(self, message: str):
+ super().__init__(message)
+
+class Severity(Enum):
+ OK = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CANCEL = 4
+
+@dataclass
+class Location:
+ startLine: int
+ endLine: int
+ offset: int
+ length: int
+ text: str
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'startLine': self.startLine,
+ 'endLine': self.endLine,
+ 'offset': self.offset,
+ 'length': self.length,
+ 'text': self.text,
+ }
+
+@dataclass
+class StatusReport:
+ plugin: str
+ severity: Severity
+ message: str
+ source: str = ""
+ code: int = 0
+ details: Optional[str] = None
+ location: Optional[Location] = None
+ children: List['StatusReport'] = field(default_factory=list)
+ exception: Optional[Exception] = field(default=None, repr=False)
+
+ def __post_init__(self):
+ if self.exception is not None:
+ if self.details is None:
+ self.details = self._get_stack_trace_as_string(self.exception)
+ self.exception = None # Don't retain non-serializable object
+
+ if self.children:
+ child_severities = [child.severity for child in self.children if child is not None]
+ if child_severities:
+ max_child_severity = max(child_severities, key=lambda s: s.value)
+ if max_child_severity.value > self.severity.value:
+ self.severity = max_child_severity
+
+ @staticmethod
+ def _get_stack_trace_as_string(exception: Exception) -> str:
+ if exception is None:
+ return None
+ tb_lines = traceback.format_exception(type(exception), exception, exception.__traceback__)
+ if len(tb_lines) > 15:
+ tb_lines = tb_lines[:15] + [f"\t... {len(tb_lines) - 15} more\n"]
+ return "".join(tb_lines)
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'plugin': self.plugin,
+ 'severity': self.severity.name,
+ 'message': self.message,
+ 'source': self.source,
+ 'code': self.code,
+ 'details': self.details,
+ 'location': self.location.to_dict() if self.location else None,
+ 'children': [child.to_dict() for child in self.children if child is not None],
+ }
+
+class StatusReporting:
+ def __init__(self, save_path: str):
+ self.save_path = Path(save_path)
+ self.reports: List[StatusReport] = []
+
+ def _log(self, severity: Severity, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, exception: Optional[Exception] = None, location: Optional[Location] = None) -> StatusReport:
+ report = StatusReport(
+ plugin="",
+ severity=severity,
+ message=message,
+ source=source,
+ code=code,
+ details=details,
+ location=location,
+ exception=exception
+ )
+ self.reports.append(report)
+ return report
+
+ def info(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.INFO, message, source, code, details, None, location)
+
+ def warning(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.WARNING, message, source, code, details, None, location)
+
+ def error(self, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.ERROR, message, source, code, details, None, location)
+
+ def exception(self, message: str, exception: Exception, source: str = "", details: str = None, code: int = 0, location: Location = None) -> StatusReport:
+ self._log(Severity.ERROR, message, source, code, details, exception, location)
+ #on exception the process is stopped
+ raise StatusException(message)
+
+ def save(self) -> Severity:
+
+ root_severity = Severity.OK
+ if self.reports:
+ root_severity = max((report.severity for report in self.reports), key=lambda s: s.value)
+
+ root_report = StatusReport(
+ plugin="",
+ severity=root_severity,
+ message=f"Python generation of issue371",
+ source="",
+ code=0,
+ details=None,
+ location=None,
+ children=self.reports,
+ exception=None
+ )
+
+ data = root_report.to_dict()
+ with open(self.save_path, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return root_severity
+
+
+_status_reporting_instance: Optional[StatusReporting] = None
+
+def initialize_reporting(save_path: str) -> StatusReporting:
+ global _status_reporting_instance
+ _status_reporting_instance = StatusReporting(save_path)
+ return _status_reporting_instance
+
+def get_reporting() -> StatusReporting:
+ global _status_reporting_instance
+ if _status_reporting_instance is None:
+ raise RuntimeError("StatusReporting not initialized. Call initialize_reporting() first.")
+ return _status_reporting_instance
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer.py b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer.py
index f3c0985d..fa6f8395 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer.py
@@ -10,10 +10,12 @@
if __package__ is None or __package__ == '':
from printer_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from printer_data import Data
+ from printer_reporting import get_reporting, initialize_reporting, Location
from printer_Simulation import Simulation, simulate
else:
from .printer_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from .printer_data import Data
+ from .printer_reporting import get_reporting, initialize_reporting, Location
from .printer_Simulation import Simulation, simulate
import subprocess
import copy
@@ -372,7 +374,8 @@ def initializeTestGeneration(self):
if k + "_" +elm.__repr__() in self.map_transition_modes_to_name:
print("WARN: duplicate modes detected for same transition.")
print(k + "_" +elm.__repr__())
- print("WARN: references to the above transitions are ambigous!")
+ print("WARN: references to the above transitions are ambiguous!")
+ get_reporting().warning("Duplicate modes detected for same transition, Check References in Details", details=f"{k}_{str.join('\n',[str(s) for s in elm.items()])}")
self.map_transition_modes_to_name[k + "_" +elm.__repr__()] = k + "_" + str(cnt)
# self.map_transition_modes_to_name[k + "_" + pprint.pformat(elm.items(), width=60, compact=True,depth=5)] = k + "_" + str(cnt)
cnt = cnt + 1
@@ -401,7 +404,7 @@ def generateTestCases(self):
for entry in pn.visitedTList:
# txt = ''
if entry:
- _test_scn = TestSCN(self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
+ _test_scn = TestSCN(pspec_path, self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
idx = idx + 1
j = 0
for step in entry:
@@ -489,103 +492,127 @@ def copy(self, name=None):
type=bool,
default=False,
help="Disable simulation")
-
+
+ parser.add_argument("-srfile","--status_report_file",
+ type=Path,
+ default=None,
+ help="The path to where the status report will be saved")
+
+ parser.add_argument("-pspath","--pspec_path",
+ type=str,
+ default="",
+ help="The relatve path to the pspec file to be used for test generation")
+
p = parser.parse_args()
p.tspec_dir.mkdir(exist_ok=True)
p.plantuml_dir.mkdir(exist_ok=True)
-
- a = datetime.datetime.now()
- pn = printerModel()
- print("[INFO] Loaded CPN model.")
- # pn.n.draw('net-gv-graph.png')
- s = StateGraph(pn.n)
- # s.build()
- # s.draw('test-gv-graph.png')
- # print(" Finished Generation, writing to file.. ")
- print("[INFO] Starting Reachability Graph Generation")
- # pn.generateScenarios(s,0,[],[],[],0,300)
- sys.setrecursionlimit(400)
- pn.generateSCN()
- print('Num Tests: ', pn.numTestCases)
- print("[INFO] Finished.")
- b = datetime.datetime.now()
+ status_report_file = p.status_report_file if p.status_report_file != None else p.tspec_dir / "status_report.json"
+ status_report_file.parent.mkdir(parents=True, exist_ok=True)
+ pspec_path = p.pspec_path
+ reporting = initialize_reporting(status_report_file)
- # s.goto(0)
+ try:
+ a = datetime.datetime.now()
+ pn = printerModel()
+ print("[INFO] Loaded CPN model.")
+ # pn.n.draw('net-gv-graph.png')
+ s = StateGraph(pn.n)
+ # s.build()
+ # s.draw('test-gv-graph.png')
+ # print(" Finished Generation, writing to file.. ")
+ print("[INFO] Starting Reachability Graph Generation")
+ # pn.generateScenarios(s,0,[],[],[],0,300)
+ sys.setrecursionlimit(400)
+ pn.generateSCN()
+ print('Num Tests: ', pn.numTestCases)
+ print("[INFO] Finished.")
+ b = datetime.datetime.now()
- fname = p.plantuml_dir / "rg.plantuml"
- with open(fname, 'w') as f:
- pn.generateReachabilityGraph(f)
- print("[INFO] Created %s" % (fname,))
- c = datetime.datetime.now()
-
- print("[INFO] Starting Test Generation.")
- pn.initializeTestGeneration()
- pn.generateTestCases()
-
- # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
- print("[INFO] Test Generation Finished.")
- d = datetime.datetime.now()
+ # s.goto(0)
+
+ fname = p.plantuml_dir / "rg.plantuml"
+ with open(fname, 'w') as f:
+ pn.generateReachabilityGraph(f)
+ print("[INFO] Created %s" % (fname,))
+ c = datetime.datetime.now()
- print("[INFO] Creating Structure and Behavior Views in PlantUML.")
- map_block_uml_txt = {}
- for t in pn.n.transition():
- map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+ print("[INFO] Starting Test Generation.")
+ pn.initializeTestGeneration()
+ pn.generateTestCases()
- for t in pn.n.transition():
- gtxt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'json.loads' in t.guard._str:
- # print(t.guard._str.replace('json.loads',''))
- # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- gtxt += 'component %s\n' % (t.name)
- if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
- gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'component %s\n' % (t.name)
- gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
- map_block_uml_txt[t.name.split('_')[0]] = gtxt
+ # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
+ print("[INFO] Test Generation Finished.")
+ d = datetime.datetime.now()
- for t in pn.n.transition():
- for inp in pn.n.pre(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in inp:
- txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ print("[INFO] Creating Structure and Behavior Views in PlantUML.")
+ map_block_uml_txt = {}
+ for t in pn.n.transition():
+ map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+
+ for t in pn.n.transition():
+ gtxt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'json.loads' in t.guard._str:
+ # print(t.guard._str.replace('json.loads',''))
+ # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ gtxt += 'component %s\n' % (t.name)
+ if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
+ gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ else:
+ gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
else:
- txt += '%s --> [%s]\n' % (inp, t.name)
- map_block_uml_txt[t.name.split('_')[0]] = txt
- for out in pn.n.post(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in out:
- txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
- else:
- txt += '[%s] --> %s\n' % (t.name, out)
- map_block_uml_txt[t.name.split('_')[0]] = txt
-
- for key in map_block_uml_txt:
- txt = map_block_uml_txt.get(key)
- txt += '@enduml\n'
- map_block_uml_txt[key] = txt
- fname = p.plantuml_dir / (key + ".plantuml")
- with open(fname, 'w') as f:
- f.write(txt)
-
- print("[INFO] View Generation Finished.")
- e = datetime.datetime.now()
- print("[INFO] Time Statistics")
- print("[INFO] * Reachability Computation: %s" % (b - a))
- print("[INFO] * Reachability PUML Creation: %s" % (c - b))
- print("[INFO] * Test Generation: %s" % (d - c))
- print("[INFO] * PlantUML View Generation: %s" % (e - d))
-
- # print("[INFO] Starting Command-Line Simulation.")
- # simulate(pn.n)
-
- #if not p.no_sim:
- # print('[SIM] Start Simulation? (Y/N) :')
- # value = input(" Enter Choice: ")
- # if value == "Y" or value == "y":
- # os.system('cls')
- # simulate(pn.n)
-
- print("[INFO] Exiting..")
+ gtxt += 'component %s\n' % (t.name)
+ gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
+ map_block_uml_txt[t.name.split('_')[0]] = gtxt
+
+ for t in pn.n.transition():
+ for inp in pn.n.pre(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in inp:
+ txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ else:
+ txt += '%s --> [%s]\n' % (inp, t.name)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+ for out in pn.n.post(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in out:
+ txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ else:
+ txt += '[%s] --> %s\n' % (t.name, out)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+
+ for key in map_block_uml_txt:
+ txt = map_block_uml_txt.get(key)
+ txt += '@enduml\n'
+ map_block_uml_txt[key] = txt
+ fname = p.plantuml_dir / (key + ".plantuml")
+ with open(fname, 'w') as f:
+ f.write(txt)
+
+ print("[INFO] View Generation Finished.")
+ e = datetime.datetime.now()
+ print("[INFO] Time Statistics")
+ print("[INFO] * Reachability Computation: %s" % (b - a))
+ print("[INFO] * Reachability PUML Creation: %s" % (c - b))
+ print("[INFO] * Test Generation: %s" % (d - c))
+ print("[INFO] * PlantUML View Generation: %s" % (e - d))
+
+ # print("[INFO] Starting Command-Line Simulation.")
+ # simulate(pn.n)
+
+ #if not p.no_sim:
+ # print('[SIM] Start Simulation? (Y/N) :')
+ # value = input(" Enter Choice: ")
+ # if value == "Y" or value == "y":
+ # os.system('cls')
+ # simulate(pn.n)
+
+ except Exception as e:
+ print("[ERROR] " + str(e))
+ if not isinstance(e, StatusException):
+ get_reporting().exception(message = e.__class__.__name__, exception = e)
+ finally:
+ print("[INFO] Saving status_report.json")
+ severity = reporting.save()
+ print("[INFO] Saved status_report.json")
+ print(f"[INFO] Exiting with status: {severity.name}")
+ exit(severity.value)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_TestSCN.py b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_TestSCN.py
index 0a1cb6be..0ec6f35a 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_TestSCN.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_TestSCN.py
@@ -22,12 +22,13 @@ class TestSCN:
constraint_dict = {}
tr_assert_ref_dict = {}
- def __init__(self, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
+ def __init__(self, _pspec_path, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
self.step_list = []
self.step_dependencies = []
self.map_transition_assert = _mapTrAssert
self.constraint_dict = _constraint_dict
self.tr_assert_ref_dict = _tr_assert_ref_dict
+ self.pspec_path = _pspec_path
def generate_viz(self, idx, output_dir):
txt = "@startuml\n"
@@ -73,7 +74,7 @@ def recurseJson(self, items, prefix):
raise TypeError('Unsupported type')
txt += f" {prefix} := {items}\n"
return txt
-
+
def printData(self, idata):
txt = ""
for k, v in idata.items():
@@ -83,10 +84,10 @@ def printData(self, idata):
# for jk in j.keys():
# txt += self.recurseJson(j[jk], "%s.%s" % (k,jk))
return txt
-
+
def generateTSpec(self, idx, sutTypesList, sutVarTransitionMap, transitionQnameMap, output_dir):
txt = ""
- txt += "import \"printer.ps\"\n\n"
+ txt += f"""import "{self.pspec_path}printer.ps"\n\n"""
txt += "using printer.PrintFactoryA3DPrinter.printJob\n"
txt += "using printer.PrintFactoryA3DPrinter.corrections\n"
txt += "using printer.PrintFactoryA3DPrinter.variants\n"
@@ -330,8 +331,8 @@ class CEntry:
name = ""
constr = ""
+
def __init__(self, n, c):
self.name = n
self.constr = c
-
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_data.py b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_data.py
index f9e363a2..f111b292 100644
--- a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_data.py
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_data.py
@@ -1,6 +1,9 @@
import copy
import json
-
+if __package__ is None or __package__ == '':
+ from printer_reporting import get_reporting, Location
+else:
+ from .printer_reporting import get_reporting, Location
class Data:
@@ -77,180 +80,375 @@ def get_Result():
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrintJob_default_Event_0jcg6zx(request,Flow_1u2qmtt,variants):
- Event_0jcg6zx = Flow_1u2qmtt
+ try:
+ Event_0jcg6zx = Flow_1u2qmtt
+ except Exception as e:
+ __location = Location(64,64,2157,29,"Event_0jcg6zx := Flow_1u2qmtt")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Event_0jcg6zx)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrintJob_default_printResult(request,Flow_1u2qmtt,variants):
- printResult = {"verdict": "Outcome::OK"}
+ try:
+ printResult = {"verdict": "Outcome::OK"}
+ except Exception as e:
+ __location = Location(67,67,2256,47,"printResult := Result { verdict = Outcome::OK }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printResult)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrintJob_default_printReport(request,Flow_1u2qmtt,variants):
- printReport = {"id": request["id"]}
+ try:
+ printReport = {"id": request["id"]}
+ except Exception as e:
+ __location = Location(70,72,2412,68,"printReport := Report { id = request.id }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printReport)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrintJob_default_variants(request,Flow_1u2qmtt,variants):
- variants = variants
+ try:
+ variants = variants
+ except Exception as e:
+ __location = Location(75,75,2561,20,"variants := variants")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(variants)
@staticmethod
def execute_PrintFactoryA3DPrinter_ComposePrintJob_default_request(corrections,printJob):
- request = printJob
+ try:
+ request = printJob
+ except Exception as e:
+ __location = Location(85,85,2996,19,"request := printJob")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(request)
@staticmethod
def execute_PrintFactoryA3DPrinter_ComposePrepareJob_default_request(printJob):
- request = printJob
+ try:
+ request = printJob
+ except Exception as e:
+ __location = Location(95,95,3386,19,"request := printJob")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(request)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrepareJob_default_Event_0mxx05p(request,Flow_0iaelzn,variants):
- Event_0mxx05p = Flow_0iaelzn
+ try:
+ Event_0mxx05p = Flow_0iaelzn
+ except Exception as e:
+ __location = Location(106,106,3888,29,"Event_0mxx05p := Flow_0iaelzn")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Event_0mxx05p)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrepareJob_default_printResult(request,Flow_0iaelzn,variants):
- printResult = {"verdict": "Outcome::OK"}
+ try:
+ printResult = {"verdict": "Outcome::OK"}
+ except Exception as e:
+ __location = Location(109,109,3987,47,"printResult := Result { verdict = Outcome::OK }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printResult)
@staticmethod
def execute_PrintFactoryA3DPrinter_RunPrepareJob_default_variants(request,Flow_0iaelzn,variants):
- variants = variants
+ try:
+ variants = variants
+ except Exception as e:
+ __location = Location(112,112,4115,20,"variants := variants")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(variants)
@staticmethod
def execute_PrintFactoryAssertions_AssertVisualInspection_default_history(inspectionReport,history):
- history = {"inspectionReports": history["inspectionReports"] + [inspectionReport["id"]]}
+ try:
+ history = {"inspectionReports": history["inspectionReports"] + [inspectionReport["id"]]}
+ except Exception as e:
+ __location = Location(149,151,5220,132,"history := AssertionsHistory { inspectionReports = add(history.inspectionReports, inspectionReport.id) }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(history)
@staticmethod
def execute_PrintFactoryAssertions_AssertVisualInspection_default_inspectionReport(inspectionReport,history):
- inspectionReport = inspectionReport
+ try:
+ inspectionReport = inspectionReport
+ except Exception as e:
+ __location = Location(154,154,5471,36,"inspectionReport := inspectionReport")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(inspectionReport)
@staticmethod
def execute_PrintFactoryInspection_RunVisualinspection_default_inspectionReport(measureRequest,Flow_07l0yyj):
- inspectionReport = {"id": measureRequest["id"]}
+ try:
+ inspectionReport = {"id": measureRequest["id"]}
+ except Exception as e:
+ __location = Location(187,189,6351,80,"inspectionReport := Report { id = measureRequest.id }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(inspectionReport)
@staticmethod
def execute_PrintFactoryInspection_RunVisualinspection_default_inspectionResult(measureRequest,Flow_07l0yyj):
- inspectionResult = {"verdict": "Outcome::OK"}
+ try:
+ inspectionResult = {"verdict": "Outcome::OK"}
+ except Exception as e:
+ __location = Location(192,192,6506,52,"inspectionResult := Result { verdict = Outcome::OK }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(inspectionResult)
@staticmethod
def execute_PrintFactoryInspection_ComposeVisualInspectionJob_default_measureRequest(printReport,inspectionJob):
- measureRequest = inspectionJob
+ try:
+ measureRequest = inspectionJob
+ except Exception as e:
+ __location = Location(205,205,7118,31,"measureRequest := inspectionJob")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(measureRequest)
@staticmethod
def execute_PrintFactoryInspection_ComposeVisualInspectionJob_default_printReport(printReport,inspectionJob):
- printReport = printReport
+ try:
+ printReport = printReport
+ except Exception as e:
+ __location = Location(208,208,7242,26,"printReport := printReport")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printReport)
@staticmethod
def execute_PrintFactoryOptimization_ComposeOptimizationJob_default_optimizeJob(optJob,inspectionReport):
- optimizeJob = optJob
+ try:
+ optimizeJob = optJob
+ except Exception as e:
+ __location = Location(243,243,8195,21,"optimizeJob := optJob")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(optimizeJob)
@staticmethod
def execute_PrintFactoryOptimization_ComposeOptimizationJob_default_inspectionReport(optJob,inspectionReport):
- inspectionReport = inspectionReport
+ try:
+ inspectionReport = inspectionReport
+ except Exception as e:
+ __location = Location(246,246,8314,36,"inspectionReport := inspectionReport")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(inspectionReport)
@staticmethod
def execute_PrintFactoryOptimization_RunOptimizationJob_default_Event_1oozdnw(optimizeJob,Flow_0y8u5pd):
- Event_1oozdnw = Flow_0y8u5pd
+ try:
+ Event_1oozdnw = Flow_0y8u5pd
+ except Exception as e:
+ __location = Location(254,254,8641,29,"Event_1oozdnw := Flow_0y8u5pd")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Event_1oozdnw)
@staticmethod
def execute_PrintFactoryOptimization_RunOptimizationJob_default_corrections(optimizeJob,Flow_0y8u5pd):
- corrections = {"id": optimizeJob["id"] + 1}
+ try:
+ corrections = {"id": optimizeJob["id"] + 1}
+ except Exception as e:
+ __location = Location(257,259,8754,87,"corrections := CorrectionsReport { id = optimizeJob.id + 1 }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(corrections)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendPrintJob_default_Flow_16s4ey1(printRequests,Gateway_1wpvmtk):
- Flow_16s4ey1 = Gateway_1wpvmtk
- Flow_16s4ey1["color"] = printRequests["color"]
- Flow_16s4ey1["resolution"] = printRequests["resolution"]
- Flow_16s4ey1["scale"] = printRequests["scale"]
+ try:
+ Flow_16s4ey1 = Gateway_1wpvmtk
+ except Exception as e:
+ __location = Location(335,335,10947,31,"Flow_16s4ey1 := Gateway_1wpvmtk")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_16s4ey1["color"] = printRequests["color"]
+ except Exception as e:
+ __location = Location(336,336,10992,41,"Flow_16s4ey1.color := printRequests.color")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_16s4ey1["resolution"] = printRequests["resolution"]
+ except Exception as e:
+ __location = Location(337,337,11047,51,"Flow_16s4ey1.resolution := printRequests.resolution")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Flow_16s4ey1["scale"] = printRequests["scale"]
+ except Exception as e:
+ __location = Location(338,338,11112,41,"Flow_16s4ey1.scale := printRequests.scale")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_16s4ey1)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendPrintJob_default_printJob(printRequests,Gateway_1wpvmtk):
- printJob = {"id": printRequests["id"], "resolution": printRequests["resolution"], "scale": printRequests["scale"], "color": printRequests["color"], "opType": printRequests["opType"]}
+ try:
+ printJob = {"id": printRequests["id"], "resolution": printRequests["resolution"], "scale": printRequests["scale"], "color": printRequests["color"], "opType": printRequests["opType"]}
+ except Exception as e:
+ __location = Location(341,347,11220,261,"printJob := PrintRequest { id = printRequests.id, resolution = printRequests.resolution, scale = printRequests.scale, color = printRequests.color, opType = printRequests.opType }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printJob)
@staticmethod
def execute_PrintFactoryFactoryAutomation_NextJob_default_Gateway_1wpvmtk(Gateway_0p2uo9v):
- Gateway_1wpvmtk = Gateway_0p2uo9v
- Gateway_1wpvmtk["id"] = Gateway_1wpvmtk["id"] + 1
+ try:
+ Gateway_1wpvmtk = Gateway_0p2uo9v
+ except Exception as e:
+ __location = Location(355,355,11687,34,"Gateway_1wpvmtk := Gateway_0p2uo9v")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
+ try:
+ Gateway_1wpvmtk["id"] = Gateway_1wpvmtk["id"] + 1
+ except Exception as e:
+ __location = Location(356,356,11735,44,"Gateway_1wpvmtk.id := Gateway_1wpvmtk.id + 1")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_1wpvmtk)
@staticmethod
def execute_PrintFactoryFactoryAutomation_WaitforOptimizationJob_default_Flow_09b0flo(Flow_01m2s0h,optResult):
- Flow_09b0flo = Flow_01m2s0h
+ try:
+ Flow_09b0flo = Flow_01m2s0h
+ except Exception as e:
+ __location = Location(364,364,12022,28,"Flow_09b0flo := Flow_01m2s0h")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_09b0flo)
@staticmethod
def execute_PrintFactoryFactoryAutomation_Gateway_1f8wap6_default_Gateway_0p2uo9v(Flow_09b0flo,Flow_1vq9t2p):
- Gateway_0p2uo9v = Flow_09b0flo
+ try:
+ Gateway_0p2uo9v = Flow_09b0flo
+ except Exception as e:
+ __location = Location(373,373,12332,31,"Gateway_0p2uo9v := Flow_09b0flo")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Gateway_0p2uo9v)
@staticmethod
def execute_PrintFactoryFactoryAutomation_Gateway_1j3rupx_default_Flow_1y4bjf4(Flow_1dcdx0e):
- Flow_1y4bjf4 = Flow_1dcdx0e
+ try:
+ Flow_1y4bjf4 = Flow_1dcdx0e
+ except Exception as e:
+ __location = Location(381,381,12578,28,"Flow_1y4bjf4 := Flow_1dcdx0e")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1y4bjf4)
@staticmethod
def execute_PrintFactoryFactoryAutomation_Gateway_1j3rupx_default_Flow_1f74bn4(Flow_1dcdx0e):
- Flow_1f74bn4 = Flow_1dcdx0e
+ try:
+ Flow_1f74bn4 = Flow_1dcdx0e
+ except Exception as e:
+ __location = Location(384,384,12677,28,"Flow_1f74bn4 := Flow_1dcdx0e")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1f74bn4)
@staticmethod
def execute_PrintFactoryFactoryAutomation_WaitforVisualInspection_default_Flow_0kbycuh(inspectionResult,Flow_1dt29vl):
- Flow_0kbycuh = Flow_1dt29vl
+ try:
+ Flow_0kbycuh = Flow_1dt29vl
+ except Exception as e:
+ __location = Location(392,392,12957,28,"Flow_0kbycuh := Flow_1dt29vl")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_0kbycuh)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendOptimizationJob_default_Flow_01m2s0h(Flow_0kbycuh):
- Flow_01m2s0h = Flow_0kbycuh
+ try:
+ Flow_01m2s0h = Flow_0kbycuh
+ except Exception as e:
+ __location = Location(400,400,13210,28,"Flow_01m2s0h := Flow_0kbycuh")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_01m2s0h)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendOptimizationJob_default_optJob(Flow_0kbycuh):
- optJob = {"id": Flow_0kbycuh["id"]}
+ try:
+ optJob = {"id": Flow_0kbycuh["id"]}
+ except Exception as e:
+ __location = Location(403,403,13303,50,"optJob := OptimizeRequest { id = Flow_0kbycuh.id }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(optJob)
@staticmethod
def execute_PrintFactoryFactoryAutomation_CleanPrinter_default_Flow_1rkhqnd(Flow_1f74bn4):
- Flow_1rkhqnd = Flow_1f74bn4
+ try:
+ Flow_1rkhqnd = Flow_1f74bn4
+ except Exception as e:
+ __location = Location(411,411,13563,28,"Flow_1rkhqnd := Flow_1f74bn4")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1rkhqnd)
@staticmethod
def execute_PrintFactoryFactoryAutomation_CleanPrinter_default_printJob(Flow_1f74bn4):
- printJob = {"id": Flow_1f74bn4["id"], "resolution": Flow_1f74bn4["resolution"], "scale": None, "color": Flow_1f74bn4["color"], "opType": "OperationType::PREP"}
+ try:
+ printJob = {"id": Flow_1f74bn4["id"], "resolution": Flow_1f74bn4["resolution"], "scale": None, "color": Flow_1f74bn4["color"], "opType": "OperationType::PREP"}
+ except Exception as e:
+ __location = Location(414,420,13658,242,"printJob := PrintRequest { id = Flow_1f74bn4.id, resolution = Flow_1f74bn4.resolution, scale = null, color = Flow_1f74bn4.color, opType = OperationType::PREP }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(printJob)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendVisualInspectionJob_default_Flow_1dt29vl(Flow_1y4bjf4):
- Flow_1dt29vl = Flow_1y4bjf4
+ try:
+ Flow_1dt29vl = Flow_1y4bjf4
+ except Exception as e:
+ __location = Location(428,428,14134,28,"Flow_1dt29vl := Flow_1y4bjf4")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1dt29vl)
@staticmethod
def execute_PrintFactoryFactoryAutomation_SendVisualInspectionJob_default_inspectionJob(Flow_1y4bjf4):
- inspectionJob = {"id": Flow_1y4bjf4["id"]}
+ try:
+ inspectionJob = {"id": Flow_1y4bjf4["id"]}
+ except Exception as e:
+ __location = Location(431,433,14276,83,"inspectionJob := MeasureRequest { id = Flow_1y4bjf4.id }")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(inspectionJob)
@staticmethod
def execute_PrintFactoryFactoryAutomation_WaitforClean_default_Flow_1vq9t2p(printResult,Flow_1rkhqnd):
- Flow_1vq9t2p = Flow_1rkhqnd
+ try:
+ Flow_1vq9t2p = Flow_1rkhqnd
+ except Exception as e:
+ __location = Location(441,441,14583,28,"Flow_1vq9t2p := Flow_1rkhqnd")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1vq9t2p)
@staticmethod
def execute_PrintFactoryFactoryAutomation_WaitforPrintJob_default_Flow_1dcdx0e(printResult,Flow_16s4ey1):
- Flow_1dcdx0e = Flow_16s4ey1
+ try:
+ Flow_1dcdx0e = Flow_16s4ey1
+ except Exception as e:
+ __location = Location(449,449,14842,28,"Flow_1dcdx0e := Flow_16s4ey1")
+ __source_file = "printer.ps"
+ get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)
return json.dumps(Flow_1dcdx0e)
diff --git a/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_reporting.py b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_reporting.py
new file mode 100644
index 00000000..4164612b
--- /dev/null
+++ b/bundles/nl.asml.matala.product.tests/resources/expected/printer/CPNServer/printer/printer_reporting.py
@@ -0,0 +1,153 @@
+import json
+import traceback
+from enum import Enum
+from typing import List, Optional, Dict, Any
+from dataclasses import dataclass, field
+from pathlib import Path
+
+class StatusException(Exception):
+ def __init__(self, message: str):
+ super().__init__(message)
+
+class Severity(Enum):
+ OK = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CANCEL = 4
+
+@dataclass
+class Location:
+ startLine: int
+ endLine: int
+ offset: int
+ length: int
+ text: str
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'startLine': self.startLine,
+ 'endLine': self.endLine,
+ 'offset': self.offset,
+ 'length': self.length,
+ 'text': self.text,
+ }
+
+@dataclass
+class StatusReport:
+ plugin: str
+ severity: Severity
+ message: str
+ source: str = ""
+ code: int = 0
+ details: Optional[str] = None
+ location: Optional[Location] = None
+ children: List['StatusReport'] = field(default_factory=list)
+ exception: Optional[Exception] = field(default=None, repr=False)
+
+ def __post_init__(self):
+ if self.exception is not None:
+ if self.details is None:
+ self.details = self._get_stack_trace_as_string(self.exception)
+ self.exception = None # Don't retain non-serializable object
+
+ if self.children:
+ child_severities = [child.severity for child in self.children if child is not None]
+ if child_severities:
+ max_child_severity = max(child_severities, key=lambda s: s.value)
+ if max_child_severity.value > self.severity.value:
+ self.severity = max_child_severity
+
+ @staticmethod
+ def _get_stack_trace_as_string(exception: Exception) -> str:
+ if exception is None:
+ return None
+ tb_lines = traceback.format_exception(type(exception), exception, exception.__traceback__)
+ if len(tb_lines) > 15:
+ tb_lines = tb_lines[:15] + [f"\t... {len(tb_lines) - 15} more\n"]
+ return "".join(tb_lines)
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'plugin': self.plugin,
+ 'severity': self.severity.name,
+ 'message': self.message,
+ 'source': self.source,
+ 'code': self.code,
+ 'details': self.details,
+ 'location': self.location.to_dict() if self.location else None,
+ 'children': [child.to_dict() for child in self.children if child is not None],
+ }
+
+class StatusReporting:
+ def __init__(self, save_path: str):
+ self.save_path = Path(save_path)
+ self.reports: List[StatusReport] = []
+
+ def _log(self, severity: Severity, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, exception: Optional[Exception] = None, location: Optional[Location] = None) -> StatusReport:
+ report = StatusReport(
+ plugin="",
+ severity=severity,
+ message=message,
+ source=source,
+ code=code,
+ details=details,
+ location=location,
+ exception=exception
+ )
+ self.reports.append(report)
+ return report
+
+ def info(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.INFO, message, source, code, details, None, location)
+
+ def warning(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.WARNING, message, source, code, details, None, location)
+
+ def error(self, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.ERROR, message, source, code, details, None, location)
+
+ def exception(self, message: str, exception: Exception, source: str = "", details: str = None, code: int = 0, location: Location = None) -> StatusReport:
+ self._log(Severity.ERROR, message, source, code, details, exception, location)
+ #on exception the process is stopped
+ raise StatusException(message)
+
+ def save(self) -> Severity:
+
+ root_severity = Severity.OK
+ if self.reports:
+ root_severity = max((report.severity for report in self.reports), key=lambda s: s.value)
+
+ root_report = StatusReport(
+ plugin="",
+ severity=root_severity,
+ message=f"Python generation of printer",
+ source="",
+ code=0,
+ details=None,
+ location=None,
+ children=self.reports,
+ exception=None
+ )
+
+ data = root_report.to_dict()
+ with open(self.save_path, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return root_severity
+
+
+_status_reporting_instance: Optional[StatusReporting] = None
+
+def initialize_reporting(save_path: str) -> StatusReporting:
+ global _status_reporting_instance
+ _status_reporting_instance = StatusReporting(save_path)
+ return _status_reporting_instance
+
+def get_reporting() -> StatusReporting:
+ global _status_reporting_instance
+ if _status_reporting_instance is None:
+ raise RuntimeError("StatusReporting not initialized. Call initialize_reporting() first.")
+ return _status_reporting_instance
diff --git a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/PetriNet.xtend b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/PetriNet.xtend
index b349cb70..af7cc3df 100644
--- a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/PetriNet.xtend
+++ b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/PetriNet.xtend
@@ -353,10 +353,12 @@ class PetriNet {
if __package__ is None or __package__ == '':
from «prod_name»_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from «prod_name»_data import Data
+ from «prod_name»_reporting import get_reporting, initialize_reporting, Location
from «prod_name»_Simulation import Simulation, simulate
else:
from .«prod_name»_TestSCN import TestSCN, Step, Tests, Constraint, CEntry
from .«prod_name»_data import Data
+ from .«prod_name»_reporting import get_reporting, initialize_reporting, Location
from .«prod_name»_Simulation import Simulation, simulate
import subprocess
import copy
@@ -433,7 +435,8 @@ class PetriNet {
if k + "_" +elm.__repr__() in self.map_transition_modes_to_name:
print("WARN: duplicate modes detected for same transition.")
print(k + "_" +elm.__repr__())
- print("WARN: references to the above transitions are ambigous!")
+ print("WARN: references to the above transitions are ambiguous!")
+ get_reporting().warning("Duplicate modes detected for same transition, Check References in Details", details=f"{k}_{str.join('\n',[str(s) for s in elm.items()])}")
self.map_transition_modes_to_name[k + "_" +elm.__repr__()] = k + "_" + str(cnt)
# self.map_transition_modes_to_name[k + "_" + pprint.pformat(elm.items(), width=60, compact=True,depth=5)] = k + "_" + str(cnt)
cnt = cnt + 1
@@ -470,7 +473,7 @@ class PetriNet {
for entry in pn.visitedTList:
# txt = ''
if entry:
- _test_scn = TestSCN(self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
+ _test_scn = TestSCN(pspec_path, self.map_transition_assert, self.constraint_dict, self.tr_assert_ref_dict)
idx = idx + 1
j = 0
for step in entry:
@@ -558,106 +561,130 @@ class PetriNet {
type=bool,
default=False,
help="Disable simulation")
-
+
+ parser.add_argument("-srfile","--status_report_file",
+ type=Path,
+ default=None,
+ help="The path to where the status report will be saved")
+
+ parser.add_argument("-pspath","--pspec_path",
+ type=str,
+ default="",
+ help="The relatve path to the pspec file to be used for test generation")
+
p = parser.parse_args()
p.tspec_dir.mkdir(exist_ok=True)
p.plantuml_dir.mkdir(exist_ok=True)
+ status_report_file = p.status_report_file if p.status_report_file != None else p.tspec_dir / "status_report.json"
+ status_report_file.parent.mkdir(parents=True, exist_ok=True)
+ pspec_path = p.pspec_path
+ reporting = initialize_reporting(status_report_file)
+
+ try:
+ a = datetime.datetime.now()
+ pn = «prod_name»Model()
+ print("[INFO] Loaded CPN model.")
+ # pn.n.draw('net-gv-graph.png')
+ s = StateGraph(pn.n)
+ # s.build()
+ # s.draw('test-gv-graph.png')
+ # print(" Finished Generation, writing to file.. ")
+ print("[INFO] Starting Reachability Graph Generation")
+ # pn.generateScenarios(s,0,[],[],[],0,«depth_limit»)
+ sys.setrecursionlimit(«depth_limit + 100»)
+ pn.generateSCN()
+ print('Num Tests: ', pn.numTestCases)
+ print("[INFO] Finished.")
+ b = datetime.datetime.now()
- a = datetime.datetime.now()
- pn = «prod_name»Model()
- print("[INFO] Loaded CPN model.")
- # pn.n.draw('net-gv-graph.png')
- s = StateGraph(pn.n)
- # s.build()
- # s.draw('test-gv-graph.png')
- # print(" Finished Generation, writing to file.. ")
- print("[INFO] Starting Reachability Graph Generation")
- # pn.generateScenarios(s,0,[],[],[],0,«depth_limit»)
- sys.setrecursionlimit(«depth_limit + 100»)
- pn.generateSCN()
- print('Num Tests: ', pn.numTestCases)
- print("[INFO] Finished.")
- b = datetime.datetime.now()
-
- # s.goto(0)
-
- fname = p.plantuml_dir / "rg.plantuml"
- with open(fname, 'w') as f:
- pn.generateReachabilityGraph(f)
- print("[INFO] Created %s" % (fname,))
- c = datetime.datetime.now()
-
- print("[INFO] Starting Test Generation.")
- pn.initializeTestGeneration()
- pn.generateTestCases()
-
- # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
- print("[INFO] Test Generation Finished.")
- d = datetime.datetime.now()
+ # s.goto(0)
+
+ fname = p.plantuml_dir / "rg.plantuml"
+ with open(fname, 'w') as f:
+ pn.generateReachabilityGraph(f)
+ print("[INFO] Created %s" % (fname,))
+ c = datetime.datetime.now()
- print("[INFO] Creating Structure and Behavior Views in PlantUML.")
- map_block_uml_txt = {}
- for t in pn.n.transition():
- map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+ print("[INFO] Starting Test Generation.")
+ pn.initializeTestGeneration()
+ pn.generateTestCases()
- for t in pn.n.transition():
- gtxt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'json.loads' in t.guard._str:
- # print(t.guard._str.replace('json.loads',''))
- # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- gtxt += 'component %s\n' % (t.name)
- if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
- gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
- else:
- gtxt += 'component %s\n' % (t.name)
- gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
- map_block_uml_txt[t.name.split('_')[0]] = gtxt
+ # print('[INFO] Number-of-generated-scenario files: ',len(pn.visitedTList))
+ print("[INFO] Test Generation Finished.")
+ d = datetime.datetime.now()
- for t in pn.n.transition():
- for inp in pn.n.pre(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in inp:
- txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
- else:
- txt += '%s --> [%s]\n' % (inp, t.name)
- map_block_uml_txt[t.name.split('_')[0]] = txt
- for out in pn.n.post(t.name):
- txt = map_block_uml_txt.get(t.name.split('_')[0])
- if 'local' in out:
- txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ print("[INFO] Creating Structure and Behavior Views in PlantUML.")
+ map_block_uml_txt = {}
+ for t in pn.n.transition():
+ map_block_uml_txt[t.name.split('_')[0]] = '@startuml\n'
+
+ for t in pn.n.transition():
+ gtxt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'json.loads' in t.guard._str:
+ # print(t.guard._str.replace('json.loads',''))
+ # print('\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ gtxt += 'component %s\n' % (t.name)
+ if len(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),68))) <= 2:
+ gtxt += 'note left of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
+ else:
+ gtxt += 'note bottom of [%s]\n %s\nendnote\n' % (t.name, '\n'.join(list(pn.chunkstring(t.guard._str.replace('json.loads','').replace(', object_pairs_hook=Data().int_keys', ''),55))))
else:
- txt += '[%s] --> %s\n' % (t.name, out)
- map_block_uml_txt[t.name.split('_')[0]] = txt
-
- for key in map_block_uml_txt:
- txt = map_block_uml_txt.get(key)
- txt += '@enduml\n'
- map_block_uml_txt[key] = txt
- fname = p.plantuml_dir / (key + ".plantuml")
- with open(fname, 'w') as f:
- f.write(txt)
-
- print("[INFO] View Generation Finished.")
- e = datetime.datetime.now()
- print("[INFO] Time Statistics")
- print("[INFO] * Reachability Computation: %s" % (b - a))
- print("[INFO] * Reachability PUML Creation: %s" % (c - b))
- print("[INFO] * Test Generation: %s" % (d - c))
- print("[INFO] * PlantUML View Generation: %s" % (e - d))
-
- # print("[INFO] Starting Command-Line Simulation.")
- # simulate(pn.n)
-
- #if not p.no_sim:
- # print('[SIM] Start Simulation? (Y/N) :')
- # value = input(" Enter Choice: ")
- # if value == "Y" or value == "y":
- # os.system('cls')
- # simulate(pn.n)
-
- print("[INFO] Exiting..")
+ gtxt += 'component %s\n' % (t.name)
+ gtxt += 'note right of [%s]\n %s\nendnote\n' % (t.name, t.guard)
+ map_block_uml_txt[t.name.split('_')[0]] = gtxt
+
+ for t in pn.n.transition():
+ for inp in pn.n.pre(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in inp:
+ txt += '%s -[#lightgrey]-> [%s]\n' % (inp, t.name)
+ else:
+ txt += '%s --> [%s]\n' % (inp, t.name)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+ for out in pn.n.post(t.name):
+ txt = map_block_uml_txt.get(t.name.split('_')[0])
+ if 'local' in out:
+ txt += '[%s] -[#lightgrey]-> %s\n' % (t.name, out)
+ else:
+ txt += '[%s] --> %s\n' % (t.name, out)
+ map_block_uml_txt[t.name.split('_')[0]] = txt
+
+ for key in map_block_uml_txt:
+ txt = map_block_uml_txt.get(key)
+ txt += '@enduml\n'
+ map_block_uml_txt[key] = txt
+ fname = p.plantuml_dir / (key + ".plantuml")
+ with open(fname, 'w') as f:
+ f.write(txt)
+
+ print("[INFO] View Generation Finished.")
+ e = datetime.datetime.now()
+ print("[INFO] Time Statistics")
+ print("[INFO] * Reachability Computation: %s" % (b - a))
+ print("[INFO] * Reachability PUML Creation: %s" % (c - b))
+ print("[INFO] * Test Generation: %s" % (d - c))
+ print("[INFO] * PlantUML View Generation: %s" % (e - d))
+
+ # print("[INFO] Starting Command-Line Simulation.")
+ # simulate(pn.n)
+
+ #if not p.no_sim:
+ # print('[SIM] Start Simulation? (Y/N) :')
+ # value = input(" Enter Choice: ")
+ # if value == "Y" or value == "y":
+ # os.system('cls')
+ # simulate(pn.n)
+
+ except Exception as e:
+ print("[ERROR] " + str(e))
+ if not isinstance(e, StatusException):
+ get_reporting().exception(message = e.__class__.__name__, exception = e)
+ finally:
+ print("[INFO] Saving status_report.json")
+ severity = reporting.save()
+ print("[INFO] Saved status_report.json")
+ print(f"[INFO] Exiting with status: {severity.name}")
+ exit(severity.value)
'''
def print_SCNGen(int num_tests, int depth_limit, int state_limit) '''
diff --git a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/ProductGenerator.xtend b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/ProductGenerator.xtend
index 6b2eee2e..9c37e836 100644
--- a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/ProductGenerator.xtend
+++ b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/ProductGenerator.xtend
@@ -174,9 +174,9 @@ class ProductGenerator extends AbstractGenerator {
init_places, depth_limit, state_limit, num_tests, sutTransitionMap
))
fsa.generateFile('CPNServer//' + specName + '//' + specName + '_Simulation.py', pnet.toSnakesSimulation)
-
- fsa.generateFile('CPNServer//' + specName + '//' + specName + '_data.py', (new Utils()).getDataContainerClass(dataGetterTxt, methodTxt))
- fsa.generateFile('CPNServer//' + specName + '//' + specName + '_TestSCN.py', (new Utils()).generateTestSCNTxt(specName + "_types", prod, resource.URI.lastSegment))
+ fsa.generateFile('CPNServer//' + specName + '//' + specName + '_reporting.py', Utils.getReportingClass(specName))
+ fsa.generateFile('CPNServer//' + specName + '//' + specName + '_data.py', Utils.getDataContainerClass(specName, dataGetterTxt, methodTxt))
+ fsa.generateFile('CPNServer//' + specName + '//' + specName + '_TestSCN.py', Utils.generateTestSCNTxt(specName + "_types", prod, resource.URI.lastSegment))
// generate utils for HTTP server
fsa.generateFile('CPNServer//' + specName + '//' + '__init__.py',
(new FlaskSimulationGenerator).generateInitForCPNSpecPkg(prod)
@@ -298,7 +298,7 @@ class ProductGenerator extends AbstractGenerator {
System.out.println(" > act: " + SnakesHelper.action(a, func))
actTxt +=
'''
- «SnakesHelper.action(a, func)»
+ «Utils.surroundWithTryCatch(a,0,SnakesHelper.action(a, func))»
'''
}
}
@@ -477,7 +477,7 @@ class ProductGenerator extends AbstractGenerator {
def generateOnlineMBTController(Product envModel, Product sutModel,
IFileSystemAccess2 fsa, IGeneratorContext context) {
- (new Utils()).generateOnlineMBTController(envModel, sutModel, fsa, context)
+ Utils.generateOnlineMBTController(envModel, sutModel, fsa, context)
}
static def Integer intValue(ExpressionConstantInt expr) {
diff --git a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/Utils.xtend b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/Utils.xtend
index 33aed49c..42ee785d 100644
--- a/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/Utils.xtend
+++ b/bundles/nl.asml.matala.product/src/nl/asml/matala/product/generator/Utils.xtend
@@ -15,6 +15,7 @@ package nl.asml.matala.product.generator
import java.util.ArrayList
import java.util.HashMap
import java.util.LinkedHashSet
+import java.util.List
import java.util.Set
import nl.asml.matala.product.product.Block
import nl.asml.matala.product.product.Blocks
@@ -28,9 +29,9 @@ import nl.asml.matala.product.product.SymbConstraint
import nl.asml.matala.product.product.Update
import nl.asml.matala.product.product.UpdateOutVar
import nl.asml.matala.product.product.VarRef
+import nl.esi.comma.assertthat.assertThat.DataAssertions
import nl.esi.xtext.actions.actions.AssignmentAction
import nl.esi.xtext.actions.actions.RecordFieldAssignmentAction
-import nl.esi.comma.assertthat.assertThat.DataAssertions
import nl.esi.xtext.expressions.expression.ExpressionAddition
import nl.esi.xtext.expressions.expression.ExpressionAnd
import nl.esi.xtext.expressions.expression.ExpressionAny
@@ -66,13 +67,17 @@ import nl.esi.xtext.expressions.expression.ExpressionVariable
import nl.esi.xtext.expressions.expression.ExpressionVector
import nl.esi.xtext.expressions.expression.Field
import nl.esi.xtext.expressions.expression.Variable
+import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils
import static nl.esi.xtext.common.lang.utilities.EcoreUtil3.serialize
class Utils
{
+ static val INDENT = 4
+
// Added for Asserts
dispatch def String printConstraint(DataAssertions ref) {
return printConstraint(ref.eContainer as Update) + "." + ref.name
@@ -339,7 +344,7 @@ class Utils
}
// The Python Test Scenario Generator Class
- def generateTestSCNTxt(String name, Product prod, String pSpecFile) {
+ static def generateTestSCNTxt(String name, Product prod, String pSpecFile) {
return
'''
import json
@@ -366,12 +371,13 @@ class Utils
constraint_dict = {}
tr_assert_ref_dict = {}
- def __init__(self, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
+ def __init__(self, _pspec_path, _mapTrAssert, _constraint_dict, _tr_assert_ref_dict):
self.step_list = []
self.step_dependencies = []
self.map_transition_assert = _mapTrAssert
self.constraint_dict = _constraint_dict
self.tr_assert_ref_dict = _tr_assert_ref_dict
+ self.pspec_path = _pspec_path
def generate_viz(self, idx, output_dir):
txt = "@startuml\n"
@@ -386,12 +392,12 @@ class Utils
# txt += "%s" % elm.payload
# txt += "\nend note\n"
txt += "@enduml"
-
+
fname = output_dir / f"scenario{str(idx)}.plantuml"
os.makedirs(os.path.dirname(fname), exist_ok=True)
with open(fname, 'w') as f:
f.write(txt)
-
+
# Deprecated. To be Removed. DB 03.04.2025
def recurseJson(self, items, prefix):
txt = ""
@@ -417,7 +423,7 @@ class Utils
raise TypeError('Unsupported type')
txt += f" {prefix} := {items}\n"
return txt
-
+
def printData(self, idata):
txt = ""
for k, v in idata.items():
@@ -427,10 +433,10 @@ class Utils
# for jk in j.keys():
# txt += self.recurseJson(j[jk], "%s.%s" % (k,jk))
return txt
-
+
def generateTSpec(self, idx, sutTypesList, sutVarTransitionMap, transitionQnameMap, output_dir):
txt = ""
- txt += "import \"«pSpecFile»\"\n\n"
+ txt += f"""import "{self.pspec_path}«pSpecFile»"\n\n"""
«(new Utils()).usageList(prod)»
txt += "\nabstract-test-definition\n\n"
txt += "Test-Scenario: S%s\n" % idx
@@ -564,22 +570,22 @@ class Utils
# print("%s" % elm.step_name)
# print("%s" % elm.depends_on)
# print("%s" % elm.payload)
-
-
+
+
class Step:
step_name = ""
input_data = {}
output_data = {}
output_suppress = []
is_assert = False
-
+
def __init__(self, _is_assert):
self.step_name = ""
self.input_data = {}
self.output_data = {}
self.output_suppress = []
self.is_assert = _is_assert
-
+
def compare(self, _step, mapTrAssert):
step_dep = StepDependency()
isMatched = False
@@ -610,45 +616,45 @@ class Utils
return step_dep
else:
return None
-
-
+
+
class StepDependency:
step_name = ""
depends_on = ""
var_ref = []
payload = ""
-
+
def __init__(self):
self.step_name = ""
self.depends_on = ""
self.var_ref = []
self.payload = ""
-
-
+
+
class Constraint:
var_ref = ""
dir = ""
centry = []
-
+
def __init__(self, v, d, ce):
self.var_ref = v
self.dir = d
self.centry = ce
-
-
+
+
class CEntry:
name = ""
constr = ""
-
+
+
def __init__(self, n, c):
self.name = n
self.constr = c
-
'''
}
- def toTypes(String class_name, ArrayList import_list, HashMap var_decl_map) {
+ static def toTypes(String class_name, ArrayList import_list, HashMap var_decl_map) {
'''
class Types:
def __init__(self):
@@ -657,14 +663,17 @@ class Utils
'''
}
- def getDataContainerClass(String dataGetterTxt, String methodTxt)
+ static def getDataContainerClass(String prod_name, String dataGetterTxt, String methodTxt)
{
// var data_container_class =
return
'''
import copy
import json
-
+ if __package__ is None or __package__ == '':
+ from «prod_name»_reporting import get_reporting, Location
+ else:
+ from .«prod_name»_reporting import get_reporting, Location
class Data:
@@ -685,7 +694,7 @@ class Utils
}
- def generateOnlineMBTController(Product envModel, Product sutModel,
+ static def generateOnlineMBTController(Product envModel, Product sutModel,
IFileSystemAccess2 fsa, IGeneratorContext context
) {
var txt =
@@ -795,6 +804,231 @@ class Utils
fsa.generateFile('OnlineMBT_Controller.py', txt)
}
+
+ static def getReportingClass(String name)
+ {
+ return
+ '''
+ import json
+ import traceback
+ from enum import Enum
+ from typing import List, Optional, Dict, Any
+ from dataclasses import dataclass, field
+ from pathlib import Path
+
+ class StatusException(Exception):
+ def __init__(self, message: str):
+ super().__init__(message)
+
+ class Severity(Enum):
+ OK = 0
+ INFO = 1
+ WARNING = 2
+ ERROR = 3
+ CANCEL = 4
+
+ @dataclass
+ class Location:
+ startLine: int
+ endLine: int
+ offset: int
+ length: int
+ text: str
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'startLine': self.startLine,
+ 'endLine': self.endLine,
+ 'offset': self.offset,
+ 'length': self.length,
+ 'text': self.text,
+ }
+
+ @dataclass
+ class StatusReport:
+ plugin: str
+ severity: Severity
+ message: str
+ source: str = ""
+ code: int = 0
+ details: Optional[str] = None
+ location: Optional[Location] = None
+ children: List['StatusReport'] = field(default_factory=list)
+ exception: Optional[Exception] = field(default=None, repr=False)
+
+ def __post_init__(self):
+ if self.exception is not None:
+ if self.details is None:
+ self.details = self._get_stack_trace_as_string(self.exception)
+ self.exception = None # Don't retain non-serializable object
+
+ if self.children:
+ child_severities = [child.severity for child in self.children if child is not None]
+ if child_severities:
+ max_child_severity = max(child_severities, key=lambda s: s.value)
+ if max_child_severity.value > self.severity.value:
+ self.severity = max_child_severity
+
+ @staticmethod
+ def _get_stack_trace_as_string(exception: Exception) -> str:
+ if exception is None:
+ return None
+ tb_lines = traceback.format_exception(type(exception), exception, exception.__traceback__)
+ if len(tb_lines) > 15:
+ tb_lines = tb_lines[:15] + [f"\t... {len(tb_lines) - 15} more\n"]
+ return "".join(tb_lines)
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ 'plugin': self.plugin,
+ 'severity': self.severity.name,
+ 'message': self.message,
+ 'source': self.source,
+ 'code': self.code,
+ 'details': self.details,
+ 'location': self.location.to_dict() if self.location else None,
+ 'children': [child.to_dict() for child in self.children if child is not None],
+ }
+
+ class StatusReporting:
+ def __init__(self, save_path: str):
+ self.save_path = Path(save_path)
+ self.reports: List[StatusReport] = []
+
+ def _log(self, severity: Severity, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, exception: Optional[Exception] = None, location: Optional[Location] = None) -> StatusReport:
+ report = StatusReport(
+ plugin="",
+ severity=severity,
+ message=message,
+ source=source,
+ code=code,
+ details=details,
+ location=location,
+ exception=exception
+ )
+ self.reports.append(report)
+ return report
+
+ def info(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.INFO, message, source, code, details, None, location)
+
+ def warning(self, message: str, source: str = "", code: int = 0, details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.WARNING, message, source, code, details, None, location)
+
+ def error(self, message: str, source: str = "", code: int = 0,
+ details: Optional[str] = None, location: Location = None) -> StatusReport:
+ return self._log(Severity.ERROR, message, source, code, details, None, location)
+
+ def exception(self, message: str, exception: Exception, source: str = "", details: str = None, code: int = 0, location: Location = None) -> StatusReport:
+ self._log(Severity.ERROR, message, source, code, details, exception, location)
+ #on exception the process is stopped
+ raise StatusException(message)
+
+ def save(self) -> Severity:
+
+ root_severity = Severity.OK
+ if self.reports:
+ root_severity = max((report.severity for report in self.reports), key=lambda s: s.value)
+
+ root_report = StatusReport(
+ plugin="",
+ severity=root_severity,
+ message=f"Python generation of «name»",
+ source="",
+ code=0,
+ details=None,
+ location=None,
+ children=self.reports,
+ exception=None
+ )
+
+ data = root_report.to_dict()
+ with open(self.save_path, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return root_severity
+
+
+ _status_reporting_instance: Optional[StatusReporting] = None
+
+ def initialize_reporting(save_path: str) -> StatusReporting:
+ global _status_reporting_instance
+ _status_reporting_instance = StatusReporting(save_path)
+ return _status_reporting_instance
+
+ def get_reporting() -> StatusReporting:
+ global _status_reporting_instance
+ if _status_reporting_instance is None:
+ raise RuntimeError("StatusReporting not initialized. Call initialize_reporting() first.")
+ return _status_reporting_instance
+ '''
+ }
+
+
+ static def String surroundWithTryCatch(EObject ref, int depth, String txt) {
+ var indent = " ".repeat(depth * INDENT)
+ var nextIndent = " ".repeat((depth + 1) * INDENT)
+ var sourceLocation = getSourceLocation(ref).replace("\n", "\n" + nextIndent)
+ var body = txt.trim().replace("\n", "\n" + nextIndent)
+
+ var result = String.join("\n",
+ indent + "try:",
+ nextIndent + body,
+ indent + "except Exception as e:",
+ nextIndent + sourceLocation,
+ nextIndent + "get_reporting().exception(str(e), e, details=__location.text, source=__source_file, location=__location)",
+ ""
+ )
+ return result
+ }
+
+ static def String getSourceLocation(EObject action) {
+ var List result = new ArrayList()
+
+ var node = NodeModelUtils.getNode(action)
+
+ if (node !== null) {
+ var text = node.getText()
+ // Escape for Python and limit to 50 chars
+ text = escapeAndLimitText(text, 500)
+ var locationStr = "__location = Location(" + node.getStartLine() + "," + node.getEndLine() + "," +
+ node.getOffset() + "," + node.getLength() + ",\"" + text + "\")"
+ result.add(locationStr)
+ }
+ if (action.eResource() !== null) {
+ result.add("__source_file = \"" + action.eResource().getURI().lastSegment() +'"')
+ }
+
+ // Try to get the line number from the ILocationData if available
+ // This depends on your setup - you may need to adjust based on your EMF configuration
+
+ return String.join("\n", result)
+ }
+
+ static def String escapeAndLimitText(String text, int limit) {
+ if (text === null) {
+ return ""
+ }
+
+ // Escape special characters for Python
+ var escaped = text.trim()
+ .replaceAll("\\s+", " ")
+ .replace("\\", "\\\\")
+ .replace("\"", "\\\"")
+ .replace("\n", "")
+ .replace("\r", "")
+ .replace("\t", " ")
+
+ // Limit to specified length with "..." suffix if truncated
+ if (escaped.length() > limit) {
+ escaped = escaped.substring(0, limit - 3) + "..."
+ }
+
+ return escaped
+ }
+
+
// /* TODO Is this deprecated? Who is using this? Commented DB 16.03.2025 */
// def Map recurseTypes(Type typ) {
// var constructors = newLinkedHashMap()
@@ -815,4 +1049,5 @@ class Utils
// }
// return constructors
// }
+
}
\ No newline at end of file
diff --git a/bundles/nl.esi.comma.project.standard.cli/META-INF/MANIFEST.MF b/bundles/nl.esi.comma.project.standard.cli/META-INF/MANIFEST.MF
index a5c3a3fb..87e693dc 100644
--- a/bundles/nl.esi.comma.project.standard.cli/META-INF/MANIFEST.MF
+++ b/bundles/nl.esi.comma.project.standard.cli/META-INF/MANIFEST.MF
@@ -5,6 +5,8 @@ Bundle-SymbolicName: nl.esi.comma.project.standard.cli
Bundle-Vendor: TNO-ESI
Bundle-Version: 4.2.0.qualifier
Export-Package: nl.esi.comma.project.standard.cli
+Import-Package: io.github.classgraph;version="[4.8.0,5.0.0)",
+ org.aopalliance.intercept;version="1.0.0"
Require-Bundle: nl.esi.comma.project.standard;visibility:=reexport,
com.google.inject,
org.eclipse.xtext.ide,
diff --git a/bundles/nl.esi.comma.project.standard.cli/dist/.vscode/launch.json b/bundles/nl.esi.comma.project.standard.cli/dist/.vscode/launch.json
index db150ecc..1111034d 100644
--- a/bundles/nl.esi.comma.project.standard.cli/dist/.vscode/launch.json
+++ b/bundles/nl.esi.comma.project.standard.cli/dist/.vscode/launch.json
@@ -8,7 +8,7 @@
"request": "launch",
"program": "server/CPNServer.py",
"console": "integratedTerminal",
- "args": ["--web-path", "/bpmn4s-editor/bpmn4s-editor/public", "--server-path", "${workspaceFolder}/../target/dist/server", "--debug"],
+ "args": ["--web-path", "/bpmn4s-editor/bpmn4s-editor/public", "--server-path", "${workspaceFolder}/../target/dist/server", "--repository-path", "${workspaceFolder}/../target/dist/models", "--debug"],
"cwd": "${workspaceFolder}"
}
,
diff --git a/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNServer.py b/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNServer.py
index bb78fc78..c522d6b2 100644
--- a/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNServer.py
+++ b/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNServer.py
@@ -77,6 +77,7 @@ def format(self, record):
BPMN4S_GEN = os.path.join(SERVER_PATH, BPMN4S_JAR_NAME)
JAVA_REL_PATH = ("jre", "bin", "java.exe")
JAVA_PATH = os.path.join(SERVER_PATH, *JAVA_REL_PATH)
+JAVA_DEBUG_PORT_LSP = 4000
SYS_TEMP = tempfile.gettempdir()
BPMN4S_TEMP = os.path.join(SYS_TEMP,'bpmn4s')
@@ -130,6 +131,7 @@ async def lifespan(app: FastAPI):
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
+ expose_headers=["Content-Disposition"],
)
def build_and_load_model(model_path:str):
@@ -199,21 +201,29 @@ def generate_tests( model_path:str, num_tests:int=1, depth_limit:int=500, state_
logger.debug("generate_tests stdout: %s", result.stdout.decode('utf-8', errors='replace').rstrip())
if result.stderr:
logger.debug("generate_tests stderr: %s", result.stderr.decode('utf-8', errors='replace').rstrip())
- if result.returncode != 0:
- raise utils.BPMN4SException(
- cliargs={
- 'bpmn-file': model_name,
- 'num-tests': num_tests,
- 'depth-limit': depth_limit,
- 'state-limit': state_limit
- },
- result=result
- )
+ cli_args= {
+ 'bpmn-file': model_name,
+ 'num-tests': num_tests,
+ 'depth-limit': depth_limit,
+ 'state-limit': state_limit,
+ }
+
# zip filename (without .zip extension)
zip_filename = os.path.join(model_dir,model_name)
+ # path to root folder
+ root_dir = os.path.join(model_dir,'src-gen')
# path to directory about to be zipped
- output_dir = os.path.join(model_dir,'src-gen',taskname)
+ output_dir = os.path.join(root_dir,taskname)
+ os.makedirs(output_dir, exist_ok=True)
+ # the backend generates a report folder in the root_dir (doesn't know taskname), we need to move it to the output_dir
+ report_path = os.path.join(output_dir, 'report')
+ os.rename(os.path.join(root_dir,'report'), report_path)
+ # store results in the report dir
+ utils.store_results(report_path, result, cli_args)
+
+ write_status_report_html(output_dir, report_path)
+
# store bpmn and prj files in bpmn directory
bpmn_dir = os.path.join(output_dir,'bpmn')
os.makedirs(bpmn_dir, exist_ok=True)
@@ -228,6 +238,29 @@ def generate_tests( model_path:str, num_tests:int=1, depth_limit:int=500, state_
logger.error(f"An error occurred while deleting generated test: {str(e)}", file=sys.stderr)
return zip_filename, result
+def write_status_report_html(output_dir, report_path):
+ """Write a self-contained status report HTML file to the output directory.
+
+ Reads the `status_report.html` template from `WEB_PATH` and embeds the
+ contents of `StatusReport.json` from `report_path` into it. The generated
+ file is fully self-contained, so it can be opened directly from the zip
+ archive without cross-origin or path issues.
+
+ Silently logs a warning if the HTML file cannot be written, but does not raise an exception.
+ """
+ try:
+ status_report_html = os.path.join(WEB_PATH, "status_report.html")
+ #read as string
+ with open(status_report_html, "r") as html_file:
+ status_report_html_str = html_file.read()
+ with open(os.path.join(report_path, "StatusReport.json"), "r") as status_report_json:
+ status_report_json_str = status_report_json.read()
+ status_report_html_str = status_report_html_str.replace("!__STATUS_REPORT_JSON__!", status_report_json_str)
+ with open(os.path.join(output_dir, "status_report.html"), "w") as output_html_file:
+ output_html_file.write(status_report_html_str)
+ except Exception as e:
+ logger.warning("Could not write status report HTML")
+
# The endpoint of our FastAPI app
@app.post("/BPMNParser")
async def handle_bpmn(bpmn_file: UploadFile = File(alias="bpmn-file")):
@@ -639,6 +672,17 @@ def find_free_port() -> Optional[int]:
logger.error(f"Failed to find free port: {e}")
return None
+ def ensure_port_available(port: int, purpose: str) -> bool:
+ """Return whether a fixed port needed for debugging is available."""
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.bind(("127.0.0.1", port))
+ s.close()
+ return True
+ except OSError:
+ logger.warning(f"Port {port} is not available for {purpose}; continuing without Java debugging.")
+ return False
+
lsp_port = find_free_port()
if lsp_port is None:
logger.error("Failed to find an available port for LSP subprocess. Please check your system resources.")
@@ -657,6 +701,15 @@ def find_free_port() -> Optional[int]:
# Start Java ServerLauncher which runs both LSP and REST servers
lsp_command = [
JAVA_PATH,
+ ]
+
+ if args.debug and ensure_port_available(JAVA_DEBUG_PORT_LSP, "the Java LSP debug agent"):
+ lsp_command.append(
+ f"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:{JAVA_DEBUG_PORT_LSP}"
+ )
+ logger.info(f"Java debug agent listening on 127.0.0.1:{JAVA_DEBUG_PORT_LSP}")
+
+ lsp_command.extend([
"-cp",
BPMN4S_GEN,
"nl.asml.matala.server.ServerLauncher",
@@ -666,7 +719,7 @@ def find_free_port() -> Optional[int]:
str(REST_PORT),
"--repository-path",
REPOSITORY_PATH_ARG,
- ]
+ ])
logger.debug(f"LSP command: {' '.join(lsp_command)}")
logger.debug(f"Using JAVA_PATH: {JAVA_PATH}")
diff --git a/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNUtils.py b/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNUtils.py
index 13ff927f..96d4dd98 100644
--- a/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNUtils.py
+++ b/bundles/nl.esi.comma.project.standard.cli/dist/server/CPNUtils.py
@@ -11,6 +11,8 @@
# SPDX-License-Identifier: MIT
#
+import json
+import os
import re
from subprocess import CompletedProcess
import typing, types
@@ -18,10 +20,21 @@
import importlib.util
import glob
import datetime
+from dataclasses import dataclass
+from dataclasses_json import dataclass_json
from abc import ABC, abstractmethod
from threading import Lock
+@dataclass_json
+@dataclass
+class BPMN4SResult():
+ cliargs: dict
+ returncode: int
+ stdout: str
+ stderr: str
+
+
class BPMN4SException(Exception):
def __init__(self,cliargs:dict, result: CompletedProcess[bytes], *args):
super().__init__(*args)
@@ -31,6 +44,23 @@ def __init__(self,cliargs:dict, result: CompletedProcess[bytes], *args):
self.stderr = result.stderr.decode('utf-8').replace('\r\n','\n')
self.returncode = result.returncode
+def store_results( output_dir: str, result : CompletedProcess[bytes], cli_args: dict):
+ process={
+ 'args': cli_args,
+ 'result': {
+ 'return-code': result.returncode
+ }
+ }
+ result_stdout_path = os.path.join(output_dir, 'stdout.txt')
+ with open(result_stdout_path, "w") as file:
+ file.write(result.stdout.decode('utf-8').replace('\r\n','\n'))
+ result_stderr_path = os.path.join(output_dir, 'stderr.txt')
+ with open(result_stderr_path, "w") as file:
+ file.write(result.stderr.decode('utf-8').replace('\r\n','\n'))
+ result_process_path = os.path.join(output_dir, 'process.json')
+ with open(result_process_path, "w") as file:
+ file.write(json.dumps(process, indent=4))
+
class AbstractCPNControl(ABC):
diff --git a/bundles/nl.esi.comma.project.standard.cli/dist/server/requirements.txt b/bundles/nl.esi.comma.project.standard.cli/dist/server/requirements.txt
index 6c01778c..1fd46845 100644
--- a/bundles/nl.esi.comma.project.standard.cli/dist/server/requirements.txt
+++ b/bundles/nl.esi.comma.project.standard.cli/dist/server/requirements.txt
@@ -4,4 +4,5 @@ fastapi
uvicorn[standard]
websockets
python-multipart
-httpx
\ No newline at end of file
+httpx
+dataclasses_json
\ No newline at end of file
diff --git a/bundles/nl.esi.comma.project.standard.ui/src/nl/esi/comma/project/standard/ui/StandardProjectUiModule.xtend b/bundles/nl.esi.comma.project.standard.ui/src/nl/esi/comma/project/standard/ui/StandardProjectUiModule.xtend
index bc6b112b..f6cec7a7 100644
--- a/bundles/nl.esi.comma.project.standard.ui/src/nl/esi/comma/project/standard/ui/StandardProjectUiModule.xtend
+++ b/bundles/nl.esi.comma.project.standard.ui/src/nl/esi/comma/project/standard/ui/StandardProjectUiModule.xtend
@@ -15,22 +15,41 @@
*/
package nl.esi.comma.project.standard.ui
+import nl.esi.xtext.common.lang.reporting.IStatusReporting
+import nl.esi.xtext.common.lang.reporting.StatusReportingEclipseRuntime
import nl.esi.xtext.types.ui.contentassist.XPlusHyperLinkDetector
import org.eclipse.core.runtime.Platform
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector
-import org.eclipse.ui.plugin.AbstractUIPlugin
+import com.google.inject.Provides
+import org.eclipse.core.runtime.Plugin
+import nl.esi.comma.project.standard.ui.internal.StandardActivator
/**
* Use this class to register components to be used within the Eclipse IDE.
*/
class StandardProjectUiModule extends AbstractStandardProjectUiModule {
- new(AbstractUIPlugin plugin) {
+
+ final StandardActivator plugin
+
+ new(StandardActivator plugin) {
super(plugin)
+ this.plugin = plugin
Platform.getBundle("org.eclipse.debug.ui").start
}
override Class extends IHyperlinkDetector> bindIHyperlinkDetector() {
return XPlusHyperLinkDetector
}
+
+ @Provides
+ def Plugin providePlugin() {
+ return this.plugin;
+ }
+
+ def Class extends IStatusReporting> bindIStatusReporter() {
+ return StatusReportingEclipseRuntime
+ }
+
+
}
diff --git a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/StandardProjectRuntimeModule.xtend b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/StandardProjectRuntimeModule.xtend
index 9c9d0df1..4d1bf9fc 100644
--- a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/StandardProjectRuntimeModule.xtend
+++ b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/StandardProjectRuntimeModule.xtend
@@ -21,6 +21,8 @@ import nl.esi.xtext.expressions.functions.ExpressionFunctionLibrariesProvider
import nl.esi.xtext.expressions.functions.IExpressionFunctionLibrariesProvider
import nl.esi.xtext.expressions.scoping.ExpressionsImportUriGlobalScopeProvider
import org.eclipse.xtext.scoping.IGlobalScopeProvider
+import nl.esi.xtext.common.lang.reporting.StatusReportCollector
+import nl.esi.xtext.common.lang.reporting.IStatusReporting
/**
* Use this class to register components to be used at runtime / without the Equinox extension registry.
@@ -39,4 +41,8 @@ class StandardProjectRuntimeModule extends AbstractStandardProjectRuntimeModule
return ExpressionConvertersProvider
}
+ def Class extends IStatusReporting> bindIStatusReporter() {
+ return StatusReportCollector
+ }
+
}
diff --git a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/PetriNetToAbstractTspecGenerator.xtend b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/PetriNetToAbstractTspecGenerator.xtend
index b8eee822..65cb3a1d 100644
--- a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/PetriNetToAbstractTspecGenerator.xtend
+++ b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/PetriNetToAbstractTspecGenerator.xtend
@@ -14,7 +14,12 @@ package nl.esi.comma.project.standard.generator
import java.io.BufferedReader
import java.io.PrintStream
+import java.nio.file.Files
+import java.nio.file.Path
import java.util.concurrent.TimeUnit
+import nl.esi.xtext.common.lang.reporting.IStatusReporting
+import nl.esi.xtext.common.lang.reporting.Severity
+import nl.esi.xtext.common.lang.reporting.StatusReportHelper
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
@@ -24,16 +29,16 @@ import org.eclipse.xtext.generator.IGeneratorContext
import static extension nl.esi.xtext.common.lang.generator.FileSystemAccessUtil.*
import static extension nl.esi.xtext.common.lang.utilities.EcoreUtil3.*
+import static extension nl.esi.comma.project.standard.generator.^extension.IStandardProjectGeneratorExtension.FOLDER_PSPEC
class PetriNetToAbstractTspecGenerator extends AbstractGenerator {
+
+ val IStatusReporting reporting;
val String pythonExe;
- new() {
- this(null)
- }
-
- new(String pythonExe) {
+ new(String pythonExe, IStatusReporting reporting) {
this.pythonExe = pythonExe ?: 'python.exe'
+ this.reporting = reporting
}
override doGenerate(Resource res, IFileSystemAccess2 fsa, IGeneratorContext ctx) {
@@ -41,19 +46,25 @@ class PetriNetToAbstractTspecGenerator extends AbstractGenerator {
}
def void doGenerate(ResourceSet rst, URI uri, IFileSystemAccess2 fsa, IGeneratorContext ctx) {
+ val statusReportFile = fsa.rootURI.appendSegment("status_report.json").toPath
val process = Runtime.getRuntime().exec(#[
pythonExe,
uri.toPath,
'-no_sim=TRUE',
'-tsdir=' + fsa.rootURI.toPath,
- '-pudir=' + fsa.getURI('plantuml').toPath
+ '-pudir=' + fsa.getURI('plantuml').toPath,
+ '-srfile=' + statusReportFile,
+ '-pspath=' + '../'+ FOLDER_PSPEC+'/'
])
process.inputReader.pipeTo(System.out)
process.errorReader.pipeTo(System.err)
if (!process.waitFor(10, TimeUnit::MINUTES)) {
process.destroyForcibly
throw new RuntimeException('Python process did not end in time')
- } else if (process.exitValue != 0) {
+ }
+ val report = StatusReportHelper.fromJson(Files.readString(Path.of(statusReportFile)))
+ reporting.addReport(report)
+ if (Severity.fromValue(process.exitValue).isError) {
throw new RuntimeException(
'''Python process exited with exit code «process.exitValue», see error output for details.''')
}
diff --git a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/StandardProjectGenerator.xtend b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/StandardProjectGenerator.xtend
index 7712cf21..4e6cf1ab 100644
--- a/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/StandardProjectGenerator.xtend
+++ b/bundles/nl.esi.comma.project.standard/src/nl/esi/comma/project/standard/generator/StandardProjectGenerator.xtend
@@ -27,14 +27,17 @@ import nl.esi.comma.project.standard.standardProject.OfflineGenerationTarget
import nl.esi.comma.project.standard.standardProject.Project
import nl.esi.comma.project.standard.standardProject.TargetConfig
import nl.esi.comma.testspecification.generator.utils.MergeConcreteDataAssigments
-import nl.esi.xtext.common.lang.base.Import
+import nl.esi.xtext.common.lang.reporting.IStatusReporting
+import nl.esi.xtext.common.lang.reporting.StatusReportHelper
+import nl.esi.xtext.common.lang.utilities.EcoreUtil3
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.xtext.generator.AbstractGenerator
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
-import static nl.esi.comma.project.standard.generator.^extension.IStandardProjectGeneratorExtension.*;
+import static nl.esi.comma.project.standard.generator.^extension.IStandardProjectGeneratorExtension.*
+
import static extension nl.esi.xtext.common.lang.generator.FileSystemAccessUtil.*
import static extension nl.esi.xtext.common.lang.utilities.EcoreUtil3.*
import static extension org.eclipse.emf.ecore.util.EcoreUtil.*
@@ -49,6 +52,9 @@ class StandardProjectGenerator extends AbstractGenerator {
@Inject
IStandardProjectGeneratorExtension.Registry generatorExtensions;
+ @Inject
+ IStatusReporting reporting;
+
override doGenerate(Resource res, IFileSystemAccess2 fsa, IGeneratorContext ctx) {
for (project : res.contents.filter(Project)) {
for (task : project.offlineBlocks) {
@@ -83,9 +89,11 @@ class StandardProjectGenerator extends AbstractGenerator {
throw new Exception('No product found in resource: ' + productURI)
}
productRes.resolveAll()
- product.imports.forEach[productRes.getResource(importURI).validate()]
- productRes.validate()
-
+ //validate but stop on the first error
+ var error = product.imports.map[productRes.getResource(importURI).validate].findFirst[it]!==null
+ if (error || productRes.validate){
+ return
+ }
// PspecToPetriNetGenerator
// Generate CPNServer (a.k.a. abstract Tspec generator) and Petri-nets
(new ProductGenerator).doGenerate(productRes, fsa, ctx)
@@ -98,44 +106,42 @@ class StandardProjectGenerator extends AbstractGenerator {
val specName = product.specification.name
val petriNetURI = fsa.getURI('''«FOLDER_CPN_SERVER»/«specName»/«specName».py''')
val absTspecFsa = fsa.createFolderAccess(FOLDER_ABSTRACT_TSPEC)
- (new PetriNetToAbstractTspecGenerator(task.pythonExe)).doGenerate(rst, petriNetURI, absTspecFsa, ctx)
+ (new PetriNetToAbstractTspecGenerator(task.pythonExe, reporting)).doGenerate(rst, petriNetURI, absTspecFsa, ctx)
for (absTspecFileName : absTspecFsa.list(ROOT_PATH).filter[endsWith('.atspec')]) {
val tspecName = absTspecFileName.replaceAll('\\.atspec$', '')
val absTspecRes = absTspecFsa.loadResource(absTspecFileName, rst)
- // Fix the pspec import
- val productImportURI = productURI.deresolve(absTspecRes.URI)
- absTspecRes.allContents.filter(Import).filter[importURI == productURI.lastSegment].forEach [
- importURI = productImportURI.toString
- ]
- absTspecRes.save(null)
- // Validate the generated abstract tspec
- absTspecRes.validate()
-
- // Generate concrete tspec
- val conTspecFsa = fsa.createFolderAccess(FOLDER_CONCRETE_TSPEC + '/' + tspecName)
- val fromAbstractToConcreteGen = new FromAbstractToConcrete()
- fromAbstractToConcreteGen.doGenerate(absTspecRes, conTspecFsa, ctx)
-
- val conTspecFileName = tspecName + '.tspec'
- val conTspecRes = conTspecFsa.loadResource(conTspecFileName, rst)
- MergeConcreteDataAssigments.transform(conTspecRes)
- conTspecRes.save(null)
- conTspecRes.validate()
-
- // TODO fetch these FAST configuration parameters from somewhere else (e.g., .prj task)
- val renamingRules = task.renamingRules !== null ? createPropertiesMap(task.renamingRules) : new HashMap
- val genParams = task.generatorParams !== null ? createPropertiesMap(task.generatorParams) : new HashMap
- // TODO fetch this from somewhere else
- genParams.putIfAbsent('prefixPath', './vfab2_scenario/FAST/testcases/' + specName + '_' + tspecName + '/')
-
- val extensionContext = new StandardProjectGeneratorContext(ctx?.cancelIndicator, renamingRules, genParams)
- generatorExtensions.forEach[doGenerate(conTspecRes, fsa, extensionContext)]
+ // Validate the generated abstract tspec, stop this transformation on error
+ val absTspecValid = !absTspecRes.validate
+ if (absTspecValid) {
+ // Generate concrete tspec
+ val conTspecFsa = fsa.createFolderAccess(FOLDER_CONCRETE_TSPEC + '/' + tspecName)
+ val fromAbstractToConcreteGen = new FromAbstractToConcrete()
+ fromAbstractToConcreteGen.doGenerate(absTspecRes, conTspecFsa, ctx)
+
+ val conTspecFileName = tspecName + '.tspec'
+ val conTspecRes = conTspecFsa.loadResource(conTspecFileName, rst)
+
+ MergeConcreteDataAssigments.transform(conTspecRes)
+ val conTspecValid = !conTspecRes.validate
+ trySave(conTspecRes)
+ // Validate the generated conctete tspec, stop this transformation on error
+ if (conTspecValid){
+ // TODO fetch these FAST configuration parameters from somewhere else (e.g., .prj task)
+ val renamingRules = task.renamingRules !== null ? createPropertiesMap(task.renamingRules) : new HashMap
+ val genParams = task.generatorParams !== null ? createPropertiesMap(task.generatorParams) : new HashMap
+ // TODO fetch this from somewhere else
+ genParams.putIfAbsent('prefixPath', './vfab2_scenario/FAST/testcases/' + specName + '_' + tspecName + '/')
+
+ val extensionContext = new StandardProjectGeneratorContext(ctx?.cancelIndicator, renamingRules, genParams)
+ generatorExtensions.forEach[ doGenerate(conTspecRes, fsa, extensionContext)]
+ }
+ }
}
}
- def createPropertiesMap(TargetConfig tgtConfig) {
+ private def createPropertiesMap(TargetConfig tgtConfig) {
var props = new HashMap()
for (elem : tgtConfig.item) {
props.put(elem.key, elem.^val)
@@ -143,4 +149,24 @@ class StandardProjectGenerator extends AbstractGenerator {
return props
}
+ private def trySave( Resource resource) {
+ try {
+ //try to test serialize the file first as it sweeps the file on save
+ resource.contents.forEach[EcoreUtil3.serialize(it)]
+ resource.save(null)
+ }
+ catch(Exception e) {
+ reporting.addReport(e)
+ }
+ }
+ /**
+ * validates the resource
+ * returns true when error
+ */
+ private def boolean validate(Resource resource) {
+ val result = StatusReportHelper.validate(resource)
+ reporting.addReport(result)
+ return result.error
+ }
}
+
diff --git a/releng/nl.esi.comma.target/nl.esi.comma.target.target b/releng/nl.esi.comma.target/nl.esi.comma.target.target
index 9cbe2f92..45e47bc1 100644
--- a/releng/nl.esi.comma.target/nl.esi.comma.target.target
+++ b/releng/nl.esi.comma.target/nl.esi.comma.target.target
@@ -95,7 +95,7 @@
-
+