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

report: Ignore missing COREDUMP_FILENAME #318

Merged
merged 2 commits into from Apr 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion apport/report.py
Expand Up @@ -21,6 +21,7 @@
import grp
import importlib.util
import io
import logging
import os
import pathlib
import pwd
Expand Down Expand Up @@ -2024,7 +2025,13 @@ def _add_coredump_from_systemd_coredump(self, coredump: dict[str, object]) -> No
filename = coredump.get("COREDUMP_FILENAME")
if filename:
assert isinstance(filename, str)
self["CoreDump"] = problem_report.CompressedFile(filename)
try:
self["CoreDump"] = problem_report.CompressedFile(filename)
except FileNotFoundError:
logging.getLogger(__name__).warning(
"Ignoring COREDUMP_FILENAME '%s' because it does not exist.",
filename,
)

@classmethod
def from_systemd_coredump(cls, coredump):
Expand Down
20 changes: 14 additions & 6 deletions problem_report.py
Expand Up @@ -189,14 +189,22 @@ class CompressedFile:

filename: str

def __init__(self, filename: str) -> None:
self.filename = filename
# pylint: disable-next=consider-using-with
self._compressed_file = open(self.filename, "rb")

def __del__(self):
if hasattr(self, "_compressed_file"):
self._compressed_file.close()

def iter_compressed(self) -> Iterator[bytes]:
"""Iterate over the compressed content of the file in 1 MB chunks."""
with open(self.filename, "rb") as compressed_file:
while True:
block = compressed_file.read(1048576)
if not block:
break
yield block
while True:
block = self._compressed_file.read(1048576)
if not block:
break
yield block

def is_readable(self) -> bool:
"""Check if the compressed file is readable by the effective user."""
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/test_report.py
Expand Up @@ -1412,6 +1412,28 @@ def test_report_from_systemd_coredump_default(self, stat_mock: MagicMock) -> Non
self.assertEqual(report_output.getvalue().decode(), expected_report)
stat_mock.assert_called_once_with("/usr/bin/divide-by-zero")

@unittest.mock.patch("os.stat")
def test_report_from_systemd_coredump_missing_crash(
self, stat_mock: MagicMock
) -> None:
"""Test converting systemd-coredump with a missing crash file."""
stat_mock.return_value = DIVIDE_BY_ZERO_EXECUTABLE_STAT
coredump = DIVIDE_BY_ZERO_SYSTEMD_COREDUMP.copy()
coredump["COREDUMP_FILENAME"] = "/non-existing/core.tracker-extract.1000.zst"

with self.assertLogs(level="WARNING") as warning_logs:
report = apport.report.Report.from_systemd_coredump(coredump)
report_output = io.BytesIO()
report.write(report_output)

self.assertEqual(report_output.getvalue().decode(), DIVIDE_BY_ZERO_REPORT)
stat_mock.assert_called_once_with("/usr/bin/divide-by-zero")
self.assertIn(
"Ignoring COREDUMP_FILENAME '/non-existing/core.tracker-extract.1000.zst'"
" because it does not exist.",
warning_logs.output[0],
)

@unittest.mock.patch("os.stat")
def test_report_from_systemd_coredump_storage_journal(
self, stat_mock: MagicMock
Expand Down