Skip to content

Commit

Permalink
Add compression of log files and one test
Browse files Browse the repository at this point in the history
  • Loading branch information
isimo00 committed Jan 8, 2025
1 parent f067bc3 commit 3e47faf
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
28 changes: 24 additions & 4 deletions autosubmit/notifications/mail_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# along with Autosubmit. If not, see <http://www.gnu.org/licenses/>.

import smtplib
import zipfile
import tempfile
import email.utils
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
Expand All @@ -38,9 +40,16 @@ def notify_experiment_status(self, exp_id,mail_to,platform):
message['Date'] = email.utils.formatdate(localtime=True)
message.attach(MIMEText(message_text))

files = []
files_compressed = []
try:
files = [f for f in BasicConfig.expid_aslog_dir(exp_id).glob('*_run.log') if Path(f).is_file()]
self._attach_files(message, files)
files_compressed = [self._compress_file(f) for f in files]
except BaseException as e:
Log.printlog('An error has occurred while compressing log files for a warning email', 6011)

try:
self._attach_files(message, files_compressed, files)
except BaseException as e:
Log.printlog('An error has occurred while attaching log files to a warning email about remote_platforms ', 6011)

Expand All @@ -50,6 +59,11 @@ 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)
# delete compressed files
try:
for f in files_compressed: Path.unlink(Path(f))
except BaseException:
Log.printlog('An error has occurred while deleting compressed log files for a warnign email', 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)
Expand All @@ -69,13 +83,19 @@ def _send_mail(self, mail_from, mail_to, message):
server.sendmail(mail_from, mail_to, message.as_string())
server.quit()

def _attach_files(self, message, files):
for f in files or []:
def _attach_files(self, message, files, original_names):
for i,f in enumerate(files) or []:
with open(f, "rb") as file:
part = MIMEApplication(file.read(), Name = Path(f).name)
part['Content-Disposition'] = 'attachment; filename="%s"' % Path(f).name
part['Content-Disposition'] = 'attachment; filename="%s"' % Path(original_names[i]).name
message.attach(part)

def _compress_file(self, file_path):
temp_zip = tempfile.NamedTemporaryFile(delete=False, suffix='.zip', dir=Path(file_path).parent)
zip_filename = temp_zip.name
with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
zipf.write(file_path, Path(file_path).name)
return zip_filename

@staticmethod
def _generate_message_text(exp_id, job_name, prev_status, status):
Expand Down
34 changes: 31 additions & 3 deletions test/unit/test_mail.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import tempfile
import zipfile
from unittest import mock
from pathlib import Path
from autosubmit.notifications.mail_notifier import MailNotifier
Expand Down Expand Up @@ -41,7 +42,7 @@ def test_attach_files(mail_notifier):

with mock.patch("builtins.open", mock.mock_open(read_data="file data")):
message = mock.Mock()
mail_notifier._attach_files(message, mock_files)
mail_notifier._attach_files(message, mock_files, mock_files)

assert message.attach.call_count == len(mock_files)
@pytest.mark.parametrize(
Expand All @@ -56,7 +57,7 @@ def test_attach_files(mail_notifier):
# Log attachment error: Simulate failure in file listing (glob raises exception)
(Exception("Failed to list files"), None,
'An error has occurred while attaching log files to a warning email about remote_platforms ', 1)
'An error has occurred while compressing log files for a warning email', 1)
],
ids=[
"Normal case: No errors",
Expand Down Expand Up @@ -103,7 +104,7 @@ def test_notify_experiment_status(mail_notifier, mock_glob_side_effect, send_mai
mail_notifier._generate_message_experiment_status.assert_called_once_with(exp_id, platform)
mock_send_mail.assert_called_once_with(mail_notifier.config.MAIL_FROM, 'recipient@example.com', mock.ANY)

if mock_glob_side_effect is None: mock_attach_files.assert_called_once_with(mock.ANY, [file1, file2])
if mock_glob_side_effect is None: mock_attach_files.assert_called_once_with(mock.ANY, mock.ANY, [file1, file2])

if expected_log_message:
mock_printlog.assert_called_once_with(expected_log_message, 6011)
Expand All @@ -114,3 +115,30 @@ def test_notify_experiment_status(mail_notifier, mock_glob_side_effect, send_mai

# Reset the local root dir.
BasicConfig.LOCAL_ROOT_DIR = original_local_root_dir

def test_compress_file(mail_notifier):
with tempfile.TemporaryDirectory() as temp_dir:
test_file = Path(temp_dir) / "test_file.log"
test_file.write_text("file data 1")

assert test_file.exists()

compressed_file = mail_notifier._compress_file(test_file)

# Check that the zip file exists
assert Path(compressed_file).exists, f"Compressed file {compressed_file} does not exist."

# Open the zip file and check its content
with zipfile.ZipFile(compressed_file, 'r') as zipf:
# Verify that the zip file contains the original file
zipf.testzip() # This ensures the zip file is valid
file_list = zipf.namelist() # Get the list of file names in the zip
assert Path(test_file).name in file_list, "The compressed file does not contain the expected file."

# Check the content of the file inside the zip
with zipf.open(Path(test_file).name, 'r') as file:
content = file.read().decode('utf-8')
assert content == "file data 1", "The content inside the zip file is incorrect."

# Clean up by removing the compressed file
Path(compressed_file).unlink

0 comments on commit 3e47faf

Please sign in to comment.