Skip to content

Commit 853850a

Browse files
author
Vasileios Karakasis
authored
Merge pull request #2031 from giordano/mg/spack-env-none
[feat] Automatically create a Spack environment when not set
2 parents 6fd76da + a2af2ea commit 853850a

File tree

3 files changed

+58
-13
lines changed

3 files changed

+58
-13
lines changed

docs/tutorial_build_automation.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ Here is the test's code:
109109

110110

111111
When :attr:`~reframe.core.pipeline.RegressionTest.build_system` is set to ``'Spack'``, ReFrame will leverage Spack environments in order to build the test code.
112-
For this reason, currently, users must specify an environment.
113-
ReFrame treats Spack environments as *test resources* so it expects to find them under the test's :attr:`~reframe.core.pipeline.RegressionTest.sourcesdir`, which defaults to ``'src'``.
112+
If the environment is not specified by the user, ReFrame will automatically create one inside the stage directory.
113+
ReFrame treats Spack environments specified by the user as *test resources* so it expects to find them under the test's :attr:`~reframe.core.pipeline.RegressionTest.sourcesdir`, which defaults to ``'src'``.
114114
Here is the directory structure for the test in this particular example that we show here:
115115

116116
.. code:: console

reframe/core/buildsystems.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -780,11 +780,41 @@ class Spack(BuildSystem):
780780
#: ReFrame looks for environments in the test's
781781
#: :attr:`~reframe.core.pipeline.RegressionTest.sourcesdir`.
782782
#:
783-
#: This field is required.
783+
#: If this field is `None`, the default, the environment name will
784+
#: be automatically set to `rfm_spack_env`.
784785
#:
785786
#: :type: :class:`str` or :class:`None`
786-
#: :default: :class:`required`
787-
environment = variable(typ.Str[r'\S+'])
787+
#: :default: :class:`None`
788+
#:
789+
#: .. note::
790+
#: .. versionchanged:: 3.7.3
791+
#: The field is no longer required and the Spack environment will be
792+
#: automatically created if not provided.
793+
environment = variable(typ.Str[r'\S+'], type(None), value=None)
794+
795+
#: The directory where Spack will install the packages requested by this
796+
#: test.
797+
#:
798+
#: After activating the Spack environment, ReFrame will set the
799+
#: `install_tree` Spack configuration in the given environment with the
800+
#: following command:
801+
#:
802+
#: .. code-block:: bash
803+
#:
804+
#: spack config add "config:install_tree:root:<install tree>"
805+
#:
806+
#: Relative paths are resolved against the test's stage directory. If this
807+
#: field and the Spack environment are both `None`, the default, the
808+
#: install directory will be automatically set to `opt/spack`. If this
809+
#: field `None` but the Spack environment is not, then `install_tree` will
810+
#: not be set automatically and the install tree of the given environment
811+
#: will not be overridden.
812+
#:
813+
#: :type: :class:`str` or :class:`None`
814+
#: :default: :class:`None`
815+
#:
816+
#: .. versionadded:: 3.7.3
817+
install_tree = variable(typ.Str[r'\S+'], type(None), value=None)
788818

789819
#: A list of additional specs to build and install within the given
790820
#: environment.
@@ -816,10 +846,13 @@ class Spack(BuildSystem):
816846
install_opts = variable(typ.List[str], value=[])
817847

818848
def emit_build_commands(self, environ):
819-
if not hasattr(self, 'environment'):
820-
raise BuildSystemError(f'no Spack environment is defined')
821-
822849
ret = self._env_activate_cmds()
850+
851+
if not self.environment:
852+
install_tree = self.install_tree or 'opt/spack'
853+
ret.append(f'spack config add '
854+
f'"config:install_tree:root:{install_tree}"')
855+
823856
if self.specs:
824857
specs_str = ' '.join(self.specs)
825858
ret.append(f'spack add {specs_str}')
@@ -832,8 +865,15 @@ def emit_build_commands(self, environ):
832865
return ret
833866

834867
def _env_activate_cmds(self):
835-
return [f'. $SPACK_ROOT/share/spack/setup-env.sh',
836-
f'spack env activate -V -d {self.environment}']
868+
cmds = ['. $SPACK_ROOT/share/spack/setup-env.sh']
869+
if self.environment:
870+
environment = self.environment
871+
else:
872+
environment = 'rfm_spack_env'
873+
cmds.append(f'spack env create -d {environment}')
874+
875+
cmds.append(f'spack env activate -V -d {environment}')
876+
return cmds
837877

838878
def prepare_cmds(self):
839879
cmds = self._env_activate_cmds()

unittests/test_buildsystems.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,14 @@ def test_spack_with_spec(environ, tmp_path):
280280

281281
def test_spack_no_env(environ, tmp_path):
282282
build_system = bs.Spack()
283-
with pytest.raises(BuildSystemError):
284-
build_system.emit_build_commands(environ)
285-
283+
with osext.change_dir(tmp_path):
284+
assert build_system.emit_build_commands(environ) == [
285+
f'. $SPACK_ROOT/share/spack/setup-env.sh',
286+
f'spack env create -d rfm_spack_env',
287+
f'spack env activate -V -d rfm_spack_env',
288+
f'spack config add "config:install_tree:root:opt/spack"',
289+
f'spack install'
290+
]
286291

287292
def test_easybuild(environ, tmp_path):
288293
build_system = bs.EasyBuild()

0 commit comments

Comments
 (0)