Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loki: Turn test sub-directories into sub-pacakges #447

Merged
merged 3 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions loki/analyse/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
6 changes: 6 additions & 0 deletions loki/backend/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
2 changes: 1 addition & 1 deletion loki/backend/tests/test_fgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from loki.backend import fgen
from loki.expression import symbols as sym
from loki.frontend import available_frontends, OMNI
from loki.ir import Intrinsic, DataDeclaration
from loki.ir import DataDeclaration
from loki.types import ProcedureType, BasicType


Expand Down
6 changes: 6 additions & 0 deletions loki/batch/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
5 changes: 5 additions & 0 deletions loki/batch/tests/test_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ def test_procedure_item1(testdir):

# To ensure any existing items from the item_cache are re-used, we instantiate one for
# the procedure binding
# pylint: disable=unsupported-binary-operation
t_mod_t_proc = get_item(
ProcedureBindingItem, proj/'module/t_mod.F90', 't_mod#t%proc',
RegexParserClass.ProgramUnitClass | RegexParserClass.TypeDefClass | RegexParserClass.DeclarationClass
Expand Down Expand Up @@ -805,6 +806,7 @@ def test_interface_item_in_subroutine(testdir):

def test_procedure_binding_item1(testdir):
proj = testdir/'sources/projBatch'
# pylint: disable=unsupported-binary-operation
parser_classes = (
RegexParserClass.ProgramUnitClass | RegexParserClass.TypeDefClass | RegexParserClass.DeclarationClass
)
Expand All @@ -830,6 +832,7 @@ def test_procedure_binding_item1(testdir):

def test_procedure_binding_item2(testdir, default_config):
proj = testdir/'sources/projBatch'
# pylint: disable=unsupported-binary-operation
parser_classes = (
RegexParserClass.ProgramUnitClass | RegexParserClass.TypeDefClass | RegexParserClass.DeclarationClass
)
Expand Down Expand Up @@ -871,6 +874,7 @@ def test_procedure_binding_item2(testdir, default_config):

def test_procedure_binding_item3(testdir):
proj = testdir/'sources/projBatch'
# pylint: disable=unsupported-binary-operation
parser_classes = (
RegexParserClass.ProgramUnitClass | RegexParserClass.TypeDefClass | RegexParserClass.DeclarationClass
)
Expand Down Expand Up @@ -909,6 +913,7 @@ def test_procedure_binding_item3(testdir):
])
def test_procedure_binding_with_config(testdir, config, expected_dependencies):
proj = testdir/'sources/projBatch'
# pylint: disable=unsupported-binary-operation
parser_classes = (
RegexParserClass.ProgramUnitClass | RegexParserClass.TypeDefClass | RegexParserClass.DeclarationClass
)
Expand Down
10 changes: 5 additions & 5 deletions loki/batch/tests/test_transformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,8 @@ def transform_subroutine(self, routine, **kwargs):
assert comments[4].text == '! No !'

# Check that the string representation is sane
assert '<YesTrafo [test_transformation]' in str(pipe)
assert '<MaybeTrafo [test_transformation]' in str(pipe)
assert '<MaybeNotTrafo [test_transformation]' in str(pipe)
assert '<YesTrafo [test_transformation]' in str(pipe)
assert '<NoTrafo [test_transformation]' in str(pipe)
assert '<YesTrafo [loki.batch.tests.test_transformation]' in str(pipe)
assert '<MaybeTrafo [loki.batch.tests.test_transformation]' in str(pipe)
assert '<MaybeNotTrafo [loki.batch.tests.test_transformation]' in str(pipe)
assert '<YesTrafo [loki.batch.tests.test_transformation]' in str(pipe)
assert '<NoTrafo [loki.batch.tests.test_transformation]' in str(pipe)
6 changes: 6 additions & 0 deletions loki/build/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
7 changes: 4 additions & 3 deletions loki/build/tests/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
from pathlib import Path
import pytest

