Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
mpsd-software-manager
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
MPSD Computational Science
mpsd-software-manager
Commits
9fff963f
Commit
9fff963f
authored
1 year ago
by
Hans Fangohr
Browse files
Options
Downloads
Plain Diff
Merge branch 'force-checking-of-error-code' into 'split-installation-tests'
# Conflicts: # tests.py
parents
2d4db7a6
38fa0d2c
No related branches found
No related tags found
No related merge requests found
Pipeline
#368561
passed
1 year ago
Stage: test
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
.gitlab-ci.yml
+4
-1
4 additions, 1 deletion
.gitlab-ci.yml
mpsd-software-environment.py
+116
-69
116 additions, 69 deletions
mpsd-software-environment.py
tests.py
+24
-11
24 additions, 11 deletions
tests.py
with
144 additions
and
81 deletions
.gitlab-ci.yml
+
4
−
1
View file @
9fff963f
...
@@ -15,7 +15,7 @@ stages:
...
@@ -15,7 +15,7 @@ stages:
-
ls -l
-
ls -l
-
pip install -U pip
-
pip install -U pip
-
pip --version
-
pip --version
-
pip install pytest black ruff
-
pip install pytest black ruff
pydocstyle
-
pytest --version
-
pytest --version
-
cat /etc/issue
-
cat /etc/issue
...
@@ -79,6 +79,9 @@ style:
...
@@ -79,6 +79,9 @@ style:
-
ruff --version
-
ruff --version
-
ruff .
-
ruff .
-
black --check --diff .
-
black --check --diff .
-
pydocstyle mpsd-software-environment.py
-
pydocstyle tests.py
# we could also use `ruff --select D` for pycodestyle. But the behaviour is not exactly the same.
test-bullseye
:
test-bullseye
:
...
...
This diff is collapsed.
Click to expand it.
mpsd-software-environment.py
+
116
−
69
View file @
9fff963f
#!/usr/bin/env python3
#!/usr/bin/env python3
"""
mpsd-software-environment: tool for installation of toolchains.
"""
import
argparse
import
argparse
import
datetime
import
datetime
import
os
import
os
...
@@ -15,6 +18,7 @@ This function builds toolchains for MPSD-HPC at the appropriate directory, \n
...
@@ -15,6 +18,7 @@ This function builds toolchains for MPSD-HPC at the appropriate directory, \n
for given system architecture and MPSD software stack version.
\n
for given system architecture and MPSD software stack version.
\n
The toolchains
The toolchains
are built using the bash script spack_setup.sh, and the results are logged.
"""
are built using the bash script spack_setup.sh, and the results are logged.
"""
config_vars
=
{
config_vars
=
{
"
cmd_log_file
"
:
"
install.log
"
,
"
cmd_log_file
"
:
"
install.log
"
,
"
build_log_file
"
:
(
"
build_log_file
"
:
(
...
@@ -28,29 +32,32 @@ config_vars = {
...
@@ -28,29 +32,32 @@ config_vars = {
# Helper class to change directory via context manager
# Helper class to change directory via context manager
class
os_chdir
:
class
os_chdir
:
"""
"""
The os_chdir class is a context manager.
The os_chdir class is a context manager that
changes the current directory to a specified directory
It
changes the current directory to a specified directory
and returns to the original directory after execution.
and returns to the original directory after execution.
"""
"""
def
__init__
(
self
,
new_dir
):
def
__init__
(
self
,
new_dir
):
"""
Initialize, save original directory.
"""
self
.
new_dir
=
new_dir
self
.
new_dir
=
new_dir
self
.
saved_dir
=
os
.
getcwd
()
self
.
saved_dir
=
os
.
getcwd
()
def
__enter__
(
self
):
def
__enter__
(
self
):
"""
Go to target directory (main action for context).
"""
os
.
chdir
(
self
.
new_dir
)
os
.
chdir
(
self
.
new_dir
)
def
__exit__
(
self
,
exc_type
,
exc_val
,
exc_tb
):
def
__exit__
(
self
,
exc_type
,
exc_val
,
exc_tb
):
"""
On exist we return to original directory.
"""
os
.
chdir
(
self
.
saved_dir
)
os
.
chdir
(
self
.
saved_dir
)
def
run
(
*
args
,
counter
=
[
0
],
**
kwargs
):
def
run
(
*
args
,
counter
=
[
0
],
**
kwargs
):
"""
"""
Call subprocess.run
(*args, **kwargs)
and print logging data.
Call subprocess.run and print logging data.
Conveniene function to call `subprocess.run
` and provide some metadata
Conveniene function to call `subprocess.run
(*args, **kwargs)`
about the call.
and provide some metadata
about the call.
Parameters
Parameters
----------
----------
...
@@ -130,22 +137,34 @@ def run(*args, counter=[0], **kwargs):
...
@@ -130,22 +137,34 @@ def run(*args, counter=[0], **kwargs):
def
setup_log_cmd
(
def
setup_log_cmd
(
mpsd_release
:
str
,
script_dir
:
str
,
msg
:
str
=
None
,
*
args
,
**
kwargs
mpsd_release
:
str
,
script_dir
:
str
,
msg
:
str
=
None
,
**
kwargs
)
->
None
:
)
->
None
:
"""
The setup_log_cmd function logs the command used to build the
"""
toolchains, along with information about the software environment installer
Log the command used to build the toolchains.
branch, the Spack environments branch, and the commit hashes of each. It
also logs steps taken in install process using the optional message
argument.
Args:
It also logs information about the software environment installer branch,
mpsd_release (str): The name of the release to install toolchains for
.
the Spack environments branch, and the commit hashes of each
.
script_dir (str): The path to the directory where the scripts are located.
It also logs steps taken
msg (str, optional): An optional message to log in the command log file
.
in the install process using the optional message argument
.
Returns:
Parameters
None
----------
- mpsd_release : str
The name of the release to install toolchains for.
- script_dir : str
The path to the directory where the scripts are located.
- msg : str, optional
An optional message to log in the command log file.
- **kwargs : dict
A dictionary with values for
- spe_branch : str
The name of the Spack environments branch.
- spe_commit_hash : str
The commit hash of the Spack environments branch.
Returns
-------
- None
"""
"""
release_base_dir
=
script_dir
/
mpsd_release
release_base_dir
=
script_dir
/
mpsd_release
...
@@ -205,17 +224,21 @@ def setup_log_cmd(
...
@@ -205,17 +224,21 @@ def setup_log_cmd(
def
create_dir_structure
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
None
:
def
create_dir_structure
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
None
:
"""
The create_dir_structure function creates the directory structure for
"""
Create the directory structure and clone spack environments repo.
The create_dir_structure function creates the directory structure for
the specified release and clones the Spack environments repository if it
the specified release and clones the Spack environments repository if it
doesn
'
t exist.
doesn
'
t exist.
Args:
Parameters
----------
- mpsd_release: A string representing the MPSD release version.
- mpsd_release: A string representing the MPSD release version.
- script_dir: A Path object representing the path to the scripts directory.
- script_dir: A Path object representing the path to the scripts directory.
Returns:
Returns
-------
- None
- None
"""
"""
# Create the directory structure for the release
# Create the directory structure for the release
release_base_dir
=
script_dir
/
mpsd_release
release_base_dir
=
script_dir
/
mpsd_release
...
@@ -248,22 +271,31 @@ def create_dir_structure(mpsd_release: str, script_dir: Path) -> None:
...
@@ -248,22 +271,31 @@ def create_dir_structure(mpsd_release: str, script_dir: Path) -> None:
def
get_release_info
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
Tuple
[
str
,
str
,
List
[
str
]]:
def
get_release_info
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
Tuple
[
str
,
str
,
List
[
str
]]:
"""
"""
Get information about the specified release.
Get information about the specified release, such as the branch and commit hash
Get information about the specified release, such as the branch and commit hash
of the Spack environments repository and the available toolchains.
of the Spack environments repository and the available toolchains.
Args:
Parameters
- mpsd_release (str) : the name of the release to get information for.
----------
- script_dir (pathlib.Path): the base directory where releases are stored.
mpsd_release : str
The name of the release to get information for.
Returns:
script_dir : pathlib.Path
- spe_branch: str, the name of the branch for the Spack environments repository.
The base directory where releases are stored.
- spe_commit_hash: str, the commit hash for the Spack environments repository.
- available_toolchains: list, a list of strings representing the available
toolchains for the release.
Raises:
Returns
- FileNotFoundError: If the release directory does not exist. Run
-------
`create_dir_structure()` first.
spe_branch : str
The name of the branch for the Spack environments repository.
spe_commit_hash : str
The commit hash for the Spack environments repository.
available_toolchains : list
A list of strings representing the available toolchains for the release.
Raises
------
FileNotFoundError
If the release directory does not exist. Run `create_dir_structure()` first.
"""
"""
# Get the info for release
# Get the info for release
release_base_dir
=
script_dir
/
mpsd_release
release_base_dir
=
script_dir
/
mpsd_release
...
@@ -294,20 +326,26 @@ def get_release_info(mpsd_release: str, script_dir: Path) -> Tuple[str, str, Lis
...
@@ -294,20 +326,26 @@ def get_release_info(mpsd_release: str, script_dir: Path) -> Tuple[str, str, Lis
def
prepare_environment
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
List
[
str
]:
def
prepare_environment
(
mpsd_release
:
str
,
script_dir
:
Path
)
->
List
[
str
]:
"""
"""
- Creates the directory structure for the given MPSD release and clones the
Create the directory structure for the given MPSD release.
spack-environments repository.
- Determines the branch and commit hash of the spack-environments repository and
It does the following steps:
the available toolchains.
Clones the spack-environments repository.
- Logs the command usage.
Determines the branch and commit hash of the spack-environments repository
and the available toolchains.
Args:
Logs the command usage.
- mpsd_release (str): The name of the MPSD release to prepare the environment for.
- script_dir (pathlib.Path): The base directory to create the release folder and
Parameters
clone the spack-environments repository into.
----------
mpsd_release : str
Returns:
The name of the MPSD release to prepare the environment for.
- available_toolchains (list): A list of available toolchains for the given MPSD
script_dir : pathlib.Path
release.
The base directory to create the release folder and
clone the spack-environments repository into.
Returns
-------
available_toolchains : list
A list of available toolchains for the given MPSD release.
"""
"""
create_dir_structure
(
mpsd_release
,
script_dir
)
create_dir_structure
(
mpsd_release
,
script_dir
)
spe_branch
,
spe_commit_hash
,
available_toolchains
=
get_release_info
(
spe_branch
,
spe_commit_hash
,
available_toolchains
=
get_release_info
(
...
@@ -326,30 +364,36 @@ def install_environment(
...
@@ -326,30 +364,36 @@ def install_environment(
force_reinstall
:
bool
=
False
,
force_reinstall
:
bool
=
False
,
enable_build_cache
:
bool
=
False
,
enable_build_cache
:
bool
=
False
,
)
->
None
:
)
->
None
:
"""
Installs the specified MPSD release and toolchains to the specified
"""
directory using Spack.
Install the specified MPSD release and toolchains.
Args:
mpsd_release: A string representing the MPSD release version.
toolchains: A list of strings representing the toolchains to install
(e.g.,
"
foss2021a-mpi
"
,
"
global_generic
"
,
"
ALL
"
).
script_dir: A Path object representing the path to the directory where
the release and toolchains will be installed.
force_reinstall: A boolean indicating whether to force a reinstallation
even if the release and toolchains already exist. Defaults to False.
enable_build_cache: A boolean indicating whether to build the build
cache when installing toolchains. Defaults to False.
Raises:
The function installs the toolchain to the specified directory, using Spack.
ValueError: If a requested toolchain is not available in the specified release.
Returns:
Parameters
None
----------
mpsd_release : str
A string representing the MPSD release version.
toolchains : list of str
A list of strings representing the toolchains to install
(e.g.,
"
foss2021a-mpi
"
,
"
global_generic
"
,
"
ALL
"
).
script_dir : pathlib.Path
A Path object representing the path to the directory where
the release and toolchains will be installed.
force_reinstall : bool, optional
A boolean indicating whether to force a reinstallation
even if the release and toolchains already exist. Defaults to False.
enable_build_cache : bool, optional
A boolean indicating whether to build the build cache
when installing toolchains. Defaults to False.
Raises
------
ValueError
If a requested toolchain is not available in the specified release.
Returns
-------
None
"""
"""
print
(
print
(
f
"
Installing release
{
mpsd_release
}
with toolchains
{
toolchains
}
"
f
"
Installing release
{
mpsd_release
}
with toolchains
{
toolchains
}
"
...
@@ -427,18 +471,21 @@ def install_environment(
...
@@ -427,18 +471,21 @@ def install_environment(
def
remove_environment
(
release
,
toolchains
,
target_dir
):
def
remove_environment
(
release
,
toolchains
,
target_dir
):
"""
Remove release from installation.
"""
msg
=
f
"
Removing release
{
release
}
with toolchains
{
toolchains
}
from
{
target_dir
}
"
msg
=
f
"
Removing release
{
release
}
with toolchains
{
toolchains
}
from
{
target_dir
}
"
print
(
msg
)
print
(
msg
)
raise
NotImplementedError
(
msg
)
raise
NotImplementedError
(
msg
)
def
start_new_environment
(
release
,
from_release
,
target_dir
):
def
start_new_environment
(
release
,
from_release
,
target_dir
):
"""
Start new MPSD software environment version.
"""
msg
=
f
"
Starting new release
{
release
}
from
{
from_release
}
to
{
target_dir
}
"
msg
=
f
"
Starting new release
{
release
}
from
{
from_release
}
to
{
target_dir
}
"
print
(
msg
)
print
(
msg
)
raise
NotImplementedError
(
msg
)
raise
NotImplementedError
(
msg
)
def
main
():
def
main
():
"""
Execute main entry point.
"""
parser
=
argparse
.
ArgumentParser
(
description
=
about_tool
)
parser
=
argparse
.
ArgumentParser
(
description
=
about_tool
)
subparsers
=
parser
.
add_subparsers
(
subparsers
=
parser
.
add_subparsers
(
dest
=
"
action
"
,
title
=
"
actions
"
,
description
=
"
valid actions
"
,
required
=
True
dest
=
"
action
"
,
title
=
"
actions
"
,
description
=
"
valid actions
"
,
required
=
True
...
...
This diff is collapsed.
Click to expand it.
tests.py
+
24
−
11
View file @
9fff963f
"""
Tests for mpsd-software-environment.py.
"""
import
importlib
import
importlib
import
os
import
os
import
shutil
import
shutil
...
@@ -45,6 +47,7 @@ def create_mock_git_repository(target_directory, create_directory=True):
...
@@ -45,6 +47,7 @@ def create_mock_git_repository(target_directory, create_directory=True):
def
test_os_chdir
(
tmp_path
):
def
test_os_chdir
(
tmp_path
):
"""
Test the os_chdir context manager.
"""
# create a temporary directory for testing
# create a temporary directory for testing
temp_dir
=
tmp_path
/
"
test_os_chdir
"
temp_dir
=
tmp_path
/
"
test_os_chdir
"
temp_dir
.
mkdir
()
temp_dir
.
mkdir
()
...
@@ -61,11 +64,13 @@ def test_os_chdir(tmp_path):
...
@@ -61,11 +64,13 @@ def test_os_chdir(tmp_path):
def
test_prepare_environment
(
tmp_path
):
def
test_prepare_environment
(
tmp_path
):
# simulate running ./install-software-environment.py --release dev-23a \
"""
Simulate running preparation of environment.
# --target-directory /tmp/test_prepare_env
# prepare_env is run when cmd is not specified, we can test cmd='prepare'
Simulate running ./install-software-environment.py --release dev-23a
\
# and cmd=None to check both cases
--target-directory /tmp/test_prepare_env
prepare_env is run when cmd is not specified, we can test cmd=
'
prepare
'
and cmd=None to check both cases
"""
script_dir
=
tmp_path
/
"
mpsd_opt
"
/
"
linux_debian_11
"
script_dir
=
tmp_path
/
"
mpsd_opt
"
/
"
linux_debian_11
"
spack_environments
=
"
spack-environments
"
spack_environments
=
"
spack-environments
"
mpsd_release_to_test
=
"
dev-23a
"
mpsd_release_to_test
=
"
dev-23a
"
...
@@ -114,7 +119,10 @@ def test_prepare_environment(tmp_path):
...
@@ -114,7 +119,10 @@ def test_prepare_environment(tmp_path):
def
test_setup_log_cmd
(
tmp_path
):
def
test_setup_log_cmd
(
tmp_path
):
# check that logs/install-software-environment.log is updated when the module is run
"""
Check that log is updated.
Check that logs/install-software-environment.log is updated when the module is run
"""
log_file
=
"
install.log
"
log_file
=
"
install.log
"
script_dir
=
tmp_path
/
"
test_prepare_env
"
script_dir
=
tmp_path
/
"
test_prepare_env
"
...
@@ -140,11 +148,13 @@ def test_setup_log_cmd(tmp_path):
...
@@ -140,11 +148,13 @@ def test_setup_log_cmd(tmp_path):
def
test_install_environment_wrong_toolchain
(
tmp_path
):
def
test_install_environment_wrong_toolchain
(
tmp_path
):
"""
Test exception is raised for non-existing toolchain.
"""
"""
Test exception is raised for non-existing toolchain.
# This is a long test, its handy to test this with print statements printed to
# stdout, use:
This is a long test, its handy to test this with print statements printed to
# pytest -s
stdout, use:
# Expect an Exception when wrong toolchains are provided
pytest -s
Expect an Exception when wrong toolchains are provided
"""
with
pytest
.
raises
(
Exception
):
with
pytest
.
raises
(
Exception
):
mod
.
install_environment
(
mod
.
install_environment
(
mpsd_release
=
"
dev-23a
"
,
mpsd_release
=
"
dev-23a
"
,
...
@@ -210,6 +220,8 @@ def test_install_environment_zlib(tmp_path):
...
@@ -210,6 +220,8 @@ def test_install_environment_zlib(tmp_path):
.
stdout
.
decode
(
"
utf-8
"
)
.
stdout
.
decode
(
"
utf-8
"
)
.
strip
()
.
strip
()
)
)
assert
len
(
gcc_ver
)
>
3
,
f
"
Couldn
'
t find gcc
{
gcc_ver
=
}
"
setup_file
=
release_base_dir
/
"
spack-environments/spack_setup.sh
"
setup_file
=
release_base_dir
/
"
spack-environments/spack_setup.sh
"
with
open
(
setup_file
,
"
r
"
)
as
f
:
with
open
(
setup_file
,
"
r
"
)
as
f
:
lines
=
f
.
read
().
replace
(
lines
=
f
.
read
().
replace
(
...
@@ -266,6 +278,7 @@ def test_install_environment_zlib(tmp_path):
...
@@ -266,6 +278,7 @@ def test_install_environment_zlib(tmp_path):
def
test_interface
(
tmp_path
):
def
test_interface
(
tmp_path
):
"""
Test other things (not implemented yet).
"""
pass
pass
# ensure that installing without toolchains only passes the available toolchains
# ensure that installing without toolchains only passes the available toolchains
# check that the script branch and hash are correct when running the script
# check that the script branch and hash are correct when running the script
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment