Skip to content

Commit

Permalink
Handle invalid license errors in get_errormsg SO107 SCMSUITE-8725
Browse files Browse the repository at this point in the history
  • Loading branch information
dormrod committed Dec 5, 2024
1 parent 2dd05f3 commit 8686f88
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 10 deletions.
42 changes: 32 additions & 10 deletions interfaces/adfsuite/ams.py
Original file line number Diff line number Diff line change
Expand Up @@ -2483,27 +2483,49 @@ def get_errormsg(self) -> Optional[str]:
if self.check():
return None
else:
# Something went wrong. The first place to check is the termination status on the ams.rkf.
# If the AMS driver stopped with a known error (called StopIt in the Fortran code), the error will be in there.
default_msg = "Could not determine error message. Please check the output manually."
msg = None
try:
msg = self.results.readrkf("General", "termination status")
if msg == "NORMAL TERMINATION with errors" or msg is None:
# Apparently this wasn't a hard stop in the middle of the job.
# Something went wrong. The first place to check is the termination status on the ams.rkf.
# If the AMS driver stopped with a known error (called StopIt in the Fortran code), the error will be in there.
# If there is no rkf file, the msg will be None
termination_status = self.results.readrkf("General", "termination status")
if termination_status == "NORMAL TERMINATION with errors" or termination_status is None:
# Apparently this wasn't a hard stop in the middle of the job
# Let's look for the last error in the logfile ...
msg = self.results.grep_file("ams.log", "ERROR: ")[-1].partition("ERROR: ")[2]
elif msg == "IN PROGRESS" and "$JN.err" in self.results:
try:
log_err_lines = self.results.grep_file("ams.log", "ERROR: ")
if log_err_lines:
return log_err_lines[-1].partition("ERROR: ")[2]
except FileError:
pass

# For a licensing issue, check the output logs directly
try:
license_err_lines = self.results.get_output_chunk(
begin="LICENSE INVALID",
end="License file",
inc_begin=True,
inc_end=True,
match=1,
)
if license_err_lines:
return str.join("\n", license_err_lines)
except FileError:
pass
elif termination_status == "IN PROGRESS" and "$JN.err" in self.results:
# If the status is still "IN PROGRESS", that probably means AMS was shut down hard from the outside.
# E.g. it got SIGKILL from the scheduler for exceeding some resource limit.
# In this case useful information may be found on stderr.
with open(self.results["$JN.err"], "r") as err:
with open(self.results["$JN.err"]) as err:
errlines = err.read().splitlines()
for el in reversed(errlines):
if el != "" and not el.isspace():
msg = "Killed while IN PROGRESS: " + el
break
except:
msg = "Could not determine error message. Please check the output manually."
return msg
pass
return msg if msg else default_msg

def hash_input(self) -> str:
"""Calculate the hash of the input file.
Expand Down
47 changes: 47 additions & 0 deletions unit_tests/test_amsjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,3 +563,50 @@ def get_runscript() -> str:
assert len(status_lines) == 4

logger.close()

def test_get_errormsg_populates_correctly_for_different_scenarios(self):
from scm.plams.core.errors import FileError

# Invalid license
job = AMSJob()
results = MagicMock(spec=AMSResults)
results.readrkf.return_value = None
results.grep_file.side_effect = FileError()
results.get_output_chunk.return_value = [
"LICENSE INVALID",
"---------------",
"Your license does not include module AMS version 2024.206 on this machine.",
"Module AMS",
"Version 2024.206",
"Machine: Foo",
"License file: ./license.txt",
]
job.results = results

assert (
job.get_errormsg()
== """LICENSE INVALID
---------------
Your license does not include module AMS version 2024.206 on this machine.
Module AMS
Version 2024.206
Machine: Foo
License file: ./license.txt"""
)

# Invalid input
results.grep_file.side_effect = None
results.grep_file.return_value = [
'<Dec05-2024> <12:03:49> ERROR: Input error: value "foo" found in line 13 for multiple choice key "Task" is not an allowed choice'
]
assert (
job.get_errormsg()
== 'Input error: value "foo" found in line 13 for multiple choice key "Task" is not an allowed choice'
)

# Error in calculation
results.readrkf.return_value = "NORMAL TERMINATION with errors"
results.grep_file.return_value = [
"<Dec05-2024> <13:44:55> ERROR: Geometry optimization failed! (Did not converge.)"
]
assert job.get_errormsg() == "Geometry optimization failed! (Did not converge.)"

0 comments on commit 8686f88

Please sign in to comment.