from loki.build import (
Obj, Lib, Builder,
Compiler, GNUCompiler, NvidiaCompiler, get_compiler_from_env, _default_compiler
from loki.build import Obj, Lib, Builder
from loki.build.compiler import (
Compiler, GNUCompiler, NvidiaCompiler, get_compiler_from_env,
_default_compiler
)


Expand Down
6 changes: 6 additions & 0 deletions loki/expression/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
6 changes: 6 additions & 0 deletions loki/frontend/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
6 changes: 6 additions & 0 deletions loki/ir/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
1 change: 0 additions & 1 deletion loki/ir/tests/test_control_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,6 @@ def test_single_line_forall_masked_stmt(tmp_path, frontend):
assert bound_var == "j"
assert bound_range == '1:n'
# Check the array mask
mask = statements[0].mask
assert statements[0].mask == 'a(i, j) != 0.0'
# Quickly check assignment
assignments = FindNodes(ir.Assignment).visit(statements[0])
Expand Down
76 changes: 38 additions & 38 deletions loki/ir/tests/test_ir_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.

import pytest

from dataclasses import FrozenInstanceError

import pytest
from pymbolic.primitives import Expression
from pydantic import ValidationError

Expand Down Expand Up @@ -52,17 +52,17 @@ def test_assignment(scope, a_i):
assert assign.comment is None

# Ensure "frozen" status of node objects
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
assign.lhs = sym.Scalar('b', scope=scope)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
assign.rhs = sym.Scalar('b', scope=scope)

# Test errors for wrong contructor usage
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Assignment(lhs='a', rhs=sym.Literal(42.0))
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Assignment(lhs=a_i, rhs='42.0 + 6.0')
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Assignment(lhs=a_i, rhs=sym.Literal(42.0), comment=a_i)


Expand All @@ -81,11 +81,11 @@ def test_loop(scope, one, i, n, a_i):
assert loop.children == ( i, bounds, (assign,) )

# Ensure "frozen" status of node objects
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
loop.variable = sym.Scalar('j', scope=scope)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
loop.bounds = sym.Range((n, sym.Scalar('k', scope=scope)))
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
loop.body = (assign, assign, assign)

# Test auto-casting of the body to tuple
Expand All @@ -97,17 +97,17 @@ def test_loop(scope, one, i, n, a_i):
assert loop.body == (assign, assign, assign)

# Test errors for wrong contructor usage
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Loop(variable=i, bounds=bounds, body=n)
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Loop(variable=None, bounds=bounds, body=(assign,))
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Loop(variable=i, bounds=None, body=(assign,))

# TODO: Test pragmas, names and labels


def test_conditional(scope, one, i, n, a_i):
def test_conditional(scope, n, a_i):
"""
Test constructors of :any:`Conditional`.
"""
Expand All @@ -124,34 +124,34 @@ def test_conditional(scope, one, i, n, a_i):
assert all(isinstance(n, ir.Node) for n in cond.else_body)
assert cond.children == ( condition, (assign, assign), (assign,) )

with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
cond.condition = parse_expr('k == 0', scope=scope)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
cond.body = (assign, assign, assign)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
cond.else_body = (assign, assign, assign)

# Test auto-casting of the body / else_body to tuple
cond = ir.Conditional(condition=condition, body=assign)
assert cond.body == (assign,) and cond.else_body == ()
assert cond.body == (assign,) and not cond.else_body
cond = ir.Conditional(condition=condition, body=( (assign,), ))
assert cond.body == (assign,) and cond.else_body == ()
assert cond.body == (assign,) and not cond.else_body
cond = ir.Conditional(condition=condition, body=( assign, (assign,), assign, None))
assert cond.body == (assign, assign, assign) and cond.else_body == ()
assert cond.body == (assign, assign, assign) and not cond.else_body

cond = ir.Conditional(condition=condition, body=(), else_body=assign)
assert cond.body == () and cond.else_body == (assign,)
assert not cond.body and cond.else_body == (assign,)
cond = ir.Conditional(condition=condition, body=(), else_body=( (assign,), ))
assert cond.body == () and cond.else_body == (assign,)
assert not cond.body and cond.else_body == (assign,)
cond = ir.Conditional(
condition=condition, body=(), else_body=( assign, (assign,), assign, None)
)
assert cond.body == () and cond.else_body == (assign, assign, assign)
assert not cond.body and cond.else_body == (assign, assign, assign)

# TODO: Test inline, name, has_elseif


def test_multi_conditional(scope, one, i, n, a_i):
def test_multi_conditional(i, a_i):
"""
Test nested chains of constructors of :any:`Conditional` to form
multi-conditional.
Expand Down Expand Up @@ -199,7 +199,7 @@ def test_multi_conditional(scope, one, i, n, a_i):
assert else_bodies[1][0].lhs == 'a(i)' and else_bodies[1][0].rhs == '1.0'


def test_section(scope, one, i, n, a_n, a_i):
def test_section(n, a_n, a_i):
"""
Test constructors and behaviour of :any:`Section` nodes.
"""
Expand All @@ -213,13 +213,13 @@ def test_section(scope, one, i, n, a_n, a_i):
sec = ir.Section(body=(assign, assign))
assert isinstance(sec.body, tuple) and len(sec.body) == 2
assert all(isinstance(n, ir.Node) for n in sec.body)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
sec.body = (assign, assign)

sec = ir.Section(body=(func, func))
assert isinstance(sec.body, tuple) and len(sec.body) == 2
assert all(isinstance(n, Scope) for n in sec.body)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
sec.body = (func, func)

sec = ir.Section((assign, assign))
Expand Down Expand Up @@ -264,29 +264,29 @@ def test_callstatement(scope, one, i, n, a_i):
)

# Ensure "frozen" status of node objects
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
call.name = sym.ProcedureSymbol('dave', scope=scope)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
call.arguments = (a_i, n, one)
with pytest.raises(FrozenInstanceError) as error:
with pytest.raises(FrozenInstanceError):
call.kwarguments = (('i', one), ('j', i))

# Test auto-casting of the body to tuple
call = ir.CallStatement(name=cname, arguments=[a_i, one])
assert call.arguments == (a_i, one) and call.kwarguments == ()
assert call.arguments == (a_i, one) and not call.kwarguments
call = ir.CallStatement(name=cname, arguments=None)
assert call.arguments == () and call.kwarguments == ()
assert not call.arguments and not call.kwarguments
call = ir.CallStatement(name=cname, kwarguments=[('i', i), ('j', one)])
assert call.arguments == () and call.kwarguments == (('i', i), ('j', one))
assert not call.arguments and call.kwarguments == (('i', i), ('j', one))
call = ir.CallStatement(name=cname, kwarguments=None)
assert call.arguments == () and call.kwarguments == ()
assert not call.arguments and not call.kwarguments

# Test errors for wrong contructor usage
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.CallStatement(name='a', arguments=(sym.Literal(42.0),))
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.CallStatement(name=cname, arguments=('a',))
with pytest.raises(ValidationError) as error:
with pytest.raises(ValidationError):
ir.Assignment(
name=cname, arguments=(sym.Literal(42.0),), kwarguments=('i', 'i')
)
Expand All @@ -304,7 +304,7 @@ def test_associate(scope, a_i):
assign = ir.Assignment(lhs=a_i, rhs=sym.Literal(42.0))
assign2 = ir.Assignment(lhs=a_i.clone(parent=b), rhs=sym.Literal(66.6))

assoc = ir.Associate(associations=((b_a, a),), body=(assign, assign2), parent=scope)
assoc = ir.Associate(associations=((b_a, a),), body=(assign, assign2), parent=scope) # pylint: disable=unexpected-keyword-arg
assert isinstance(assoc.associations, tuple)
assert all(isinstance(n, tuple) and len(n) == 2 for n in assoc.associations)
assert isinstance(assoc.body, tuple)
Expand Down
4 changes: 2 additions & 2 deletions loki/ir/tests/test_pragma_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_get_pragma_parameters_multiline(frontend):
assert pragmas[0].keyword == 'OMP'
params = get_pragma_parameters(pragmas[0], only_loki_pragmas=False)
assert len(params) == 3
assert params['PARALLEL'] == None
assert params['PARALLEL'] is None
assert params['PRIVATE'].strip() == 'i, j'
assert params['FIRSTPRIVATE'].strip() == 'n, a, b'

Expand Down Expand Up @@ -656,7 +656,7 @@ def test_pragmas_mixed_key_value_attrs(frontend):

routine = Subroutine.from_source(fcode, frontend=frontend)

pragma = Pragma(keyword='acc', content=f'kernels num_gangs ( 1 ) async wait')
pragma = Pragma(keyword='acc', content='kernels num_gangs ( 1 ) async wait')
assert get_pragma_parameters(pragma, only_loki_pragmas=False) == {
'kernels': None,
'num_gangs': ' 1 ',
Expand Down
2 changes: 1 addition & 1 deletion loki/ir/tests/test_scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_scoped_node_get_symbols(frontend, tmp_path):
assert routine.get_symbol('b') == 'b(n)'
assert routine.get_symbol('b').scope == routine
assert routine.get_symbol('c') == 'c'
assert routine.get_symbol('c').scope == routine
assert routine.get_symbol('c').scope == routine
assert routine.get_symbol('jprb') == 'jprb'
assert routine.get_symbol('jprb').scope == module
assert routine.get_symbol('jprb').initial == 8
Expand Down
2 changes: 1 addition & 1 deletion loki/program_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def __initialize__(self, name, docstring=None, spec=None, contains=None,
if not isinstance(contains, ir.Section):
contains = ir.Section(body=as_tuple(contains))
for node in contains.body:
if isinstance(node, ir.Intrinsic) and 'contains' in node.text.lower():
if isinstance(node, ir.Intrinsic) and 'contains' in node.text.lower(): # pylint: disable=no-member
break
if isinstance(node, ProgramUnit):
contains.prepend(ir.Intrinsic(text='CONTAINS'))
Expand Down
6 changes: 6 additions & 0 deletions loki/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# (C) Copyright 2018- ECMWF.
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation
# nor does it submit to any jurisdiction.
4 changes: 2 additions & 2 deletions loki/tests/test_dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,5 @@ def test_dimension_config(tmp_path):
assert dim_b.size == nblocks
assert dim_b.index == ibl
assert dim_b.bounds == (sym.IntLiteral(1), nblocks)
assert dim_b.lower == (one, start, start.clone(parent=dim))
assert dim_b.upper == (nblocks, end, end.clone(parent=dim))
assert dim_b.lower == (one, start, start.clone(parent=dim)) # pylint: disable=no-member
assert dim_b.upper == (nblocks, end, end.clone(parent=dim)) # pylint: disable=no-member
8 changes: 5 additions & 3 deletions loki/tests/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,8 @@ def test_module_rename_imports_no_definitions(frontend, tmp_path):
end module test_other_rename_mod
""".strip()

mod1 = Module.from_source(fcode_mod1, frontend=frontend, xmods=[tmp_path])
mod2 = Module.from_source(fcode_mod2, frontend=frontend, xmods=[tmp_path])
_ = Module.from_source(fcode_mod1, frontend=frontend, xmods=[tmp_path])
_ = Module.from_source(fcode_mod2, frontend=frontend, xmods=[tmp_path])

fcode_mod3 = """
module some_mod
Expand Down Expand Up @@ -1306,7 +1306,9 @@ def test_module_all_imports(frontend, tmp_path):

header_a = Module.from_source(fcode['header_a'], frontend=frontend, xmods=[tmp_path])
header_b = Module.from_source(fcode['header_b'], frontend=frontend, xmods=[tmp_path])
routine_mod = Module.from_source(fcode['routine'], definitions=(header_a, header_b), frontend=frontend, xmods=[tmp_path])
routine_mod = Module.from_source(
fcode['routine'], definitions=(header_a, header_b), frontend=frontend, xmods=[tmp_path]
)
routine = routine_mod['routine']

assert routine_mod.parents == ()
Expand Down
Loading
Loading