Skip to content

Commit 052ee72

Browse files
committed
adding tests for dot files (workflows with and without iterables)
1 parent f860ad6 commit 052ee72

File tree

1 file changed

+143
-1
lines changed

1 file changed

+143
-1
lines changed

nipype/pipeline/engine/tests/test_engine.py

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from builtins import open
1010
from copy import deepcopy
1111
from glob import glob
12-
import os
12+
import os, pdb
1313

1414

1515
import pytest
@@ -441,6 +441,7 @@ def test_write_graph_runs(tmpdir):
441441

442442
assert os.path.exists('graph.dot') or os.path.exists(
443443
'graph_detailed.dot')
444+
444445
try:
445446
os.remove('graph.dot')
446447
except OSError:
@@ -484,6 +485,147 @@ def test_deep_nested_write_graph_runs(tmpdir):
484485
pass
485486

486487

488+
# examples of dot files used in the following test
489+
dotfile_orig = ('strict digraph {\n'
490+
'"mod1 (engine)";\n'
491+
'"mod2 (engine)";\n'
492+
'"mod1 (engine)" -> "mod2 (engine)";\n'
493+
'}\n')
494+
495+
dotfile_detailed_orig = ('digraph structs {\n'
496+
'node [shape=record];\n'
497+
'pipemod1 [label="{IN}|{ mod1 | engine | }|{OUT|<outoutput1> output1}"];\n'
498+
'pipemod2 [label="{IN|<ininput1> input1}|{ mod2 | engine | }|{OUT}"];\n'
499+
'pipemod1:outoutput1:e -> pipemod2:ininput1:w;\n'
500+
'}')
501+
502+
dotfile_flat = dotfile_orig
503+
dotfile_detailed_flat = dotfile_detailed_orig
504+
505+
dotfile_exec = dotfile_orig
506+
dotfile_detailed_exec = dotfile_detailed_orig
507+
508+
509+
dotfile_hierarchical = ('digraph pipe{\n'
510+
' label="pipe";\n'
511+
' pipe_mod1[label="mod1 (engine)"];\n'
512+
' pipe_mod2[label="mod2 (engine)"];\n'
513+
' pipe_mod1 -> pipe_mod2;\n'
514+
'}')
515+
516+
dotfile_colored = ('digraph pipe{\n'
517+
' label="pipe";\n'
518+
' pipe_mod1[label="mod1 (engine)", style=filled, fillcolor="#FFFFC8"];\n'
519+
' pipe_mod2[label="mod2 (engine)", style=filled, fillcolor="#FFFFC8"];\n'
520+
' pipe_mod1 -> pipe_mod2;\n'
521+
'}')
522+
523+
@pytest.mark.parametrize("simple", [True, False])
524+
@pytest.mark.parametrize("graph_type", ['orig', 'flat', 'exec', 'hierarchical', 'colored'])
525+
def test_write_graph_dotfile(tmpdir, graph_type, simple):
526+
""" checking dot files for a workflow without iterables"""
527+
tmpdir.chdir()
528+
529+
pipe = pe.Workflow(name='pipe')
530+
mod1 = pe.Node(interface=EngineTestInterface(), name='mod1')
531+
mod2 = pe.Node(interface=EngineTestInterface(), name='mod2')
532+
pipe.connect([(mod1, mod2, [('output1', 'input1')])])
533+
pipe.write_graph(
534+
graph2use=graph_type, simple_form=simple, format='dot')
535+
536+
with open("graph.dot") as f:
537+
graph_str = f.read()
538+
if simple:
539+
assert graph_str == eval("dotfile_{}".format(graph_type))
540+
else:
541+
# if simple=False graph.dot uses longer names
542+
if graph_type in ["hierarchical", "colored"]:
543+
assert graph_str == eval("dotfile_{}".format(graph_type)).replace(
544+
"mod1 (engine)", "mod1.EngineTestInterface.engine").replace(
545+
"mod2 (engine)", "mod2.EngineTestInterface.engine")
546+
else:
547+
assert graph_str == eval("dotfile_{}".format(graph_type)).replace(
548+
"mod1 (engine)", "pipe.mod1.EngineTestInterface.engine").replace(
549+
"mod2 (engine)", "pipe.mod2.EngineTestInterface.engine")
550+
551+
# graph_detailed is not created for hierachical or colored
552+
if graph_type not in ["hierarchical", "colored"]:
553+
with open("graph_detailed.dot") as f:
554+
graph_str =f.read()
555+
assert graph_str == eval("dotfile_detailed_{}".format(graph_type))
556+
557+
558+
# examples of dot files used in the following test
559+
dotfile_iter_orig = dotfile_orig
560+
dotfile_detailed_iter_orig = dotfile_detailed_orig
561+
562+
dotfile_iter_flat = dotfile_orig
563+
dotfile_detailed_iter_flat = dotfile_detailed_orig
564+
565+
dotfile_iter_exec = dotfile_orig
566+
dotfile_detailed_iter_exec = (
567+
'digraph structs {\n'
568+
'node [shape=record];\n'
569+
'pipemod1aIa1 [label="{IN}|{ a1 | engine | mod1.aI }|{OUT|<outoutput1> output1}"];\n'
570+
'pipemod2a1 [label="{IN|<ininput1> input1}|{ a1 | engine | mod2 }|{OUT}"];\n'
571+
'pipemod1aIa0 [label="{IN}|{ a0 | engine | mod1.aI }|{OUT|<outoutput1> output1}"];\n'
572+
'pipemod2a0 [label="{IN|<ininput1> input1}|{ a0 | engine | mod2 }|{OUT}"];\n'
573+
'pipemod1aIa0:outoutput1:e -> pipemod2a0:ininput1:w;\n'
574+
'pipemod1aIa1:outoutput1:e -> pipemod2a1:ininput1:w;\n'
575+
'}')
576+
577+
dotfile_iter_hierarchical = (
578+
'digraph pipe{\n'
579+
' label="pipe";\n'
580+
' pipe_mod1[label="mod1 (engine)", shape=box3d,style=filled, color=black, colorscheme=greys7 fillcolor=2];\n'
581+
' pipe_mod2[label="mod2 (engine)"];\n'
582+
' pipe_mod1 -> pipe_mod2;\n'
583+
'}')
584+
585+
dotfile_iter_colored = (
586+
'digraph pipe{\n'
587+
' label="pipe";\n'
588+
' pipe_mod1[label="mod1 (engine)", shape=box3d,style=filled, color=black, colorscheme=greys7 fillcolor=2];\n'
589+
' pipe_mod2[label="mod2 (engine)", style=filled, fillcolor="#FFFFC8"];\n'
590+
' pipe_mod1 -> pipe_mod2;\n'
591+
'}')
592+
593+
@pytest.mark.parametrize("simple", [True, False])
594+
@pytest.mark.parametrize("graph_type", ['orig', 'flat', 'exec', 'hierarchical', 'colored'])
595+
def test_write_graph_dotfile_iterables(tmpdir, graph_type, simple):
596+
""" checking dot files for a workflow with iterables"""
597+
tmpdir.chdir()
598+
599+
pipe = pe.Workflow(name='pipe')
600+
mod1 = pe.Node(interface=EngineTestInterface(), name='mod1')
601+
mod1.iterables = ('input1', [1, 2])
602+
mod2 = pe.Node(interface=EngineTestInterface(), name='mod2')
603+
pipe.connect([(mod1, mod2, [('output1', 'input1')])])
604+
pipe.write_graph(
605+
graph2use=graph_type, simple_form=simple, format='dot')
606+
607+
with open("graph.dot") as f:
608+
graph_str = f.read()
609+
if simple:
610+
assert graph_str == eval("dotfile_iter_{}".format(graph_type))
611+
else:
612+
# if simple=False graph.dot uses longer names
613+
if graph_type in ["hierarchical", "colored"]:
614+
assert graph_str == eval("dotfile_iter_{}".format(graph_type)).replace(
615+
"mod1 (engine)", "mod1.EngineTestInterface.engine").replace(
616+
"mod2 (engine)", "mod2.EngineTestInterface.engine")
617+
else:
618+
assert graph_str == eval("dotfile_iter_{}".format(graph_type)).replace(
619+
"mod1 (engine)", "pipe.mod1.EngineTestInterface.engine").replace(
620+
"mod2 (engine)", "pipe.mod2.EngineTestInterface.engine")
621+
622+
# graph_detailed is not created for hierachical or colored
623+
if graph_type not in ["hierarchical", "colored"]:
624+
with open("graph_detailed.dot") as f:
625+
graph_str =f.read()
626+
assert graph_str == eval("dotfile_detailed_iter_{}".format(graph_type))
627+
628+
487629
def test_io_subclass():
488630
"""Ensure any io subclass allows dynamic traits"""
489631
from nipype.interfaces.io import IOBase

0 commit comments

Comments
 (0)