Skip to content

Commit 2dd5b9f

Browse files
authored
Do not overwrite process log file across test units (#105)
* do not overwrite process log files * add changelog entry * rollback server.py handler * add changelog entry * stop overwriting log files * remove comment
1 parent 3f1087a commit 2dd5b9f

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

CHANGELOG.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
0.21.0 (Unreleased)
2+
-------------------
3+
4+
- Process log files will not be overwritten for each new process anymore, making it
5+
easier to debug issues that occurred in the middle of failed test runs
6+
17
0.20.0 (2022-08-29)
28
-------------------
39

4-
- cleanup reminders will now only be printed for verbosity
10+
- Cleanup reminders will now only be printed for verbosity
511
levels equal or greater than 1
612

7-
813
0.19.0 (2022-05-23)
914
-------------------
1015

xprocess/pytest_xprocess.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1+
import os
2+
13
import py
24
import pytest
35

46
from xprocess import XProcess
57

68

9+
def get_log_files(root_dir):
10+
proc_dirs = [f.path for f in os.scandir(root_dir) if f.is_dir()]
11+
return [
12+
os.path.join(proc_dir, f)
13+
for proc_dir in proc_dirs
14+
for f in os.listdir(proc_dir)
15+
if f.endswith("log")
16+
]
17+
18+
719
def getrootdir(config):
820
return config.cache.makedir(".xprocess")
921

@@ -42,6 +54,9 @@ def xprocess(request):
4254
# pass in xprocess object into pytest_unconfigure
4355
# through config for proper cleanup during teardown
4456
request.config._xprocess = xproc
57+
# start every run with clean log files
58+
for log_file in get_log_files(xproc.rootdir):
59+
open(log_file, "w").close()
4560
yield xproc
4661

4762

xprocess/xprocess.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
from py import std
1414

1515

16+
XPROCESS_BLOCK_DELIMITER = "@@__xproc_block_delimiter__@@"
17+
18+
1619
class XProcessInfo:
1720
"""Holds information of an active process instance represented by
1821
a XProcess Object and offers recursive termination functionality of
@@ -81,7 +84,7 @@ def terminate(self, *, kill_proc_tree=True, timeout=20):
8184
self._signal_process(p, signal.SIGTERM)
8285
_, alive = psutil.wait_procs(kill_list, timeout=timeout)
8386

84-
# forcefuly terminate procs still running
87+
# forcefully terminate procs still running
8588
for p in alive:
8689
self._signal_process(p, signal.SIGKILL)
8790
_, alive = psutil.wait_procs(kill_list, timeout=timeout)
@@ -229,7 +232,8 @@ def ensure(self, name, preparefunc, restart=False):
229232
starter = preparefunc(controldir, self)
230233
args = [str(x) for x in starter.args]
231234
self.log.debug("%s$ %s", controldir, " ".join(args))
232-
stdout = open(str(info.logpath), "wb", 0)
235+
stdout = open(str(info.logpath), "a+b", 0)
236+
stdout.write(bytes(f"{XPROCESS_BLOCK_DELIMITER}\n", "utf8"))
233237

234238
# is env still necessary? we could pass all in popen_kwargs
235239
kwargs = {"env": starter.env}
@@ -266,6 +270,18 @@ def ensure(self, name, preparefunc, restart=False):
266270
# cleanup later during teardown phase
267271
xresource.fhandle = info.logpath.open()
268272

273+
# skip previous process logs
274+
lines = info.logpath.open().readlines()
275+
if lines:
276+
proc_block_counter = sum(
277+
1 for line in lines if XPROCESS_BLOCK_DELIMITER in line
278+
)
279+
for line in xresource.fhandle:
280+
if XPROCESS_BLOCK_DELIMITER in line:
281+
proc_block_counter -= 1
282+
if proc_block_counter <= 0:
283+
break
284+
269285
self.resources.append(xresource)
270286

271287
if not restart:

0 commit comments

Comments
 (0)