def _report_crash(self, node, result=None): if result and result['traceback']: node._result = result['result'] node._traceback = result['traceback'] return report_crash(node, traceback=result['traceback']) else: return report_crash(node)
def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline in a serial order. Parameters ---------- graph : networkx digraph defines order of execution """ import networkx as nx try: dfs_preorder = nx.dfs_preorder # type: ignore except AttributeError: dfs_preorder = nx.dfs_preorder_nodes if not isinstance(graph, nx.DiGraph): raise ValueError("Input must be a networkx digraph object") logger.info("Running serially.") old_wd = os.getcwd() notrun = [] donotrun = [] nodes, _ = topological_sort(graph) for node in nodes: endstatus = "end" try: if node in donotrun: continue if self._status_callback: self._status_callback(node, "start") node.run(updatehash=updatehash) except Exception: import pdb pdb.post_mortem() endstatus = "exception" # bare except, but i really don't know where a # node might fail crashfile = report_crash(node) if str2bool(config["execution"]["stop_on_first_crash"]): raise # remove dependencies from queue subnodes = [s for s in dfs_preorder(graph, node)] notrun.append({ "node": node, "dependents": subnodes, "crashfile": crashfile }) donotrun.extend(subnodes) # Delay raising the crash until we cleaned the house if str2bool(config["execution"]["stop_on_first_crash"]): os.chdir(old_wd) # Return wherever we were before report_nodes_not_run(notrun) # report before raising raise finally: if self._status_callback: self._status_callback(node, endstatus) os.chdir(old_wd) # Return wherever we were before report_nodes_not_run(notrun)
def test_report_crash(): with mock.patch('pickle.dump', mock.MagicMock()) as mock_pickle_dump: with mock.patch('nipype.pipeline.plugins.base.format_exception', mock.MagicMock()): # see iss 1517 mock_pickle_dump.return_value = True mock_node = mock.MagicMock(name='mock_node') mock_node._id = 'an_id' mock_node.config = {'execution': {'crashdump_dir': '.'}} actual_crashfile = pb.report_crash(mock_node) expected_crashfile = re.compile( '.*/crash-.*-an_id-[0-9a-f\-]*.pklz') yield assert_regexp_matches, actual_crashfile, expected_crashfile yield assert_true, mock_pickle_dump.call_count == 1
def test_report_crash(): with mock.patch('pickle.dump', mock.MagicMock()) as mock_pickle_dump: with mock.patch('nipype.pipeline.plugins.base.format_exception', mock.MagicMock()): # see iss 1517 mock_pickle_dump.return_value = True mock_node = mock.MagicMock(name='mock_node') mock_node._id = 'an_id' mock_node.config = { 'execution' : { 'crashdump_dir' : '.' } } actual_crashfile = pb.report_crash(mock_node) expected_crashfile = re.compile('.*/crash-.*-an_id-[0-9a-f\-]*.pklz') assert expected_crashfile.match(actual_crashfile).group() == actual_crashfile assert mock_pickle_dump.call_count == 1
def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline in a serial order. modifed for XNAT workflow XML updates Parameters ---------- graph : networkx digraph defines order of execution """ if not isinstance(graph, nx.DiGraph): raise ValueError('Input must be a networkx digraph object') logger.info("Running serially.") old_wd = os.getcwd() notrun = [] donotrun = [] nodes = nx.topological_sort(graph) for (i, node) in enumerate(nodes): try: pct = 100.0*i/len(nodes) workflow_info.update(str(i+1), str(node), '%.1f' % pct) if node in donotrun: continue node.run(updatehash=updatehash) except: os.chdir(old_wd) if str2bool(config['execution']['stop_on_first_crash']): raise # bare except, but i really don't know where a # node might fail crashfile = report_crash(node) # remove dependencies from queue subnodes = [s for s in dfs_preorder(graph, node)] notrun.append(dict(node = node, dependents = subnodes, crashfile = crashfile)) donotrun.extend(subnodes) report_nodes_not_run(notrun)