Skip to content

Commit 8841126

Browse files
authored
Improve psydac test command (#567)
### Main changes - Allow selecting a specific test function in a module by passing `--mod test_<MODULE>::test_<FUNCTION>` - Pass `--dist loadgroup` to group test execution by the `xdist_group` mark (see the documentation of [pytest-xdist](https://pytest-xdist.readthedocs.io/en/stable/distribution.html#running-tests-across-multiple-cpus)), which allows running non-thread-safe tests sequentially on a single runner - Remove local `.pytest_cache` folder before running tests - Move `pytest.ini` to package root, so it can be used after installation - If not present, copy `pytest.ini` to local working directory before running tests ### Additional changes - Fix the parallel creation of the folder `__psydac__` in `psydac.api.fem_bilinear_form`: only root process creates it
1 parent 6f2842b commit 8841126

3 files changed

Lines changed: 35 additions & 18 deletions

File tree

psydac/api/fem_bilinear_form.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,12 +1440,12 @@ def make_file(self, temps, ordered_stmts, field_derivatives, max_logical_derivat
14401440
assembly_code += '\n return\n'
14411441

14421442
#------------------------- MAKE FILE -------------------------
1443-
import os
1444-
if not os.path.isdir('__psydac__'):
1445-
os.makedirs('__psydac__')
14461443

14471444
# Root process writes the assembly code to a file
14481445
if comm is None or comm.rank == 0:
1446+
import os
1447+
if not os.path.isdir('__psydac__'):
1448+
os.makedirs('__psydac__')
14491449
filename = f'__psydac__/assemble_{file_id}.py'
14501450
f = open(filename, 'w')
14511451
f.writelines(assembly_code)
@@ -1996,26 +1996,23 @@ def construct_arguments_generate_assembly_file(self):
19961996
assembly_backend = self.backend
19971997
if self._pyccelize_test_trial_computation and assembly_backend['name'] == 'pyccel':
19981998

1999-
import os
2000-
if not os.path.isdir('__psydac__'):
2001-
os.makedirs('__psydac__')
2002-
20031999
comm = self.comm
20042000

2005-
if comm is not None and comm.size > 1:
2006-
if comm.rank == 0:
2007-
filename = '__psydac__/test_trial_computation.py'
2008-
code = self.test_trial_template
2009-
f = open(filename, 'w')
2010-
f.writelines(code)
2011-
f.close()
2012-
else:
2001+
# Root process writes the assembly code to a file
2002+
if comm is None or comm.rank == 0:
2003+
import os
2004+
if not os.path.isdir('__psydac__'):
2005+
os.makedirs('__psydac__')
20132006
filename = '__psydac__/test_trial_computation.py'
20142007
code = self.test_trial_template
20152008
f = open(filename, 'w')
20162009
f.writelines(code)
20172010
f.close()
20182011

2012+
# Parallel case: wait for the file to be closed before proceeding
2013+
if comm is not None and comm.size > 1:
2014+
_ = comm.bcast(None, root=0)
2015+
20192016
base_dirpath = os.getcwd()
20202017
sys.path.insert(0, base_dirpath)
20212018

psydac/cmd/psydac_test.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,37 @@ def psydac_test(*, mod, mpi, petsc, verbose, exitfirst):
7272
elif submods[0] != 'psydac':
7373
exit_with_error_message("module name must start with 'psydac'")
7474
try:
75+
modname = mod.split('::')[0]
7576
import importlib
76-
importlib.import_module(mod)
77+
importlib.import_module(modname)
7778
except ImportError:
78-
exit_with_error_message(f"module '{mod}' not found")
79+
exit_with_error_message(f"module '{modname}' not found")
7980

8081
# Import modules here to speed up parser
8182
import os
8283
import shutil
8384
import subprocess
8485
import time
8586

87+
# Clear Pytest cache from the current working directory
88+
cache_dir = '.pytest_cache'
89+
if os.path.isdir(cache_dir):
90+
print(f'Removing existing Pytest cache directory: {cache_dir}\n', flush=True)
91+
shutil.rmtree(cache_dir)
92+
93+
# If no pytest.ini file exists in the current working directory, copy it
94+
# from the parent directory of this script (which is installed with PSYDAC)
95+
if not os.path.isfile('pytest.ini'):
96+
script_dir = os.path.dirname(os.path.abspath(__file__))
97+
parent_dir = os.path.dirname(script_dir)
98+
pytest_ini = os.path.join(parent_dir, 'pytest.ini')
99+
if not os.path.isfile(pytest_ini):
100+
exit_with_error_message(f'could not find pytest.ini file in {parent_dir}')
101+
else:
102+
print(f'Copying pytest.ini from: {parent_dir}\n', flush=True)
103+
shutil.copy(pytest_ini, os.getcwd())
104+
105+
# Build the list of flags for pytest
86106
flags = []
87107

88108
# Set up MPI execution command, if needed
@@ -112,7 +132,7 @@ def psydac_test(*, mod, mpi, petsc, verbose, exitfirst):
112132

113133
else:
114134
mpi_exe = []
115-
flags.extend(['-n', 'auto'])
135+
flags.extend(['-n', 'auto', '--dist', 'loadgroup']) # for pytest-xdist
116136

117137
# If PETSc tests are requested, check that petsc4py is installed
118138
if petsc:
File renamed without changes.

0 commit comments

Comments
 (0)