From 6121d88b691a4f20f75c2559a6b77bd1c822c609 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Sat, 22 Jan 2022 21:58:11 -0500 Subject: [PATCH] fix: capture data on SIGTERM #1307 This covers multiprocessing.Process.terminate(), and maybe other cases also. --- coverage/control.py | 11 +++++++++-- coverage/multiproc.py | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/coverage/control.py b/coverage/control.py index bd51ffc56..a24600832 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -9,6 +9,7 @@ import os import os.path import platform +import signal import sys import time import warnings @@ -526,6 +527,7 @@ def _init_for_start(self): self._should_write_debug = True atexit.register(self._atexit) + self._old_sigterm = signal.signal(signal.SIGTERM, self._on_sigterm) def _init_data(self, suffix): """Create a data file if we don't have one yet.""" @@ -583,15 +585,20 @@ def stop(self): self._collector.stop() self._started = False - def _atexit(self): + def _atexit(self, event="atexit"): """Clean up on process shutdown.""" if self._debug.should("process"): - self._debug.write(f"atexit: pid: {os.getpid()}, instance: {self!r}") + self._debug.write(f"{event}: pid: {os.getpid()}, instance: {self!r}") if self._started: self.stop() if self._auto_save: self.save() + def _on_sigterm(self, signum, frame): + self._atexit("sigterm") + signal.signal(signal.SIGTERM, self._old_sigterm) + signal.raise_signal(signal.SIGTERM) + def erase(self): """Erase previously collected coverage data. diff --git a/coverage/multiproc.py b/coverage/multiproc.py index 1f9225f3e..3a9bd6339 100644 --- a/coverage/multiproc.py +++ b/coverage/multiproc.py @@ -27,7 +27,7 @@ def _bootstrap(self, *args, **kwargs): """Wrapper around _bootstrap to start coverage.""" try: from coverage import Coverage # avoid circular import - cov = Coverage(data_suffix=True) + cov = Coverage(data_suffix=True, auto_data=True) cov._warn_preimported_source = False cov.start() debug = cov._debug