Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: re-added notify_on #2020

Merged
merged 2 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions autosubmit/job/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,16 @@ def splits(self):
def splits(self, value):
self._splits = value

@property
@autosubmit_parameter(name='notify_on')
def notify_on(self):
"""Send mail notification on job status change."""
return self._notify_on

@notify_on.setter
def notify_on(self, value):
self._notify_on = value

def __getstate__(self):
return {k: v for k, v in self.__dict__.items() if k not in ["_platform", "_children", "_parents", "submitter"]}

Expand Down Expand Up @@ -1943,6 +1953,7 @@ def update_job_parameters(self,as_conf, parameters):
self.shape = as_conf.jobs_data[self.section].get("SHAPE", "")
self.script = as_conf.jobs_data[self.section].get("SCRIPT", "")
self.x11 = False if str(as_conf.jobs_data[self.section].get("X11", False)).lower() == "false" else True
self.notify_on = as_conf.jobs_data[self.section].get("NOTIFY_ON", [])
self.update_stat_file()
if self.checkpoint: # To activate placeholder sustitution per <empty> in the template
parameters["AS_CHECKPOINT"] = self.checkpoint
Expand Down
5 changes: 3 additions & 2 deletions autosubmit/notifications/mail_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ def notify_experiment_status(self, exp_id,mail_to,platform):
self._send_mail(self.config.MAIL_FROM, mail, message)
except BaseException as e:
Log.printlog('An error has occurred while sending a mail for warn about remote_platform', 6011)

def notify_status_change(self, exp_id, job_name, prev_status, status, mail_to):
message_text = self._generate_message_text(exp_id, job_name, prev_status, status)
message = MIMEText(message_text)
message['From'] = email.utils.formataddr(('Autosubmit', self.config.MAIL_FROM))
message['Subject'] = f'[Autosubmit] The job {job_name} status has changed to {str(status)}'
message['Date'] = email.utils.formatdate(localtime=True)
for mail in mail_to:
for mail in mail_to: # expects a list
message['To'] = email.utils.formataddr((mail, mail))
try:
self._send_mail(self.config.MAIL_FROM, mail, message)
Expand Down Expand Up @@ -74,4 +75,4 @@ def _generate_message_experiment_status(exp_id, platform=""):
+ f'Platform affected:{str(platform.name)} using as host:{str(platform.host)} \n\n' \
f'[WARN] Autosubmit encountered an issue with an remote_platform.\n It will resume itself, whenever is possible\n If issue persist, you can change the host IP or put multiple hosts in the platform.yml' + '\n\n\n\n\n' \
f'INFO: This message was auto generated by Autosubmit, '\
f'remember that you can disable these messages on Autosubmit config file. \n'
f'remember that you can disable these messages on Autosubmit config file. \n'
17 changes: 15 additions & 2 deletions docs/source/userguide/configure/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ Example:
# Default: False
NOTIFICATIONS: True
# Mail address where notifications will be received
TO: [email protected] [email protected]
TO:
- [email protected]
- [email protected]
2. Then you have to define for which jobs you want to be notified.

Expand All @@ -232,7 +235,7 @@ Edit ``jobs_cxxx.yml`` in the ``conf`` folder of the experiment.
defined on the parameter ``NOTIFY_ON``

.. hint::
Remember that you can define more than one job status divided by a whitespace.
Remember that you can define more than one job status separated by a whitespace, a comma (`,`), or using a list.

Example:
::
Expand All @@ -246,6 +249,16 @@ Example:
FILE: LOCAL_SETUP.sh
PLATFORM: LOCAL
NOTIFY_ON: FAILED COMPLETED
EXAMPLE_JOB:
FILE: EXAMPLE_JOB.sh
PLATFORM: LOCAL
NOTIFY_ON: FAILED, COMPLETED
EXAMPLE_JOB_2:
FILE: EXAMPLE_JOB_2.sh
PLATFORM: LOCAL
NOTIFY_ON:
- FAILED
- COMPLETED
How to add a new platform
-------------------------
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
'py3dotplus==1.1.0',
'numpy<2',
'rocrate==0.*',
'autosubmitconfigparser==1.0.75',
'autosubmitconfigparser==1.0.76',
'configparser',
'setproctitle',
'invoke>=2.0',
Expand Down
58 changes: 45 additions & 13 deletions test/unit/test_job_pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,29 @@
from pathlib import Path


