"""Test Turbo-Turtle SCons builders and support functions"""
import pytest
import SCons
from turbo_turtle import scons_extensions
from turbo_turtle._settings import _default_abaqus_options
from turbo_turtle._settings import _default_cubit_options
from turbo_turtle._settings import _default_backend
[docs]
def check_nodes(nodes, post_action, node_count, action_count, expected_string, expected_env_kwargs):
"""Verify the expected action string against a builder's target nodes
:param SCons.Node.NodeList nodes: Target node list returned by a builder
:param list post_action: list of post action strings passed to builder
:param int node_count: expected length of ``nodes``
:param int action_count: expected length of action list for each node
:param str expected_string: the builder's action string.
:param dict expected_env_kwargs: the builder's expected environment keyword arguments
.. note::
The method of interrogating a node's action list results in a newline separated string instead of a list of
actions. The ``expected_string`` should contain all elements of the expected action list as a single, newline
separated string. The ``action_count`` should be set to ``1`` until this method is updated to search for the
finalized action list.
"""
for action in post_action:
expected_string = expected_string + f"\ncd ${{TARGET.dir.abspath}} && {action}"
assert len(nodes) == node_count
for node in nodes:
node.get_executor()
assert len(node.executor.action_list) == action_count
assert str(node.executor.action_list[0]) == expected_string
for key, value in expected_env_kwargs.items():
assert node.env[key] == value
# TODO: Figure out how to cleanly reset the construction environment between parameter sets
test_cli_builder = {
"cli_builder": (
"cli_builder",
{},
1,
1,
["cli_builder.txt"],
["cli_builder.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
},
),
"cli_builder": (
"cli_builder",
{"subcommand": "subcommand"},
1,
1,
["cli_builder.txt"],
["cli_builder.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "subcommand",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
},
),
}
@pytest.mark.parametrize(
"builder, kwargs, node_count, action_count, source_list, target_list, env",
test_cli_builder.values(),
ids=test_cli_builder.keys(),
)
def test_cli_builder(builder, kwargs, node_count, action_count, source_list, target_list, env):
env = SCons.Environment.Environment()
expected_string = (
"${cd_action_prefix} ${program} ${subcommand} ${required} ${options} "
"--abaqus-command ${abaqus_command} --cubit-command ${cubit_command} "
"--backend ${backend} ${redirect_action_postfix}"
)
env.Append(BUILDERS={builder: scons_extensions.cli_builder(**kwargs)})
nodes = env["BUILDERS"][builder](env, target=target_list, source=source_list)
check_nodes(nodes, [], node_count, action_count, expected_string, env)
test_builders = {
"geometry": (
"geometry",
{},
1,
1,
["geometry.txt"],
["geometry.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "geometry",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCES.abspath} --output-file ${TARGET.abspath}",
},
),
"geometry_xyplot": (
"geometry_xyplot",
{},
1,
1,
["geometry_xyplot.txt"],
["geometry_xyplot.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "geometry-xyplot",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCES.abspath} --output-file ${TARGET.abspath}",
},
),
"cylinder": (
"cylinder",
{},
1,
1,
["cylinder.txt"],
["cylinder.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "cylinder",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--output-file ${TARGET.abspath} --inner-radius ${inner_radius} --outer-radius ${outer_radius} "
"--height ${height}",
},
),
"sphere": (
"sphere",
{},
1,
1,
["sphere.txt"],
["sphere.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "sphere",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--output-file ${TARGET.abspath} --inner-radius ${inner_radius} --outer-radius ${outer_radius}",
},
),
"partition": (
"partition",
{},
1,
1,
["partition.txt"],
["partition.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "partition",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCE.abspath} --output-file ${TARGET.abspath}",
},
),
"mesh": (
"mesh",
{},
1,
1,
["mesh.txt"],
["mesh.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "mesh",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCE.abspath} --output-file ${TARGET.abspath} --element-type ${element_type}",
},
),
"image": (
"image",
{},
1,
1,
["image.txt"],
["image.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "image",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCE.abspath} --output-file ${TARGET.abspath}",
},
),
"merge": (
"merge",
{},
1,
1,
["merge.txt"],
["merge.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "merge",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCES.abspath} --output-file ${TARGET.abspath}",
},
),
"export": (
"export",
{},
1,
1,
["export.txt"],
["export.txt.stdout"],
{
"program": "turbo-turtle",
"subcommand": "export",
"abaqus_command": _default_abaqus_options,
"cubit_command": _default_cubit_options,
"backend": _default_backend,
"required": "--input-file ${SOURCE.abspath}",
},
),
}
@pytest.mark.parametrize(
"builder, kwargs, node_count, action_count, source_list, target_list, env",
test_builders.values(),
ids=test_builders.keys(),
)
def test_builders(builder, kwargs, node_count, action_count, source_list, target_list, env):
env = SCons.Environment.Environment()
expected_string = (
"${cd_action_prefix} ${program} ${subcommand} ${required} ${options} "
"--abaqus-command ${abaqus_command} --cubit-command ${cubit_command} "
"--backend ${backend} ${redirect_action_postfix}"
)
builder_function = getattr(scons_extensions, builder)
env.Append(BUILDERS={builder: builder_function(**kwargs)})
nodes = env["BUILDERS"][builder](env, target=target_list, source=source_list)
check_nodes(nodes, [], node_count, action_count, expected_string, env)