Skip to content

Commit d27a37d

Browse files
committed
fix comments
1 parent b2d9cd6 commit d27a37d

File tree

4 files changed

+113
-86
lines changed

4 files changed

+113
-86
lines changed

reframe/core/containerplatform.py renamed to reframe/core/containers.py

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import reframe.core.fields as fields
44
import reframe.utility.typecheck as typ
5-
from reframe.core.exceptions import ContainerPlatformError
5+
from reframe.core.exceptions import ContainerError
66

77

88
class ContainerPlatform:
@@ -15,72 +15,83 @@ class ContainerPlatform:
1515
registry = fields.TypedField('registry', str, type(None))
1616
image = fields.TypedField('image', str, type(None))
1717
requires_mpi = fields.TypedField('requires_mpi', bool)
18-
commands = fields.TypedField('commands', typ.List[str], type(None))
18+
commands = fields.TypedField('commands', typ.List[str])
1919
mount_points = fields.TypedField('mount_points',
20-
typ.List[typ.Tuple[str, str]], type(None))
20+
typ.List[typ.Tuple[str, str]])
21+
workdir = fields.TypedField('workdir', str, type(None))
2122

2223
def __init__(self):
2324
self.registry = None
2425
self.image = None
2526
self.requires_mpi = False
26-
self.commands = None
27+
self.commands = []
2728
self.mount_points = []
29+
self.workdir = None
2830

2931
@abc.abstractmethod
3032
def emit_prepare_cmds(self):
31-
"""xxx."""
33+
"""Returns commands that are necessary before running with this
34+
container platform.
35+
36+
:raises: `ContainerError` in case of errors.
37+
38+
.. note:
39+
This method is relevant only to developers of new container
40+
platforms.
41+
"""
3242

3343
@abc.abstractmethod
3444
def emit_launch_cmds(self):
3545
"""Returns the command for running with this container platform.
3646
37-
:raises: `ContainerPlatformError` in case of missing mandatory
38-
fields.
47+
:raises: `ContainerError` in case of errors.
48+
49+
.. note:
50+
This method is relevant only to developers of new container
51+
platforms.
52+
"""
53+
if self.registry:
54+
self.image = '/'.join([self.registry, self.image])
55+
56+
@abc.abstractmethod
57+
def validate(self):
58+
"""Validates this container platform.
59+
60+
:raises: `ContainerError` in case of errors.
3961
4062
.. note:
4163
This method is relevant only to developers of new container
42-
plataforms.
64+
platforms.
4365
"""
66+
if self.image is None:
67+
raise ContainerError('no image specified.')
68+
69+
if not self.commands:
70+
raise ContainerError('no command specified')
4471

4572

4673
class Docker(ContainerPlatform):
47-
"""An implementation of the container platform to run containers with
74+
"""An implementation of ContainerPlatform to run containers with
4875
Docker.
4976
"""
50-
# def __init__(self):
51-
# super().__init__()
52-
5377
def emit_prepare_cmds(self):
5478
pass
5579

5680
def emit_launch_commands(self):
81+
super().emit_launch_cmds()
5782
docker_opts = []
58-
59-
if self.image is None:
60-
raise ContainerPlatformError('Please, specify the name of'
61-
'the image')
62-
63-
if self.commands is None:
64-
raise ContainerPlatformError('Please, specify a command')
65-
66-
if self.registry:
67-
self.image = '%s/%s' % (self.registry, self.image)
68-
69-
self.mount_points.append(('$PWD', '/stagedir'))
70-
for mp in self.mount_points:
71-
docker_opts.append('-v %s:%s' % mp)
72-
73-
cmd_base = "docker run %s %s bash -c 'cd /stagedir; %s'"
74-
75-
return [cmd_base % (' '.join(docker_opts), self.image,
76-
'; '.join(self.commands))]
83+
docker_opts = ['-v "%s":"%s"' % mp for mp in self.mount_points]
84+
run_cmd = 'docker run %s %s bash -c ' % (' '.join(docker_opts),
85+
self.image)
86+
return run_cmd + "'" + '; '.join(
87+
['cd ' + self.workdir] + self.commands) + "'"
7788

7889

7990
class ContainerPlatformField(fields.TypedField):
80-
"""A field representing a build system.
91+
"""A field representing a container platforms.
8192
8293
You may either assign an instance of :class:`ContainerPlatform:` or a
83-
string representing the name of the concrete class of a build system.
94+
string representing the name of the concrete class of a container platform.
8495
"""
8596

8697
def __init__(self, fieldname, *other_types):

reframe/core/exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class BuildSystemError(ReframeError):
108108
"""Raised when a build system is not configured properly."""
109109

110110

111-
class ContainerPlatformError(ReframeError):
111+
class ContainerError(ReframeError):
112112
"""Raised when a container platform is not configured properly."""
113113

114114

unittests/test_containerplatform.py

Lines changed: 0 additions & 52 deletions
This file was deleted.

unittests/test_containers.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import abc
2+
import unittest
3+
4+
import pytest
5+
import reframe.core.containers as containers
6+
from reframe.core.exceptions import ContainerError
7+
8+
9+
class _ContainerPlatformTest:
10+
@abc.abstractmethod
11+
def create_container_platform(self):
12+
pass
13+
14+
@property
15+
@abc.abstractmethod
16+
def exp_cmd_mount_points(self):
17+
pass
18+
19+
@property
20+
@abc.abstractmethod
21+
def exp_cmd_custom_registry(self):
22+
pass
23+
24+
def setUp(self):
25+
self.container_platform = self.create_container_platform()
26+
27+
def test_mount_points(self):
28+
self.container_platform.image = 'name:tag'
29+
self.container_platform.mount_points = [('/path/one', '/one'),
30+
('/path/two', '/two')]
31+
self.container_platform.commands = ['cmd1', 'cmd2']
32+
self.container_platform.workdir = '/stagedir'
33+
self.assertEqual(self.exp_cmd_mount_points,
34+
self.container_platform.emit_launch_commands())
35+
36+
def test_missing_image(self):
37+
self.container_platform.commands = ['cmd']
38+
with pytest.raises(ContainerError):
39+
self.container_platform.validate()
40+
41+
def test_missing_commands(self):
42+
self.container_platform.image = 'name:tag'
43+
with pytest.raises(ContainerError):
44+
self.container_platform.validate()
45+
46+
def test_custom_registry(self):
47+
self.container_platform.registry = 'registry/custom'
48+
self.container_platform.image = 'name:tag'
49+
self.container_platform.commands = ['cmd']
50+
self.container_platform.mount_points = [('/path/one', '/one')]
51+
self.container_platform.workdir = '/stagedir'
52+
self.assertEqual(self.exp_cmd_custom_registry,
53+
self.container_platform.emit_launch_commands())
54+
55+
56+
class TestDocker(_ContainerPlatformTest, unittest.TestCase):
57+
def create_container_platform(self):
58+
return containers.Docker()
59+
60+
@property
61+
def exp_cmd_mount_points(self):
62+
return ('docker run -v "/path/one":"/one" -v "/path/two":"/two" '
63+
"name:tag bash -c 'cd /stagedir; cmd1; cmd2'")
64+
65+
@property
66+
def exp_cmd_custom_registry(self):
67+
return ('docker run -v "/path/one":"/one" registry/custom/name:tag '
68+
"bash -c 'cd /stagedir; cmd'")

0 commit comments

Comments
 (0)