Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1bce774

Browse files
committedNov 18, 2024··
TEST: Update Gantt chart tests for coverage
1 parent 376d6e2 commit 1bce774

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed
 

‎nipype/pipeline/plugins/tests/test_callback.py

+24-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
22
# vi: set ft=python sts=4 ts=4 sw=4 et:
3-
"""Tests for workflow callbacks
4-
"""
3+
"""Tests for workflow callbacks."""
4+
from pathlib import Path
55
from time import sleep
6+
import json
67
import pytest
78
import nipype.interfaces.utility as niu
89
import nipype.pipeline.engine as pe
@@ -71,22 +72,22 @@ def test_callback_exception(tmpdir, plugin, stop_on_first_crash):
7172

7273
@pytest.mark.parametrize("plugin", ["Linear", "MultiProc", "LegacyMultiProc"])
7374
@pytest.mark.skipif(not has_pandas, reason="Test requires pandas")
74-
def test_callback_gantt(tmpdir, plugin):
75+
def test_callback_gantt(tmp_path: Path, plugin: str) -> None:
7576
import logging
7677

7778
from os import path
7879

7980
from nipype.utils.profiler import log_nodes_cb
8081
from nipype.utils.draw_gantt_chart import generate_gantt_chart
8182

82-
log_filename = path.join(tmpdir, "callback.log")
83+
log_filename = tmp_path / "callback.log"
8384
logger = logging.getLogger("callback")
8485
logger.setLevel(logging.DEBUG)
8586
handler = logging.FileHandler(log_filename)
8687
logger.addHandler(handler)
8788

8889
# create workflow
89-
wf = pe.Workflow(name="test", base_dir=tmpdir.strpath)
90+
wf = pe.Workflow(name="test", base_dir=str(tmp_path))
9091
f_node = pe.Node(
9192
niu.Function(function=func, input_names=[], output_names=[]), name="f_node"
9293
)
@@ -98,7 +99,21 @@ def test_callback_gantt(tmpdir, plugin):
9899
plugin_args["n_procs"] = 8
99100
wf.run(plugin=plugin, plugin_args=plugin_args)
100101

101-
generate_gantt_chart(
102-
path.join(tmpdir, "callback.log"), 1 if plugin == "Linear" else 8
103-
)
104-
assert path.exists(path.join(tmpdir, "callback.log.html"))
102+
with open(log_filename, "r") as _f:
103+
loglines = _f.readlines()
104+
105+
# test missing duration
106+
first_line = json.loads(loglines[0])
107+
if "duration" in first_line:
108+
del first_line["duration"]
109+
loglines[0] = json.dumps(first_line)
110+
111+
# test duplicate timestamp warning
112+
loglines.append(loglines[-1])
113+
114+
with open(log_filename, "w") as _f:
115+
_f.write("".join(loglines))
116+
117+
with pytest.warns(Warning):
118+
generate_gantt_chart(str(log_filename), 1 if plugin == "Linear" else 8)
119+
assert (tmp_path / "callback.log.html").exists()

‎nipype/utils/draw_gantt_chart.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,25 @@ def log_to_dict(logfile):
102102

103103
nodes_list = [json.loads(l) for l in lines]
104104

105-
def _convert_string_to_datetime(datestring):
106-
try:
105+
def _convert_string_to_datetime(
106+
datestring: str | datetime.datetime,
107+
) -> datetime.datetime:
108+
"""Convert a date string to a datetime object."""
109+
if isinstance(datestring, datetime.datetime):
110+
datetime_object = datestring
111+
elif isinstance(datestring, str):
112+
date_format = (
113+
"%Y-%m-%dT%H:%M:%S.%f%z"
114+
if "+" in datestring
115+
else "%Y-%m-%dT%H:%M:%S.%f"
116+
)
107117
datetime_object: datetime.datetime = datetime.datetime.strptime(
108-
datestring, "%Y-%m-%dT%H:%M:%S.%f"
118+
datestring, date_format
109119
)
110-
return datetime_object
111-
except Exception as _:
112-
pass
113-
return datestring
120+
else:
121+
msg = f"{datestring} is not a string or datetime object."
122+
raise TypeError(msg)
123+
return datetime_object
114124

115125
date_object_node_list: list = list()
116126
for n in nodes_list:

0 commit comments

Comments
 (0)
Please sign in to comment.