Skip to content

Commit

Permalink
Updated tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
hiker committed Dec 3, 2024
1 parent 39a8204 commit 7b189e8
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 25 deletions.
3 changes: 1 addition & 2 deletions source/fab/tools/linker.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ def get_pre_link_flags(self) -> List[str]:
wrapped linkers
'''
params: List[str] = []
print("gplf", self._pre_lib_flags, self, self._linker)
if self._pre_lib_flags:
params.extend(self._pre_lib_flags)
if self._linker:
Expand Down Expand Up @@ -202,7 +201,7 @@ def link(self, input_files: List[Path], output_file: Path,
linker = linker._linker
# Now we must have a compiler
compiler = linker._compiler
assert compiler
assert compiler # make mypy happy
params.extend(compiler.flags)

if openmp:
Expand Down
37 changes: 28 additions & 9 deletions tests/unit_tests/steps/test_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@
# For further details please refer to the file COPYRIGHT
# which you should have received as part of this distribution
# ##############################################################################

'''
Tests linking an executable.
'''

from pathlib import Path
from types import SimpleNamespace
from unittest import mock

from fab.artefacts import ArtefactSet, ArtefactStore
from fab.steps.link import link_exe
from fab.tools import Linker
from fab.tools import FortranCompiler, Linker

import pytest


class TestLinkExe:
def test_run(self, tool_box, mock_fortran_compiler):
# ensure the command is formed correctly, with the flags at the
# end (why?!)

'''Test class for linking an executable.
'''
def test_run(self, tool_box):
'''Ensure the command is formed correctly, with the flags at the
end and that environment variable FFLAGS is picked up.
'''
config = SimpleNamespace(
project_workspace=Path('workspace'),
artefact_store=ArtefactStore(),
Expand All @@ -29,9 +36,20 @@ def test_run(self, tool_box, mock_fortran_compiler):
config.artefact_store[ArtefactSet.OBJECT_FILES] = \
{'foo': {'foo.o', 'bar.o'}}

with mock.patch.dict("os.environ", {"FFLAGS": "-L/foo1/lib -L/foo2/lib"}):
# We need to create a linker here to pick up the env var:
linker = Linker(compiler=mock_fortran_compiler)
with mock.patch.dict("os.environ",
{"FFLAGS": "-L/foo1/lib -L/foo2/lib"}):
# We need to create the compiler here in order to pick
# up the environment
mock_compiler = FortranCompiler("mock_fortran_compiler",
"mock_fortran_compiler.exe",
"suite", module_folder_flag="",
version_regex="something",
syntax_only_flag=None,
compile_flag=None,
output_flag=None, openmp_flag=None)
mock_compiler.run = mock.Mock()

linker = Linker(compiler=mock_compiler)
# Mark the linker as available to it can be added to the tool box
linker._is_available = True

Expand All @@ -44,7 +62,8 @@ def test_run(self, tool_box, mock_fortran_compiler):
pytest.warns(UserWarning,
match="_metric_send_conn not "
"set, cannot send metrics"):
link_exe(config, libs=['mylib'], flags=['-fooflag', '-barflag'])
link_exe(config, libs=['mylib'],
flags=['-fooflag', '-barflag'])

tool_run.assert_called_with(
['mock_fortran_compiler.exe', '-L/foo1/lib', '-L/foo2/lib',
Expand Down
22 changes: 16 additions & 6 deletions tests/unit_tests/steps/test_link_shared_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

from fab.artefacts import ArtefactSet, ArtefactStore
from fab.steps.link import link_shared_object
from fab.tools import Linker
from fab.tools import FortranCompiler, Linker

import pytest


def test_run(tool_box, mock_c_compiler):
def test_run(tool_box):
'''Ensure the command is formed correctly, with the flags at the
end since they are typically libraries.'''

Expand All @@ -33,8 +33,17 @@ def test_run(tool_box, mock_c_compiler):
{None: {'foo.o', 'bar.o'}}

with mock.patch.dict("os.environ", {"FFLAGS": "-L/foo1/lib -L/foo2/lib"}):
# We need to create a linker here to pick up the env var:
linker = Linker(mock_c_compiler)
# We need to create the compiler here in order to pick
# up the environment
mock_compiler = FortranCompiler("mock_fortran_compiler",
"mock_fortran_compiler.exe",
"suite", module_folder_flag="",
version_regex="something",
syntax_only_flag=None,
compile_flag=None, output_flag=None,
openmp_flag=None)
mock_compiler.run = mock.Mock()
linker = Linker(mock_compiler)
# Mark the linker as available so it can added to the tool box:
linker._is_available = True
tool_box.add_tool(linker, silent_replace=True)
Expand All @@ -47,6 +56,7 @@ def test_run(tool_box, mock_c_compiler):
flags=['-fooflag', '-barflag'])

tool_run.assert_called_with(
['mock_c_compiler.exe', '-L/foo1/lib', '-L/foo2/lib', 'bar.o', 'foo.o',
'-fooflag', '-barflag', '-fPIC', '-shared', '-o', '/tmp/lib_my.so'],
['mock_fortran_compiler.exe', '-L/foo1/lib', '-L/foo2/lib', 'bar.o',
'foo.o', '-fooflag', '-barflag', '-fPIC', '-shared',
'-o', '/tmp/lib_my.so'],
capture_output=True, env=None, cwd=None, check=False)
35 changes: 27 additions & 8 deletions tests/unit_tests/tools/test_linker.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,31 @@ def test_linker(mock_c_compiler, mock_fortran_compiler):
assert linker.flags == []


def test_linker_constructor_error(mock_c_compiler):
'''Test the linker constructor with invalid parameters.'''

with pytest.raises(RuntimeError) as err:
Linker()
assert ("Neither compiler nor linker is specified in linker constructor."
in str(err.value))
with pytest.raises(RuntimeError) as err:
Linker(compiler=mock_c_compiler, linker=mock_c_compiler)
assert ("Both compiler and linker is specified in linker constructor."
in str(err.value))


@pytest.mark.parametrize("mpi", [True, False])
def test_linker_mpi(mock_c_compiler, mpi):
'''Test the linker constructor with invalid parameters.'''

mock_c_compiler._mpi = mpi
linker = Linker(compiler=mock_c_compiler)
assert linker.mpi == mpi

wrapped_linker = Linker(linker=linker)
assert wrapped_linker.mpi == mpi


def test_linker_gets_ldflags(mock_c_compiler):
"""Tests that the linker retrieves env.LDFLAGS"""
with mock.patch.dict("os.environ", {"LDFLAGS": "-lm"}):
Expand Down Expand Up @@ -250,14 +275,8 @@ def test_linker_all_flag_types(mock_c_compiler):
"""Make sure all possible sources of linker flags are used in the right
order"""

# Environment variables for both the compiler and linker
# TODO: THIS IS ACTUALLY WRONG - The FFLAGS shouldn't be picked up here,
# because the compiler already exists. It is being added twice, because
# Linker inherits Compiler (in addition to wrapping it)
with mock.patch.dict("os.environ", {
"FFLAGS": "-fflag",
"LDFLAGS": "-ldflag"
}):
# Environment variables for both the linker
with mock.patch.dict("os.environ", {"LDFLAGS": "-ldflag"}):
linker = Linker(compiler=mock_c_compiler)

mock_c_compiler.add_flags(["-compiler-flag1", "-compiler-flag2"])
Expand Down

0 comments on commit 7b189e8

Please sign in to comment.