Skip to content

Commit 8211ad0

Browse files
committed
Added option to specify timeout
For #495
1 parent 3dcd7e1 commit 8211ad0

File tree

1 file changed

+77
-21
lines changed

1 file changed

+77
-21
lines changed

buildingspy/development/regressiontest.py

+77-21
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ def _verify_model_exists(model_name):
12011201

12021202
if self._modelica_tool == 'dymola':
12031203
for ent in self._data:
1204-
ent['dymola']['time_out'] = 300
1204+
ent['dymola']['time_out'] = 10 #fixme 300
12051205
else: # Non-dymola
12061206
def_dic = {}
12071207
def_dic[self._modelica_tool] = {
@@ -1441,7 +1441,7 @@ def _getDymolaTranslationStatistics(self, data, warnings, errors):
14411441
:param warning: A list to which all warnings will be appended.
14421442
:param errors: A list to which all errors will be appended.
14431443
:return: The translation log from the `*.translation.log` file as
1444-
a list of dictionaries.
1444+
a list of dictionaries, or `None` if `*.translation.log` does not exist.
14451445
14461446
Extracts and returns the translation log from the `*.translation.log` file as
14471447
a list of dictionaries.
@@ -1450,7 +1450,10 @@ def _getDymolaTranslationStatistics(self, data, warnings, errors):
14501450
# Get the working directory that contains the ".log" file
14511451
fulFilNam = os.path.join(data['ResultDirectory'],
14521452
self.getLibraryName(), data['dymola']['TranslationLogFile'])
1453-
return of.get_model_statistics(fulFilNam, self._modelica_tool)
1453+
if os.path.exists(fulFilNam):
1454+
return of.get_model_statistics(fulFilNam, self._modelica_tool)
1455+
else:
1456+
return None
14541457

14551458
def _legacy_comp(self, tOld, yOld, tNew, yNew, tGriOld, tGriNew, varNam, filNam, tol):
14561459
# Interpolate the new variables to the old time stamps
@@ -2898,23 +2901,28 @@ def _checkSimulationError(self, errorFile):
28982901
else:
28992902
key = 'FMUExport'
29002903

2904+
logFil = None
29012905
if key in ele:
2902-
logFil = ele[key]["translationLog"]
2903-
ele[key] = self._performTranslationErrorChecks(logFil, ele[key])
2904-
for k, v in list(self._error_dict.get_dictionary().items()):
2905-
# For OPTIMICA, we neither have simulate nor FMUExport
2906-
if ele[key][k] > 0:
2907-
self._reporter.writeWarning(v["model_message"].format(ele[key]["command"]))
2908-
self._error_dict.increment_counter(k)
2909-
2910-
if hasTranslationError:
2911-
hasTranslationErrors = True
2906+
if "translationLog" in ele[key]:
2907+
logFil = ele[key]["translationLog"]
2908+
ele[key] = self._performTranslationErrorChecks(logFil, ele[key])
2909+
for k, v in list(self._error_dict.get_dictionary().items()):
2910+
# For OPTIMICA, we neither have simulate nor FMUExport
2911+
if ele[key][k] > 0:
2912+
self._reporter.writeWarning(v["model_message"].format(ele[key]["command"]))
2913+
self._error_dict.increment_counter(k)
2914+
2915+
if hasTranslationError and logFil is not None:
29122916
with open(self._failed_simulator_log_file, "a") as f:
29132917
f.write("===============================\n")
29142918
f.write("=====START OF NEW LOG FILE=====\n")
29152919
f.write("===============================\n")
2916-
with open(logFil, "r") as f2:
2917-
f.write(f2.read())
2920+
if os.path.exists(logFil):
2921+
with open(logFil, "r") as f2:
2922+
f.write(f2.read())
2923+
else:
2924+
# Logfile does not exists, which may be because simulation was terminated due to time out
2925+
f.write(f"Log file {logFil} does not exist, this can happen if the process was terminated due to time out.")
29182926
f.write("\n\n\n")
29192927

29202928
if iChe > 0:
@@ -3717,6 +3725,13 @@ def _setTemporaryDirectories(self):
37173725
def _run_simulation_info(self):
37183726
""" Extract simulation data from statistics.json when run unit test with dymola
37193727
"""
3728+
3729+
def _get(model, key, data):
3730+
for ent in data:
3731+
if ent['model_name'] == model:
3732+
return ent[key]
3733+
return 0
3734+
37203735
with open(self._statistics_log, 'r') as f:
37213736
staVal = simplejson.loads(f.read())
37223737
data = []
@@ -3731,11 +3746,11 @@ def _run_simulation_info(self):
37313746
temp = {}
37323747
temp['model'] = case['model']
37333748
temp['simulation'] = {}
3734-
temp['simulation']['elapsed_time'] = case['simulate']['elapsed_time']
3735-
temp['simulation']['start_time'] = case['simulate']['start_time']
3736-
temp['simulation']['final_time'] = case['simulate']['final_time']
3737-
temp['simulation']['jacobians'] = case['simulate']['jacobians']
3738-
temp['simulation']['state_events'] = case['simulate']['state_events']
3749+
temp['simulation']['elapsed_time'] = case['simulate']['elapsed_time'] if 'elapsed_time' in case['simulate'] else 0
3750+
temp['simulation']['start_time'] = case['simulate']['start_time'] if 'start_time' in case['simulate'] else _get(case['model'], 'startTime', self._data)
3751+
temp['simulation']['final_time'] = case['simulate']['final_time'] if 'final_time' in case['simulate'] else _get(case['model'], 'stopTime', self._data)
3752+
temp['simulation']['jacobians'] = case['simulate']['jacobians'] if 'jacobians' in case['simulate'] else 0
3753+
temp['simulation']['state_events'] = case['simulate']['state_events'] if 'state_events' in case['simulate'] else 0
37393754
temp['simulation']['success'] = case['simulate']['result']
37403755
data.append(temp)
37413756
dataJson = simplejson.dumps(data)
@@ -3889,9 +3904,50 @@ def run(self):
38893904
# Iterate over all test cases of this output file
38903905
for ele in cas:
38913906
stat.append(ele)
3907+
except json.decoder.JSONDecodeError as e:
3908+
# If a run timed out, then temLogFilNam is not a valid json file
3909+
# because the file is written on the fly, and dymola did not finish
3910+
# writing all of it, which results in an invalid file.
3911+
# Check if /tmp/tmp-Buildings-1-o_m7nj7p/Buildings_Examples_VAVReheat_ASHRAE2006_buildingspy.json
3912+
# exists
3913+
modelName = os.path.split(temLogFilNam)[1].replace('.statistics.log', '')
3914+
buiLogNam = os.path.join(
3915+
d,
3916+
f"{modelName.replace('.', '_')}_buildingspy.json")
3917+
if os.path.exists(buiLogNam):
3918+
# Read the log file of the python script that invoked dymola
3919+
with open(buiLogNam, mode="r", encoding="utf-8-sig") as buiLog:
3920+
jsonBui = json.load(buiLog)
3921+
# Build up the entry for reporting the case
3922+
if "simulation" in jsonBui and "exception" in jsonBui["simulation"]:
3923+
exception = ''.join(jsonBui['simulation']['exception'])
3924+
else:
3925+
exception = f"JSONDecodeError in {temLogFilNam}: {str(e)}"
3926+
ele = {
3927+
"model": modelName,
3928+
"simulate": {
3929+
"command": ''.join(jsonBui['simulation']['cmd']),
3930+
"result": False,
3931+
"exception": exception
3932+
}
3933+
}
3934+
self._reporter.writeError(
3935+
f"Model '{modelName}' failed: {exception}")
3936+
stat.append(ele)
3937+
# Add the failure also to self._data so that _checkReferencePoints is not trying to read the output.
3938+
for ele in self._data:
3939+
if ele['model_name'] == modelName:
3940+
if "simulation" in ele[self._modelica_tool]:
3941+
ele[self._modelica_tool]['simulation']['success'] = False
3942+
else:
3943+
ele[self._modelica_tool]['simulation'] = {'success': False}
3944+
else:
3945+
self._reporter.writeError(
3946+
f"Decoding '{temLogFilNam}' failed and '{buiLogNam}' does not exist: {e}")
3947+
raise
38923948
except ValueError as e:
38933949
self._reporter.writeError(
3894-
"Decoding '%s' failed: %s" % (temLogFilNam, e))
3950+
"Loading '%s' failed: %s" % (temLogFilNam, e))
38953951
raise
38963952
else:
38973953
self._reporter.writeError(

0 commit comments

Comments
 (0)