Skip to content

Commit f8467b6

Browse files
feat: add tests for WorkflowTopology
1 parent 4ff8c4e commit f8467b6

File tree

2 files changed

+185
-1
lines changed

2 files changed

+185
-1
lines changed

src/ansys/dpf/core/workflow.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,9 @@ def to_graphviz(self, path: Union[os.PathLike, str]):
955955
return self._api.work_flow_export_graphviz(self, str(path))
956956

957957
def get_topology(self):
958-
workflow_to_workflow_topology_op = dpf_operator.Operator("workflow_to_workflow_topology")
958+
workflow_to_workflow_topology_op = dpf_operator.Operator(
959+
"workflow_to_workflow_topology", server=self._server
960+
)
959961
workflow_to_workflow_topology_op.inputs.workflow.connect(self)
960962
workflow_topology_container = workflow_to_workflow_topology_op.outputs.workflow_topology()
961963

tests/test_workflow_topology.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# Copyright (C) 2020 - 2024 ANSYS, Inc. and/or its affiliates.
2+
# SPDX-License-Identifier: MIT
3+
#
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in all
13+
# copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
# SOFTWARE.
22+
23+
import pytest
24+
25+
from ansys import dpf
26+
import ansys.dpf.core.operators as op
27+
28+
29+
def test_instantiate_workflow_to_workflow_topology_op(server_type):
30+
workflow_to_workflow_topology_op = dpf.core.Operator(
31+
"workflow_to_workflow_topology", server=server_type
32+
)
33+
34+
assert workflow_to_workflow_topology_op
35+
36+
37+
def workflow_forward(server_type) -> dpf.core.Workflow:
38+
"""
39+
┌─────────┐ ┌────────────┐ ┌────────────┐ ┌──────────┐
40+
│"Input 0"├─────►│forward_op_1├─────►│forward_op_1├─────►│"Output 0"│
41+
└─────────┘ └────────────┘ └────────────┘ └──────────┘
42+
┌───────┐ ┌────────────┐ ┌──────────┐
43+
│"hello"├──────────►│forward_op_3├─────►│"Output 1"│
44+
└───────┘ └────────────┘ └──────────┘
45+
"""
46+
47+
forward_op_1 = op.utility.forward(server=server_type)
48+
forward_op_2 = op.utility.forward(server=server_type)
49+
forward_op_3 = op.utility.forward(server=server_type)
50+
51+
forward_op_2.inputs.connect(forward_op_1.outputs)
52+
forward_op_3.inputs.connect("hello")
53+
54+
workflow = dpf.core.Workflow(server=server_type)
55+
56+
workflow.add_operators([forward_op_1, forward_op_2, forward_op_3])
57+
58+
workflow.set_input_name("Input 0", forward_op_1.inputs.any)
59+
workflow.set_output_name("Output 0", forward_op_2.outputs.any)
60+
workflow.set_output_name("Output 1", forward_op_3.outputs.any)
61+
62+
return workflow
63+
64+
65+
def workflow_forward_5(server_type) -> dpf.core.Workflow:
66+
"""
67+
┌─────────┐ ┌──────────┐
68+
│"Input 0"├──┐ ┌──►│"Output 0"│
69+
└─────────┘ │ │ └──────────┘
70+
┌─────────┐ │ │ ┌──────────┐
71+
│"Input 1"├──┤ ├──►│"Output 1"│
72+
└─────────┘ │ │ └──────────┘
73+
┌─────────┐ │ ┌──────────┐ │ ┌──────────┐
74+
│"Input 2"├──┼──►│forward_op├──┼──►│"Output 2"│
75+
└─────────┘ │ └──────────┘ │ └──────────┘
76+
┌─────────┐ │ │ ┌──────────┐
77+
│"Input 3"├──┤ ├──►│"Output 3"│
78+
└─────────┘ │ │ └──────────┘
79+
┌─────────┐ │ │ ┌──────────┐
80+
│"Input 4"├──┘ └──►│"Output 4"│
81+
└─────────┘ └──────────┘
82+
"""
83+
84+
forward_op = op.utility.forward(server=server_type)
85+
86+
workflow = dpf.core.Workflow(server=server_type)
87+
88+
workflow.add_operators([forward_op])
89+
90+
for i in range(5):
91+
workflow.set_input_name(f"Input {i}", forward_op, i)
92+
workflow.set_output_name(f"Output {i}", forward_op, i)
93+
94+
return workflow
95+
96+
97+
def workflow_disp_min_max(server_type) -> dpf.core.Workflow:
98+
"""
99+
┌──────────────┐ ┌───────┐ ┌─────────────┐ ┌─────┐
100+
│"data_sources"├─────►│disp_op├─────►│min_max_fc_op├──┬──►│"min"│
101+
└──────────────┘ └───────┘ └─────────────┘ │ └─────┘
102+
│ ┌─────┐
103+
└──►│"max"│
104+
└─────┘
105+
"""
106+
107+
disp_op = op.result.displacement(server=server_type)
108+
min_max_fc_op = op.min_max.min_max_fc(disp_op, server=server_type)
109+
110+
workflow = dpf.core.Workflow(server=server_type)
111+
112+
workflow.add_operators([disp_op, min_max_fc_op])
113+
114+
workflow.set_input_name("data_sources", disp_op.inputs.data_sources)
115+
workflow.set_output_name("min", min_max_fc_op.outputs.field_min)
116+
workflow.set_output_name("max", min_max_fc_op.outputs.field_max)
117+
118+
return workflow
119+
120+
121+
workflows = {
122+
"workflow_forward": workflow_forward,
123+
"workflow_forward_5": workflow_forward_5,
124+
"workflow_disp_min_max": workflow_disp_min_max,
125+
}
126+
workflow_topologies = {
127+
"workflow_forward": {
128+
"operators": 3,
129+
"operator_connections": 1,
130+
"data_connections": 1,
131+
"exposed_inputs": 1,
132+
"exposed_outputs": 2,
133+
},
134+
"workflow_forward_5": {
135+
"operators": 1,
136+
"operator_connections": 0,
137+
"data_connections": 0,
138+
"exposed_inputs": 5,
139+
"exposed_outputs": 5,
140+
},
141+
"workflow_disp_min_max": {
142+
"operators": 2,
143+
"operator_connections": 1,
144+
"data_connections": 0,
145+
"exposed_inputs": 1,
146+
"exposed_outputs": 2,
147+
},
148+
}
149+
150+
151+
@pytest.fixture(
152+
params=list(workflows.values()),
153+
ids=list(workflows.keys()),
154+
)
155+
def workflow(server_type, request) -> dpf.core.Workflow:
156+
wf = request.param(server_type)
157+
wf.name = list(workflows.keys())[request.param_index]
158+
return wf
159+
160+
161+
@pytest.fixture()
162+
def expected_workflow_topology(workflow):
163+
return workflow_topologies[workflow.name]
164+
165+
166+
def test_workflow_get_topology(workflow):
167+
workflow_topology = workflow.get_topology()
168+
169+
assert workflow_topology
170+
171+
172+
def test_workflow_topology_sizes(workflow, expected_workflow_topology):
173+
workflow_topology = workflow.get_topology()
174+
175+
assert len(workflow_topology.operators) == expected_workflow_topology["operators"]
176+
assert (
177+
len(workflow_topology.operator_connections)
178+
== expected_workflow_topology["operator_connections"]
179+
)
180+
assert len(workflow_topology.data_connections) == expected_workflow_topology["data_connections"]
181+
assert len(workflow_topology.exposed_inputs) == expected_workflow_topology["exposed_inputs"]
182+
assert len(workflow_topology.exposed_outputs) == expected_workflow_topology["exposed_outputs"]

0 commit comments

Comments
 (0)