Skip to content

Commit b262768

Browse files
kurmanfacebook-github-bot
authored andcommitted
(Testing) Test Helper to test components with a runner. (#511)
Summary: Pull Request resolved: #511 Exposing test helper method for covering component behavior using Runner and scheduler that is has a parity of running cli. More details: #370 Reviewed By: d4l3k Differential Revision: D36948958 fbshipit-source-id: 03f4853aab5e66f1e38727b715f44aae0fa2d8c0
1 parent 44f0633 commit b262768

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

torchx/components/component_test_base.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,32 @@
1515
"""
1616

1717
import os
18+
import shutil
19+
import tempfile
20+
import time
1821
import unittest
1922
from types import ModuleType
23+
from typing import Any, Callable, Dict, Optional
24+
25+
from torchx.runner import get_runner
26+
27+
from torchx.specs import AppDef, AppStatus
2028

2129
from torchx.specs.builders import _create_args_parser
2230
from torchx.specs.finder import get_component
2331

2432

2533
class ComponentTestCase(unittest.TestCase):
34+
def setUp(self) -> None:
35+
self.test_dir = tempfile.mkdtemp("torchx_component_test")
36+
37+
self.old_cwd = os.getcwd()
38+
os.chdir(os.path.dirname(os.path.dirname(__file__)))
39+
40+
def tearDown(self) -> None:
41+
shutil.rmtree(self.test_dir)
42+
os.chdir(self.old_cwd)
43+
2644
"""
2745
ComponentTestCase is an extension of TestCase with helper methods for use
2846
with testing component definitions.
@@ -58,3 +76,43 @@ def validate(self, module: ModuleType, function_name: str) -> None:
5876
# this will raise an exception and the test will fail
5977
with self.assertRaises(SystemExit):
6078
_ = _create_args_parser(component_def.fn).parse_args(["--help"])
79+
80+
def run_component(
81+
self,
82+
component: Callable[..., AppDef],
83+
args: Optional[Dict[str, Any]] = None,
84+
scheduler_params: Optional[Dict[str, Any]] = None,
85+
scheduler: str = "local_cwd",
86+
interval: float = 0.1,
87+
timeout: float = 1,
88+
) -> Optional[AppStatus]:
89+
"""
90+
Helper function that hides complexity of setting up the runner and polling results.
91+
Note: method is blocking until either scheduler exits or timeout is reached (for non-blocking schedulers).
92+
93+
Args:
94+
components: component function, factory for AppDef
95+
args: optional component factory arguments
96+
scheduler_params: optional parameters for scheduler factory method
97+
scheduler: scheduler name
98+
interval: scheduler comppletion polling interval
99+
timeout: max time for scheduler to complete
100+
101+
"""
102+
103+
app_def = component(**args)
104+
if scheduler_params:
105+
runner = get_runner(name=None, component_defaults=None, **scheduler_params)
106+
else:
107+
runner = get_runner(name=None, component_defaults=None)
108+
109+
app_handle = runner.run(app_def, scheduler)
110+
111+
elapsed = 0
112+
status = runner.status(app_handle)
113+
while (status and not status.is_terminal) or elapsed < timeout:
114+
time.sleep(interval)
115+
elapsed += interval
116+
status = runner.status(app_handle)
117+
118+
return status

torchx/components/test/utils_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import torchx.components.utils as utils
88
from torchx.components.component_test_base import ComponentTestCase
9+
from torchx.specs import AppState
910

1011

1112
class UtilsComponentTest(ComponentTestCase):
@@ -29,3 +30,18 @@ def test_copy(self) -> None:
2930

3031
def test_booth(self) -> None:
3132
self.validate(utils, "booth")
33+
34+
def test_run_sh(self) -> None:
35+
result = self.run_component(
36+
utils.echo, {"msg": "from test"}, scheduler_params={"cache_size": 1}
37+
)
38+
self.assertIsNotNone(result)
39+
self.assertEqual(result.state, AppState.SUCCEEDED)
40+
41+
def test_run_sh_scheduler_factory_failure(self) -> None:
42+
self.assertRaises(
43+
ValueError,
44+
lambda: self.run_component(
45+
utils.echo, {"msg": "from test"}, scheduler_params={"cache_size": -1}
46+
),
47+
)

0 commit comments

Comments
 (0)