def create_job_and_update_parameters(autosubmit_config, experiment_data):
as_conf = autosubmit_config("test-expid", experiment_data)
as_conf.experiment_data = as_conf.deep_normalize(as_conf.experiment_data)
as_conf.experiment_data = as_conf.normalize_variables(as_conf.experiment_data, must_exists=True)
as_conf.experiment_data = as_conf.deep_read_loops(as_conf.experiment_data)
as_conf.experiment_data = as_conf.substitute_dynamic_variables(as_conf.experiment_data)
as_conf.experiment_data = as_conf.parse_data_loops(as_conf.experiment_data)
# Create some jobs
job = Job('A', '1', 0, 1)
platform = PsPlatform(expid='a000', name='DUMMY_PLATFORM', config=as_conf.experiment_data)
job.section = 'RANDOM-SECTION'
job.platform = platform
job.update_parameters(as_conf, {})
return job


@pytest.mark.parametrize('experiment_data, expected_data', [(
{
'JOBS': {
'RANDOM-SECTION': {
'FILE': "test.sh",
'PLATFORM': 'DUMMY_PLATFORM',
'TEST': "%other%"
'TEST': "%other%",
},
},
'PLATFORMS': {
Expand All @@ -38,18 +54,7 @@
}
)])
def test_update_parameters_current_variables(autosubmit_config, experiment_data, expected_data):
as_conf = autosubmit_config("test-expid", experiment_data)
as_conf.experiment_data = as_conf.deep_normalize(as_conf.experiment_data)
as_conf.experiment_data = as_conf.normalize_variables(as_conf.experiment_data, must_exists=True)
as_conf.experiment_data = as_conf.deep_read_loops(as_conf.experiment_data)
as_conf.experiment_data = as_conf.substitute_dynamic_variables(as_conf.experiment_data)
as_conf.experiment_data = as_conf.parse_data_loops(as_conf.experiment_data)
# Create some jobs
job = Job('A', '1', 0, 1)
platform = PsPlatform(expid='a000', name='DUMMY_PLATFORM', config=as_conf.experiment_data)
job.section = 'RANDOM-SECTION'
job.platform = platform
job.update_parameters(as_conf, {})
job = create_job_and_update_parameters(autosubmit_config, experiment_data)
for key, value in expected_data.items():
assert job.parameters[key] == value

Expand Down Expand Up @@ -116,3 +121,30 @@ def test_recover_last_log_name(tmpdir, test_with_logfiles, file_timestamp_greate
assert job.updated_log == expected_update_log
assert job.local_logs[0] == str(expected_local_logs[0])
assert job.local_logs[1] == str(expected_local_logs[1])


@pytest.mark.parametrize('experiment_data, attributes_to_check', [(
{
'JOBS': {
'RANDOM-SECTION': {
'FILE': "test.sh",
'PLATFORM': 'DUMMY_PLATFORM',
'NOTIFY_ON': 'COMPLETED',
},
},
'PLATFORMS': {
'dummy_platform': {
'type': 'ps',
},
},
'ROOTDIR': 'dummy_rootdir',
'LOCAL_TMP_DIR': 'dummy_tmpdir',
'LOCAL_ROOT_DIR': 'dummy_rootdir',
},
{'notify_on': ['COMPLETED']}
)])
def test_update_parameters_attributes(autosubmit_config, experiment_data, attributes_to_check):
job = create_job_and_update_parameters(autosubmit_config, experiment_data)
for attr in attributes_to_check:
assert hasattr(job, attr)
assert getattr(job, attr) == attributes_to_check[attr]
Loading